From 3e15173b17ef4b7c99963fbc818344ff9878884f Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sun, 4 Apr 2021 17:51:31 +0200
Subject: [PATCH 001/166] MultiAsset TWO

---
 xcm/src/v0/mod.rs        |   2 +
 xcm/src/v0/multiasset.rs | 128 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 130 insertions(+)
 create mode 100644 xcm/src/v0/multiasset.rs

diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index c69093d4f851..7fef83987d94 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -27,6 +27,8 @@ mod multi_asset;
 mod multi_location;
 mod order;
 mod traits;
+pub mod multiasset;	// the new multiasset.
+
 pub use junction::{Junction, NetworkId};
 pub use multi_asset::{MultiAsset, AssetInstance};
 pub use multi_location::MultiLocation;
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
new file mode 100644
index 000000000000..8e1839719f09
--- /dev/null
+++ b/xcm/src/v0/multiasset.rs
@@ -0,0 +1,128 @@
+// Copyright 2020 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Cross-Consensus Message format asset data structure.
+
+use alloc::vec::Vec;
+use parity_scale_codec::{self as codec, Encode, Decode};
+use super::{MultiLocation, multi_asset::{AssetInstance, MultiAsset as OldMultiAsset}};
+
+/// Classification of an asset being concrete or abstract.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+pub enum AssetId {
+	Concrete(MultiLocation),
+	Abstract(Vec<u8>),
+}
+
+impl AssetId {
+	/// Prepend a MultiLocation to a concrete asset, giving it a new root location.
+	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
+		if let AssetId::Concrete(ref mut l) = self {
+			l.prepend_with(prepend.clone()).map_err(|_| ())?;
+		}
+		Ok(())
+	}
+}
+
+/// Classification of whether an asset is fungible or not, along with an optional amount or instance.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+pub enum Fungibility {
+	Fungible(Option<u128>),
+	NonFungible(Option<AssetInstance>),
+}
+
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+pub enum MultiAsset {
+	None,
+	Asset(Fungibility, Option<AssetId>),
+	All,
+}
+
+impl From<(AssetId, Fungibility)> for MultiAsset {
+	fn from((asset_id, fungibility): (AssetId, Fungibility)) -> MultiAsset {
+		MultiAsset::Asset(fungibility, Some(asset_id))
+	}
+}
+
+impl From<Fungibility> for MultiAsset {
+	fn from(fungibility: Fungibility) -> MultiAsset {
+		MultiAsset::Asset(fungibility, None)
+	}
+}
+
+impl From<()> for MultiAsset {
+	fn from(_: ()) -> MultiAsset {
+		MultiAsset::None
+	}
+}
+
+impl Encode for MultiAsset {
+	fn encode(&self) -> Vec<u8> {
+		OldMultiAsset::from(self.clone()).encode()
+	}
+}
+
+impl Decode for MultiAsset {
+	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
+		OldMultiAsset::decode(input).map(Into::into)
+	}
+}
+
+impl From<MultiAsset> for OldMultiAsset {
+	fn from(a: MultiAsset) -> Self {
+		use {AssetId::*, Fungibility::*, OldMultiAsset::*, MultiAsset::Asset};
+		match a {
+			MultiAsset::None => OldMultiAsset::None,
+			MultiAsset::All => All,
+
+			Asset(Fungible(_), Option::None) => AllFungible,
+			Asset(NonFungible(_), Option::None) => AllNonFungible,
+
+			Asset(Fungible(Option::None), Some(Concrete(id))) => AllConcreteFungible { id },
+			Asset(Fungible(Option::None), Some(Abstract(id))) => AllAbstractFungible { id },
+			Asset(NonFungible(Option::None), Some(Concrete(class))) => AllConcreteNonFungible { class },
+			Asset(NonFungible(Option::None), Some(Abstract(class))) => AllAbstractNonFungible { class },
+
+			Asset(Fungible(Some(amount)), Some(Concrete(id))) => ConcreteFungible { id, amount },
+			Asset(Fungible(Some(amount)), Some(Abstract(id))) => AbstractFungible { id, amount },
+			Asset(NonFungible(Some(instance)), Some(Concrete(class))) => ConcreteNonFungible { class, instance },
+			Asset(NonFungible(Some(instance)), Some(Abstract(class))) => AbstractNonFungible { class, instance },
+		}
+	}
+}
+
+impl From<OldMultiAsset> for MultiAsset {
+	fn from(a: OldMultiAsset) -> Self {
+		use {AssetId::*, Fungibility::*, OldMultiAsset::*, MultiAsset::Asset};
+		match a {
+			None => MultiAsset::None,
+			All => MultiAsset::All,
+
+			AllFungible => Asset(Fungible(Option::None), Option::None),
+			AllNonFungible => Asset(NonFungible(Option::None), Option::None),
+
+			AllConcreteFungible { id } => Asset(Fungible(Option::None), Some(Concrete(id))),
+			AllAbstractFungible { id } => Asset(Fungible(Option::None), Some(Abstract(id))),
+			AllConcreteNonFungible { class } => Asset(NonFungible(Option::None), Some(Concrete(class))),
+			AllAbstractNonFungible { class } => Asset(NonFungible(Option::None), Some(Abstract(class))),
+
+			ConcreteFungible { id, amount } => Asset(Fungible(Some(amount)), Some(Concrete(id))),
+			AbstractFungible { id, amount } => Asset(Fungible(Some(amount)), Some(Abstract(id))),
+			ConcreteNonFungible { class, instance } => Asset(NonFungible(Some(instance)), Some(Concrete(class))),
+			AbstractNonFungible { class, instance } => Asset(NonFungible(Some(instance)), Some(Abstract(class))),
+		}
+	}
+}

From a7c51a89b3bb89e5643f74185b15970553472077 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 3 Jul 2021 21:34:36 -0700
Subject: [PATCH 002/166] Ensure MultiLocation always has a canonical
 representation

---
 xcm/src/lib.rs               |  11 +
 xcm/src/v0/mod.rs            |   1 +
 xcm/src/v0/multi_asset.rs    |   1 +
 xcm/src/v0/multi_location.rs |   1 +
 xcm/src/v1/junction.rs       | 133 ++++++
 xcm/src/v1/mod.rs            | 317 +++++++++++++
 xcm/src/v1/multi_asset.rs    | 380 +++++++++++++++
 xcm/src/v1/multi_location.rs | 867 +++++++++++++++++++++++++++++++++++
 xcm/src/v1/order.rs          | 140 ++++++
 xcm/src/v1/traits.rs         | 246 ++++++++++
 10 files changed, 2097 insertions(+)
 create mode 100644 xcm/src/v1/junction.rs
 create mode 100644 xcm/src/v1/mod.rs
 create mode 100644 xcm/src/v1/multi_asset.rs
 create mode 100644 xcm/src/v1/multi_location.rs
 create mode 100644 xcm/src/v1/order.rs
 create mode 100644 xcm/src/v1/traits.rs

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index 9768be8dacaa..35a53b2ac1dd 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -27,6 +27,7 @@ use parity_scale_codec::{Encode, Decode};
 use derivative::Derivative;
 
 pub mod v0;
+pub mod v1;
 
 mod double_encoded;
 pub use double_encoded::DoubleEncoded;
@@ -38,6 +39,7 @@ pub use double_encoded::DoubleEncoded;
 #[codec(decode_bound())]
 pub enum VersionedXcm<Call> {
 	V0(v0::Xcm<Call>),
+	V1(v1::Xcm<Call>),
 }
 
 pub mod opaque {
@@ -48,6 +50,13 @@ pub mod opaque {
 		pub use crate::v0::opaque::{Xcm, Order};
 	}
 
+	pub mod v1 {
+		// Everything from v1
+		pub use crate::v1::*;
+		// Then override with the opaque types in v1
+		pub use crate::v1::opaque::{Xcm, Order};
+	}
+
 	/// The basic VersionedXcm type which just uses the `Vec<u8>` as an encoded call.
 	pub type VersionedXcm = super::VersionedXcm<()>;
 }
@@ -56,10 +65,12 @@ pub mod opaque {
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum VersionedMultiLocation {
 	V0(v0::MultiLocation),
+	V1(v1::MultiLocation),
 }
 
 /// A versioned multi-asset, an identifier for an asset within a consensus system.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum VersionedMultiAsset {
 	V0(v0::MultiAsset),
+	V1(v1::MultiAsset),
 }
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 368353f2d82a..6dfe54c79322 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -272,6 +272,7 @@ impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
 	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
 		match x {
 			VersionedXcm::V0(x) => Ok(x),
+			_ => Err(()),
 		}
 	}
 }
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
index 20032e7169a4..2d65d2912088 100644
--- a/xcm/src/v0/multi_asset.rs
+++ b/xcm/src/v0/multi_asset.rs
@@ -317,6 +317,7 @@ impl TryFrom<VersionedMultiAsset> for MultiAsset {
 	fn try_from(x: VersionedMultiAsset) -> result::Result<Self, ()> {
 		match x {
 			VersionedMultiAsset::V0(x) => Ok(x),
+			_ => Err(()),
 		}
 	}
 }
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 17df340eca07..851ef90cf226 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -636,6 +636,7 @@ impl TryFrom<VersionedMultiLocation> for MultiLocation {
 	fn try_from(x: VersionedMultiLocation) -> result::Result<Self, ()> {
 		match x {
 			VersionedMultiLocation::V0(x) => Ok(x),
+			_ => Err(()),
 		}
 	}
 }
diff --git a/xcm/src/v1/junction.rs b/xcm/src/v1/junction.rs
new file mode 100644
index 000000000000..5375f286d44d
--- /dev/null
+++ b/xcm/src/v1/junction.rs
@@ -0,0 +1,133 @@
+// Copyright 2021 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Support datastructures for `MultiLocation`, primarily the `Junction` datatype.
+
+use alloc::vec::Vec;
+use parity_scale_codec::{self, Encode, Decode};
+
+/// A global identifier of an account-bearing consensus system.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum NetworkId {
+	/// Unidentified/any.
+	Any,
+	/// Some named network.
+	Named(Vec<u8>),
+	/// The Polkadot Relay chain
+	Polkadot,
+	/// Kusama.
+	Kusama,
+}
+
+/// An identifier of a pluralistic body.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum BodyId {
+	/// The only body in its context.
+	Unit,
+	/// A named body.
+	Named(Vec<u8>),
+	/// An indexed body.
+	// TODO: parity-scale-codec#262: Change to be a tuple.
+	Index { #[codec(compact)] id: u32 },
+	/// The unambiguous executive body (for Polkadot, this would be the Polkadot council).
+	Executive,
+	/// The unambiguous technical body (for Polkadot, this would be the Technical Committee).
+	Technical,
+	/// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a majority of
+	/// lock-voters).
+	Legislative,
+	/// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a "grand oracle", it
+	/// may be considered as that).
+	Judicial,
+}
+
+/// A part of a pluralistic body.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum BodyPart {
+	/// The body's declaration, under whatever means it decides.
+	Voice,
+	/// A given number of members of the body.
+	Members { #[codec(compact)] count: u32 },
+	/// A given number of members of the body, out of some larger caucus.
+	Fraction { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 },
+	/// No less than the given proportion of members of the body.
+	AtLeastProportion { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 },
+	/// More than than the given proportion of members of the body.
+	MoreThanProportion { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 },
+}
+
+impl BodyPart {
+	/// Returns `true` if the part represents a strict majority (> 50%) of the body in question.
+	pub fn is_majority(&self) -> bool {
+		match self {
+			BodyPart::Fraction { nom, denom } if *nom * 2 > *denom => true,
+			BodyPart::AtLeastProportion { nom, denom } if *nom * 2 > *denom => true,
+			BodyPart::MoreThanProportion { nom, denom } if *nom * 2 >= *denom => true,
+			_ => false,
+		}
+	}
+}
+
+/// A single item in a path to describe the relative location of a consensus system.
+///
+/// Each item assumes a pre-existing location as its context and is defined in terms of it.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum Junction {
+	/// An indexed parachain belonging to and operated by the context.
+	///
+	/// Generally used when the context is a Polkadot Relay-chain.
+	Parachain(#[codec(compact)] u32),
+	/// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
+	/// the context.
+	///
+	/// Generally used when the context is a Substrate-based chain.
+	AccountId32 { network: NetworkId, id: [u8; 32] },
+	/// An 8-byte index for an account of a specific network that is respected as a sovereign endpoint within
+	/// the context.
+	///
+	/// May be used when the context is a Frame-based chain and includes e.g. an indices pallet.
+	AccountIndex64 { network: NetworkId, #[codec(compact)] index: u64 },
+	/// A 20-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
+	/// the context.
+	///
+	/// May be used when the context is an Ethereum or Bitcoin chain or smart-contract.
+	AccountKey20 { network: NetworkId, key: [u8; 20] },
+	/// An instanced, indexed pallet that forms a constituent part of the context.
+	///
+	/// Generally used when the context is a Frame-based chain.
+	PalletInstance(u8),
+	/// A non-descript index within the context location.
+	///
+	/// Usage will vary widely owing to its generality.
+	///
+	/// NOTE: Try to avoid using this and instead use a more specific item.
+	GeneralIndex { #[codec(compact)] id: u128 },
+	/// A nondescript datum acting as a key within the context location.
+	///
+	/// Usage will vary widely owing to its generality.
+	///
+	/// NOTE: Try to avoid using this and instead use a more specific item.
+	GeneralKey(Vec<u8>),
+	/// The unambiguous child.
+	///
+	/// Not currently used except as a fallback when deriving ancestry.
+	OnlyChild,
+	/// A pluralistic body existing within consensus.
+	///
+	/// Typical to be used to represent a governance origin of a chain, but could in principle be used to represent
+	/// things such as multisigs also.
+	Plurality { id: BodyId, part: BodyPart },
+}
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
new file mode 100644
index 000000000000..7be850a087c6
--- /dev/null
+++ b/xcm/src/v1/mod.rs
@@ -0,0 +1,317 @@
+// Copyright 2021 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Version 1 of the Cross-Consensus Message format data structures.
+
+use core::{result, convert::TryFrom, fmt::Debug};
+use derivative::Derivative;
+use alloc::vec::Vec;
+use parity_scale_codec::{self, Encode, Decode};
+use crate::{VersionedMultiAsset, DoubleEncoded, VersionedXcm};
+
+mod junction;
+mod multi_asset;
+mod multi_location;
+mod order;
+mod traits;
+pub use junction::{Junction, NetworkId, BodyId, BodyPart};
+pub use multi_asset::{MultiAsset, AssetInstance};
+pub use multi_location::{Junctions, MultiLocation};
+pub use order::Order;
+pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
+
+/// A prelude for importing all types typically used when interacting with XCM messages.
+pub mod prelude {
+	pub use super::junction::{Junction::*, NetworkId, BodyId, BodyPart};
+	pub use super::multi_asset::{MultiAsset::{self, *}, AssetInstance::{self, *}};
+	pub use super::multi_location::{Junctions::{self, *}, MultiLocation};
+	pub use super::order::Order::{self, *};
+	pub use super::traits::{Error as XcmError, Result as XcmResult, SendXcm, ExecuteXcm, Outcome};
+	pub use super::{Xcm::{self, *}, OriginKind};
+}
+
+// TODO: #2841 #XCMENCODE Efficient encodings for Vec<MultiAsset>, Vec<Order>, using initial byte values 128+ to encode
+//   the number of items in the vector.
+
+/// Basically just the XCM (more general) version of `ParachainDispatchOrigin`.
+#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug)]
+pub enum OriginKind {
+	/// Origin should just be the native dispatch origin representation for the sender in the
+	/// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin
+	/// if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a
+	/// primary/native dispatch origin form.
+	Native,
+
+	/// Origin should just be the standard account-based origin with the sovereign account of
+	/// the sender. For Cumulus/Frame chains, this is the `Signed` origin.
+	SovereignAccount,
+
+	/// Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin.
+	/// This will not usually be an available option.
+	Superuser,
+
+	/// Origin should be interpreted as an XCM native origin and the `MultiLocation` should be
+	/// encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be
+	/// the `pallet_xcm::Origin::Xcm` type.
+	Xcm,
+}
+
+/// Response data to a query.
+#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
+pub enum Response {
+	/// Some assets.
+	Assets(Vec<MultiAsset>),
+}
+
+/// Cross-Consensus Message: A message from one consensus system to another.
+///
+/// Consensus systems that may send and receive messages include blockchains and smart contracts.
+///
+/// All messages are delivered from a known *origin*, expressed as a `MultiLocation`.
+///
+/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer
+/// XCM format, known as `VersionedXcm`.
+#[derive(Derivative, Encode, Decode)]
+#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
+#[codec(encode_bound())]
+#[codec(decode_bound())]
+pub enum Xcm<Call> {
+	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into `holding`. Execute the
+	/// orders (`effects`).
+	///
+	/// - `assets`: The asset(s) to be withdrawn into holding.
+	/// - `effects`: The order(s) to execute on the holding account.
+	///
+	/// Kind: *Instruction*.
+	///
+	/// Errors:
+	#[codec(index = 0)]
+	WithdrawAsset { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+
+	/// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` system.
+	///
+	/// Some orders are given (`effects`) which should be executed once the corresponding derivative assets have
+	/// been placed into `holding`.
+	///
+	/// - `assets`: The asset(s) that are minted into holding.
+	/// - `effects`: The order(s) to execute on the holding account.
+	///
+	/// Safety: `origin` must be trusted to have received and be storing `assets` such that they may later be
+	/// withdrawn should this system send a corresponding message.
+	///
+	/// Kind: *Trusted Indication*.
+	///
+	/// Errors:
+	#[codec(index = 1)]
+	ReserveAssetDeposit { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+
+	/// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be
+	/// created on this system.
+	///
+	/// Some orders are given (`effects`) which should be executed once the corresponding derivative assets have
+	/// been placed into `holding`.
+	///
+	/// - `assets`: The asset(s) that are minted into holding.
+	/// - `effects`: The order(s) to execute on the holding account.
+	///
+	/// Safety: `origin` must be trusted to have irrevocably destroyed the `assets` prior as a consequence of
+	/// sending this message.
+	///
+	/// Kind: *Trusted Indication*.
+	///
+	/// Errors:
+	#[codec(index = 2)]
+	TeleportAsset { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+
+	/// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`.
+	///
+	/// - `query_id`: The identifier of the query that resulted in this message being sent.
+	/// - `assets`: The message content.
+	///
+	/// Safety: No concerns.
+	///
+	/// Kind: *Information*.
+	///
+	/// Errors:
+	#[codec(index = 3)]
+	QueryResponse { #[codec(compact)] query_id: u64, response: Response },
+
+	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
+	/// ownership of `dest` within this consensus system.
+	///
+	/// - `assets`: The asset(s) to be withdrawn.
+	/// - `dest`: The new owner for the assets.
+	///
+	/// Safety: No concerns.
+	///
+	/// Kind: *Instruction*.
+	///
+	/// Errors:
+	#[codec(index = 4)]
+	TransferAsset { assets: Vec<MultiAsset>, dest: MultiLocation },
+
+	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
+	/// ownership of `dest` within this consensus system.
+	///
+	/// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`.
+	///
+	/// - `assets`: The asset(s) to be withdrawn.
+	/// - `dest`: The new owner for the assets.
+	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to
+	///   `dest.
+	///
+	/// Safety: No concerns.
+	///
+	/// Kind: *Instruction*.
+	///
+	/// Errors:
+	#[codec(index = 5)]
+	TransferReserveAsset { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+
+	/// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed by the kind
+	/// of origin `origin_type`.
+	///
+	/// - `origin_type`: The means of expressing the message origin as a dispatch origin.
+	/// - `max_weight`: The weight of `call`; this should be at least the chain's calculated weight and will
+	///   be used in the weight determination arithmetic.
+	/// - `call`: The encoded transaction to be applied.
+	///
+	/// Safety: No concerns.
+	///
+	/// Kind: *Instruction*.
+	///
+	/// Errors:
+	#[codec(index = 6)]
+	Transact { origin_type: OriginKind, require_weight_at_most: u64, call: DoubleEncoded<Call> },
+
+	/// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the
+	/// relay-chain to a para.
+	///
+	/// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel opening.
+	/// - `max_message_size`: The maximum size of a message proposed by the sender.
+	/// - `max_capacity`: The maximum number of messages that can be queued in the channel.
+	///
+	/// Safety: The message should originate directly from the relay-chain.
+	///
+	/// Kind: *System Notification*
+	#[codec(index = 7)]
+	HrmpNewChannelOpenRequest {
+		#[codec(compact)] sender: u32,
+		#[codec(compact)] max_message_size: u32,
+		#[codec(compact)] max_capacity: u32,
+	},
+
+	/// A message to notify about that a previously sent open channel request has been accepted by
+	/// the recipient. That means that the channel will be opened during the next relay-chain session
+	/// change. This message is meant to be sent by the relay-chain to a para.
+	///
+	/// Safety: The message should originate directly from the relay-chain.
+	///
+	/// Kind: *System Notification*
+	///
+	/// Errors:
+	#[codec(index = 8)]
+	HrmpChannelAccepted {
+		#[codec(compact)] recipient: u32,
+	},
+
+	/// A message to notify that the other party in an open channel decided to close it. In particular,
+	/// `initiator` is going to close the channel opened from `sender` to the `recipient`. The close
+	/// will be enacted at the next relay-chain session change. This message is meant to be sent by
+	/// the relay-chain to a para.
+	///
+	/// Safety: The message should originate directly from the relay-chain.
+	///
+	/// Kind: *System Notification*
+	///
+	/// Errors:
+	#[codec(index = 9)]
+	HrmpChannelClosing {
+		#[codec(compact)] initiator: u32,
+		#[codec(compact)] sender: u32,
+		#[codec(compact)] recipient: u32,
+	},
+
+	/// A message to indicate that the embedded XCM is actually arriving on behalf of some consensus
+	/// location within the origin.
+	///
+	/// Safety: `who` must be an interior location of the context. This basically means that no `Parent`
+	/// junctions are allowed in it. This should be verified at the time of XCM execution.
+	///
+	/// Kind: *Instruction*
+	///
+	/// Errors:
+	#[codec(index = 10)]
+	RelayedFrom {
+		who: MultiLocation,
+		message: alloc::boxed::Box<Xcm<Call>>,
+	},
+}
+
+impl<Call> From<Xcm<Call>> for VersionedXcm<Call> {
+	fn from(x: Xcm<Call>) -> Self {
+		VersionedXcm::V1(x)
+	}
+}
+
+impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
+	type Error = ();
+	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
+		match x {
+			VersionedXcm::V1(x) => Ok(x),
+			_ => Err(()),
+		}
+	}
+}
+
+impl<Call> Xcm<Call> {
+	pub fn into<C>(self) -> Xcm<C> { Xcm::from(self) }
+	pub fn from<C>(xcm: Xcm<C>) -> Self {
+		use Xcm::*;
+		match xcm {
+			WithdrawAsset { assets, effects }
+			=> WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
+			ReserveAssetDeposit { assets, effects }
+			=> ReserveAssetDeposit { assets, effects: effects.into_iter().map(Order::into).collect() },
+			TeleportAsset { assets, effects }
+			=> TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
+			QueryResponse { query_id: u64, response }
+			=> QueryResponse { query_id: u64, response },
+			TransferAsset { assets, dest }
+			=> TransferAsset { assets, dest },
+			TransferReserveAsset { assets, dest, effects }
+			=> TransferReserveAsset { assets, dest, effects },
+			HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity}
+			=> HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity},
+			HrmpChannelAccepted { recipient}
+			=> HrmpChannelAccepted { recipient},
+			HrmpChannelClosing { initiator, sender, recipient}
+			=> HrmpChannelClosing { initiator, sender, recipient},
+			Transact { origin_type, require_weight_at_most, call}
+			=> Transact { origin_type, require_weight_at_most, call: call.into() },
+			RelayedFrom { who, message }
+			=> RelayedFrom { who, message: alloc::boxed::Box::new((*message).into()) },
+		}
+	}
+}
+
+pub mod opaque {
+	/// The basic concrete type of `generic::Xcm`, which doesn't make any assumptions about the format of a
+	/// call other than it is pre-encoded.
+	pub type Xcm = super::Xcm<()>;
+
+	pub use super::order::opaque::*;
+}
diff --git a/xcm/src/v1/multi_asset.rs b/xcm/src/v1/multi_asset.rs
new file mode 100644
index 000000000000..552e67f03d8e
--- /dev/null
+++ b/xcm/src/v1/multi_asset.rs
@@ -0,0 +1,380 @@
+// Copyright 2021 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Cross-Consensus Message format data structures.
+
+use core::{result, convert::TryFrom};
+use alloc::vec::Vec;
+
+use parity_scale_codec::{self, Encode, Decode};
+use super::{MultiLocation, VersionedMultiAsset};
+
+/// A general identifier for an instance of a non-fungible asset class.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum AssetInstance {
+	/// Undefined - used if the NFA class has only one instance.
+	Undefined,
+
+	/// A compact index. Technically this could be greater than u128, but this implementation supports only
+	/// values up to `2**128 - 1`.
+	Index { #[codec(compact)] id: u128 },
+
+	/// A 4-byte fixed-length datum.
+	Array4([u8; 4]),
+
+	/// An 8-byte fixed-length datum.
+	Array8([u8; 8]),
+
+	/// A 16-byte fixed-length datum.
+	Array16([u8; 16]),
+
+	/// A 32-byte fixed-length datum.
+	Array32([u8; 32]),
+
+	/// An arbitrary piece of data. Use only when necessary.
+	Blob(Vec<u8>),
+}
+
+/// A single general identifier for an asset.
+///
+/// Represents both fungible and non-fungible assets. May only be used to represent a single asset class.
+///
+/// Wildcards may or may not be allowed by the interpreting context.
+///
+/// Assets classes may be identified in one of two ways: either an abstract identifier or a concrete identifier.
+/// Implementations may support only one of these. A single asset may be referenced from multiple asset identifiers,
+/// though will tend to have only a single *preferred* identifier.
+///
+/// ### Abstract identifiers
+///
+/// Abstract identifiers are absolute identifiers that represent a notional asset which can exist within multiple
+/// consensus systems. These tend to be simpler to deal with since their broad meaning is unchanged regardless stay of
+/// the consensus system in which it is interpreted.
+///
+/// However, in the attempt to provide uniformity across consensus systems, they may conflate different instantiations
+/// of some notional asset (e.g. the reserve asset and a local reserve-backed derivative of it) under the same name,
+/// leading to confusion. It also implies that one notional asset is accounted for locally in only one way. This may not
+/// be the case, e.g. where there are multiple bridge instances each providing a bridged "BTC" token yet none being
+/// fungible between the others.
+///
+/// Since they are meant to be absolute and universal, a global registry is needed to ensure that name collisions do not
+/// occur.
+///
+/// An abstract identifier is represented as a simple variable-size byte string. As of writing, no global registry
+/// exists and no proposals have been put forth for asset labeling.
+///
+/// ### Concrete identifiers
+///
+/// Concrete identifiers are *relative identifiers* that specifically identify a single asset through its location in a
+/// consensus system relative to the context interpreting. Use of a `MultiLocation` ensures that similar but non
+/// fungible variants of the same underlying asset can be properly distinguished, and obviates the need for any kind of
+/// central registry.
+///
+/// The limitation is that the asset identifier cannot be trivially copied between consensus systems and must instead be
+/// "re-anchored" whenever being moved to a new consensus system, using the two systems' relative paths.
+///
+/// Throughout XCM, messages are authored such that *when interpreted from the receiver's point of view* they will have
+/// the desired meaning/effect. This means that relative paths should always by constructed to be read from the point of
+/// view of the receiving system, *which may be have a completely different meaning in the authoring system*.
+///
+/// Concrete identifiers are the preferred way of identifying an asset since they are entirely unambiguous.
+///
+/// A concrete identifier is represented by a `MultiLocation`. If a system has an unambiguous primary asset (such as
+/// Bitcoin with BTC or Ethereum with ETH), then it will conventionally be identified as the chain itself. Alternative
+/// and more specific ways of referring to an asset within a system include:
+///
+/// - `<chain>/PalletInstance(<id>)` for a Frame chain with a single-asset pallet instance (such as an instance of the
+///   Balances pallet).
+/// - `<chain>/PalletInstance(<id>)/GeneralIndex(<index>)` for a Frame chain with an indexed multi-asset pallet instance
+///   (such as an instance of the Assets pallet).
+/// - `<chain>/AccountId32` for an ERC-20-style single-asset smart-contract on a Frame-based contracts chain.
+/// - `<chain>/AccountKey20` for an ERC-20-style single-asset smart-contract on an Ethereum-like chain.
+///
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum MultiAsset {
+	/// No assets. Rarely used.
+	None,
+
+	/// All assets. Typically used for the subset of assets to be used for an `Order`, and in that context means
+	/// "all assets currently in holding".
+	All,
+
+	/// All fungible assets. Typically used for the subset of assets to be used for an `Order`, and in that context
+	/// means "all fungible assets currently in holding".
+	AllFungible,
+
+	/// All non-fungible assets. Typically used for the subset of assets to be used for an `Order`, and in that
+	/// context means "all non-fungible assets currently in holding".
+	AllNonFungible,
+
+	/// All fungible assets of a given abstract asset `id`entifier.
+	AllAbstractFungible { id: Vec<u8> },
+
+	/// All non-fungible assets of a given abstract asset `class`.
+	AllAbstractNonFungible { class: Vec<u8> },
+
+	/// All fungible assets of a given concrete asset `id`entifier.
+	AllConcreteFungible { id: MultiLocation },
+
+	/// All non-fungible assets of a given concrete asset `class`.
+	AllConcreteNonFungible { class: MultiLocation },
+
+	/// Some specific `amount` of the fungible asset identified by an abstract `id`.
+	AbstractFungible { id: Vec<u8>, #[codec(compact)] amount: u128 },
+
+	/// Some specific `instance` of the non-fungible asset whose `class` is identified abstractly.
+	AbstractNonFungible { class: Vec<u8>, instance: AssetInstance },
+
+	/// Some specific `amount` of the fungible asset identified by an concrete `id`.
+	ConcreteFungible { id: MultiLocation, #[codec(compact)] amount: u128 },
+
+	/// Some specific `instance` of the non-fungible asset whose `class` is identified concretely.
+	ConcreteNonFungible { class: MultiLocation, instance: AssetInstance },
+}
+
+impl MultiAsset {
+	/// Returns `true` if the `MultiAsset` is a wildcard and can refer to classes of assets, instead of just one.
+	///
+	/// Typically can also be inferred by the name starting with `All`.
+	pub fn is_wildcard(&self) -> bool {
+		match self {
+			MultiAsset::None
+			| MultiAsset::AbstractFungible {..}
+			| MultiAsset::AbstractNonFungible {..}
+			| MultiAsset::ConcreteFungible {..}
+			| MultiAsset::ConcreteNonFungible {..}
+			=> false,
+
+			MultiAsset::All
+			| MultiAsset::AllFungible
+			| MultiAsset::AllNonFungible
+			| MultiAsset::AllAbstractFungible {..}
+			| MultiAsset::AllConcreteFungible {..}
+			| MultiAsset::AllAbstractNonFungible {..}
+			| MultiAsset::AllConcreteNonFungible {..}
+			=> true,
+		}
+	}
+
+	fn is_none(&self) -> bool {
+		match self {
+			MultiAsset::None
+			| MultiAsset::AbstractFungible { amount: 0, .. }
+			| MultiAsset::ConcreteFungible { amount: 0, .. }
+			=> true,
+
+			_ => false,
+		}
+	}
+
+	fn is_fungible(&self) -> bool {
+		match self {
+			MultiAsset::All
+			| MultiAsset::AllFungible
+			| MultiAsset::AllAbstractFungible {..}
+			| MultiAsset::AllConcreteFungible {..}
+			| MultiAsset::AbstractFungible {..}
+			| MultiAsset::ConcreteFungible {..}
+			=> true,
+
+			_ => false,
+		}
+	}
+
+	fn is_non_fungible(&self) -> bool {
+		match self {
+			MultiAsset::All
+			| MultiAsset::AllNonFungible
+			| MultiAsset::AllAbstractNonFungible {..}
+			| MultiAsset::AllConcreteNonFungible {..}
+			| MultiAsset::AbstractNonFungible {..}
+			| MultiAsset::ConcreteNonFungible {..}
+			=> true,
+
+			_ => false,
+		}
+	}
+
+	fn is_concrete_fungible(&self, id: &MultiLocation) -> bool {
+		match self {
+			MultiAsset::AllFungible => true,
+			MultiAsset::AllConcreteFungible { id: i }
+			| MultiAsset::ConcreteFungible { id: i, .. }
+			=> i == id,
+
+			_ => false,
+		}
+	}
+
+	fn is_abstract_fungible(&self, id: &[u8]) -> bool {
+		match self {
+			MultiAsset::AllFungible => true,
+			MultiAsset::AllAbstractFungible { id: i }
+			| MultiAsset::AbstractFungible { id: i, .. }
+			=> i == id,
+			_ => false,
+		}
+	}
+
+	fn is_concrete_non_fungible(&self, class: &MultiLocation) -> bool {
+		match self {
+			MultiAsset::AllNonFungible => true,
+			MultiAsset::AllConcreteNonFungible { class: i }
+			| MultiAsset::ConcreteNonFungible { class: i, .. }
+			=> i == class,
+			_ => false,
+		}
+	}
+
+	fn is_abstract_non_fungible(&self, class: &[u8]) -> bool {
+		match self {
+			MultiAsset::AllNonFungible => true,
+			MultiAsset::AllAbstractNonFungible { class: i }
+			| MultiAsset::AbstractNonFungible { class: i, .. }
+			=> i == class,
+			_ => false,
+		}
+	}
+
+	fn is_all(&self) -> bool { matches!(self, MultiAsset::All) }
+
+	/// Returns true if `self` is a super-set of the given `inner`.
+	///
+	/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
+	/// For more details, see the implementation and tests.
+	pub fn contains(&self, inner: &MultiAsset) -> bool {
+		use MultiAsset::*;
+
+		// Inner cannot be wild
+		if inner.is_wildcard() { return false }
+		// Everything contains nothing.
+		if inner.is_none() { return true }
+
+		// Everything contains anything.
+		if self.is_all() { return true }
+		// Nothing contains nothing.
+		if self.is_none() { return false }
+
+		match self {
+			// Anything fungible contains "all fungibles"
+			AllFungible => inner.is_fungible(),
+			// Anything non-fungible contains "all non-fungibles"
+			AllNonFungible => inner.is_non_fungible(),
+
+			AllConcreteFungible { id } => inner.is_concrete_fungible(id),
+			AllAbstractFungible { id } => inner.is_abstract_fungible(id),
+			AllConcreteNonFungible { class } => inner.is_concrete_non_fungible(class),
+			AllAbstractNonFungible { class } => inner.is_abstract_non_fungible(class),
+
+			ConcreteFungible { id, amount } => matches!(
+				inner,
+				ConcreteFungible { id: inner_id , amount: inner_amount } if inner_id == id && amount >= inner_amount
+			),
+			AbstractFungible { id, amount } => matches!(
+				inner,
+				AbstractFungible { id: inner_id , amount: inner_amount } if inner_id == id && amount >= inner_amount
+			),
+			ConcreteNonFungible { .. } => self == inner,
+			AbstractNonFungible { .. } => self == inner,
+			_ => false,
+		}
+	}
+
+	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
+		use MultiAsset::*;
+		match self {
+			AllConcreteFungible { ref mut id }
+			| AllConcreteNonFungible { class: ref mut id }
+			| ConcreteFungible { ref mut id, .. }
+			| ConcreteNonFungible { class: ref mut id, .. }
+			=> id.prepend_with(prepend.clone()).map_err(|_| ()),
+			_ => Ok(()),
+		}
+	}
+}
+
+impl From<MultiAsset> for VersionedMultiAsset {
+	fn from(x: MultiAsset) -> Self {
+		VersionedMultiAsset::V1(x)
+	}
+}
+
+impl TryFrom<VersionedMultiAsset> for MultiAsset {
+	type Error = ();
+	fn try_from(x: VersionedMultiAsset) -> result::Result<Self, ()> {
+		match x {
+			VersionedMultiAsset::V1(x) => Ok(x),
+			_ => Err(()),
+		}
+	}
+}
+
+#[cfg(test)]
+mod tests {
+	use super::*;
+
+	#[test]
+	fn contains_works() {
+		use alloc::vec;
+		use MultiAsset::*;
+		// trivial case: all contains any non-wildcard.
+		assert!(All.contains(&None));
+		assert!(All.contains(&AbstractFungible { id: alloc::vec![99u8], amount: 1 }));
+
+		// trivial case: none contains nothing, except itself.
+		assert!(None.contains(&None));
+		assert!(!None.contains(&AllFungible));
+		assert!(!None.contains(&All));
+
+		// A bit more sneaky: Nothing can contain wildcard, even All ir the thing itself.
+		assert!(!All.contains(&All));
+		assert!(!All.contains(&AllFungible));
+		assert!(!AllFungible.contains(&AllFungible));
+		assert!(!AllNonFungible.contains(&AllNonFungible));
+
+		// For fungibles, containing is basically equality, or equal id with higher amount.
+		assert!(
+			!AbstractFungible { id: vec![99u8], amount: 99 }
+			.contains(&AbstractFungible { id: vec![1u8], amount: 99 })
+		);
+		assert!(
+			AbstractFungible { id: vec![99u8], amount: 99 }
+			.contains(&AbstractFungible { id: vec![99u8], amount: 99 })
+		);
+		assert!(
+			AbstractFungible { id: vec![99u8], amount: 99 }
+			.contains(&AbstractFungible { id: vec![99u8], amount: 9 })
+		);
+		assert!(
+			!AbstractFungible { id: vec![99u8], amount: 99 }
+			.contains(&AbstractFungible { id: vec![99u8], amount: 100 })
+		);
+
+		// For non-fungibles, containing is equality.
+		assert!(
+			!AbstractNonFungible {class: vec![99u8], instance: AssetInstance::Index { id: 9 } }
+			.contains(&AbstractNonFungible { class: vec![98u8], instance: AssetInstance::Index { id: 9 } })
+		);
+		assert!(
+			!AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 8 } }
+			.contains(&AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } })
+		);
+		assert!(
+			AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } }
+			.contains(&AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } })
+		);
+	}
+}
diff --git a/xcm/src/v1/multi_location.rs b/xcm/src/v1/multi_location.rs
new file mode 100644
index 000000000000..ecffb26f8838
--- /dev/null
+++ b/xcm/src/v1/multi_location.rs
@@ -0,0 +1,867 @@
+// Copyright 2021 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Cross-Consensus Message format data structures.
+
+use core::{convert::TryFrom, mem, result};
+
+use parity_scale_codec::{self, Encode, Decode};
+use super::Junction;
+use crate::VersionedMultiLocation;
+
+/// A relative path between state-bearing consensus systems.
+///
+/// A location in a consensus system is defined as an *isolatable state machine* held within global consensus. The
+/// location in question need not have a sophisticated consensus algorithm of its own; a single account within
+/// Ethereum, for example, could be considered a location.
+///
+/// A very-much non-exhaustive list of types of location include:
+/// - A (normal, layer-1) block chain, e.g. the Bitcoin mainnet or a parachain.
+/// - A layer-0 super-chain, e.g. the Polkadot Relay chain.
+/// - A layer-2 smart contract, e.g. an ERC-20 on Ethereum.
+/// - A logical functional component of a chain, e.g. a single instance of a pallet on a Frame-based Substrate chain.
+/// - An account.
+///
+/// A `MultiLocation` is a *relative identifier*, meaning that it can only be used to define the relative path
+/// between two locations, and cannot generally be used to refer to a location universally. It is comprised of a
+/// number of *junctions*, each morphing the previous location, either diving down into one of its internal locations,
+/// called a *sub-consensus*, or going up into its parent location. Correct `MultiLocation` values must have all
+/// `Parent` junctions as a prefix to all *sub-consensus* junctions.
+///
+/// This specific `MultiLocation` implementation uses a Rust `enum` in order to make pattern matching easier.
+///
+/// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub struct MultiLocation {
+	parents: u8,
+	junctions: Junctions,
+}
+
+/// Maximum number of junctions a multilocation can contain.
+pub const MAX_MULTILOCATION_LENGTH: usize = 8;
+
+impl MultiLocation {
+	/// Creates a new MultiLocation, ensuring that the length of it does not exceed the maximum,
+	/// otherwise returns `Err`.
+	pub fn new(parents: u8, junctions: Junctions) -> result::Result<MultiLocation, ()> {
+		if parents as usize + junctions.len() > MAX_MULTILOCATION_LENGTH {
+			return Err(())
+		}
+		Ok(MultiLocation {
+			parents,
+			junctions,
+		})
+	}
+
+	/// Return a reference to the junctions field.
+	pub fn junctions(&self) -> &Junctions {
+		&self.junctions
+	}
+
+	/// Return a mutable reference to the junctions field.
+	pub fn junctions_mut(&mut self) -> &mut Junctions {
+		&mut self.junctions
+	}
+
+	/// Returns the number of `Parent` junctions at the beginning of `self`.
+	pub fn parent_count(&self) -> usize {
+		self.parents as usize
+	}
+
+	/// Returns the number of parents and junctions in `self`.
+	pub fn len(&self) -> usize {
+		self.parent_count() + self.junctions.len()
+	}
+
+	/// Returns first junction that is not a parent, or `None` if the location is empty or
+	/// contains only parents.
+	pub fn first_non_parent(&self) -> Option<&Junction> {
+		self.junctions.first()
+	}
+
+	/// Returns last junction, or `None` if the location is empty or contains only parents.
+	pub fn last(&self) -> Option<&Junction> {
+		self.junctions.last()
+	}
+
+	/// Splits off the first non-parent junction, returning the remaining suffix (first item in tuple)
+	/// and the first element (second item in tuple) or `None` if it was empty.
+	pub fn split_first_non_parent(self) -> (MultiLocation, Option<Junction>) {
+		let MultiLocation { parents, junctions } = self;
+		let (prefix, suffix) = junctions.split_first();
+		let multilocation = MultiLocation {
+			parents,
+			junctions: prefix,
+		};
+		(multilocation, suffix)
+	}
+
+	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
+	/// (second item in tuple) or `None` if it was empty or that `self` only contains parents.
+	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
+		let MultiLocation { parents, junctions } = self;
+		let (prefix, suffix) = junctions.split_last();
+		let multilocation = MultiLocation {
+			parents,
+			junctions: prefix,
+		};
+		(multilocation, suffix)
+	}
+	
+	/// Bumps the parent count up by 1. Returns `Err` in case of overflow.
+	pub fn push_parent(&mut self) -> result::Result<(), ()> {
+		if self.len() >= MAX_MULTILOCATION_LENGTH {
+			return Err(())
+		}
+		self.parents = self.parents.saturating_add(1);
+		Ok(())
+	}
+
+	/// Mutates `self`, suffixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
+	pub fn push_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
+		let mut n = Junctions::Null;
+		mem::swap(&mut self.junctions, &mut n);
+		match n.pushed_with(new) {
+			Ok(result) => { self.junctions = result; Ok(()) }
+			Err(old) => { self.junctions = old; Err(()) }
+		}
+	}
+
+	/// Mutates `self`, prefixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
+	pub fn push_front_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
+		let mut n = Junctions::Null;
+		mem::swap(&mut self.junctions, &mut n);
+		match n.pushed_front_with(new) {
+			Ok(result) => { self.junctions = result; Ok(()) }
+			Err(old) => { self.junctions = old; Err(()) }
+		}
+	}
+
+	/// Consumes `self` and returns a `MultiLocation` with its parent count incremented by 1, or
+	/// an `Err` with the original value of `self` in case of overflow.
+	pub fn pushed_with_parent(self) -> result::Result<Self, Self> {
+		if self.len() >= MAX_MULTILOCATION_LENGTH {
+			return Err(self)
+		}
+		Ok(MultiLocation {
+			parents: self.parents.saturating_add(1),
+			..self
+		})
+	}
+
+	/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with the original value of
+	/// `self` in case of overflow.
+	pub fn pushed_with_non_parent(self, new: Junction) -> result::Result<Self, Self> {
+		if self.len() >= MAX_MULTILOCATION_LENGTH {
+			return Err(self)
+		}
+		Ok(MultiLocation {
+			parents: self.parents,
+			junctions: self.junctions.pushed_with(new).expect("length is less than max length; qed"),
+		})
+	}
+
+	/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
+	/// `self` in case of overflow.
+	pub fn pushed_front_with_non_parent(self, new: Junction) -> result::Result<Self, Self> {
+		if self.len() >= MAX_MULTILOCATION_LENGTH {
+			return Err(self)
+		}
+		Ok(MultiLocation {
+			parents: self.parents,
+			junctions: self.junctions.pushed_front_with(new).expect("length is less than max length; qed"),
+		})
+	}
+
+	/// Returns the junction at index `i`, or `None` if the location is a parent or if the location
+	/// does not contain that many elements.
+	pub fn at(&self, i: usize) -> Option<&Junction> {
+		let num_parents = self.parents as usize;
+		if i < num_parents {
+			return None
+		}
+		self.junctions.at(i - num_parents)
+	}
+
+	/// Returns a mutable reference to the junction at index `i`, or `None` if the location is a
+	/// parent or if it doesn't contain that many elements.
+	pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
+		let num_parents = self.parents as usize;
+		if i < num_parents {
+			return None
+		}
+		self.junctions.at_mut(i - num_parents)
+	}
+
+	/// Decrement the parent count by 1.
+	pub fn pop_parent(&mut self) {
+		self.parents = self.parents.saturating_sub(1);
+	}
+
+	/// Removes the first non-parent element from `self`, returning it
+	/// (or `None` if it was empty or if `self` contains only parents).
+	pub fn take_first_non_parent(&mut self) -> Option<Junction> {
+		self.junctions.take_first()
+	}
+
+	/// Removes the last element from `junctions`, returning it (or `None` if it was empty or if
+	/// `self` only contains parents).
+	pub fn take_last(&mut self) -> Option<Junction> {
+		self.junctions.take_last()
+	}
+
+	/// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with
+	/// the junctions of `prefix` and that it has a single `Junction` item following.
+	/// If so, returns a reference to this `Junction` item.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
+	/// # fn main() {
+	/// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)).unwrap();
+	/// assert_eq!(
+	///     m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3))).unwrap()),
+	///     Some(&OnlyChild),
+	/// );
+	/// assert_eq!(m.match_and_split(&MultiLocation::new(1, Null).unwrap()), None);
+	/// # }
+	/// ```
+	pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> {
+		if self.parents != prefix.parents {
+			return None
+		}
+		self.junctions.match_and_split(&prefix.junctions)
+	}
+
+	/// Mutate `self` so that it is suffixed with `suffix`. The correct normalized form is returned,
+	/// removing any internal [Non-Parent, `Parent`]  combinations.
+	///
+	/// Does not modify `self` and returns `Err` with `suffix` in case of overflow.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
+	/// # fn main() {
+	/// let mut m = MultiLocation::new(1, X2(Parachain(21), OnlyChild)).unwrap();
+	/// assert_eq!(m.append_with(MultiLocation::new(1, X1(PalletInstance(3))).unwrap()), Ok(()));
+	/// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3))).unwrap());
+	/// # }
+	/// ```
+	pub fn append_with(&mut self, suffix: MultiLocation) -> Result<(), MultiLocation> {
+		let mut prefix = suffix;
+		core::mem::swap(self, &mut prefix);
+		match self.prepend_with(prefix) {
+			Ok(()) => Ok(()),
+			Err(prefix) => {
+				let mut suffix = prefix;
+				core::mem::swap(self, &mut suffix);
+				Err(suffix)
+			}
+		}
+	}
+
+	/// Mutate `self` so that it is prefixed with `prefix`.
+	///
+	/// Does not modify `self` and returns `Err` with `prefix` in case of overflow.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
+	/// # fn main() {
+	/// let mut m = MultiLocation::new(2, X1(PalletInstance(3))).unwrap();
+	/// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild)).unwrap()), Ok(()));
+	/// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3))).unwrap());
+	/// # }
+	/// ```
+	pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> {
+		let self_parents = self.parent_count();
+		let prepend_len = (self_parents as isize - prefix.junctions.len() as isize).abs() as usize;
+		if self.junctions.len() + prefix.parent_count() + prepend_len > MAX_MULTILOCATION_LENGTH {
+			return Err(prefix)
+		}
+
+		let mut final_parent_count = prefix.parents;
+		for _ in 0..self_parents {
+			if prefix.take_last().is_none() {
+				// If true, this means self parent count is greater than prefix junctions length;
+				// add the resulting self parent count to final_parent_count
+				final_parent_count += self.parents;
+				break
+			}
+			self.pop_parent();
+		}
+
+		self.parents = final_parent_count;
+		for j in prefix.junctions.into_iter_rev() {
+			self.push_front_non_parent(j).expect(
+				"self junctions len + prefix parent count + prepend len is less than max length; qed"
+			);
+		}
+		Ok(())
+	}
+}
+
+impl From<Junctions> for MultiLocation {
+	fn from(junctions: Junctions) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions,
+		}
+	}
+}
+
+impl From<Junction> for MultiLocation {
+	fn from(x: Junction) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X1(x),
+		}
+	}
+}
+
+impl From<()> for MultiLocation {
+	fn from(_: ()) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::Null,
+		}
+	}
+}
+impl From<(Junction,)> for MultiLocation {
+	fn from(x: (Junction,)) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X1(x.0),
+		}
+	}
+}
+impl From<(Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction)) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X2(x.0, x.1),
+		}
+	}
+}
+impl From<(Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction)) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X3(x.0, x.1, x.2),
+		}
+	}
+}
+impl From<(Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X4(x.0, x.1, x.2, x.3),
+		}
+	}
+}
+impl From<(Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X5(x.0, x.1, x.2, x.3, x.4),
+		}
+	}
+}
+impl From<(Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X6(x.0, x.1, x.2, x.3, x.4, x.5),
+		}
+	}
+}
+impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X7(x.0, x.1, x.2, x.3, x.4, x.5, x.6),
+		}
+	}
+}
+impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X8(x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7),
+		}
+	}
+}
+
+impl From<[Junction; 0]> for MultiLocation {
+	fn from(_: [Junction; 0]) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::Null,
+		}
+	}
+}
+impl From<[Junction; 1]> for MultiLocation {
+	fn from(x: [Junction; 1]) -> Self {
+		let [x0] = x;
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X1(x0),
+		}
+	}
+}
+impl From<[Junction; 2]> for MultiLocation {
+	fn from(x: [Junction; 2]) -> Self {
+		let [x0, x1] = x;
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X2(x0, x1),
+		}
+	}
+}
+impl From<[Junction; 3]> for MultiLocation {
+	fn from(x: [Junction; 3]) -> Self {
+		let [x0, x1, x2] = x;
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X3(x0, x1, x2),
+		}
+	}
+}
+impl From<[Junction; 4]> for MultiLocation {
+	fn from(x: [Junction; 4]) -> Self {
+		let [x0, x1, x2, x3] = x;
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X4(x0, x1, x2, x3),
+		}
+	}
+}
+impl From<[Junction; 5]> for MultiLocation {
+	fn from(x: [Junction; 5]) -> Self {
+		let [x0, x1, x2, x3, x4] = x;
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X5(x0, x1, x2, x3, x4),
+		}
+	}
+}
+impl From<[Junction; 6]> for MultiLocation {
+	fn from(x: [Junction; 6]) -> Self {
+		let [x0, x1, x2, x3, x4, x5] = x;
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X6(x0, x1, x2, x3, x4, x5),
+		}
+	}
+}
+impl From<[Junction; 7]> for MultiLocation {
+	fn from(x: [Junction; 7]) -> Self {
+		let [x0, x1, x2, x3, x4, x5, x6] = x;
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X7(x0, x1, x2, x3, x4, x5, x6),
+		}
+	}
+}
+impl From<[Junction; 8]> for MultiLocation {
+	fn from(x: [Junction; 8]) -> Self {
+		let [x0, x1, x2, x3, x4, x5, x6, x7] = x;
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X8(x0, x1, x2, x3, x4, x5, x6, x7),
+		}
+	}
+}
+
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum Junctions {
+	/// The interpreting consensus system.
+	Null,
+	/// A relative path comprising 1 junction.
+	X1(Junction),
+	/// A relative path comprising 2 junctions.
+	X2(Junction, Junction),
+	/// A relative path comprising 3 junctions.
+	X3(Junction, Junction, Junction),
+	/// A relative path comprising 4 junctions.
+	X4(Junction, Junction, Junction, Junction),
+	/// A relative path comprising 5 junctions.
+	X5(Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 6 junctions.
+	X6(Junction, Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 7 junctions.
+	X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 8 junctions.
+	X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction),
+}
+
+pub struct JunctionsIterator(Junctions);
+impl Iterator for JunctionsIterator {
+	type Item = Junction;
+	fn next(&mut self) -> Option<Junction> {
+		self.0.take_first()
+	}
+}
+
+pub struct JunctionsReverseIterator(Junctions);
+impl Iterator for JunctionsReverseIterator {
+	type Item = Junction;
+	fn next(&mut self) -> Option<Junction> {
+		self.0.take_last()
+	}
+}
+
+pub struct JunctionsRefIterator<'a>(&'a Junctions, usize);
+impl<'a> Iterator for JunctionsRefIterator<'a> {
+	type Item = &'a Junction;
+	fn next(&mut self) -> Option<&'a Junction> {
+		let result = self.0.at(self.1);
+		self.1 += 1;
+		result
+	}
+}
+
+pub struct JunctionsReverseRefIterator<'a>(&'a Junctions, usize);
+impl<'a> Iterator for JunctionsReverseRefIterator<'a> {
+	type Item = &'a Junction;
+	fn next(&mut self) -> Option<&'a Junction> {
+		self.1 += 1;
+		self.0.at(self.0.len().checked_sub(self.1)?)
+	}
+}
+
+impl Junctions {
+	/// Returns first junction, or `None` if the location is empty.
+	pub fn first(&self) -> Option<&Junction> {
+		match &self {
+			Junctions::Null => None,
+			Junctions::X1(ref a) => Some(a),
+			Junctions::X2(ref a, ..) => Some(a),
+			Junctions::X3(ref a, ..) => Some(a),
+			Junctions::X4(ref a, ..) => Some(a),
+			Junctions::X5(ref a, ..) => Some(a),
+			Junctions::X6(ref a, ..) => Some(a),
+			Junctions::X7(ref a, ..) => Some(a),
+			Junctions::X8(ref a, ..) => Some(a),
+		}
+	}
+
+	/// Returns last junction, or `None` if the location is empty.
+	pub fn last(&self) -> Option<&Junction> {
+		match &self {
+			Junctions::Null => None,
+			Junctions::X1(ref a) => Some(a),
+			Junctions::X2(.., ref a) => Some(a),
+			Junctions::X3(.., ref a) => Some(a),
+			Junctions::X4(.., ref a) => Some(a),
+			Junctions::X5(.., ref a) => Some(a),
+			Junctions::X6(.., ref a) => Some(a),
+			Junctions::X7(.., ref a) => Some(a),
+			Junctions::X8(.., ref a) => Some(a),
+		}
+	}
+
+	/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the first element
+	/// (second item in tuple) or `None` if it was empty.
+	pub fn split_first(self) -> (Junctions, Option<Junction>) {
+		match self {
+			Junctions::Null => (Junctions::Null, None),
+			Junctions::X1(a) => (Junctions::Null, Some(a)),
+			Junctions::X2(a, b) => (Junctions::X1(b), Some(a)),
+			Junctions::X3(a, b, c) => (Junctions::X2(b, c), Some(a)),
+			Junctions::X4(a, b, c ,d) => (Junctions::X3(b, c, d), Some(a)),
+			Junctions::X5(a, b, c ,d, e) => (Junctions::X4(b, c, d, e), Some(a)),
+			Junctions::X6(a, b, c ,d, e, f) => (Junctions::X5(b, c, d, e, f), Some(a)),
+			Junctions::X7(a, b, c ,d, e, f, g) => (Junctions::X6(b, c, d, e, f, g), Some(a)),
+			Junctions::X8(a, b, c ,d, e, f, g, h) => (Junctions::X7(b, c, d, e, f, g, h), Some(a)),
+		}
+	}
+
+	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
+	/// (second item in tuple) or `None` if it was empty.
+	pub fn split_last(self) -> (Junctions, Option<Junction>) {
+		match self {
+			Junctions::Null => (Junctions::Null, None),
+			Junctions::X1(a) => (Junctions::Null, Some(a)),
+			Junctions::X2(a, b) => (Junctions::X1(a), Some(b)),
+			Junctions::X3(a, b, c) => (Junctions::X2(a, b), Some(c)),
+			Junctions::X4(a, b, c ,d) => (Junctions::X3(a, b, c), Some(d)),
+			Junctions::X5(a, b, c, d, e) => (Junctions::X4(a, b, c, d), Some(e)),
+			Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(a, b, c, d, e), Some(f)),
+			Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(a, b, c, d, e, f), Some(g)),
+			Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(a, b, c, d, e, f, g), Some(h)),
+		}
+	}
+
+	/// Removes the first element from `self`, returning it (or `None` if it was empty).
+	pub fn take_first(&mut self) -> Option<Junction> {
+		let mut d = Junctions::Null;
+		mem::swap(&mut *self, &mut d);
+		let (tail, head) = d.split_first();
+		*self = tail;
+		head
+	}
+
+	/// Removes the last element from `self`, returning it (or `None` if it was empty).
+	pub fn take_last(&mut self) -> Option<Junction> {
+		let mut d = Junctions::Null;
+		mem::swap(&mut *self, &mut d);
+		let (head, tail) = d.split_last();
+		*self = head;
+		tail
+	}
+
+	/// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the original value of
+	/// `self` in case of overflow.
+	pub fn pushed_with(self, new: Junction) -> result::Result<Self, Self> {
+		Ok(match self {
+			Junctions::Null => Junctions::X1(new),
+			Junctions::X1(a) => Junctions::X2(a, new),
+			Junctions::X2(a, b) => Junctions::X3(a, b, new),
+			Junctions::X3(a, b, c) => Junctions::X4(a, b, c, new),
+			Junctions::X4(a, b, c, d) => Junctions::X5(a, b, c, d, new),
+			Junctions::X5(a, b, c, d, e) => Junctions::X6(a, b, c, d, e, new),
+			Junctions::X6(a, b, c, d, e, f) => Junctions::X7(a, b, c, d, e, f, new),
+			Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(a, b, c, d, e, f, g, new),
+			s => Err(s)?,
+		})
+	}
+
+	/// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the original value of
+	/// `self` in case of overflow.
+	pub fn pushed_front_with(self, new: Junction) -> result::Result<Self, Self> {
+		Ok(match self {
+			Junctions::Null => Junctions::X1(new),
+			Junctions::X1(a) => Junctions::X2(new, a),
+			Junctions::X2(a, b) => Junctions::X3(new, a, b),
+			Junctions::X3(a, b, c) => Junctions::X4(new, a, b, c),
+			Junctions::X4(a, b, c, d) => Junctions::X5(new, a, b, c, d),
+			Junctions::X5(a, b, c, d, e) => Junctions::X6(new, a, b, c, d, e),
+			Junctions::X6(a, b, c, d, e, f) => Junctions::X7(new, a, b, c, d, e, f),
+			Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(new, a, b, c, d, e, f, g),
+			s => Err(s)?,
+		})
+	}
+
+	/// Returns the number of junctions in `self`.
+	pub fn len(&self) -> usize {
+		match &self {
+			Junctions::Null => 0,
+			Junctions::X1(..) => 1,
+			Junctions::X2(..) => 2,
+			Junctions::X3(..) => 3,
+			Junctions::X4(..) => 4,
+			Junctions::X5(..) => 5,
+			Junctions::X6(..) => 6,
+			Junctions::X7(..) => 7,
+			Junctions::X8(..) => 8,
+		}
+	}
+
+	/// Returns the junction at index `i`, or `None` if the location doesn't contain that many elements.
+	pub fn at(&self, i: usize) -> Option<&Junction> {
+		Some(match (i, &self) {
+			(0, Junctions::X1(ref a)) => a,
+			(0, Junctions::X2(ref a, ..)) => a,
+			(0, Junctions::X3(ref a, ..)) => a,
+			(0, Junctions::X4(ref a, ..)) => a,
+			(0, Junctions::X5(ref a, ..)) => a,
+			(0, Junctions::X6(ref a, ..)) => a,
+			(0, Junctions::X7(ref a, ..)) => a,
+			(0, Junctions::X8(ref a, ..)) => a,
+			(1, Junctions::X2(_, ref a)) => a,
+			(1, Junctions::X3(_, ref a, ..)) => a,
+			(1, Junctions::X4(_, ref a, ..)) => a,
+			(1, Junctions::X5(_, ref a, ..)) => a,
+			(1, Junctions::X6(_, ref a, ..)) => a,
+			(1, Junctions::X7(_, ref a, ..)) => a,
+			(1, Junctions::X8(_, ref a, ..)) => a,
+			(2, Junctions::X3(_, _, ref a)) => a,
+			(2, Junctions::X4(_, _, ref a, ..)) => a,
+			(2, Junctions::X5(_, _, ref a, ..)) => a,
+			(2, Junctions::X6(_, _, ref a, ..)) => a,
+			(2, Junctions::X7(_, _, ref a, ..)) => a,
+			(2, Junctions::X8(_, _, ref a, ..)) => a,
+			(3, Junctions::X4(_, _, _, ref a)) => a,
+			(3, Junctions::X5(_, _, _, ref a, ..)) => a,
+			(3, Junctions::X6(_, _, _, ref a, ..)) => a,
+			(3, Junctions::X7(_, _, _, ref a, ..)) => a,
+			(3, Junctions::X8(_, _, _, ref a, ..)) => a,
+			(4, Junctions::X5(_, _, _, _, ref a)) => a,
+			(4, Junctions::X6(_, _, _, _, ref a, ..)) => a,
+			(4, Junctions::X7(_, _, _, _, ref a, ..)) => a,
+			(4, Junctions::X8(_, _, _, _, ref a, ..)) => a,
+			(5, Junctions::X6(_, _, _, _, _, ref a)) => a,
+			(5, Junctions::X7(_, _, _, _, _, ref a, ..)) => a,
+			(5, Junctions::X8(_, _, _, _, _, ref a, ..)) => a,
+			(6, Junctions::X7(_, _, _, _, _, _, ref a)) => a,
+			(6, Junctions::X8(_, _, _, _, _, _, ref a, ..)) => a,
+			(7, Junctions::X8(_, _, _, _, _, _, _, ref a)) => a,
+			_ => return None,
+		})
+	}
+
+	/// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't contain that many
+	/// elements.
+	pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
+		Some(match (i, self) {
+			(0, Junctions::X1(ref mut a)) => a,
+			(0, Junctions::X2(ref mut a, ..)) => a,
+			(0, Junctions::X3(ref mut a, ..)) => a,
+			(0, Junctions::X4(ref mut a, ..)) => a,
+			(0, Junctions::X5(ref mut a, ..)) => a,
+			(0, Junctions::X6(ref mut a, ..)) => a,
+			(0, Junctions::X7(ref mut a, ..)) => a,
+			(0, Junctions::X8(ref mut a, ..)) => a,
+			(1, Junctions::X2(_, ref mut a)) => a,
+			(1, Junctions::X3(_, ref mut a, ..)) => a,
+			(1, Junctions::X4(_, ref mut a, ..)) => a,
+			(1, Junctions::X5(_, ref mut a, ..)) => a,
+			(1, Junctions::X6(_, ref mut a, ..)) => a,
+			(1, Junctions::X7(_, ref mut a, ..)) => a,
+			(1, Junctions::X8(_, ref mut a, ..)) => a,
+			(2, Junctions::X3(_, _, ref mut a)) => a,
+			(2, Junctions::X4(_, _, ref mut a, ..)) => a,
+			(2, Junctions::X5(_, _, ref mut a, ..)) => a,
+			(2, Junctions::X6(_, _, ref mut a, ..)) => a,
+			(2, Junctions::X7(_, _, ref mut a, ..)) => a,
+			(2, Junctions::X8(_, _, ref mut a, ..)) => a,
+			(3, Junctions::X4(_, _, _, ref mut a)) => a,
+			(3, Junctions::X5(_, _, _, ref mut a, ..)) => a,
+			(3, Junctions::X6(_, _, _, ref mut a, ..)) => a,
+			(3, Junctions::X7(_, _, _, ref mut a, ..)) => a,
+			(3, Junctions::X8(_, _, _, ref mut a, ..)) => a,
+			(4, Junctions::X5(_, _, _, _, ref mut a)) => a,
+			(4, Junctions::X6(_, _, _, _, ref mut a, ..)) => a,
+			(4, Junctions::X7(_, _, _, _, ref mut a, ..)) => a,
+			(4, Junctions::X8(_, _, _, _, ref mut a, ..)) => a,
+			(5, Junctions::X6(_, _, _, _, _, ref mut a)) => a,
+			(5, Junctions::X7(_, _, _, _, _, ref mut a, ..)) => a,
+			(5, Junctions::X8(_, _, _, _, _, ref mut a, ..)) => a,
+			(6, Junctions::X7(_, _, _, _, _, _, ref mut a)) => a,
+			(6, Junctions::X8(_, _, _, _, _, _, ref mut a, ..)) => a,
+			(7, Junctions::X8(_, _, _, _, _, _, _, ref mut a)) => a,
+			_ => return None,
+		})
+	}
+
+	/// Returns a reference iterator over the junctions.
+	pub fn iter(&self) -> JunctionsRefIterator {
+		JunctionsRefIterator(&self, 0)
+	}
+
+	/// Returns a reference iterator over the junctions in reverse.
+	pub fn iter_rev(&self) -> JunctionsReverseRefIterator {
+		JunctionsReverseRefIterator(&self, 0)
+	}
+
+	/// Consumes `self` and returns an iterator over the junctions.
+	pub fn into_iter(self) -> JunctionsIterator {
+		JunctionsIterator(self)
+	}
+
+	/// Consumes `self` and returns an iterator over the junctions in reverse.
+	pub fn into_iter_rev(self) -> JunctionsReverseIterator {
+		JunctionsReverseIterator(self)
+	}
+
+	/// Ensures that self begins with `prefix` and that it has a single `Junction` item following.
+	/// If so, returns a reference to this `Junction` item.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v1::{Junctions::*, Junction::*};
+	/// # fn main() {
+	/// let mut m = X3(Parachain(2), PalletInstance(3), OnlyChild);
+	/// assert_eq!(m.match_and_split(&X2(Parachain(2), PalletInstance(3))), Some(&OnlyChild));
+	/// assert_eq!(m.match_and_split(&X1(Parachain(2))), None);
+	/// # }
+	/// ```
+	pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> {
+		if prefix.len() + 1 != self.len() {
+			return None
+		}
+		for i in 0..prefix.len() {
+			if prefix.at(i) != self.at(i) {
+				return None
+			}
+		}
+		return self.at(prefix.len())
+	}
+}
+
+impl From<MultiLocation> for VersionedMultiLocation {
+	fn from(x: MultiLocation) -> Self {
+		VersionedMultiLocation::V1(x)
+	}
+}
+
+impl TryFrom<VersionedMultiLocation> for MultiLocation {
+	type Error = ();
+	fn try_from(x: VersionedMultiLocation) -> result::Result<Self, ()> {
+		match x {
+			VersionedMultiLocation::V1(x) => Ok(x),
+			_ => Err(()),
+		}
+	}
+}
+
+#[cfg(test)]
+mod tests {
+	use super::{Junctions::*, MultiLocation};
+	use crate::opaque::v1::{Junction::*, NetworkId::Any};
+
+	#[test]
+	fn match_and_split_works() {
+		let m = MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
+		assert_eq!(m.match_and_split(&MultiLocation { parents: 1, junctions: Null }), None);
+		assert_eq!(
+			m.match_and_split(&MultiLocation { parents: 1, junctions: X1(Parachain(42)) }),
+			Some(&AccountIndex64 { network: Any, index: 23 })
+		);
+		assert_eq!(m.match_and_split(&m), None);
+	}
+
+	#[test]
+	fn append_with_works() {
+		let acc = AccountIndex64 { network: Any, index: 23 };
+		let mut m = MultiLocation { parents: 1, junctions: X1(Parachain(42)) };
+		assert_eq!(m.append_with(MultiLocation::from(X2(PalletInstance(3), acc.clone()))), Ok(()));
+		assert_eq!(m, MultiLocation { parents: 1, junctions: X3(Parachain(42), PalletInstance(3), acc.clone()) });
+
+		// cannot append to create overly long multilocation
+		let acc = AccountIndex64 { network: Any, index: 23 };
+		let mut m = MultiLocation { parents: 6, junctions: X1(Parachain(42)) };
+		let suffix = MultiLocation::from(X2(PalletInstance(3), acc.clone()));
+		assert_eq!(m.append_with(suffix.clone()), Err(suffix));
+	}
+
+	#[test]
+	fn prepend_with_works() {
+		let mut m = MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
+		assert_eq!(m.prepend_with(MultiLocation { parents: 1, junctions: X1(OnlyChild) }), Ok(()));
+		assert_eq!(m, MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) });
+
+		// cannot prepend to create overly long multilocation
+		let mut m = MultiLocation { parents: 6, junctions: X1(Parachain(42)) };
+		let prefix = MultiLocation { parents: 2, junctions: Null };
+		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
+
+		let prefix = MultiLocation { parents: 1, junctions: Null };
+		assert_eq!(m.prepend_with(prefix), Ok(()));
+		assert_eq!(m, MultiLocation { parents: 7, junctions: X1(Parachain(42)) });
+	}
+}
diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
new file mode 100644
index 000000000000..f1e48c3b90c2
--- /dev/null
+++ b/xcm/src/v1/order.rs
@@ -0,0 +1,140 @@
+// Copyright 2021 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Version 1 of the Cross-Consensus Message format data structures.
+
+use alloc::vec::Vec;
+use derivative::Derivative;
+use parity_scale_codec::{self, Encode, Decode};
+use super::{MultiAsset, MultiLocation, Xcm};
+
+/// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
+#[derive(Derivative, Encode, Decode)]
+#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))]
+#[codec(encode_bound())]
+#[codec(decode_bound())]
+pub enum Order<Call> {
+	/// Do nothing. Not generally used.
+	#[codec(index = 0)]
+	Null,
+
+	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
+	/// this consensus system.
+	///
+	/// - `assets`: The asset(s) to remove from holding.
+	/// - `dest`: The new owner for the assets.
+	///
+	/// Errors:
+	#[codec(index = 1)]
+	DepositAsset { assets: Vec<MultiAsset>, dest: MultiLocation },
+
+	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
+	/// this consensus system.
+	///
+	/// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`.
+	///
+	/// - `assets`: The asset(s) to remove from holding.
+	/// - `dest`: The new owner for the assets.
+	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to
+	///   `dest.
+	///
+	/// Errors:
+	#[codec(index = 2)]
+	DepositReserveAsset { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+
+	/// Remove the asset(s) (`give`) from holding and replace them with alternative assets.
+	///
+	/// The minimum amount of assets to be received into holding for the order not to fail may be stated.
+	///
+	/// - `give`: The asset(s) to remove from holding.
+	/// - `receive`: The minimum amount of assets(s) which `give` should be exchanged for. The meaning of wildcards
+	///   is undefined and they should be not be used.
+	///
+	/// Errors:
+	#[codec(index = 3)]
+	ExchangeAsset { give: Vec<MultiAsset>, receive: Vec<MultiAsset> },
+
+	/// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a reserve location.
+	///
+	/// - `assets`: The asset(s) to remove from holding.
+	/// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The sovereign account
+	///   of this consensus system *on the reserve location* will have appropriate assets withdrawn and `effects` will
+	///   be executed on them. There will typically be only one valid location on any given asset/chain combination.
+	/// - `effects`: The orders to execute on the assets once withdrawn *on the reserve location*.
+	///
+	/// Errors:
+	#[codec(index = 4)]
+	InitiateReserveWithdraw { assets: Vec<MultiAsset>, reserve: MultiLocation, effects: Vec<Order<()>> },
+
+	/// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location.
+	///
+	/// - `assets`: The asset(s) to remove from holding.
+	/// - `destination`: A valid location that has a bi-lateral teleportation arrangement.
+	/// - `effects`: The orders to execute on the assets once arrived *on the destination location*.
+	///
+	/// Errors:
+	#[codec(index = 5)]
+	InitiateTeleport { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+
+	/// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a portion thereof.
+	///
+	/// - `query_id`: An identifier that will be replicated into the returned XCM message.
+	/// - `dest`: A valid destination for the returned XCM message. This may be limited to the current origin.
+	/// - `assets`: A filter for the assets that should be reported back. The assets reported back will be, asset-
+	///   wise, *the lesser of this value and the holding account*. No wildcards will be used when reporting assets
+	///   back.
+	///
+	/// Errors:
+	#[codec(index = 6)]
+	QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: Vec<MultiAsset> },
+
+	/// Pay for the execution of some Xcm with up to `weight` picoseconds of execution time, paying for this with
+	/// up to `fees` from the holding account.
+	///
+	/// Errors:
+	#[codec(index = 7)]
+	BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec<Xcm<Call>> },
+}
+
+pub mod opaque {
+	pub type Order = super::Order<()>;
+}
+
+impl<Call> Order<Call> {
+	pub fn into<C>(self) -> Order<C> { Order::from(self) }
+	pub fn from<C>(order: Order<C>) -> Self {
+		use Order::*;
+		match order {
+			Null => Null,
+			DepositAsset { assets, dest }
+				=> DepositAsset { assets, dest },
+			DepositReserveAsset { assets, dest, effects }
+				=> DepositReserveAsset { assets, dest, effects },
+			ExchangeAsset { give, receive }
+				=> ExchangeAsset { give, receive },
+			InitiateReserveWithdraw { assets, reserve, effects }
+				=> InitiateReserveWithdraw { assets, reserve, effects },
+			InitiateTeleport { assets, dest, effects }
+				=> InitiateTeleport { assets, dest, effects },
+			QueryHolding { query_id, dest, assets }
+				=> QueryHolding { query_id, dest, assets },
+			BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
+				let xcm = xcm.into_iter().map(Xcm::from).collect();
+				BuyExecution { fees, weight, debt, halt_on_error, xcm }
+			},
+		}
+	}
+}
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
new file mode 100644
index 000000000000..6f3dccce1630
--- /dev/null
+++ b/xcm/src/v1/traits.rs
@@ -0,0 +1,246 @@
+// Copyright 2021 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Cross-Consensus Message format data structures.
+
+use core::result;
+use parity_scale_codec::{Encode, Decode};
+
+use super::{MultiLocation, Xcm};
+
+#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
+pub enum Error {
+	Undefined,
+	Overflow,
+	/// The operation is intentionally unsupported.
+	Unimplemented,
+	UnhandledXcmVersion,
+	UnhandledXcmMessage,
+	UnhandledEffect,
+	EscalationOfPrivilege,
+	UntrustedReserveLocation,
+	UntrustedTeleportLocation,
+	DestinationBufferOverflow,
+	/// The message and destination was recognized as being reachable but the operation could not be completed.
+	/// A human-readable explanation of the specific issue is provided.
+	SendFailed(#[codec(skip)] &'static str),
+	/// The message and destination combination was not recognized as being reachable.
+	CannotReachDestination(MultiLocation, Xcm<()>),
+	MultiLocationFull,
+	FailedToDecode,
+	BadOrigin,
+	ExceedsMaxMessageSize,
+	FailedToTransactAsset(#[codec(skip)] &'static str),
+	/// Execution of the XCM would potentially result in a greater weight used than the pre-specified
+	/// weight limit. The amount that is potentially required is the parameter.
+	WeightLimitReached(Weight),
+	Wildcard,
+	/// The case where an XCM message has specified a optional weight limit and the weight required for
+	/// processing is too great.
+	///
+	/// Used by:
+	/// - `Transact`
+	TooMuchWeightRequired,
+	/// The fees specified by the XCM message were not found in the holding account.
+	///
+	/// Used by:
+	/// - `BuyExecution`
+	NotHoldingFees,
+	/// The weight of an XCM message is not computable ahead of execution. This generally means at least part
+	/// of the message is invalid, which could be due to it containing overly nested structures or an invalid
+	/// nested data segment (e.g. for the call in `Transact`).
+	WeightNotComputable,
+	/// The XCM did not pass the barrier condition for execution. The barrier condition differs on different
+	/// chains and in different circumstances, but generally it means that the conditions surrounding the message
+	/// were not such that the chain considers the message worth spending time executing. Since most chains
+	/// lift the barrier to execution on appropriate payment, presentation of an NFT voucher, or based on the
+	/// message origin, it means that none of those were the case.
+	Barrier,
+	/// Indicates that it is not possible for a location to have an asset be withdrawn or transferred from its
+	/// ownership. This probably means it doesn't own (enough of) it, but may also indicate that it is under a
+	/// lock, hold, freeze or is otherwise unavailable.
+	NotWithdrawable,
+	/// Indicates that the consensus system cannot deposit an asset under the ownership of a particular location.
+	LocationCannotHold,
+	/// The assets given to purchase weight is are insufficient for the weight desired.
+	TooExpensive,
+	/// The given asset is not handled.
+	AssetNotFound,
+}
+
+impl From<()> for Error {
+	fn from(_: ()) -> Self {
+		Self::Undefined
+	}
+}
+
+pub type Result = result::Result<(), Error>;
+
+/// Local weight type; execution time in picoseconds.
+pub type Weight = u64;
+
+/// Outcome of an XCM execution.
+#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
+pub enum Outcome {
+	/// Execution completed successfully; given weight was used.
+	Complete(Weight),
+	/// Execution started, but did not complete successfully due to the given error; given weight was used.
+	Incomplete(Weight, Error),
+	/// Execution did not start due to the given error.
+	Error(Error),
+}
+
+impl Outcome {
+	pub fn ensure_complete(self) -> Result {
+		match self {
+			Outcome::Complete(_) => Ok(()),
+			Outcome::Incomplete(_, e) => Err(e),
+			Outcome::Error(e) => Err(e),
+		}
+	}
+	pub fn ensure_execution(self) -> result::Result<Weight, Error> {
+		match self {
+			Outcome::Complete(w) => Ok(w),
+			Outcome::Incomplete(w, _) => Ok(w),
+			Outcome::Error(e) => Err(e),
+		}
+	}
+	/// How much weight was used by the XCM execution attempt.
+	pub fn weight_used(&self) -> Weight {
+		match self {
+			Outcome::Complete(w) => *w,
+			Outcome::Incomplete(w, _) => *w,
+			Outcome::Error(_) => 0,
+		}
+	}
+}
+
+/// Type of XCM message executor.
+pub trait ExecuteXcm<Call> {
+	/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The weight limit is
+	/// a basic hard-limit and the implementation may place further restrictions or requirements on weight and
+	/// other aspects.
+	fn execute_xcm(origin: MultiLocation, message: Xcm<Call>, weight_limit: Weight) -> Outcome {
+		Self::execute_xcm_in_credit(origin, message, weight_limit, 0)
+	}
+
+	/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight.
+	///
+	/// Some amount of `weight_credit` may be provided which, depending on the implementation, may allow
+	/// execution without associated payment.
+	fn execute_xcm_in_credit(
+		origin: MultiLocation,
+		message: Xcm<Call>,
+		weight_limit: Weight,
+		weight_credit: Weight,
+	) -> Outcome;
+}
+
+impl<C> ExecuteXcm<C> for () {
+	fn execute_xcm_in_credit(
+		_origin: MultiLocation,
+		_message: Xcm<C>,
+		_weight_limit: Weight,
+		_weight_credit: Weight,
+	) -> Outcome {
+		Outcome::Error(Error::Unimplemented)
+	}
+}
+
+/// Utility for sending an XCM message.
+///
+/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each router might return
+/// `CannotReachDestination` to pass the execution to the next sender item. Note that each `CannotReachDestination`
+/// might alter the destination and the xcm message for to the next router.
+///
+///
+/// # Example
+/// ```rust
+/// # use xcm::v0::{MultiLocation, Xcm, Junction, Error, OriginKind, SendXcm, Result};
+/// # use parity_scale_codec::Encode;
+///
+/// /// A sender that only passes the message through and does nothing.
+/// struct Sender1;
+/// impl SendXcm for Sender1 {
+///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
+///         return Err(Error::CannotReachDestination(destination, message))
+///     }
+/// }
+///
+/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing.
+/// struct Sender2;
+/// impl SendXcm for Sender2 {
+///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
+///         if let MultiLocation::X2(j1, j2) = destination {
+///             Ok(())
+///         } else {
+///             Err(Error::Undefined)
+///         }
+///     }
+/// }
+///
+/// /// A sender that accepts a message from an X1 parent junction, passing through otherwise.
+/// struct Sender3;
+/// impl SendXcm for Sender3 {
+///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
+///         match destination {
+///             MultiLocation::X1(j) if j == Junction::Parent => Ok(()),
+///             _ => Err(Error::CannotReachDestination(destination, message)),
+///         }
+///     }
+/// }
+///
+/// // A call to send via XCM. We don't really care about this.
+/// # fn main() {
+/// let call: Vec<u8> = ().encode();
+/// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
+/// let destination = MultiLocation::X1(Junction::Parent);
+///
+/// assert!(
+///     // Sender2 will block this.
+///     <(Sender1, Sender2, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
+///         .is_err()
+/// );
+///
+/// assert!(
+///     // Sender3 will catch this.
+///     <(Sender1, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
+///         .is_ok()
+/// );
+/// # }
+/// ```
+pub trait SendXcm {
+	/// Send an XCM `message` to a given `destination`.
+	///
+	/// If it is not a destination which can be reached with this type but possibly could by others, then it *MUST*
+	/// return `CannotReachDestination`. Any other error will cause the tuple implementation to exit early without
+	/// trying other type fields.
+	fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result;
+}
+
+#[impl_trait_for_tuples::impl_for_tuples(30)]
+impl SendXcm for Tuple {
+	fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
+		for_tuples!( #(
+			// we shadow `destination` and `message` in each expansion for the next one.
+			let (destination, message) = match Tuple::send_xcm(destination, message) {
+				Err(Error::CannotReachDestination(d, m)) => (d, m),
+				o @ _ => return o,
+			};
+		)* );
+		Err(Error::CannotReachDestination(destination, message))
+	}
+}

From 621e8737368257deacea7aa46da2e751539d775d Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 30 Jul 2021 09:09:39 -0700
Subject: [PATCH 003/166] Remove v1 module

---
 xcm/src/lib.rs               |   11 -
 xcm/src/v0/junction.rs       |   34 --
 xcm/src/v0/mod.rs            |    5 +-
 xcm/src/v0/multi_asset.rs    |    1 -
 xcm/src/v0/multi_location.rs | 1025 ++++++++++++++++++----------------
 xcm/src/v0/traits.rs         |   17 +-
 xcm/src/v1/junction.rs       |  133 -----
 xcm/src/v1/mod.rs            |  317 -----------
 xcm/src/v1/multi_asset.rs    |  380 -------------
 xcm/src/v1/multi_location.rs |  867 ----------------------------
 xcm/src/v1/order.rs          |  140 -----
 xcm/src/v1/traits.rs         |  246 --------
 12 files changed, 563 insertions(+), 2613 deletions(-)
 delete mode 100644 xcm/src/v1/junction.rs
 delete mode 100644 xcm/src/v1/mod.rs
 delete mode 100644 xcm/src/v1/multi_asset.rs
 delete mode 100644 xcm/src/v1/multi_location.rs
 delete mode 100644 xcm/src/v1/order.rs
 delete mode 100644 xcm/src/v1/traits.rs

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index b2d8d3a2a487..1addc44bd552 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -27,7 +27,6 @@ use parity_scale_codec::{Encode, Decode};
 use derivative::Derivative;
 
 pub mod v0;
-pub mod v1;
 
 mod double_encoded;
 pub use double_encoded::DoubleEncoded;
@@ -39,7 +38,6 @@ pub use double_encoded::DoubleEncoded;
 #[codec(decode_bound())]
 pub enum VersionedXcm<Call> {
 	V0(v0::Xcm<Call>),
-	V1(v1::Xcm<Call>),
 }
 
 pub mod opaque {
@@ -50,13 +48,6 @@ pub mod opaque {
 		pub use crate::v0::opaque::{Xcm, Order};
 	}
 
-	pub mod v1 {
-		// Everything from v1
-		pub use crate::v1::*;
-		// Then override with the opaque types in v1
-		pub use crate::v1::opaque::{Xcm, Order};
-	}
-
 	/// The basic `VersionedXcm` type which just uses the `Vec<u8>` as an encoded call.
 	pub type VersionedXcm = super::VersionedXcm<()>;
 }
@@ -65,12 +56,10 @@ pub mod opaque {
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum VersionedMultiLocation {
 	V0(v0::MultiLocation),
-	V1(v1::MultiLocation),
 }
 
 /// A versioned multi-asset, an identifier for an asset within a consensus system.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum VersionedMultiAsset {
 	V0(v0::MultiAsset),
-	V1(v1::MultiAsset),
 }
diff --git a/xcm/src/v0/junction.rs b/xcm/src/v0/junction.rs
index b89c665a3903..3785e11b672c 100644
--- a/xcm/src/v0/junction.rs
+++ b/xcm/src/v0/junction.rs
@@ -86,11 +86,6 @@ impl BodyPart {
 /// Each item assumes a pre-existing location as its context and is defined in terms of it.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
 pub enum Junction {
-	/// The consensus system of which the context is a member and state-wise super-set.
-	///
-	/// NOTE: This item is *not* a sub-consensus item: a consensus system may not identify itself trustlessly as
-	/// a location that includes this junction.
-	Parent,
 	/// An indexed parachain belonging to and operated by the context.
 	///
 	/// Generally used when the context is a Polkadot Relay-chain.
@@ -136,32 +131,3 @@ pub enum Junction {
 	/// things such as multisigs also.
 	Plurality { id: BodyId, part: BodyPart },
 }
-
-impl Junction {
-	/// Returns true if this junction is a `Parent` item.
-	pub fn is_parent(&self) -> bool {
-		match self {
-			Junction::Parent => true,
-			_ => false,
-		}
-	}
-
-	/// Returns true if this junction can be considered an interior part of its context. This is generally `true`,
-	/// except for the `Parent` item.
-	pub fn is_interior(&self) -> bool {
-		match self {
-			Junction::Parent => false,
-
-			Junction::Parachain(..)
-			| Junction::AccountId32 { .. }
-			| Junction::AccountIndex64 { .. }
-			| Junction::AccountKey20 { .. }
-			| Junction::PalletInstance { .. }
-			| Junction::GeneralIndex { .. }
-			| Junction::GeneralKey(..)
-			| Junction::OnlyChild
-			| Junction::Plurality { .. }
-			=> true,
-		}
-	}
-}
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 1263297aff2b..0ff166efb15a 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -29,7 +29,7 @@ mod order;
 mod traits;
 pub use junction::{Junction, NetworkId, BodyId, BodyPart};
 pub use multi_asset::{MultiAsset, AssetInstance};
-pub use multi_location::MultiLocation;
+pub use multi_location::{Junctions::{self, *}, MultiLocation};
 pub use order::Order;
 pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
 
@@ -37,7 +37,7 @@ pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
 pub mod prelude {
 	pub use super::junction::{Junction::*, NetworkId, BodyId, BodyPart};
 	pub use super::multi_asset::{MultiAsset::{self, *}, AssetInstance::{self, *}};
-	pub use super::multi_location::MultiLocation::{self, *};
+	pub use super::multi_location::{Junctions::{self, *}, MultiLocation};
 	pub use super::order::Order::{self, *};
 	pub use super::traits::{Error as XcmError, Result as XcmResult, SendXcm, ExecuteXcm, Outcome};
 	pub use super::{Xcm::{self, *}, OriginKind};
@@ -272,7 +272,6 @@ impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
 	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
 		match x {
 			VersionedXcm::V0(x) => Ok(x),
-			_ => Err(()),
 		}
 	}
 }
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
index 4dd0ba1cb4d2..dc682902df65 100644
--- a/xcm/src/v0/multi_asset.rs
+++ b/xcm/src/v0/multi_asset.rs
@@ -317,7 +317,6 @@ impl TryFrom<VersionedMultiAsset> for MultiAsset {
 	fn try_from(x: VersionedMultiAsset) -> result::Result<Self, ()> {
 		match x {
 			VersionedMultiAsset::V0(x) => Ok(x),
-			_ => Err(()),
 		}
 	}
 }
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 772c9738b8b7..c92efd903a21 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -16,7 +16,7 @@
 
 //! Cross-Consensus Message format data structures.
 
-use core::{result, mem, convert::TryFrom};
+use core::{convert::TryFrom, mem, result};
 
 use parity_scale_codec::{self, Encode, Decode};
 use super::Junction;
@@ -45,154 +45,487 @@ use crate::VersionedMultiLocation;
 ///
 /// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum MultiLocation {
-	/// The interpreting consensus system.
-	Null,
-	/// A relative path comprising 1 junction.
-	X1(Junction),
-	/// A relative path comprising 2 junctions.
-	X2(Junction, Junction),
-	/// A relative path comprising 3 junctions.
-	X3(Junction, Junction, Junction),
-	/// A relative path comprising 4 junctions.
-	X4(Junction, Junction, Junction, Junction),
-	/// A relative path comprising 5 junctions.
-	X5(Junction, Junction, Junction, Junction, Junction),
-	/// A relative path comprising 6 junctions.
-	X6(Junction, Junction, Junction, Junction, Junction, Junction),
-	/// A relative path comprising 7 junctions.
-	X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction),
-	/// A relative path comprising 8 junctions.
-	X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction),
+pub struct MultiLocation {
+	parents: u8,
+	junctions: Junctions,
 }
 
 /// Maximum number of junctions a `MultiLocation` can contain.
 pub const MAX_MULTILOCATION_LENGTH: usize = 8;
 
+impl MultiLocation {
+	/// Creates a new MultiLocation, ensuring that the length of it does not exceed the maximum,
+	/// otherwise returns `Err`.
+	pub fn new(parents: u8, junctions: Junctions) -> result::Result<MultiLocation, ()> {
+		if parents as usize + junctions.len() > MAX_MULTILOCATION_LENGTH {
+			return Err(())
+		}
+		Ok(MultiLocation {
+			parents,
+			junctions,
+		})
+	}
+
+	/// Return a reference to the junctions field.
+	pub fn junctions(&self) -> &Junctions {
+		&self.junctions
+	}
+
+	/// Return a mutable reference to the junctions field.
+	pub fn junctions_mut(&mut self) -> &mut Junctions {
+		&mut self.junctions
+	}
+
+	/// Returns the number of `Parent` junctions at the beginning of `self`.
+	pub fn parent_count(&self) -> usize {
+		self.parents as usize
+	}
+
+	/// Returns the number of parents and junctions in `self`.
+	pub fn len(&self) -> usize {
+		self.parent_count() + self.junctions.len()
+	}
+
+	/// Returns first junction that is not a parent, or `None` if the location is empty or
+	/// contains only parents.
+	pub fn first_non_parent(&self) -> Option<&Junction> {
+		self.junctions.first()
+	}
+
+	/// Returns last junction, or `None` if the location is empty or contains only parents.
+	pub fn last(&self) -> Option<&Junction> {
+		self.junctions.last()
+	}
+
+	/// Splits off the first non-parent junction, returning the remaining suffix (first item in tuple)
+	/// and the first element (second item in tuple) or `None` if it was empty.
+	pub fn split_first_non_parent(self) -> (MultiLocation, Option<Junction>) {
+		let MultiLocation { parents, junctions } = self;
+		let (prefix, suffix) = junctions.split_first();
+		let multilocation = MultiLocation {
+			parents,
+			junctions: prefix,
+		};
+		(multilocation, suffix)
+	}
+
+	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
+	/// (second item in tuple) or `None` if it was empty or that `self` only contains parents.
+	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
+		let MultiLocation { parents, junctions } = self;
+		let (prefix, suffix) = junctions.split_last();
+		let multilocation = MultiLocation {
+			parents,
+			junctions: prefix,
+		};
+		(multilocation, suffix)
+	}
+
+	/// Bumps the parent count up by 1. Returns `Err` in case of overflow.
+	pub fn push_parent(&mut self) -> result::Result<(), ()> {
+		if self.len() >= MAX_MULTILOCATION_LENGTH {
+			return Err(())
+		}
+		self.parents = self.parents.saturating_add(1);
+		Ok(())
+	}
+
+	/// Mutates `self`, suffixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
+	pub fn push_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
+		let mut n = Junctions::Null;
+		mem::swap(&mut self.junctions, &mut n);
+		match n.pushed_with(new) {
+			Ok(result) => { self.junctions = result; Ok(()) }
+			Err(old) => { self.junctions = old; Err(()) }
+		}
+	}
+
+	/// Mutates `self`, prefixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
+	pub fn push_front_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
+		let mut n = Junctions::Null;
+		mem::swap(&mut self.junctions, &mut n);
+		match n.pushed_front_with(new) {
+			Ok(result) => { self.junctions = result; Ok(()) }
+			Err(old) => { self.junctions = old; Err(()) }
+		}
+	}
+
+	/// Consumes `self` and returns a `MultiLocation` with its parent count incremented by 1, or
+	/// an `Err` with the original value of `self` in case of overflow.
+	pub fn pushed_with_parent(self) -> result::Result<Self, Self> {
+		if self.len() >= MAX_MULTILOCATION_LENGTH {
+			return Err(self)
+		}
+		Ok(MultiLocation {
+			parents: self.parents.saturating_add(1),
+			..self
+		})
+	}
+
+	/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with the original value of
+	/// `self` in case of overflow.
+	pub fn pushed_with_non_parent(self, new: Junction) -> result::Result<Self, Self> {
+		if self.len() >= MAX_MULTILOCATION_LENGTH {
+			return Err(self)
+		}
+		Ok(MultiLocation {
+			parents: self.parents,
+			junctions: self.junctions.pushed_with(new).expect("length is less than max length; qed"),
+		})
+	}
+
+	/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
+	/// `self` in case of overflow.
+	pub fn pushed_front_with_non_parent(self, new: Junction) -> result::Result<Self, Self> {
+		if self.len() >= MAX_MULTILOCATION_LENGTH {
+			return Err(self)
+		}
+		Ok(MultiLocation {
+			parents: self.parents,
+			junctions: self.junctions.pushed_front_with(new).expect("length is less than max length; qed"),
+		})
+	}
+
+	/// Returns the junction at index `i`, or `None` if the location is a parent or if the location
+	/// does not contain that many elements.
+	pub fn at(&self, i: usize) -> Option<&Junction> {
+		let num_parents = self.parents as usize;
+		if i < num_parents {
+			return None
+		}
+		self.junctions.at(i - num_parents)
+	}
+
+	/// Returns a mutable reference to the junction at index `i`, or `None` if the location is a
+	/// parent or if it doesn't contain that many elements.
+	pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
+		let num_parents = self.parents as usize;
+		if i < num_parents {
+			return None
+		}
+		self.junctions.at_mut(i - num_parents)
+	}
+
+	/// Decrement the parent count by 1.
+	pub fn pop_parent(&mut self) {
+		self.parents = self.parents.saturating_sub(1);
+	}
+
+	/// Removes the first non-parent element from `self`, returning it
+	/// (or `None` if it was empty or if `self` contains only parents).
+	pub fn take_first_non_parent(&mut self) -> Option<Junction> {
+		self.junctions.take_first()
+	}
+
+	/// Removes the last element from `junctions`, returning it (or `None` if it was empty or if
+	/// `self` only contains parents).
+	pub fn take_last(&mut self) -> Option<Junction> {
+		self.junctions.take_last()
+	}
+
+	/// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with
+	/// the junctions of `prefix` and that it has a single `Junction` item following.
+	/// If so, returns a reference to this `Junction` item.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v0::{Junctions::*, Junction::*, MultiLocation};
+	/// # fn main() {
+	/// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)).unwrap();
+	/// assert_eq!(
+	///     m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3))).unwrap()),
+	///     Some(&OnlyChild),
+	/// );
+	/// assert_eq!(m.match_and_split(&MultiLocation::new(1, Null).unwrap()), None);
+	/// # }
+	/// ```
+	pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> {
+		if self.parents != prefix.parents {
+			return None
+		}
+		self.junctions.match_and_split(&prefix.junctions)
+	}
+
+	/// Mutate `self` so that it is suffixed with `suffix`. The correct normalized form is returned,
+	/// removing any internal [Non-Parent, `Parent`]  combinations.
+	///
+	/// Does not modify `self` and returns `Err` with `suffix` in case of overflow.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v0::{Junctions::*, Junction::*, MultiLocation};
+	/// # fn main() {
+	/// let mut m = MultiLocation::new(1, X2(Parachain(21), OnlyChild)).unwrap();
+	/// assert_eq!(m.append_with(MultiLocation::new(1, X1(PalletInstance(3))).unwrap()), Ok(()));
+	/// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3))).unwrap());
+	/// # }
+	/// ```
+	pub fn append_with(&mut self, suffix: MultiLocation) -> Result<(), MultiLocation> {
+		let mut prefix = suffix;
+		core::mem::swap(self, &mut prefix);
+		match self.prepend_with(prefix) {
+			Ok(()) => Ok(()),
+			Err(prefix) => {
+				let mut suffix = prefix;
+				core::mem::swap(self, &mut suffix);
+				Err(suffix)
+			}
+		}
+	}
+
+	/// Mutate `self` so that it is prefixed with `prefix`.
+	///
+	/// Does not modify `self` and returns `Err` with `prefix` in case of overflow.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v0::{Junctions::*, Junction::*, MultiLocation};
+	/// # fn main() {
+	/// let mut m = MultiLocation::new(2, X1(PalletInstance(3))).unwrap();
+	/// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild)).unwrap()), Ok(()));
+	/// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3))).unwrap());
+	/// # }
+	/// ```
+	pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> {
+		let self_parents = self.parent_count();
+		let prepend_len = (self_parents as isize - prefix.junctions.len() as isize).abs() as usize;
+		if self.junctions.len() + prefix.parent_count() + prepend_len > MAX_MULTILOCATION_LENGTH {
+			return Err(prefix)
+		}
+
+		let mut final_parent_count = prefix.parents;
+		for _ in 0..self_parents {
+			if prefix.take_last().is_none() {
+				// If true, this means self parent count is greater than prefix junctions length;
+				// add the resulting self parent count to final_parent_count
+				final_parent_count += self.parents;
+				break
+			}
+			self.pop_parent();
+		}
+
+		self.parents = final_parent_count;
+		for j in prefix.junctions.into_iter_rev() {
+			self.push_front_non_parent(j).expect(
+				"self junctions len + prefix parent count + prepend len is less than max length; qed"
+			);
+		}
+		Ok(())
+	}
+}
+
+impl From<Junctions> for MultiLocation {
+	fn from(junctions: Junctions) -> Self {
+		MultiLocation {
+			parents: 0,
+			junctions,
+		}
+	}
+}
+
 impl From<Junction> for MultiLocation {
 	fn from(x: Junction) -> Self {
-		MultiLocation::X1(x)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X1(x),
+		}
 	}
 }
 
 impl From<()> for MultiLocation {
 	fn from(_: ()) -> Self {
-		MultiLocation::Null
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::Null,
+		}
 	}
 }
 impl From<(Junction,)> for MultiLocation {
 	fn from(x: (Junction,)) -> Self {
-		MultiLocation::X1(x.0)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X1(x.0),
+		}
 	}
 }
 impl From<(Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction)) -> Self {
-		MultiLocation::X2(x.0, x.1)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X2(x.0, x.1),
+		}
 	}
 }
 impl From<(Junction, Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction, Junction)) -> Self {
-		MultiLocation::X3(x.0, x.1, x.2)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X3(x.0, x.1, x.2),
+		}
 	}
 }
 impl From<(Junction, Junction, Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation::X4(x.0, x.1, x.2, x.3)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X4(x.0, x.1, x.2, x.3),
+		}
 	}
 }
 impl From<(Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation::X5(x.0, x.1, x.2, x.3, x.4)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X5(x.0, x.1, x.2, x.3, x.4),
+		}
 	}
 }
 impl From<(Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation::X6(x.0, x.1, x.2, x.3, x.4, x.5)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X6(x.0, x.1, x.2, x.3, x.4, x.5),
+		}
 	}
 }
 impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation::X7(x.0, x.1, x.2, x.3, x.4, x.5, x.6)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X7(x.0, x.1, x.2, x.3, x.4, x.5, x.6),
+		}
 	}
 }
 impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation::X8(x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X8(x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7),
+		}
 	}
 }
 
 impl From<[Junction; 0]> for MultiLocation {
 	fn from(_: [Junction; 0]) -> Self {
-		MultiLocation::Null
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::Null,
+		}
 	}
 }
 impl From<[Junction; 1]> for MultiLocation {
 	fn from(x: [Junction; 1]) -> Self {
 		let [x0] = x;
-		MultiLocation::X1(x0)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X1(x0),
+		}
 	}
 }
 impl From<[Junction; 2]> for MultiLocation {
 	fn from(x: [Junction; 2]) -> Self {
 		let [x0, x1] = x;
-		MultiLocation::X2(x0, x1)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X2(x0, x1),
+		}
 	}
 }
 impl From<[Junction; 3]> for MultiLocation {
 	fn from(x: [Junction; 3]) -> Self {
 		let [x0, x1, x2] = x;
-		MultiLocation::X3(x0, x1, x2)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X3(x0, x1, x2),
+		}
 	}
 }
 impl From<[Junction; 4]> for MultiLocation {
 	fn from(x: [Junction; 4]) -> Self {
 		let [x0, x1, x2, x3] = x;
-		MultiLocation::X4(x0, x1, x2, x3)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X4(x0, x1, x2, x3),
+		}
 	}
 }
 impl From<[Junction; 5]> for MultiLocation {
 	fn from(x: [Junction; 5]) -> Self {
 		let [x0, x1, x2, x3, x4] = x;
-		MultiLocation::X5(x0, x1, x2, x3, x4)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X5(x0, x1, x2, x3, x4),
+		}
 	}
 }
 impl From<[Junction; 6]> for MultiLocation {
 	fn from(x: [Junction; 6]) -> Self {
 		let [x0, x1, x2, x3, x4, x5] = x;
-		MultiLocation::X6(x0, x1, x2, x3, x4, x5)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X6(x0, x1, x2, x3, x4, x5),
+		}
 	}
 }
 impl From<[Junction; 7]> for MultiLocation {
 	fn from(x: [Junction; 7]) -> Self {
 		let [x0, x1, x2, x3, x4, x5, x6] = x;
-		MultiLocation::X7(x0, x1, x2, x3, x4, x5, x6)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X7(x0, x1, x2, x3, x4, x5, x6),
+		}
 	}
 }
 impl From<[Junction; 8]> for MultiLocation {
 	fn from(x: [Junction; 8]) -> Self {
 		let [x0, x1, x2, x3, x4, x5, x6, x7] = x;
-		MultiLocation::X8(x0, x1, x2, x3, x4, x5, x6, x7)
+		MultiLocation {
+			parents: 0,
+			junctions: Junctions::X8(x0, x1, x2, x3, x4, x5, x6, x7),
+		}
 	}
 }
 
-pub struct MultiLocationIterator(MultiLocation);
-impl Iterator for MultiLocationIterator {
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum Junctions {
+	/// The interpreting consensus system.
+	Null,
+	/// A relative path comprising 1 junction.
+	X1(Junction),
+	/// A relative path comprising 2 junctions.
+	X2(Junction, Junction),
+	/// A relative path comprising 3 junctions.
+	X3(Junction, Junction, Junction),
+	/// A relative path comprising 4 junctions.
+	X4(Junction, Junction, Junction, Junction),
+	/// A relative path comprising 5 junctions.
+	X5(Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 6 junctions.
+	X6(Junction, Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 7 junctions.
+	X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 8 junctions.
+	X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction),
+}
+
+pub struct JunctionsIterator(Junctions);
+impl Iterator for JunctionsIterator {
 	type Item = Junction;
 	fn next(&mut self) -> Option<Junction> {
 		self.0.take_first()
 	}
 }
 
-pub struct MultiLocationReverseIterator(MultiLocation);
-impl Iterator for MultiLocationReverseIterator {
+pub struct JunctionsReverseIterator(Junctions);
+impl Iterator for JunctionsReverseIterator {
 	type Item = Junction;
 	fn next(&mut self) -> Option<Junction> {
 		self.0.take_last()
 	}
 }
 
-pub struct MultiLocationRefIterator<'a>(&'a MultiLocation, usize);
-impl<'a> Iterator for MultiLocationRefIterator<'a> {
+pub struct JunctionsRefIterator<'a>(&'a Junctions, usize);
+impl<'a> Iterator for JunctionsRefIterator<'a> {
 	type Item = &'a Junction;
 	fn next(&mut self) -> Option<&'a Junction> {
 		let result = self.0.at(self.1);
@@ -201,8 +534,8 @@ impl<'a> Iterator for MultiLocationRefIterator<'a> {
 	}
 }
 
-pub struct MultiLocationReverseRefIterator<'a>(&'a MultiLocation, usize);
-impl<'a> Iterator for MultiLocationReverseRefIterator<'a> {
+pub struct JunctionsReverseRefIterator<'a>(&'a Junctions, usize);
+impl<'a> Iterator for JunctionsReverseRefIterator<'a> {
 	type Item = &'a Junction;
 	fn next(&mut self) -> Option<&'a Junction> {
 		self.1 += 1;
@@ -210,72 +543,72 @@ impl<'a> Iterator for MultiLocationReverseRefIterator<'a> {
 	}
 }
 
-impl MultiLocation {
+impl Junctions {
 	/// Returns first junction, or `None` if the location is empty.
 	pub fn first(&self) -> Option<&Junction> {
 		match &self {
-			MultiLocation::Null => None,
-			MultiLocation::X1(ref a) => Some(a),
-			MultiLocation::X2(ref a, ..) => Some(a),
-			MultiLocation::X3(ref a, ..) => Some(a),
-			MultiLocation::X4(ref a, ..) => Some(a),
-			MultiLocation::X5(ref a, ..) => Some(a),
-			MultiLocation::X6(ref a, ..) => Some(a),
-			MultiLocation::X7(ref a, ..) => Some(a),
-			MultiLocation::X8(ref a, ..) => Some(a),
+			Junctions::Null => None,
+			Junctions::X1(ref a) => Some(a),
+			Junctions::X2(ref a, ..) => Some(a),
+			Junctions::X3(ref a, ..) => Some(a),
+			Junctions::X4(ref a, ..) => Some(a),
+			Junctions::X5(ref a, ..) => Some(a),
+			Junctions::X6(ref a, ..) => Some(a),
+			Junctions::X7(ref a, ..) => Some(a),
+			Junctions::X8(ref a, ..) => Some(a),
 		}
 	}
 
 	/// Returns last junction, or `None` if the location is empty.
 	pub fn last(&self) -> Option<&Junction> {
 		match &self {
-			MultiLocation::Null => None,
-			MultiLocation::X1(ref a) => Some(a),
-			MultiLocation::X2(.., ref a) => Some(a),
-			MultiLocation::X3(.., ref a) => Some(a),
-			MultiLocation::X4(.., ref a) => Some(a),
-			MultiLocation::X5(.., ref a) => Some(a),
-			MultiLocation::X6(.., ref a) => Some(a),
-			MultiLocation::X7(.., ref a) => Some(a),
-			MultiLocation::X8(.., ref a) => Some(a),
+			Junctions::Null => None,
+			Junctions::X1(ref a) => Some(a),
+			Junctions::X2(.., ref a) => Some(a),
+			Junctions::X3(.., ref a) => Some(a),
+			Junctions::X4(.., ref a) => Some(a),
+			Junctions::X5(.., ref a) => Some(a),
+			Junctions::X6(.., ref a) => Some(a),
+			Junctions::X7(.., ref a) => Some(a),
+			Junctions::X8(.., ref a) => Some(a),
 		}
 	}
 
 	/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the first element
 	/// (second item in tuple) or `None` if it was empty.
-	pub fn split_first(self) -> (MultiLocation, Option<Junction>) {
+	pub fn split_first(self) -> (Junctions, Option<Junction>) {
 		match self {
-			MultiLocation::Null => (MultiLocation::Null, None),
-			MultiLocation::X1(a) => (MultiLocation::Null, Some(a)),
-			MultiLocation::X2(a, b) => (MultiLocation::X1(b), Some(a)),
-			MultiLocation::X3(a, b, c) => (MultiLocation::X2(b, c), Some(a)),
-			MultiLocation::X4(a, b, c ,d) => (MultiLocation::X3(b, c, d), Some(a)),
-			MultiLocation::X5(a, b, c ,d, e) => (MultiLocation::X4(b, c, d, e), Some(a)),
-			MultiLocation::X6(a, b, c ,d, e, f) => (MultiLocation::X5(b, c, d, e, f), Some(a)),
-			MultiLocation::X7(a, b, c ,d, e, f, g) => (MultiLocation::X6(b, c, d, e, f, g), Some(a)),
-			MultiLocation::X8(a, b, c ,d, e, f, g, h) => (MultiLocation::X7(b, c, d, e, f, g, h), Some(a)),
+			Junctions::Null => (Junctions::Null, None),
+			Junctions::X1(a) => (Junctions::Null, Some(a)),
+			Junctions::X2(a, b) => (Junctions::X1(b), Some(a)),
+			Junctions::X3(a, b, c) => (Junctions::X2(b, c), Some(a)),
+			Junctions::X4(a, b, c ,d) => (Junctions::X3(b, c, d), Some(a)),
+			Junctions::X5(a, b, c ,d, e) => (Junctions::X4(b, c, d, e), Some(a)),
+			Junctions::X6(a, b, c ,d, e, f) => (Junctions::X5(b, c, d, e, f), Some(a)),
+			Junctions::X7(a, b, c ,d, e, f, g) => (Junctions::X6(b, c, d, e, f, g), Some(a)),
+			Junctions::X8(a, b, c ,d, e, f, g, h) => (Junctions::X7(b, c, d, e, f, g, h), Some(a)),
 		}
 	}
 
 	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
 	/// (second item in tuple) or `None` if it was empty.
-	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
+	pub fn split_last(self) -> (Junctions, Option<Junction>) {
 		match self {
-			MultiLocation::Null => (MultiLocation::Null, None),
-			MultiLocation::X1(a) => (MultiLocation::Null, Some(a)),
-			MultiLocation::X2(a, b) => (MultiLocation::X1(a), Some(b)),
-			MultiLocation::X3(a, b, c) => (MultiLocation::X2(a, b), Some(c)),
-			MultiLocation::X4(a, b, c ,d) => (MultiLocation::X3(a, b, c), Some(d)),
-			MultiLocation::X5(a, b, c, d, e) => (MultiLocation::X4(a, b, c, d), Some(e)),
-			MultiLocation::X6(a, b, c, d, e, f) => (MultiLocation::X5(a, b, c, d, e), Some(f)),
-			MultiLocation::X7(a, b, c, d, e, f, g) => (MultiLocation::X6(a, b, c, d, e, f), Some(g)),
-			MultiLocation::X8(a, b, c, d, e, f, g, h) => (MultiLocation::X7(a, b, c, d, e, f, g), Some(h)),
+			Junctions::Null => (Junctions::Null, None),
+			Junctions::X1(a) => (Junctions::Null, Some(a)),
+			Junctions::X2(a, b) => (Junctions::X1(a), Some(b)),
+			Junctions::X3(a, b, c) => (Junctions::X2(a, b), Some(c)),
+			Junctions::X4(a, b, c ,d) => (Junctions::X3(a, b, c), Some(d)),
+			Junctions::X5(a, b, c, d, e) => (Junctions::X4(a, b, c, d), Some(e)),
+			Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(a, b, c, d, e), Some(f)),
+			Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(a, b, c, d, e, f), Some(g)),
+			Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(a, b, c, d, e, f, g), Some(h)),
 		}
 	}
 
 	/// Removes the first element from `self`, returning it (or `None` if it was empty).
 	pub fn take_first(&mut self) -> Option<Junction> {
-		let mut d = MultiLocation::Null;
+		let mut d = Junctions::Null;
 		mem::swap(&mut *self, &mut d);
 		let (tail, head) = d.split_first();
 		*self = tail;
@@ -284,41 +617,41 @@ impl MultiLocation {
 
 	/// Removes the last element from `self`, returning it (or `None` if it was empty).
 	pub fn take_last(&mut self) -> Option<Junction> {
-		let mut d = MultiLocation::Null;
+		let mut d = Junctions::Null;
 		mem::swap(&mut *self, &mut d);
 		let (head, tail) = d.split_last();
 		*self = head;
 		tail
 	}
 
-	/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with the original value of
+	/// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the original value of
 	/// `self` in case of overflow.
 	pub fn pushed_with(self, new: Junction) -> result::Result<Self, Self> {
 		Ok(match self {
-			MultiLocation::Null => MultiLocation::X1(new),
-			MultiLocation::X1(a) => MultiLocation::X2(a, new),
-			MultiLocation::X2(a, b) => MultiLocation::X3(a, b, new),
-			MultiLocation::X3(a, b, c) => MultiLocation::X4(a, b, c, new),
-			MultiLocation::X4(a, b, c, d) => MultiLocation::X5(a, b, c, d, new),
-			MultiLocation::X5(a, b, c, d, e) => MultiLocation::X6(a, b, c, d, e, new),
-			MultiLocation::X6(a, b, c, d, e, f) => MultiLocation::X7(a, b, c, d, e, f, new),
-			MultiLocation::X7(a, b, c, d, e, f, g) => MultiLocation::X8(a, b, c, d, e, f, g, new),
+			Junctions::Null => Junctions::X1(new),
+			Junctions::X1(a) => Junctions::X2(a, new),
+			Junctions::X2(a, b) => Junctions::X3(a, b, new),
+			Junctions::X3(a, b, c) => Junctions::X4(a, b, c, new),
+			Junctions::X4(a, b, c, d) => Junctions::X5(a, b, c, d, new),
+			Junctions::X5(a, b, c, d, e) => Junctions::X6(a, b, c, d, e, new),
+			Junctions::X6(a, b, c, d, e, f) => Junctions::X7(a, b, c, d, e, f, new),
+			Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(a, b, c, d, e, f, g, new),
 			s => Err(s)?,
 		})
 	}
 
-	/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
+	/// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the original value of
 	/// `self` in case of overflow.
 	pub fn pushed_front_with(self, new: Junction) -> result::Result<Self, Self> {
 		Ok(match self {
-			MultiLocation::Null => MultiLocation::X1(new),
-			MultiLocation::X1(a) => MultiLocation::X2(new, a),
-			MultiLocation::X2(a, b) => MultiLocation::X3(new, a, b),
-			MultiLocation::X3(a, b, c) => MultiLocation::X4(new, a, b, c),
-			MultiLocation::X4(a, b, c, d) => MultiLocation::X5(new, a, b, c, d),
-			MultiLocation::X5(a, b, c, d, e) => MultiLocation::X6(new, a, b, c, d, e),
-			MultiLocation::X6(a, b, c, d, e, f) => MultiLocation::X7(new, a, b, c, d, e, f),
-			MultiLocation::X7(a, b, c, d, e, f, g) => MultiLocation::X8(new, a, b, c, d, e, f, g),
+			Junctions::Null => Junctions::X1(new),
+			Junctions::X1(a) => Junctions::X2(new, a),
+			Junctions::X2(a, b) => Junctions::X3(new, a, b),
+			Junctions::X3(a, b, c) => Junctions::X4(new, a, b, c),
+			Junctions::X4(a, b, c, d) => Junctions::X5(new, a, b, c, d),
+			Junctions::X5(a, b, c, d, e) => Junctions::X6(new, a, b, c, d, e),
+			Junctions::X6(a, b, c, d, e, f) => Junctions::X7(new, a, b, c, d, e, f),
+			Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(new, a, b, c, d, e, f, g),
 			s => Err(s)?,
 		})
 	}
@@ -326,57 +659,57 @@ impl MultiLocation {
 	/// Returns the number of junctions in `self`.
 	pub fn len(&self) -> usize {
 		match &self {
-			MultiLocation::Null => 0,
-			MultiLocation::X1(..) => 1,
-			MultiLocation::X2(..) => 2,
-			MultiLocation::X3(..) => 3,
-			MultiLocation::X4(..) => 4,
-			MultiLocation::X5(..) => 5,
-			MultiLocation::X6(..) => 6,
-			MultiLocation::X7(..) => 7,
-			MultiLocation::X8(..) => 8,
+			Junctions::Null => 0,
+			Junctions::X1(..) => 1,
+			Junctions::X2(..) => 2,
+			Junctions::X3(..) => 3,
+			Junctions::X4(..) => 4,
+			Junctions::X5(..) => 5,
+			Junctions::X6(..) => 6,
+			Junctions::X7(..) => 7,
+			Junctions::X8(..) => 8,
 		}
 	}
 
 	/// Returns the junction at index `i`, or `None` if the location doesn't contain that many elements.
 	pub fn at(&self, i: usize) -> Option<&Junction> {
 		Some(match (i, &self) {
-			(0, MultiLocation::X1(ref a)) => a,
-			(0, MultiLocation::X2(ref a, ..)) => a,
-			(0, MultiLocation::X3(ref a, ..)) => a,
-			(0, MultiLocation::X4(ref a, ..)) => a,
-			(0, MultiLocation::X5(ref a, ..)) => a,
-			(0, MultiLocation::X6(ref a, ..)) => a,
-			(0, MultiLocation::X7(ref a, ..)) => a,
-			(0, MultiLocation::X8(ref a, ..)) => a,
-			(1, MultiLocation::X2(_, ref a)) => a,
-			(1, MultiLocation::X3(_, ref a, ..)) => a,
-			(1, MultiLocation::X4(_, ref a, ..)) => a,
-			(1, MultiLocation::X5(_, ref a, ..)) => a,
-			(1, MultiLocation::X6(_, ref a, ..)) => a,
-			(1, MultiLocation::X7(_, ref a, ..)) => a,
-			(1, MultiLocation::X8(_, ref a, ..)) => a,
-			(2, MultiLocation::X3(_, _, ref a)) => a,
-			(2, MultiLocation::X4(_, _, ref a, ..)) => a,
-			(2, MultiLocation::X5(_, _, ref a, ..)) => a,
-			(2, MultiLocation::X6(_, _, ref a, ..)) => a,
-			(2, MultiLocation::X7(_, _, ref a, ..)) => a,
-			(2, MultiLocation::X8(_, _, ref a, ..)) => a,
-			(3, MultiLocation::X4(_, _, _, ref a)) => a,
-			(3, MultiLocation::X5(_, _, _, ref a, ..)) => a,
-			(3, MultiLocation::X6(_, _, _, ref a, ..)) => a,
-			(3, MultiLocation::X7(_, _, _, ref a, ..)) => a,
-			(3, MultiLocation::X8(_, _, _, ref a, ..)) => a,
-			(4, MultiLocation::X5(_, _, _, _, ref a)) => a,
-			(4, MultiLocation::X6(_, _, _, _, ref a, ..)) => a,
-			(4, MultiLocation::X7(_, _, _, _, ref a, ..)) => a,
-			(4, MultiLocation::X8(_, _, _, _, ref a, ..)) => a,
-			(5, MultiLocation::X6(_, _, _, _, _, ref a)) => a,
-			(5, MultiLocation::X7(_, _, _, _, _, ref a, ..)) => a,
-			(5, MultiLocation::X8(_, _, _, _, _, ref a, ..)) => a,
-			(6, MultiLocation::X7(_, _, _, _, _, _, ref a)) => a,
-			(6, MultiLocation::X8(_, _, _, _, _, _, ref a, ..)) => a,
-			(7, MultiLocation::X8(_, _, _, _, _, _, _, ref a)) => a,
+			(0, Junctions::X1(ref a)) => a,
+			(0, Junctions::X2(ref a, ..)) => a,
+			(0, Junctions::X3(ref a, ..)) => a,
+			(0, Junctions::X4(ref a, ..)) => a,
+			(0, Junctions::X5(ref a, ..)) => a,
+			(0, Junctions::X6(ref a, ..)) => a,
+			(0, Junctions::X7(ref a, ..)) => a,
+			(0, Junctions::X8(ref a, ..)) => a,
+			(1, Junctions::X2(_, ref a)) => a,
+			(1, Junctions::X3(_, ref a, ..)) => a,
+			(1, Junctions::X4(_, ref a, ..)) => a,
+			(1, Junctions::X5(_, ref a, ..)) => a,
+			(1, Junctions::X6(_, ref a, ..)) => a,
+			(1, Junctions::X7(_, ref a, ..)) => a,
+			(1, Junctions::X8(_, ref a, ..)) => a,
+			(2, Junctions::X3(_, _, ref a)) => a,
+			(2, Junctions::X4(_, _, ref a, ..)) => a,
+			(2, Junctions::X5(_, _, ref a, ..)) => a,
+			(2, Junctions::X6(_, _, ref a, ..)) => a,
+			(2, Junctions::X7(_, _, ref a, ..)) => a,
+			(2, Junctions::X8(_, _, ref a, ..)) => a,
+			(3, Junctions::X4(_, _, _, ref a)) => a,
+			(3, Junctions::X5(_, _, _, ref a, ..)) => a,
+			(3, Junctions::X6(_, _, _, ref a, ..)) => a,
+			(3, Junctions::X7(_, _, _, ref a, ..)) => a,
+			(3, Junctions::X8(_, _, _, ref a, ..)) => a,
+			(4, Junctions::X5(_, _, _, _, ref a)) => a,
+			(4, Junctions::X6(_, _, _, _, ref a, ..)) => a,
+			(4, Junctions::X7(_, _, _, _, ref a, ..)) => a,
+			(4, Junctions::X8(_, _, _, _, ref a, ..)) => a,
+			(5, Junctions::X6(_, _, _, _, _, ref a)) => a,
+			(5, Junctions::X7(_, _, _, _, _, ref a, ..)) => a,
+			(5, Junctions::X8(_, _, _, _, _, ref a, ..)) => a,
+			(6, Junctions::X7(_, _, _, _, _, _, ref a)) => a,
+			(6, Junctions::X8(_, _, _, _, _, _, ref a, ..)) => a,
+			(7, Junctions::X8(_, _, _, _, _, _, _, ref a)) => a,
 			_ => return None,
 		})
 	}
@@ -385,64 +718,64 @@ impl MultiLocation {
 	/// elements.
 	pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
 		Some(match (i, self) {
-			(0, MultiLocation::X1(ref mut a)) => a,
-			(0, MultiLocation::X2(ref mut a, ..)) => a,
-			(0, MultiLocation::X3(ref mut a, ..)) => a,
-			(0, MultiLocation::X4(ref mut a, ..)) => a,
-			(0, MultiLocation::X5(ref mut a, ..)) => a,
-			(0, MultiLocation::X6(ref mut a, ..)) => a,
-			(0, MultiLocation::X7(ref mut a, ..)) => a,
-			(0, MultiLocation::X8(ref mut a, ..)) => a,
-			(1, MultiLocation::X2(_, ref mut a)) => a,
-			(1, MultiLocation::X3(_, ref mut a, ..)) => a,
-			(1, MultiLocation::X4(_, ref mut a, ..)) => a,
-			(1, MultiLocation::X5(_, ref mut a, ..)) => a,
-			(1, MultiLocation::X6(_, ref mut a, ..)) => a,
-			(1, MultiLocation::X7(_, ref mut a, ..)) => a,
-			(1, MultiLocation::X8(_, ref mut a, ..)) => a,
-			(2, MultiLocation::X3(_, _, ref mut a)) => a,
-			(2, MultiLocation::X4(_, _, ref mut a, ..)) => a,
-			(2, MultiLocation::X5(_, _, ref mut a, ..)) => a,
-			(2, MultiLocation::X6(_, _, ref mut a, ..)) => a,
-			(2, MultiLocation::X7(_, _, ref mut a, ..)) => a,
-			(2, MultiLocation::X8(_, _, ref mut a, ..)) => a,
-			(3, MultiLocation::X4(_, _, _, ref mut a)) => a,
-			(3, MultiLocation::X5(_, _, _, ref mut a, ..)) => a,
-			(3, MultiLocation::X6(_, _, _, ref mut a, ..)) => a,
-			(3, MultiLocation::X7(_, _, _, ref mut a, ..)) => a,
-			(3, MultiLocation::X8(_, _, _, ref mut a, ..)) => a,
-			(4, MultiLocation::X5(_, _, _, _, ref mut a)) => a,
-			(4, MultiLocation::X6(_, _, _, _, ref mut a, ..)) => a,
-			(4, MultiLocation::X7(_, _, _, _, ref mut a, ..)) => a,
-			(4, MultiLocation::X8(_, _, _, _, ref mut a, ..)) => a,
-			(5, MultiLocation::X6(_, _, _, _, _, ref mut a)) => a,
-			(5, MultiLocation::X7(_, _, _, _, _, ref mut a, ..)) => a,
-			(5, MultiLocation::X8(_, _, _, _, _, ref mut a, ..)) => a,
-			(6, MultiLocation::X7(_, _, _, _, _, _, ref mut a)) => a,
-			(6, MultiLocation::X8(_, _, _, _, _, _, ref mut a, ..)) => a,
-			(7, MultiLocation::X8(_, _, _, _, _, _, _, ref mut a)) => a,
+			(0, Junctions::X1(ref mut a)) => a,
+			(0, Junctions::X2(ref mut a, ..)) => a,
+			(0, Junctions::X3(ref mut a, ..)) => a,
+			(0, Junctions::X4(ref mut a, ..)) => a,
+			(0, Junctions::X5(ref mut a, ..)) => a,
+			(0, Junctions::X6(ref mut a, ..)) => a,
+			(0, Junctions::X7(ref mut a, ..)) => a,
+			(0, Junctions::X8(ref mut a, ..)) => a,
+			(1, Junctions::X2(_, ref mut a)) => a,
+			(1, Junctions::X3(_, ref mut a, ..)) => a,
+			(1, Junctions::X4(_, ref mut a, ..)) => a,
+			(1, Junctions::X5(_, ref mut a, ..)) => a,
+			(1, Junctions::X6(_, ref mut a, ..)) => a,
+			(1, Junctions::X7(_, ref mut a, ..)) => a,
+			(1, Junctions::X8(_, ref mut a, ..)) => a,
+			(2, Junctions::X3(_, _, ref mut a)) => a,
+			(2, Junctions::X4(_, _, ref mut a, ..)) => a,
+			(2, Junctions::X5(_, _, ref mut a, ..)) => a,
+			(2, Junctions::X6(_, _, ref mut a, ..)) => a,
+			(2, Junctions::X7(_, _, ref mut a, ..)) => a,
+			(2, Junctions::X8(_, _, ref mut a, ..)) => a,
+			(3, Junctions::X4(_, _, _, ref mut a)) => a,
+			(3, Junctions::X5(_, _, _, ref mut a, ..)) => a,
+			(3, Junctions::X6(_, _, _, ref mut a, ..)) => a,
+			(3, Junctions::X7(_, _, _, ref mut a, ..)) => a,
+			(3, Junctions::X8(_, _, _, ref mut a, ..)) => a,
+			(4, Junctions::X5(_, _, _, _, ref mut a)) => a,
+			(4, Junctions::X6(_, _, _, _, ref mut a, ..)) => a,
+			(4, Junctions::X7(_, _, _, _, ref mut a, ..)) => a,
+			(4, Junctions::X8(_, _, _, _, ref mut a, ..)) => a,
+			(5, Junctions::X6(_, _, _, _, _, ref mut a)) => a,
+			(5, Junctions::X7(_, _, _, _, _, ref mut a, ..)) => a,
+			(5, Junctions::X8(_, _, _, _, _, ref mut a, ..)) => a,
+			(6, Junctions::X7(_, _, _, _, _, _, ref mut a)) => a,
+			(6, Junctions::X8(_, _, _, _, _, _, ref mut a, ..)) => a,
+			(7, Junctions::X8(_, _, _, _, _, _, _, ref mut a)) => a,
 			_ => return None,
 		})
 	}
 
 	/// Returns a reference iterator over the junctions.
-	pub fn iter(&self) -> MultiLocationRefIterator {
-		MultiLocationRefIterator(&self, 0)
+	pub fn iter(&self) -> JunctionsRefIterator {
+		JunctionsRefIterator(&self, 0)
 	}
 
 	/// Returns a reference iterator over the junctions in reverse.
-	pub fn iter_rev(&self) -> MultiLocationReverseRefIterator {
-		MultiLocationReverseRefIterator(&self, 0)
+	pub fn iter_rev(&self) -> JunctionsReverseRefIterator {
+		JunctionsReverseRefIterator(&self, 0)
 	}
 
 	/// Consumes `self` and returns an iterator over the junctions.
-	pub fn into_iter(self) -> MultiLocationIterator {
-		MultiLocationIterator(self)
+	pub fn into_iter(self) -> JunctionsIterator {
+		JunctionsIterator(self)
 	}
 
 	/// Consumes `self` and returns an iterator over the junctions in reverse.
-	pub fn into_iter_rev(self) -> MultiLocationReverseIterator {
-		MultiLocationReverseIterator(self)
+	pub fn into_iter_rev(self) -> JunctionsReverseIterator {
+		JunctionsReverseIterator(self)
 	}
 
 	/// Ensures that self begins with `prefix` and that it has a single `Junction` item following.
@@ -450,14 +783,14 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v0::{MultiLocation::*, Junction::*};
+	/// # use xcm::v0::{Junctions::*, Junction::*};
 	/// # fn main() {
-	/// let mut m = X3(Parent, PalletInstance(3), OnlyChild);
-	/// assert_eq!(m.match_and_split(&X2(Parent, PalletInstance(3))), Some(&OnlyChild));
-	/// assert_eq!(m.match_and_split(&X1(Parent)), None);
+	/// let mut m = X3(Parachain(2), PalletInstance(3), OnlyChild);
+	/// assert_eq!(m.match_and_split(&X2(Parachain(2), PalletInstance(3))), Some(&OnlyChild));
+	/// assert_eq!(m.match_and_split(&X1(Parachain(2))), None);
 	/// # }
 	/// ```
-	pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> {
+	pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> {
 		if prefix.len() + 1 != self.len() {
 			return None
 		}
@@ -468,212 +801,6 @@ impl MultiLocation {
 		}
 		return self.at(prefix.len())
 	}
-
-	/// Mutates `self`, suffixing it with `new`. Returns `Err` in case of overflow.
-	pub fn push(&mut self, new: Junction) -> result::Result<(), ()> {
-		let mut n = MultiLocation::Null;
-		mem::swap(&mut *self, &mut n);
-		match n.pushed_with(new) {
-			Ok(result) => { *self = result; Ok(()) }
-			Err(old) => { *self = old; Err(()) }
-		}
-	}
-
-
-	/// Mutates `self`, prefixing it with `new`. Returns `Err` in case of overflow.
-	pub fn push_front(&mut self, new: Junction) -> result::Result<(), ()> {
-		let mut n = MultiLocation::Null;
-		mem::swap(&mut *self, &mut n);
-		match n.pushed_front_with(new) {
-			Ok(result) => { *self = result; Ok(()) }
-			Err(old) => { *self = old; Err(()) }
-		}
-	}
-
-	/// Returns the number of `Parent` junctions at the beginning of `self`.
-	pub fn leading_parent_count(&self) -> usize {
-		use Junction::Parent;
-		match self {
-			MultiLocation::X8(Parent, Parent, Parent, Parent, Parent, Parent, Parent, Parent) => 8,
-
-			MultiLocation::X8(Parent, Parent, Parent, Parent, Parent, Parent, Parent, ..) => 7,
-			MultiLocation::X7(Parent, Parent, Parent, Parent, Parent, Parent, Parent) => 7,
-
-			MultiLocation::X8(Parent, Parent, Parent, Parent, Parent, Parent, ..) => 6,
-			MultiLocation::X7(Parent, Parent, Parent, Parent, Parent, Parent, ..) => 6,
-			MultiLocation::X6(Parent, Parent, Parent, Parent, Parent, Parent) => 6,
-
-			MultiLocation::X8(Parent, Parent, Parent, Parent, Parent, ..) => 5,
-			MultiLocation::X7(Parent, Parent, Parent, Parent, Parent, ..) => 5,
-			MultiLocation::X6(Parent, Parent, Parent, Parent, Parent, ..) => 5,
-			MultiLocation::X5(Parent, Parent, Parent, Parent, Parent) => 5,
-
-			MultiLocation::X8(Parent, Parent, Parent, Parent, ..) => 4,
-			MultiLocation::X7(Parent, Parent, Parent, Parent, ..) => 4,
-			MultiLocation::X6(Parent, Parent, Parent, Parent, ..) => 4,
-			MultiLocation::X5(Parent, Parent, Parent, Parent, ..) => 4,
-			MultiLocation::X4(Parent, Parent, Parent, Parent) => 4,
-
-			MultiLocation::X8(Parent, Parent, Parent, ..) => 3,
-			MultiLocation::X7(Parent, Parent, Parent, ..) => 3,
-			MultiLocation::X6(Parent, Parent, Parent, ..) => 3,
-			MultiLocation::X5(Parent, Parent, Parent, ..) => 3,
-			MultiLocation::X4(Parent, Parent, Parent, ..) => 3,
-			MultiLocation::X3(Parent, Parent, Parent) => 3,
-
-			MultiLocation::X8(Parent, Parent, ..) => 2,
-			MultiLocation::X7(Parent, Parent, ..) => 2,
-			MultiLocation::X6(Parent, Parent, ..) => 2,
-			MultiLocation::X5(Parent, Parent, ..) => 2,
-			MultiLocation::X4(Parent, Parent, ..) => 2,
-			MultiLocation::X3(Parent, Parent, ..) => 2,
-			MultiLocation::X2(Parent, Parent) => 2,
-
-			MultiLocation::X8(Parent, ..) => 1,
-			MultiLocation::X7(Parent, ..) => 1,
-			MultiLocation::X6(Parent, ..) => 1,
-			MultiLocation::X5(Parent, ..) => 1,
-			MultiLocation::X4(Parent, ..) => 1,
-			MultiLocation::X3(Parent, ..) => 1,
-			MultiLocation::X2(Parent, ..) => 1,
-			MultiLocation::X1(Parent) => 1,
-			_ => 0,
-		}
-	}
-
-	/// This function ensures a multi-junction is in its canonicalized/normalized form, removing
-	/// any internal `[Non-Parent, Parent]` combinations.
-	pub fn canonicalize(&mut self) {
-		let mut normalized = MultiLocation::Null;
-		let mut iter = self.iter();
-		// We build up the the new normalized path by taking items from the original multi-location.
-		// When the next item we would add is `Parent`, we instead remove the last item assuming
-		// it is non-parent.
-		const EXPECT_MESSAGE: &'static str =
-			"`self` is a well formed multi-location with N junctions; \
-			this loop iterates over the junctions of `self`; \
-			the loop can push to the new multi-location at most one time; \
-			thus the size of the new multi-location is at most N junctions; \
-			qed";
-		while let Some(j) = iter.next() {
-			if j == &Junction::Parent {
-				match normalized.last() {
-					None | Some(Junction::Parent) => {}
-					Some(_) => {
-						normalized.take_last();
-						continue;
-					},
-				}
-			}
-
-			normalized.push(j.clone()).expect(EXPECT_MESSAGE);
-		}
-
-		core::mem::swap(self, &mut normalized);
-	}
-
-
-	/// Mutate `self` so that it is suffixed with `suffix`. The correct normalized form is returned,
-	/// removing any internal `[Non-Parent, Parent]`  combinations.
-	///
-	/// In the case of overflow, `self` is unmodified and  we return `Err` with `suffix`.
-	///
-	/// # Example
-	/// ```rust
-	/// # use xcm::v0::{MultiLocation::*, Junction::*};
-	/// # fn main() {
-	/// let mut m = X3(Parent, Parachain(21), OnlyChild);
-	/// assert_eq!(m.append_with(X2(Parent, PalletInstance(3))), Ok(()));
-	/// assert_eq!(m, X3(Parent, Parachain(21), PalletInstance(3)));
-	/// # }
-	/// ```
-	pub fn append_with(&mut self, suffix: MultiLocation) -> Result<(), MultiLocation> {
-		let mut prefix = suffix;
-		core::mem::swap(self, &mut prefix);
-		match self.prepend_with(prefix) {
-			Ok(()) => Ok(()),
-			Err(prefix) => {
-				let mut suffix = prefix;
-				core::mem::swap(self, &mut suffix);
-				Err(suffix)
-			}
-		}
-	}
-
-	/// Mutate `self` so that it is prefixed with `prefix`. The correct normalized form is returned,
-	/// removing any internal [Non-Parent, `Parent`] combinations.
-	///
-	/// In the case of overflow, `self` is unmodified and  we return `Err` with `prefix`.
-	///
-	/// # Example
-	/// ```rust
-	/// # use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
-	/// # fn main() {
-	/// let mut m = X3(Parent, Parent, PalletInstance(3));
-	/// assert_eq!(m.prepend_with(X3(Parent, Parachain(21), OnlyChild)), Ok(()));
-	/// assert_eq!(m, X2(Parent, PalletInstance(3)));
-	/// # }
-	/// ```
-	pub fn prepend_with(&mut self, prefix: MultiLocation) -> Result<(), MultiLocation> {
-		let mut prefix = prefix;
-
-		// This will guarantee that all `Parent` junctions in the prefix are leading, which is
-		// important for calculating the `skipped` items below.
-		prefix.canonicalize();
-
-		let self_leading_parents = self.leading_parent_count();
-		// These are the number of `non-parent` items in the prefix that we can
-		// potentially remove if the original location leads with parents.
-		let prefix_rest = prefix.len() - prefix.leading_parent_count();
-		// 2 * skipped items will be removed when performing the normalization below.
-		let skipped = self_leading_parents.min(prefix_rest);
-
-		// Pre-pending this prefix would create a multi-location with too many junctions.
-		if self.len() + prefix.len() - 2 * skipped > MAX_MULTILOCATION_LENGTH {
-			return Err(prefix);
-		}
-
-		// Here we cancel out `[Non-Parent, Parent]` items (normalization), where
-		// the non-parent item comes from the end of the prefix, and the parent item
-		// comes from the front of the original location.
-		//
-		// We calculated already how many of these there should be above.
-		for _ in 0 .. skipped {
-				let _non_parent = prefix.take_last();
-				let _parent = self.take_first();
-				debug_assert!(
-					_non_parent.is_some() && _non_parent != Some(Junction::Parent),
-					"prepend_with should always remove a non-parent from the end of the prefix",
-				);
-				debug_assert!(
-					_parent == Some(Junction::Parent),
-					"prepend_with should always remove a parent from the front of the location",
-				);
-		}
-
-		for j in prefix.into_iter_rev() {
-			self.push_front(j).expect("len + prefix minus 2*skipped is less than max length; qed");
-		}
-		Ok(())
-	}
-
-	/// Returns true iff `self` is an interior location. For this it may not contain any `Junction`s
-	/// for which `Junction::is_interior` returns `false`. This is generally true, except for the
-	/// `Parent` item.
-	///
-	/// # Example
-	/// ```rust
-	/// # use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
-	/// # fn main() {
-	/// let parent = X1(Parent);
-	/// assert_eq!(parent.is_interior(), false);
-	/// let m = X2(PalletInstance(12), AccountIndex64 { network: Any, index: 23 });
-	/// assert_eq!(m.is_interior(), true);
-	/// # }
-	/// ```
-	pub fn is_interior(&self) -> bool {
-		self.iter().all(Junction::is_interior)
-	}
 }
 
 impl From<MultiLocation> for VersionedMultiLocation {
@@ -687,22 +814,21 @@ impl TryFrom<VersionedMultiLocation> for MultiLocation {
 	fn try_from(x: VersionedMultiLocation) -> result::Result<Self, ()> {
 		match x {
 			VersionedMultiLocation::V0(x) => Ok(x),
-			_ => Err(()),
 		}
 	}
 }
 
 #[cfg(test)]
 mod tests {
-	use super::MultiLocation::*;
+	use super::{Junctions::*, MultiLocation};
 	use crate::opaque::v0::{Junction::*, NetworkId::Any};
 
 	#[test]
 	fn match_and_split_works() {
-		let m = X3(Parent, Parachain(42), AccountIndex64 { network: Any, index: 23 });
-		assert_eq!(m.match_and_split(&X1(Parent)), None);
+		let m = MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
+		assert_eq!(m.match_and_split(&MultiLocation { parents: 1, junctions: Null }), None);
 		assert_eq!(
-			m.match_and_split(&X2(Parent, Parachain(42))),
+			m.match_and_split(&MultiLocation { parents: 1, junctions: X1(Parachain(42)) }),
 			Some(&AccountIndex64 { network: Any, index: 23 })
 		);
 		assert_eq!(m.match_and_split(&m), None);
@@ -711,81 +837,30 @@ mod tests {
 	#[test]
 	fn append_with_works() {
 		let acc = AccountIndex64 { network: Any, index: 23 };
-		let mut m = X2(Parent, Parachain(42));
-		assert_eq!(m.append_with(X2(PalletInstance(3), acc.clone())), Ok(()));
-		assert_eq!(m, X4(Parent, Parachain(42), PalletInstance(3), acc.clone()));
+		let mut m = MultiLocation { parents: 1, junctions: X1(Parachain(42)) };
+		assert_eq!(m.append_with(MultiLocation::from(X2(PalletInstance(3), acc.clone()))), Ok(()));
+		assert_eq!(m, MultiLocation { parents: 1, junctions: X3(Parachain(42), PalletInstance(3), acc.clone()) });
 
 		// cannot append to create overly long multilocation
 		let acc = AccountIndex64 { network: Any, index: 23 };
-		let mut m = X7(Parent, Parent, Parent, Parent, Parent, Parent, Parachain(42));
-		let suffix = X2(PalletInstance(3), acc.clone());
+		let mut m = MultiLocation { parents: 6, junctions: X1(Parachain(42)) };
+		let suffix = MultiLocation::from(X2(PalletInstance(3), acc.clone()));
 		assert_eq!(m.append_with(suffix.clone()), Err(suffix));
 	}
 
 	#[test]
 	fn prepend_with_works() {
-		let mut m = X3(Parent, Parachain(42), AccountIndex64 { network: Any, index: 23 });
-		assert_eq!(m.prepend_with(X2(Parent, OnlyChild)), Ok(()));
-		assert_eq!(m, X3(Parent, Parachain(42), AccountIndex64 { network: Any, index: 23 }));
+		let mut m = MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
+		assert_eq!(m.prepend_with(MultiLocation { parents: 1, junctions: X1(OnlyChild) }), Ok(()));
+		assert_eq!(m, MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) });
 
 		// cannot prepend to create overly long multilocation
-		let mut m = X7(Parent, Parent, Parent, Parent, Parent, Parent, Parachain(42));
-		let prefix = X2(Parent, Parent);
+		let mut m = MultiLocation { parents: 6, junctions: X1(Parachain(42)) };
+		let prefix = MultiLocation { parents: 2, junctions: Null };
 		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
 
-		// Can handle shared prefix and resizing correctly.
-		let mut m = X1(Parent);
-		let prefix = X8(Parachain(100), OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, OnlyChild, Parent);
-		assert_eq!(m.prepend_with(prefix.clone()), Ok(()));
-		assert_eq!(m, X5(Parachain(100), OnlyChild, OnlyChild, OnlyChild, OnlyChild));
-
-		let mut m = X1(Parent);
-		let prefix = X8(Parent, Parent, Parent, Parent, Parent, Parent, Parent, Parent);
-		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
-
-		let mut m = X1(Parent);
-		let prefix = X7(Parent, Parent, Parent, Parent, Parent, Parent, Parent);
-		assert_eq!(m.prepend_with(prefix.clone()), Ok(()));
-		assert_eq!(m, X8(Parent, Parent, Parent, Parent, Parent, Parent, Parent, Parent));
-
-		let mut m = X1(Parent);
-		let prefix = X8(Parent, Parent, Parent, Parent, OnlyChild, Parent, Parent, Parent);
-		assert_eq!(m.prepend_with(prefix.clone()), Ok(()));
-		assert_eq!(m, X7(Parent, Parent, Parent, Parent, Parent, Parent, Parent));
-	}
-
-	#[test]
-	fn canonicalize_works() {
-		let mut m = X1(Parent);
-		m.canonicalize();
-		assert_eq!(m, X1(Parent));
-
-		let mut m = X1(Parachain(1));
-		m.canonicalize();
-		assert_eq!(m, X1(Parachain(1)));
-
-		let mut m = X6(Parent, Parachain(1), Parent, Parachain(2), Parent, Parachain(3));
-		m.canonicalize();
-		assert_eq!(m, X2(Parent, Parachain(3)));
-
-		let mut m = X5(Parachain(1), Parent, Parachain(2), Parent, Parachain(3));
-		m.canonicalize();
-		assert_eq!(m, X1(Parachain(3)));
-
-		let mut m = X6(Parachain(1), Parent, Parachain(2), Parent, Parachain(3), Parent);
-		m.canonicalize();
-		assert_eq!(m, Null);
-
-		let mut m = X5(Parachain(1), Parent, Parent, Parent, Parachain(3));
-		m.canonicalize();
-		assert_eq!(m, X3(Parent, Parent, Parachain(3)));
-
-		let mut m = X4(Parachain(1), Parachain(2), Parent, Parent);
-		m.canonicalize();
-		assert_eq!(m, Null);
-
-		let mut m = X4( Parent, Parent, Parachain(1), Parachain(2));
-		m.canonicalize();
-		assert_eq!(m, X4( Parent, Parent, Parachain(1), Parachain(2)));
+		let prefix = MultiLocation { parents: 1, junctions: Null };
+		assert_eq!(m.prepend_with(prefix), Ok(()));
+		assert_eq!(m, MultiLocation { parents: 7, junctions: X1(Parachain(42)) });
 	}
 }
diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs
index 9a01f227e766..9f8bab7f7d19 100644
--- a/xcm/src/v0/traits.rs
+++ b/xcm/src/v0/traits.rs
@@ -184,7 +184,7 @@ impl<C> ExecuteXcm<C> for () {
 ///
 /// # Example
 /// ```rust
-/// # use xcm::v0::{MultiLocation, Xcm, Junction, Error, OriginKind, SendXcm, Result};
+/// # use xcm::v0::{MultiLocation, Junctions, Xcm, Junction, Error, OriginKind, SendXcm, Result};
 /// # use parity_scale_codec::Encode;
 ///
 /// /// A sender that only passes the message through and does nothing.
@@ -199,7 +199,9 @@ impl<C> ExecuteXcm<C> for () {
 /// struct Sender2;
 /// impl SendXcm for Sender2 {
 ///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-///         if let MultiLocation::X2(j1, j2) = destination {
+///         if matches!(destination.junctions(), Junctions::X2(j1, j2))
+///             && destination.parent_count() == 0
+///         {
 ///             Ok(())
 ///         } else {
 ///             Err(Error::Undefined)
@@ -211,9 +213,12 @@ impl<C> ExecuteXcm<C> for () {
 /// struct Sender3;
 /// impl SendXcm for Sender3 {
 ///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-///         match destination {
-///             MultiLocation::X1(j) if j == Junction::Parent => Ok(()),
-///             _ => Err(Error::CannotReachDestination(destination, message)),
+///         if matches!(destination.junctions(), Junctions::Null)
+///             && destination.parent_count() == 1
+///         {
+///             Ok(())
+///         } else {
+///             Err(Error::CannotReachDestination(destination, message))
 ///         }
 ///     }
 /// }
@@ -222,7 +227,7 @@ impl<C> ExecuteXcm<C> for () {
 /// # fn main() {
 /// let call: Vec<u8> = ().encode();
 /// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
-/// let destination = MultiLocation::X1(Junction::Parent);
+/// let destination = MultiLocation::new(1, Junctions::Null).unwrap();
 ///
 /// assert!(
 ///     // Sender2 will block this.
diff --git a/xcm/src/v1/junction.rs b/xcm/src/v1/junction.rs
deleted file mode 100644
index 5375f286d44d..000000000000
--- a/xcm/src/v1/junction.rs
+++ /dev/null
@@ -1,133 +0,0 @@
-// Copyright 2021 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Support datastructures for `MultiLocation`, primarily the `Junction` datatype.
-
-use alloc::vec::Vec;
-use parity_scale_codec::{self, Encode, Decode};
-
-/// A global identifier of an account-bearing consensus system.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum NetworkId {
-	/// Unidentified/any.
-	Any,
-	/// Some named network.
-	Named(Vec<u8>),
-	/// The Polkadot Relay chain
-	Polkadot,
-	/// Kusama.
-	Kusama,
-}
-
-/// An identifier of a pluralistic body.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum BodyId {
-	/// The only body in its context.
-	Unit,
-	/// A named body.
-	Named(Vec<u8>),
-	/// An indexed body.
-	// TODO: parity-scale-codec#262: Change to be a tuple.
-	Index { #[codec(compact)] id: u32 },
-	/// The unambiguous executive body (for Polkadot, this would be the Polkadot council).
-	Executive,
-	/// The unambiguous technical body (for Polkadot, this would be the Technical Committee).
-	Technical,
-	/// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a majority of
-	/// lock-voters).
-	Legislative,
-	/// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a "grand oracle", it
-	/// may be considered as that).
-	Judicial,
-}
-
-/// A part of a pluralistic body.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum BodyPart {
-	/// The body's declaration, under whatever means it decides.
-	Voice,
-	/// A given number of members of the body.
-	Members { #[codec(compact)] count: u32 },
-	/// A given number of members of the body, out of some larger caucus.
-	Fraction { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 },
-	/// No less than the given proportion of members of the body.
-	AtLeastProportion { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 },
-	/// More than than the given proportion of members of the body.
-	MoreThanProportion { #[codec(compact)] nom: u32, #[codec(compact)] denom: u32 },
-}
-
-impl BodyPart {
-	/// Returns `true` if the part represents a strict majority (> 50%) of the body in question.
-	pub fn is_majority(&self) -> bool {
-		match self {
-			BodyPart::Fraction { nom, denom } if *nom * 2 > *denom => true,
-			BodyPart::AtLeastProportion { nom, denom } if *nom * 2 > *denom => true,
-			BodyPart::MoreThanProportion { nom, denom } if *nom * 2 >= *denom => true,
-			_ => false,
-		}
-	}
-}
-
-/// A single item in a path to describe the relative location of a consensus system.
-///
-/// Each item assumes a pre-existing location as its context and is defined in terms of it.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum Junction {
-	/// An indexed parachain belonging to and operated by the context.
-	///
-	/// Generally used when the context is a Polkadot Relay-chain.
-	Parachain(#[codec(compact)] u32),
-	/// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
-	/// the context.
-	///
-	/// Generally used when the context is a Substrate-based chain.
-	AccountId32 { network: NetworkId, id: [u8; 32] },
-	/// An 8-byte index for an account of a specific network that is respected as a sovereign endpoint within
-	/// the context.
-	///
-	/// May be used when the context is a Frame-based chain and includes e.g. an indices pallet.
-	AccountIndex64 { network: NetworkId, #[codec(compact)] index: u64 },
-	/// A 20-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
-	/// the context.
-	///
-	/// May be used when the context is an Ethereum or Bitcoin chain or smart-contract.
-	AccountKey20 { network: NetworkId, key: [u8; 20] },
-	/// An instanced, indexed pallet that forms a constituent part of the context.
-	///
-	/// Generally used when the context is a Frame-based chain.
-	PalletInstance(u8),
-	/// A non-descript index within the context location.
-	///
-	/// Usage will vary widely owing to its generality.
-	///
-	/// NOTE: Try to avoid using this and instead use a more specific item.
-	GeneralIndex { #[codec(compact)] id: u128 },
-	/// A nondescript datum acting as a key within the context location.
-	///
-	/// Usage will vary widely owing to its generality.
-	///
-	/// NOTE: Try to avoid using this and instead use a more specific item.
-	GeneralKey(Vec<u8>),
-	/// The unambiguous child.
-	///
-	/// Not currently used except as a fallback when deriving ancestry.
-	OnlyChild,
-	/// A pluralistic body existing within consensus.
-	///
-	/// Typical to be used to represent a governance origin of a chain, but could in principle be used to represent
-	/// things such as multisigs also.
-	Plurality { id: BodyId, part: BodyPart },
-}
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
deleted file mode 100644
index 7be850a087c6..000000000000
--- a/xcm/src/v1/mod.rs
+++ /dev/null
@@ -1,317 +0,0 @@
-// Copyright 2021 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Version 1 of the Cross-Consensus Message format data structures.
-
-use core::{result, convert::TryFrom, fmt::Debug};
-use derivative::Derivative;
-use alloc::vec::Vec;
-use parity_scale_codec::{self, Encode, Decode};
-use crate::{VersionedMultiAsset, DoubleEncoded, VersionedXcm};
-
-mod junction;
-mod multi_asset;
-mod multi_location;
-mod order;
-mod traits;
-pub use junction::{Junction, NetworkId, BodyId, BodyPart};
-pub use multi_asset::{MultiAsset, AssetInstance};
-pub use multi_location::{Junctions, MultiLocation};
-pub use order::Order;
-pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
-
-/// A prelude for importing all types typically used when interacting with XCM messages.
-pub mod prelude {
-	pub use super::junction::{Junction::*, NetworkId, BodyId, BodyPart};
-	pub use super::multi_asset::{MultiAsset::{self, *}, AssetInstance::{self, *}};
-	pub use super::multi_location::{Junctions::{self, *}, MultiLocation};
-	pub use super::order::Order::{self, *};
-	pub use super::traits::{Error as XcmError, Result as XcmResult, SendXcm, ExecuteXcm, Outcome};
-	pub use super::{Xcm::{self, *}, OriginKind};
-}
-
-// TODO: #2841 #XCMENCODE Efficient encodings for Vec<MultiAsset>, Vec<Order>, using initial byte values 128+ to encode
-//   the number of items in the vector.
-
-/// Basically just the XCM (more general) version of `ParachainDispatchOrigin`.
-#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug)]
-pub enum OriginKind {
-	/// Origin should just be the native dispatch origin representation for the sender in the
-	/// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin
-	/// if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a
-	/// primary/native dispatch origin form.
-	Native,
-
-	/// Origin should just be the standard account-based origin with the sovereign account of
-	/// the sender. For Cumulus/Frame chains, this is the `Signed` origin.
-	SovereignAccount,
-
-	/// Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin.
-	/// This will not usually be an available option.
-	Superuser,
-
-	/// Origin should be interpreted as an XCM native origin and the `MultiLocation` should be
-	/// encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be
-	/// the `pallet_xcm::Origin::Xcm` type.
-	Xcm,
-}
-
-/// Response data to a query.
-#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
-pub enum Response {
-	/// Some assets.
-	Assets(Vec<MultiAsset>),
-}
-
-/// Cross-Consensus Message: A message from one consensus system to another.
-///
-/// Consensus systems that may send and receive messages include blockchains and smart contracts.
-///
-/// All messages are delivered from a known *origin*, expressed as a `MultiLocation`.
-///
-/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer
-/// XCM format, known as `VersionedXcm`.
-#[derive(Derivative, Encode, Decode)]
-#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
-#[codec(encode_bound())]
-#[codec(decode_bound())]
-pub enum Xcm<Call> {
-	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into `holding`. Execute the
-	/// orders (`effects`).
-	///
-	/// - `assets`: The asset(s) to be withdrawn into holding.
-	/// - `effects`: The order(s) to execute on the holding account.
-	///
-	/// Kind: *Instruction*.
-	///
-	/// Errors:
-	#[codec(index = 0)]
-	WithdrawAsset { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
-
-	/// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` system.
-	///
-	/// Some orders are given (`effects`) which should be executed once the corresponding derivative assets have
-	/// been placed into `holding`.
-	///
-	/// - `assets`: The asset(s) that are minted into holding.
-	/// - `effects`: The order(s) to execute on the holding account.
-	///
-	/// Safety: `origin` must be trusted to have received and be storing `assets` such that they may later be
-	/// withdrawn should this system send a corresponding message.
-	///
-	/// Kind: *Trusted Indication*.
-	///
-	/// Errors:
-	#[codec(index = 1)]
-	ReserveAssetDeposit { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
-
-	/// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be
-	/// created on this system.
-	///
-	/// Some orders are given (`effects`) which should be executed once the corresponding derivative assets have
-	/// been placed into `holding`.
-	///
-	/// - `assets`: The asset(s) that are minted into holding.
-	/// - `effects`: The order(s) to execute on the holding account.
-	///
-	/// Safety: `origin` must be trusted to have irrevocably destroyed the `assets` prior as a consequence of
-	/// sending this message.
-	///
-	/// Kind: *Trusted Indication*.
-	///
-	/// Errors:
-	#[codec(index = 2)]
-	TeleportAsset { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
-
-	/// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`.
-	///
-	/// - `query_id`: The identifier of the query that resulted in this message being sent.
-	/// - `assets`: The message content.
-	///
-	/// Safety: No concerns.
-	///
-	/// Kind: *Information*.
-	///
-	/// Errors:
-	#[codec(index = 3)]
-	QueryResponse { #[codec(compact)] query_id: u64, response: Response },
-
-	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
-	/// ownership of `dest` within this consensus system.
-	///
-	/// - `assets`: The asset(s) to be withdrawn.
-	/// - `dest`: The new owner for the assets.
-	///
-	/// Safety: No concerns.
-	///
-	/// Kind: *Instruction*.
-	///
-	/// Errors:
-	#[codec(index = 4)]
-	TransferAsset { assets: Vec<MultiAsset>, dest: MultiLocation },
-
-	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
-	/// ownership of `dest` within this consensus system.
-	///
-	/// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`.
-	///
-	/// - `assets`: The asset(s) to be withdrawn.
-	/// - `dest`: The new owner for the assets.
-	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to
-	///   `dest.
-	///
-	/// Safety: No concerns.
-	///
-	/// Kind: *Instruction*.
-	///
-	/// Errors:
-	#[codec(index = 5)]
-	TransferReserveAsset { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
-
-	/// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed by the kind
-	/// of origin `origin_type`.
-	///
-	/// - `origin_type`: The means of expressing the message origin as a dispatch origin.
-	/// - `max_weight`: The weight of `call`; this should be at least the chain's calculated weight and will
-	///   be used in the weight determination arithmetic.
-	/// - `call`: The encoded transaction to be applied.
-	///
-	/// Safety: No concerns.
-	///
-	/// Kind: *Instruction*.
-	///
-	/// Errors:
-	#[codec(index = 6)]
-	Transact { origin_type: OriginKind, require_weight_at_most: u64, call: DoubleEncoded<Call> },
-
-	/// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the
-	/// relay-chain to a para.
-	///
-	/// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel opening.
-	/// - `max_message_size`: The maximum size of a message proposed by the sender.
-	/// - `max_capacity`: The maximum number of messages that can be queued in the channel.
-	///
-	/// Safety: The message should originate directly from the relay-chain.
-	///
-	/// Kind: *System Notification*
-	#[codec(index = 7)]
-	HrmpNewChannelOpenRequest {
-		#[codec(compact)] sender: u32,
-		#[codec(compact)] max_message_size: u32,
-		#[codec(compact)] max_capacity: u32,
-	},
-
-	/// A message to notify about that a previously sent open channel request has been accepted by
-	/// the recipient. That means that the channel will be opened during the next relay-chain session
-	/// change. This message is meant to be sent by the relay-chain to a para.
-	///
-	/// Safety: The message should originate directly from the relay-chain.
-	///
-	/// Kind: *System Notification*
-	///
-	/// Errors:
-	#[codec(index = 8)]
-	HrmpChannelAccepted {
-		#[codec(compact)] recipient: u32,
-	},
-
-	/// A message to notify that the other party in an open channel decided to close it. In particular,
-	/// `initiator` is going to close the channel opened from `sender` to the `recipient`. The close
-	/// will be enacted at the next relay-chain session change. This message is meant to be sent by
-	/// the relay-chain to a para.
-	///
-	/// Safety: The message should originate directly from the relay-chain.
-	///
-	/// Kind: *System Notification*
-	///
-	/// Errors:
-	#[codec(index = 9)]
-	HrmpChannelClosing {
-		#[codec(compact)] initiator: u32,
-		#[codec(compact)] sender: u32,
-		#[codec(compact)] recipient: u32,
-	},
-
-	/// A message to indicate that the embedded XCM is actually arriving on behalf of some consensus
-	/// location within the origin.
-	///
-	/// Safety: `who` must be an interior location of the context. This basically means that no `Parent`
-	/// junctions are allowed in it. This should be verified at the time of XCM execution.
-	///
-	/// Kind: *Instruction*
-	///
-	/// Errors:
-	#[codec(index = 10)]
-	RelayedFrom {
-		who: MultiLocation,
-		message: alloc::boxed::Box<Xcm<Call>>,
-	},
-}
-
-impl<Call> From<Xcm<Call>> for VersionedXcm<Call> {
-	fn from(x: Xcm<Call>) -> Self {
-		VersionedXcm::V1(x)
-	}
-}
-
-impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
-	type Error = ();
-	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
-		match x {
-			VersionedXcm::V1(x) => Ok(x),
-			_ => Err(()),
-		}
-	}
-}
-
-impl<Call> Xcm<Call> {
-	pub fn into<C>(self) -> Xcm<C> { Xcm::from(self) }
-	pub fn from<C>(xcm: Xcm<C>) -> Self {
-		use Xcm::*;
-		match xcm {
-			WithdrawAsset { assets, effects }
-			=> WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
-			ReserveAssetDeposit { assets, effects }
-			=> ReserveAssetDeposit { assets, effects: effects.into_iter().map(Order::into).collect() },
-			TeleportAsset { assets, effects }
-			=> TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
-			QueryResponse { query_id: u64, response }
-			=> QueryResponse { query_id: u64, response },
-			TransferAsset { assets, dest }
-			=> TransferAsset { assets, dest },
-			TransferReserveAsset { assets, dest, effects }
-			=> TransferReserveAsset { assets, dest, effects },
-			HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity}
-			=> HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity},
-			HrmpChannelAccepted { recipient}
-			=> HrmpChannelAccepted { recipient},
-			HrmpChannelClosing { initiator, sender, recipient}
-			=> HrmpChannelClosing { initiator, sender, recipient},
-			Transact { origin_type, require_weight_at_most, call}
-			=> Transact { origin_type, require_weight_at_most, call: call.into() },
-			RelayedFrom { who, message }
-			=> RelayedFrom { who, message: alloc::boxed::Box::new((*message).into()) },
-		}
-	}
-}
-
-pub mod opaque {
-	/// The basic concrete type of `generic::Xcm`, which doesn't make any assumptions about the format of a
-	/// call other than it is pre-encoded.
-	pub type Xcm = super::Xcm<()>;
-
-	pub use super::order::opaque::*;
-}
diff --git a/xcm/src/v1/multi_asset.rs b/xcm/src/v1/multi_asset.rs
deleted file mode 100644
index 552e67f03d8e..000000000000
--- a/xcm/src/v1/multi_asset.rs
+++ /dev/null
@@ -1,380 +0,0 @@
-// Copyright 2021 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Cross-Consensus Message format data structures.
-
-use core::{result, convert::TryFrom};
-use alloc::vec::Vec;
-
-use parity_scale_codec::{self, Encode, Decode};
-use super::{MultiLocation, VersionedMultiAsset};
-
-/// A general identifier for an instance of a non-fungible asset class.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum AssetInstance {
-	/// Undefined - used if the NFA class has only one instance.
-	Undefined,
-
-	/// A compact index. Technically this could be greater than u128, but this implementation supports only
-	/// values up to `2**128 - 1`.
-	Index { #[codec(compact)] id: u128 },
-
-	/// A 4-byte fixed-length datum.
-	Array4([u8; 4]),
-
-	/// An 8-byte fixed-length datum.
-	Array8([u8; 8]),
-
-	/// A 16-byte fixed-length datum.
-	Array16([u8; 16]),
-
-	/// A 32-byte fixed-length datum.
-	Array32([u8; 32]),
-
-	/// An arbitrary piece of data. Use only when necessary.
-	Blob(Vec<u8>),
-}
-
-/// A single general identifier for an asset.
-///
-/// Represents both fungible and non-fungible assets. May only be used to represent a single asset class.
-///
-/// Wildcards may or may not be allowed by the interpreting context.
-///
-/// Assets classes may be identified in one of two ways: either an abstract identifier or a concrete identifier.
-/// Implementations may support only one of these. A single asset may be referenced from multiple asset identifiers,
-/// though will tend to have only a single *preferred* identifier.
-///
-/// ### Abstract identifiers
-///
-/// Abstract identifiers are absolute identifiers that represent a notional asset which can exist within multiple
-/// consensus systems. These tend to be simpler to deal with since their broad meaning is unchanged regardless stay of
-/// the consensus system in which it is interpreted.
-///
-/// However, in the attempt to provide uniformity across consensus systems, they may conflate different instantiations
-/// of some notional asset (e.g. the reserve asset and a local reserve-backed derivative of it) under the same name,
-/// leading to confusion. It also implies that one notional asset is accounted for locally in only one way. This may not
-/// be the case, e.g. where there are multiple bridge instances each providing a bridged "BTC" token yet none being
-/// fungible between the others.
-///
-/// Since they are meant to be absolute and universal, a global registry is needed to ensure that name collisions do not
-/// occur.
-///
-/// An abstract identifier is represented as a simple variable-size byte string. As of writing, no global registry
-/// exists and no proposals have been put forth for asset labeling.
-///
-/// ### Concrete identifiers
-///
-/// Concrete identifiers are *relative identifiers* that specifically identify a single asset through its location in a
-/// consensus system relative to the context interpreting. Use of a `MultiLocation` ensures that similar but non
-/// fungible variants of the same underlying asset can be properly distinguished, and obviates the need for any kind of
-/// central registry.
-///
-/// The limitation is that the asset identifier cannot be trivially copied between consensus systems and must instead be
-/// "re-anchored" whenever being moved to a new consensus system, using the two systems' relative paths.
-///
-/// Throughout XCM, messages are authored such that *when interpreted from the receiver's point of view* they will have
-/// the desired meaning/effect. This means that relative paths should always by constructed to be read from the point of
-/// view of the receiving system, *which may be have a completely different meaning in the authoring system*.
-///
-/// Concrete identifiers are the preferred way of identifying an asset since they are entirely unambiguous.
-///
-/// A concrete identifier is represented by a `MultiLocation`. If a system has an unambiguous primary asset (such as
-/// Bitcoin with BTC or Ethereum with ETH), then it will conventionally be identified as the chain itself. Alternative
-/// and more specific ways of referring to an asset within a system include:
-///
-/// - `<chain>/PalletInstance(<id>)` for a Frame chain with a single-asset pallet instance (such as an instance of the
-///   Balances pallet).
-/// - `<chain>/PalletInstance(<id>)/GeneralIndex(<index>)` for a Frame chain with an indexed multi-asset pallet instance
-///   (such as an instance of the Assets pallet).
-/// - `<chain>/AccountId32` for an ERC-20-style single-asset smart-contract on a Frame-based contracts chain.
-/// - `<chain>/AccountKey20` for an ERC-20-style single-asset smart-contract on an Ethereum-like chain.
-///
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum MultiAsset {
-	/// No assets. Rarely used.
-	None,
-
-	/// All assets. Typically used for the subset of assets to be used for an `Order`, and in that context means
-	/// "all assets currently in holding".
-	All,
-
-	/// All fungible assets. Typically used for the subset of assets to be used for an `Order`, and in that context
-	/// means "all fungible assets currently in holding".
-	AllFungible,
-
-	/// All non-fungible assets. Typically used for the subset of assets to be used for an `Order`, and in that
-	/// context means "all non-fungible assets currently in holding".
-	AllNonFungible,
-
-	/// All fungible assets of a given abstract asset `id`entifier.
-	AllAbstractFungible { id: Vec<u8> },
-
-	/// All non-fungible assets of a given abstract asset `class`.
-	AllAbstractNonFungible { class: Vec<u8> },
-
-	/// All fungible assets of a given concrete asset `id`entifier.
-	AllConcreteFungible { id: MultiLocation },
-
-	/// All non-fungible assets of a given concrete asset `class`.
-	AllConcreteNonFungible { class: MultiLocation },
-
-	/// Some specific `amount` of the fungible asset identified by an abstract `id`.
-	AbstractFungible { id: Vec<u8>, #[codec(compact)] amount: u128 },
-
-	/// Some specific `instance` of the non-fungible asset whose `class` is identified abstractly.
-	AbstractNonFungible { class: Vec<u8>, instance: AssetInstance },
-
-	/// Some specific `amount` of the fungible asset identified by an concrete `id`.
-	ConcreteFungible { id: MultiLocation, #[codec(compact)] amount: u128 },
-
-	/// Some specific `instance` of the non-fungible asset whose `class` is identified concretely.
-	ConcreteNonFungible { class: MultiLocation, instance: AssetInstance },
-}
-
-impl MultiAsset {
-	/// Returns `true` if the `MultiAsset` is a wildcard and can refer to classes of assets, instead of just one.
-	///
-	/// Typically can also be inferred by the name starting with `All`.
-	pub fn is_wildcard(&self) -> bool {
-		match self {
-			MultiAsset::None
-			| MultiAsset::AbstractFungible {..}
-			| MultiAsset::AbstractNonFungible {..}
-			| MultiAsset::ConcreteFungible {..}
-			| MultiAsset::ConcreteNonFungible {..}
-			=> false,
-
-			MultiAsset::All
-			| MultiAsset::AllFungible
-			| MultiAsset::AllNonFungible
-			| MultiAsset::AllAbstractFungible {..}
-			| MultiAsset::AllConcreteFungible {..}
-			| MultiAsset::AllAbstractNonFungible {..}
-			| MultiAsset::AllConcreteNonFungible {..}
-			=> true,
-		}
-	}
-
-	fn is_none(&self) -> bool {
-		match self {
-			MultiAsset::None
-			| MultiAsset::AbstractFungible { amount: 0, .. }
-			| MultiAsset::ConcreteFungible { amount: 0, .. }
-			=> true,
-
-			_ => false,
-		}
-	}
-
-	fn is_fungible(&self) -> bool {
-		match self {
-			MultiAsset::All
-			| MultiAsset::AllFungible
-			| MultiAsset::AllAbstractFungible {..}
-			| MultiAsset::AllConcreteFungible {..}
-			| MultiAsset::AbstractFungible {..}
-			| MultiAsset::ConcreteFungible {..}
-			=> true,
-
-			_ => false,
-		}
-	}
-
-	fn is_non_fungible(&self) -> bool {
-		match self {
-			MultiAsset::All
-			| MultiAsset::AllNonFungible
-			| MultiAsset::AllAbstractNonFungible {..}
-			| MultiAsset::AllConcreteNonFungible {..}
-			| MultiAsset::AbstractNonFungible {..}
-			| MultiAsset::ConcreteNonFungible {..}
-			=> true,
-
-			_ => false,
-		}
-	}
-
-	fn is_concrete_fungible(&self, id: &MultiLocation) -> bool {
-		match self {
-			MultiAsset::AllFungible => true,
-			MultiAsset::AllConcreteFungible { id: i }
-			| MultiAsset::ConcreteFungible { id: i, .. }
-			=> i == id,
-
-			_ => false,
-		}
-	}
-
-	fn is_abstract_fungible(&self, id: &[u8]) -> bool {
-		match self {
-			MultiAsset::AllFungible => true,
-			MultiAsset::AllAbstractFungible { id: i }
-			| MultiAsset::AbstractFungible { id: i, .. }
-			=> i == id,
-			_ => false,
-		}
-	}
-
-	fn is_concrete_non_fungible(&self, class: &MultiLocation) -> bool {
-		match self {
-			MultiAsset::AllNonFungible => true,
-			MultiAsset::AllConcreteNonFungible { class: i }
-			| MultiAsset::ConcreteNonFungible { class: i, .. }
-			=> i == class,
-			_ => false,
-		}
-	}
-
-	fn is_abstract_non_fungible(&self, class: &[u8]) -> bool {
-		match self {
-			MultiAsset::AllNonFungible => true,
-			MultiAsset::AllAbstractNonFungible { class: i }
-			| MultiAsset::AbstractNonFungible { class: i, .. }
-			=> i == class,
-			_ => false,
-		}
-	}
-
-	fn is_all(&self) -> bool { matches!(self, MultiAsset::All) }
-
-	/// Returns true if `self` is a super-set of the given `inner`.
-	///
-	/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
-	/// For more details, see the implementation and tests.
-	pub fn contains(&self, inner: &MultiAsset) -> bool {
-		use MultiAsset::*;
-
-		// Inner cannot be wild
-		if inner.is_wildcard() { return false }
-		// Everything contains nothing.
-		if inner.is_none() { return true }
-
-		// Everything contains anything.
-		if self.is_all() { return true }
-		// Nothing contains nothing.
-		if self.is_none() { return false }
-
-		match self {
-			// Anything fungible contains "all fungibles"
-			AllFungible => inner.is_fungible(),
-			// Anything non-fungible contains "all non-fungibles"
-			AllNonFungible => inner.is_non_fungible(),
-
-			AllConcreteFungible { id } => inner.is_concrete_fungible(id),
-			AllAbstractFungible { id } => inner.is_abstract_fungible(id),
-			AllConcreteNonFungible { class } => inner.is_concrete_non_fungible(class),
-			AllAbstractNonFungible { class } => inner.is_abstract_non_fungible(class),
-
-			ConcreteFungible { id, amount } => matches!(
-				inner,
-				ConcreteFungible { id: inner_id , amount: inner_amount } if inner_id == id && amount >= inner_amount
-			),
-			AbstractFungible { id, amount } => matches!(
-				inner,
-				AbstractFungible { id: inner_id , amount: inner_amount } if inner_id == id && amount >= inner_amount
-			),
-			ConcreteNonFungible { .. } => self == inner,
-			AbstractNonFungible { .. } => self == inner,
-			_ => false,
-		}
-	}
-
-	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
-		use MultiAsset::*;
-		match self {
-			AllConcreteFungible { ref mut id }
-			| AllConcreteNonFungible { class: ref mut id }
-			| ConcreteFungible { ref mut id, .. }
-			| ConcreteNonFungible { class: ref mut id, .. }
-			=> id.prepend_with(prepend.clone()).map_err(|_| ()),
-			_ => Ok(()),
-		}
-	}
-}
-
-impl From<MultiAsset> for VersionedMultiAsset {
-	fn from(x: MultiAsset) -> Self {
-		VersionedMultiAsset::V1(x)
-	}
-}
-
-impl TryFrom<VersionedMultiAsset> for MultiAsset {
-	type Error = ();
-	fn try_from(x: VersionedMultiAsset) -> result::Result<Self, ()> {
-		match x {
-			VersionedMultiAsset::V1(x) => Ok(x),
-			_ => Err(()),
-		}
-	}
-}
-
-#[cfg(test)]
-mod tests {
-	use super::*;
-
-	#[test]
-	fn contains_works() {
-		use alloc::vec;
-		use MultiAsset::*;
-		// trivial case: all contains any non-wildcard.
-		assert!(All.contains(&None));
-		assert!(All.contains(&AbstractFungible { id: alloc::vec![99u8], amount: 1 }));
-
-		// trivial case: none contains nothing, except itself.
-		assert!(None.contains(&None));
-		assert!(!None.contains(&AllFungible));
-		assert!(!None.contains(&All));
-
-		// A bit more sneaky: Nothing can contain wildcard, even All ir the thing itself.
-		assert!(!All.contains(&All));
-		assert!(!All.contains(&AllFungible));
-		assert!(!AllFungible.contains(&AllFungible));
-		assert!(!AllNonFungible.contains(&AllNonFungible));
-
-		// For fungibles, containing is basically equality, or equal id with higher amount.
-		assert!(
-			!AbstractFungible { id: vec![99u8], amount: 99 }
-			.contains(&AbstractFungible { id: vec![1u8], amount: 99 })
-		);
-		assert!(
-			AbstractFungible { id: vec![99u8], amount: 99 }
-			.contains(&AbstractFungible { id: vec![99u8], amount: 99 })
-		);
-		assert!(
-			AbstractFungible { id: vec![99u8], amount: 99 }
-			.contains(&AbstractFungible { id: vec![99u8], amount: 9 })
-		);
-		assert!(
-			!AbstractFungible { id: vec![99u8], amount: 99 }
-			.contains(&AbstractFungible { id: vec![99u8], amount: 100 })
-		);
-
-		// For non-fungibles, containing is equality.
-		assert!(
-			!AbstractNonFungible {class: vec![99u8], instance: AssetInstance::Index { id: 9 } }
-			.contains(&AbstractNonFungible { class: vec![98u8], instance: AssetInstance::Index { id: 9 } })
-		);
-		assert!(
-			!AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 8 } }
-			.contains(&AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } })
-		);
-		assert!(
-			AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } }
-			.contains(&AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } })
-		);
-	}
-}
diff --git a/xcm/src/v1/multi_location.rs b/xcm/src/v1/multi_location.rs
deleted file mode 100644
index ecffb26f8838..000000000000
--- a/xcm/src/v1/multi_location.rs
+++ /dev/null
@@ -1,867 +0,0 @@
-// Copyright 2021 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Cross-Consensus Message format data structures.
-
-use core::{convert::TryFrom, mem, result};
-
-use parity_scale_codec::{self, Encode, Decode};
-use super::Junction;
-use crate::VersionedMultiLocation;
-
-/// A relative path between state-bearing consensus systems.
-///
-/// A location in a consensus system is defined as an *isolatable state machine* held within global consensus. The
-/// location in question need not have a sophisticated consensus algorithm of its own; a single account within
-/// Ethereum, for example, could be considered a location.
-///
-/// A very-much non-exhaustive list of types of location include:
-/// - A (normal, layer-1) block chain, e.g. the Bitcoin mainnet or a parachain.
-/// - A layer-0 super-chain, e.g. the Polkadot Relay chain.
-/// - A layer-2 smart contract, e.g. an ERC-20 on Ethereum.
-/// - A logical functional component of a chain, e.g. a single instance of a pallet on a Frame-based Substrate chain.
-/// - An account.
-///
-/// A `MultiLocation` is a *relative identifier*, meaning that it can only be used to define the relative path
-/// between two locations, and cannot generally be used to refer to a location universally. It is comprised of a
-/// number of *junctions*, each morphing the previous location, either diving down into one of its internal locations,
-/// called a *sub-consensus*, or going up into its parent location. Correct `MultiLocation` values must have all
-/// `Parent` junctions as a prefix to all *sub-consensus* junctions.
-///
-/// This specific `MultiLocation` implementation uses a Rust `enum` in order to make pattern matching easier.
-///
-/// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub struct MultiLocation {
-	parents: u8,
-	junctions: Junctions,
-}
-
-/// Maximum number of junctions a multilocation can contain.
-pub const MAX_MULTILOCATION_LENGTH: usize = 8;
-
-impl MultiLocation {
-	/// Creates a new MultiLocation, ensuring that the length of it does not exceed the maximum,
-	/// otherwise returns `Err`.
-	pub fn new(parents: u8, junctions: Junctions) -> result::Result<MultiLocation, ()> {
-		if parents as usize + junctions.len() > MAX_MULTILOCATION_LENGTH {
-			return Err(())
-		}
-		Ok(MultiLocation {
-			parents,
-			junctions,
-		})
-	}
-
-	/// Return a reference to the junctions field.
-	pub fn junctions(&self) -> &Junctions {
-		&self.junctions
-	}
-
-	/// Return a mutable reference to the junctions field.
-	pub fn junctions_mut(&mut self) -> &mut Junctions {
-		&mut self.junctions
-	}
-
-	/// Returns the number of `Parent` junctions at the beginning of `self`.
-	pub fn parent_count(&self) -> usize {
-		self.parents as usize
-	}
-
-	/// Returns the number of parents and junctions in `self`.
-	pub fn len(&self) -> usize {
-		self.parent_count() + self.junctions.len()
-	}
-
-	/// Returns first junction that is not a parent, or `None` if the location is empty or
-	/// contains only parents.
-	pub fn first_non_parent(&self) -> Option<&Junction> {
-		self.junctions.first()
-	}
-
-	/// Returns last junction, or `None` if the location is empty or contains only parents.
-	pub fn last(&self) -> Option<&Junction> {
-		self.junctions.last()
-	}
-
-	/// Splits off the first non-parent junction, returning the remaining suffix (first item in tuple)
-	/// and the first element (second item in tuple) or `None` if it was empty.
-	pub fn split_first_non_parent(self) -> (MultiLocation, Option<Junction>) {
-		let MultiLocation { parents, junctions } = self;
-		let (prefix, suffix) = junctions.split_first();
-		let multilocation = MultiLocation {
-			parents,
-			junctions: prefix,
-		};
-		(multilocation, suffix)
-	}
-
-	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
-	/// (second item in tuple) or `None` if it was empty or that `self` only contains parents.
-	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
-		let MultiLocation { parents, junctions } = self;
-		let (prefix, suffix) = junctions.split_last();
-		let multilocation = MultiLocation {
-			parents,
-			junctions: prefix,
-		};
-		(multilocation, suffix)
-	}
-	
-	/// Bumps the parent count up by 1. Returns `Err` in case of overflow.
-	pub fn push_parent(&mut self) -> result::Result<(), ()> {
-		if self.len() >= MAX_MULTILOCATION_LENGTH {
-			return Err(())
-		}
-		self.parents = self.parents.saturating_add(1);
-		Ok(())
-	}
-
-	/// Mutates `self`, suffixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
-	pub fn push_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
-		let mut n = Junctions::Null;
-		mem::swap(&mut self.junctions, &mut n);
-		match n.pushed_with(new) {
-			Ok(result) => { self.junctions = result; Ok(()) }
-			Err(old) => { self.junctions = old; Err(()) }
-		}
-	}
-
-	/// Mutates `self`, prefixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
-	pub fn push_front_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
-		let mut n = Junctions::Null;
-		mem::swap(&mut self.junctions, &mut n);
-		match n.pushed_front_with(new) {
-			Ok(result) => { self.junctions = result; Ok(()) }
-			Err(old) => { self.junctions = old; Err(()) }
-		}
-	}
-
-	/// Consumes `self` and returns a `MultiLocation` with its parent count incremented by 1, or
-	/// an `Err` with the original value of `self` in case of overflow.
-	pub fn pushed_with_parent(self) -> result::Result<Self, Self> {
-		if self.len() >= MAX_MULTILOCATION_LENGTH {
-			return Err(self)
-		}
-		Ok(MultiLocation {
-			parents: self.parents.saturating_add(1),
-			..self
-		})
-	}
-
-	/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with the original value of
-	/// `self` in case of overflow.
-	pub fn pushed_with_non_parent(self, new: Junction) -> result::Result<Self, Self> {
-		if self.len() >= MAX_MULTILOCATION_LENGTH {
-			return Err(self)
-		}
-		Ok(MultiLocation {
-			parents: self.parents,
-			junctions: self.junctions.pushed_with(new).expect("length is less than max length; qed"),
-		})
-	}
-
-	/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
-	/// `self` in case of overflow.
-	pub fn pushed_front_with_non_parent(self, new: Junction) -> result::Result<Self, Self> {
-		if self.len() >= MAX_MULTILOCATION_LENGTH {
-			return Err(self)
-		}
-		Ok(MultiLocation {
-			parents: self.parents,
-			junctions: self.junctions.pushed_front_with(new).expect("length is less than max length; qed"),
-		})
-	}
-
-	/// Returns the junction at index `i`, or `None` if the location is a parent or if the location
-	/// does not contain that many elements.
-	pub fn at(&self, i: usize) -> Option<&Junction> {
-		let num_parents = self.parents as usize;
-		if i < num_parents {
-			return None
-		}
-		self.junctions.at(i - num_parents)
-	}
-
-	/// Returns a mutable reference to the junction at index `i`, or `None` if the location is a
-	/// parent or if it doesn't contain that many elements.
-	pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
-		let num_parents = self.parents as usize;
-		if i < num_parents {
-			return None
-		}
-		self.junctions.at_mut(i - num_parents)
-	}
-
-	/// Decrement the parent count by 1.
-	pub fn pop_parent(&mut self) {
-		self.parents = self.parents.saturating_sub(1);
-	}
-
-	/// Removes the first non-parent element from `self`, returning it
-	/// (or `None` if it was empty or if `self` contains only parents).
-	pub fn take_first_non_parent(&mut self) -> Option<Junction> {
-		self.junctions.take_first()
-	}
-
-	/// Removes the last element from `junctions`, returning it (or `None` if it was empty or if
-	/// `self` only contains parents).
-	pub fn take_last(&mut self) -> Option<Junction> {
-		self.junctions.take_last()
-	}
-
-	/// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with
-	/// the junctions of `prefix` and that it has a single `Junction` item following.
-	/// If so, returns a reference to this `Junction` item.
-	///
-	/// # Example
-	/// ```rust
-	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
-	/// # fn main() {
-	/// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)).unwrap();
-	/// assert_eq!(
-	///     m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3))).unwrap()),
-	///     Some(&OnlyChild),
-	/// );
-	/// assert_eq!(m.match_and_split(&MultiLocation::new(1, Null).unwrap()), None);
-	/// # }
-	/// ```
-	pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> {
-		if self.parents != prefix.parents {
-			return None
-		}
-		self.junctions.match_and_split(&prefix.junctions)
-	}
-
-	/// Mutate `self` so that it is suffixed with `suffix`. The correct normalized form is returned,
-	/// removing any internal [Non-Parent, `Parent`]  combinations.
-	///
-	/// Does not modify `self` and returns `Err` with `suffix` in case of overflow.
-	///
-	/// # Example
-	/// ```rust
-	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
-	/// # fn main() {
-	/// let mut m = MultiLocation::new(1, X2(Parachain(21), OnlyChild)).unwrap();
-	/// assert_eq!(m.append_with(MultiLocation::new(1, X1(PalletInstance(3))).unwrap()), Ok(()));
-	/// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3))).unwrap());
-	/// # }
-	/// ```
-	pub fn append_with(&mut self, suffix: MultiLocation) -> Result<(), MultiLocation> {
-		let mut prefix = suffix;
-		core::mem::swap(self, &mut prefix);
-		match self.prepend_with(prefix) {
-			Ok(()) => Ok(()),
-			Err(prefix) => {
-				let mut suffix = prefix;
-				core::mem::swap(self, &mut suffix);
-				Err(suffix)
-			}
-		}
-	}
-
-	/// Mutate `self` so that it is prefixed with `prefix`.
-	///
-	/// Does not modify `self` and returns `Err` with `prefix` in case of overflow.
-	///
-	/// # Example
-	/// ```rust
-	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
-	/// # fn main() {
-	/// let mut m = MultiLocation::new(2, X1(PalletInstance(3))).unwrap();
-	/// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild)).unwrap()), Ok(()));
-	/// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3))).unwrap());
-	/// # }
-	/// ```
-	pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> {
-		let self_parents = self.parent_count();
-		let prepend_len = (self_parents as isize - prefix.junctions.len() as isize).abs() as usize;
-		if self.junctions.len() + prefix.parent_count() + prepend_len > MAX_MULTILOCATION_LENGTH {
-			return Err(prefix)
-		}
-
-		let mut final_parent_count = prefix.parents;
-		for _ in 0..self_parents {
-			if prefix.take_last().is_none() {
-				// If true, this means self parent count is greater than prefix junctions length;
-				// add the resulting self parent count to final_parent_count
-				final_parent_count += self.parents;
-				break
-			}
-			self.pop_parent();
-		}
-
-		self.parents = final_parent_count;
-		for j in prefix.junctions.into_iter_rev() {
-			self.push_front_non_parent(j).expect(
-				"self junctions len + prefix parent count + prepend len is less than max length; qed"
-			);
-		}
-		Ok(())
-	}
-}
-
-impl From<Junctions> for MultiLocation {
-	fn from(junctions: Junctions) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions,
-		}
-	}
-}
-
-impl From<Junction> for MultiLocation {
-	fn from(x: Junction) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X1(x),
-		}
-	}
-}
-
-impl From<()> for MultiLocation {
-	fn from(_: ()) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::Null,
-		}
-	}
-}
-impl From<(Junction,)> for MultiLocation {
-	fn from(x: (Junction,)) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X1(x.0),
-		}
-	}
-}
-impl From<(Junction, Junction)> for MultiLocation {
-	fn from(x: (Junction, Junction)) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X2(x.0, x.1),
-		}
-	}
-}
-impl From<(Junction, Junction, Junction)> for MultiLocation {
-	fn from(x: (Junction, Junction, Junction)) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X3(x.0, x.1, x.2),
-		}
-	}
-}
-impl From<(Junction, Junction, Junction, Junction)> for MultiLocation {
-	fn from(x: (Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X4(x.0, x.1, x.2, x.3),
-		}
-	}
-}
-impl From<(Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
-	fn from(x: (Junction, Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X5(x.0, x.1, x.2, x.3, x.4),
-		}
-	}
-}
-impl From<(Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
-	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X6(x.0, x.1, x.2, x.3, x.4, x.5),
-		}
-	}
-}
-impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
-	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X7(x.0, x.1, x.2, x.3, x.4, x.5, x.6),
-		}
-	}
-}
-impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
-	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X8(x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7),
-		}
-	}
-}
-
-impl From<[Junction; 0]> for MultiLocation {
-	fn from(_: [Junction; 0]) -> Self {
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::Null,
-		}
-	}
-}
-impl From<[Junction; 1]> for MultiLocation {
-	fn from(x: [Junction; 1]) -> Self {
-		let [x0] = x;
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X1(x0),
-		}
-	}
-}
-impl From<[Junction; 2]> for MultiLocation {
-	fn from(x: [Junction; 2]) -> Self {
-		let [x0, x1] = x;
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X2(x0, x1),
-		}
-	}
-}
-impl From<[Junction; 3]> for MultiLocation {
-	fn from(x: [Junction; 3]) -> Self {
-		let [x0, x1, x2] = x;
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X3(x0, x1, x2),
-		}
-	}
-}
-impl From<[Junction; 4]> for MultiLocation {
-	fn from(x: [Junction; 4]) -> Self {
-		let [x0, x1, x2, x3] = x;
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X4(x0, x1, x2, x3),
-		}
-	}
-}
-impl From<[Junction; 5]> for MultiLocation {
-	fn from(x: [Junction; 5]) -> Self {
-		let [x0, x1, x2, x3, x4] = x;
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X5(x0, x1, x2, x3, x4),
-		}
-	}
-}
-impl From<[Junction; 6]> for MultiLocation {
-	fn from(x: [Junction; 6]) -> Self {
-		let [x0, x1, x2, x3, x4, x5] = x;
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X6(x0, x1, x2, x3, x4, x5),
-		}
-	}
-}
-impl From<[Junction; 7]> for MultiLocation {
-	fn from(x: [Junction; 7]) -> Self {
-		let [x0, x1, x2, x3, x4, x5, x6] = x;
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X7(x0, x1, x2, x3, x4, x5, x6),
-		}
-	}
-}
-impl From<[Junction; 8]> for MultiLocation {
-	fn from(x: [Junction; 8]) -> Self {
-		let [x0, x1, x2, x3, x4, x5, x6, x7] = x;
-		MultiLocation {
-			parents: 0,
-			junctions: Junctions::X8(x0, x1, x2, x3, x4, x5, x6, x7),
-		}
-	}
-}
-
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum Junctions {
-	/// The interpreting consensus system.
-	Null,
-	/// A relative path comprising 1 junction.
-	X1(Junction),
-	/// A relative path comprising 2 junctions.
-	X2(Junction, Junction),
-	/// A relative path comprising 3 junctions.
-	X3(Junction, Junction, Junction),
-	/// A relative path comprising 4 junctions.
-	X4(Junction, Junction, Junction, Junction),
-	/// A relative path comprising 5 junctions.
-	X5(Junction, Junction, Junction, Junction, Junction),
-	/// A relative path comprising 6 junctions.
-	X6(Junction, Junction, Junction, Junction, Junction, Junction),
-	/// A relative path comprising 7 junctions.
-	X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction),
-	/// A relative path comprising 8 junctions.
-	X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction),
-}
-
-pub struct JunctionsIterator(Junctions);
-impl Iterator for JunctionsIterator {
-	type Item = Junction;
-	fn next(&mut self) -> Option<Junction> {
-		self.0.take_first()
-	}
-}
-
-pub struct JunctionsReverseIterator(Junctions);
-impl Iterator for JunctionsReverseIterator {
-	type Item = Junction;
-	fn next(&mut self) -> Option<Junction> {
-		self.0.take_last()
-	}
-}
-
-pub struct JunctionsRefIterator<'a>(&'a Junctions, usize);
-impl<'a> Iterator for JunctionsRefIterator<'a> {
-	type Item = &'a Junction;
-	fn next(&mut self) -> Option<&'a Junction> {
-		let result = self.0.at(self.1);
-		self.1 += 1;
-		result
-	}
-}
-
-pub struct JunctionsReverseRefIterator<'a>(&'a Junctions, usize);
-impl<'a> Iterator for JunctionsReverseRefIterator<'a> {
-	type Item = &'a Junction;
-	fn next(&mut self) -> Option<&'a Junction> {
-		self.1 += 1;
-		self.0.at(self.0.len().checked_sub(self.1)?)
-	}
-}
-
-impl Junctions {
-	/// Returns first junction, or `None` if the location is empty.
-	pub fn first(&self) -> Option<&Junction> {
-		match &self {
-			Junctions::Null => None,
-			Junctions::X1(ref a) => Some(a),
-			Junctions::X2(ref a, ..) => Some(a),
-			Junctions::X3(ref a, ..) => Some(a),
-			Junctions::X4(ref a, ..) => Some(a),
-			Junctions::X5(ref a, ..) => Some(a),
-			Junctions::X6(ref a, ..) => Some(a),
-			Junctions::X7(ref a, ..) => Some(a),
-			Junctions::X8(ref a, ..) => Some(a),
-		}
-	}
-
-	/// Returns last junction, or `None` if the location is empty.
-	pub fn last(&self) -> Option<&Junction> {
-		match &self {
-			Junctions::Null => None,
-			Junctions::X1(ref a) => Some(a),
-			Junctions::X2(.., ref a) => Some(a),
-			Junctions::X3(.., ref a) => Some(a),
-			Junctions::X4(.., ref a) => Some(a),
-			Junctions::X5(.., ref a) => Some(a),
-			Junctions::X6(.., ref a) => Some(a),
-			Junctions::X7(.., ref a) => Some(a),
-			Junctions::X8(.., ref a) => Some(a),
-		}
-	}
-
-	/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the first element
-	/// (second item in tuple) or `None` if it was empty.
-	pub fn split_first(self) -> (Junctions, Option<Junction>) {
-		match self {
-			Junctions::Null => (Junctions::Null, None),
-			Junctions::X1(a) => (Junctions::Null, Some(a)),
-			Junctions::X2(a, b) => (Junctions::X1(b), Some(a)),
-			Junctions::X3(a, b, c) => (Junctions::X2(b, c), Some(a)),
-			Junctions::X4(a, b, c ,d) => (Junctions::X3(b, c, d), Some(a)),
-			Junctions::X5(a, b, c ,d, e) => (Junctions::X4(b, c, d, e), Some(a)),
-			Junctions::X6(a, b, c ,d, e, f) => (Junctions::X5(b, c, d, e, f), Some(a)),
-			Junctions::X7(a, b, c ,d, e, f, g) => (Junctions::X6(b, c, d, e, f, g), Some(a)),
-			Junctions::X8(a, b, c ,d, e, f, g, h) => (Junctions::X7(b, c, d, e, f, g, h), Some(a)),
-		}
-	}
-
-	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
-	/// (second item in tuple) or `None` if it was empty.
-	pub fn split_last(self) -> (Junctions, Option<Junction>) {
-		match self {
-			Junctions::Null => (Junctions::Null, None),
-			Junctions::X1(a) => (Junctions::Null, Some(a)),
-			Junctions::X2(a, b) => (Junctions::X1(a), Some(b)),
-			Junctions::X3(a, b, c) => (Junctions::X2(a, b), Some(c)),
-			Junctions::X4(a, b, c ,d) => (Junctions::X3(a, b, c), Some(d)),
-			Junctions::X5(a, b, c, d, e) => (Junctions::X4(a, b, c, d), Some(e)),
-			Junctions::X6(a, b, c, d, e, f) => (Junctions::X5(a, b, c, d, e), Some(f)),
-			Junctions::X7(a, b, c, d, e, f, g) => (Junctions::X6(a, b, c, d, e, f), Some(g)),
-			Junctions::X8(a, b, c, d, e, f, g, h) => (Junctions::X7(a, b, c, d, e, f, g), Some(h)),
-		}
-	}
-
-	/// Removes the first element from `self`, returning it (or `None` if it was empty).
-	pub fn take_first(&mut self) -> Option<Junction> {
-		let mut d = Junctions::Null;
-		mem::swap(&mut *self, &mut d);
-		let (tail, head) = d.split_first();
-		*self = tail;
-		head
-	}
-
-	/// Removes the last element from `self`, returning it (or `None` if it was empty).
-	pub fn take_last(&mut self) -> Option<Junction> {
-		let mut d = Junctions::Null;
-		mem::swap(&mut *self, &mut d);
-		let (head, tail) = d.split_last();
-		*self = head;
-		tail
-	}
-
-	/// Consumes `self` and returns a `Junctions` suffixed with `new`, or an `Err` with the original value of
-	/// `self` in case of overflow.
-	pub fn pushed_with(self, new: Junction) -> result::Result<Self, Self> {
-		Ok(match self {
-			Junctions::Null => Junctions::X1(new),
-			Junctions::X1(a) => Junctions::X2(a, new),
-			Junctions::X2(a, b) => Junctions::X3(a, b, new),
-			Junctions::X3(a, b, c) => Junctions::X4(a, b, c, new),
-			Junctions::X4(a, b, c, d) => Junctions::X5(a, b, c, d, new),
-			Junctions::X5(a, b, c, d, e) => Junctions::X6(a, b, c, d, e, new),
-			Junctions::X6(a, b, c, d, e, f) => Junctions::X7(a, b, c, d, e, f, new),
-			Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(a, b, c, d, e, f, g, new),
-			s => Err(s)?,
-		})
-	}
-
-	/// Consumes `self` and returns a `Junctions` prefixed with `new`, or an `Err` with the original value of
-	/// `self` in case of overflow.
-	pub fn pushed_front_with(self, new: Junction) -> result::Result<Self, Self> {
-		Ok(match self {
-			Junctions::Null => Junctions::X1(new),
-			Junctions::X1(a) => Junctions::X2(new, a),
-			Junctions::X2(a, b) => Junctions::X3(new, a, b),
-			Junctions::X3(a, b, c) => Junctions::X4(new, a, b, c),
-			Junctions::X4(a, b, c, d) => Junctions::X5(new, a, b, c, d),
-			Junctions::X5(a, b, c, d, e) => Junctions::X6(new, a, b, c, d, e),
-			Junctions::X6(a, b, c, d, e, f) => Junctions::X7(new, a, b, c, d, e, f),
-			Junctions::X7(a, b, c, d, e, f, g) => Junctions::X8(new, a, b, c, d, e, f, g),
-			s => Err(s)?,
-		})
-	}
-
-	/// Returns the number of junctions in `self`.
-	pub fn len(&self) -> usize {
-		match &self {
-			Junctions::Null => 0,
-			Junctions::X1(..) => 1,
-			Junctions::X2(..) => 2,
-			Junctions::X3(..) => 3,
-			Junctions::X4(..) => 4,
-			Junctions::X5(..) => 5,
-			Junctions::X6(..) => 6,
-			Junctions::X7(..) => 7,
-			Junctions::X8(..) => 8,
-		}
-	}
-
-	/// Returns the junction at index `i`, or `None` if the location doesn't contain that many elements.
-	pub fn at(&self, i: usize) -> Option<&Junction> {
-		Some(match (i, &self) {
-			(0, Junctions::X1(ref a)) => a,
-			(0, Junctions::X2(ref a, ..)) => a,
-			(0, Junctions::X3(ref a, ..)) => a,
-			(0, Junctions::X4(ref a, ..)) => a,
-			(0, Junctions::X5(ref a, ..)) => a,
-			(0, Junctions::X6(ref a, ..)) => a,
-			(0, Junctions::X7(ref a, ..)) => a,
-			(0, Junctions::X8(ref a, ..)) => a,
-			(1, Junctions::X2(_, ref a)) => a,
-			(1, Junctions::X3(_, ref a, ..)) => a,
-			(1, Junctions::X4(_, ref a, ..)) => a,
-			(1, Junctions::X5(_, ref a, ..)) => a,
-			(1, Junctions::X6(_, ref a, ..)) => a,
-			(1, Junctions::X7(_, ref a, ..)) => a,
-			(1, Junctions::X8(_, ref a, ..)) => a,
-			(2, Junctions::X3(_, _, ref a)) => a,
-			(2, Junctions::X4(_, _, ref a, ..)) => a,
-			(2, Junctions::X5(_, _, ref a, ..)) => a,
-			(2, Junctions::X6(_, _, ref a, ..)) => a,
-			(2, Junctions::X7(_, _, ref a, ..)) => a,
-			(2, Junctions::X8(_, _, ref a, ..)) => a,
-			(3, Junctions::X4(_, _, _, ref a)) => a,
-			(3, Junctions::X5(_, _, _, ref a, ..)) => a,
-			(3, Junctions::X6(_, _, _, ref a, ..)) => a,
-			(3, Junctions::X7(_, _, _, ref a, ..)) => a,
-			(3, Junctions::X8(_, _, _, ref a, ..)) => a,
-			(4, Junctions::X5(_, _, _, _, ref a)) => a,
-			(4, Junctions::X6(_, _, _, _, ref a, ..)) => a,
-			(4, Junctions::X7(_, _, _, _, ref a, ..)) => a,
-			(4, Junctions::X8(_, _, _, _, ref a, ..)) => a,
-			(5, Junctions::X6(_, _, _, _, _, ref a)) => a,
-			(5, Junctions::X7(_, _, _, _, _, ref a, ..)) => a,
-			(5, Junctions::X8(_, _, _, _, _, ref a, ..)) => a,
-			(6, Junctions::X7(_, _, _, _, _, _, ref a)) => a,
-			(6, Junctions::X8(_, _, _, _, _, _, ref a, ..)) => a,
-			(7, Junctions::X8(_, _, _, _, _, _, _, ref a)) => a,
-			_ => return None,
-		})
-	}
-
-	/// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't contain that many
-	/// elements.
-	pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
-		Some(match (i, self) {
-			(0, Junctions::X1(ref mut a)) => a,
-			(0, Junctions::X2(ref mut a, ..)) => a,
-			(0, Junctions::X3(ref mut a, ..)) => a,
-			(0, Junctions::X4(ref mut a, ..)) => a,
-			(0, Junctions::X5(ref mut a, ..)) => a,
-			(0, Junctions::X6(ref mut a, ..)) => a,
-			(0, Junctions::X7(ref mut a, ..)) => a,
-			(0, Junctions::X8(ref mut a, ..)) => a,
-			(1, Junctions::X2(_, ref mut a)) => a,
-			(1, Junctions::X3(_, ref mut a, ..)) => a,
-			(1, Junctions::X4(_, ref mut a, ..)) => a,
-			(1, Junctions::X5(_, ref mut a, ..)) => a,
-			(1, Junctions::X6(_, ref mut a, ..)) => a,
-			(1, Junctions::X7(_, ref mut a, ..)) => a,
-			(1, Junctions::X8(_, ref mut a, ..)) => a,
-			(2, Junctions::X3(_, _, ref mut a)) => a,
-			(2, Junctions::X4(_, _, ref mut a, ..)) => a,
-			(2, Junctions::X5(_, _, ref mut a, ..)) => a,
-			(2, Junctions::X6(_, _, ref mut a, ..)) => a,
-			(2, Junctions::X7(_, _, ref mut a, ..)) => a,
-			(2, Junctions::X8(_, _, ref mut a, ..)) => a,
-			(3, Junctions::X4(_, _, _, ref mut a)) => a,
-			(3, Junctions::X5(_, _, _, ref mut a, ..)) => a,
-			(3, Junctions::X6(_, _, _, ref mut a, ..)) => a,
-			(3, Junctions::X7(_, _, _, ref mut a, ..)) => a,
-			(3, Junctions::X8(_, _, _, ref mut a, ..)) => a,
-			(4, Junctions::X5(_, _, _, _, ref mut a)) => a,
-			(4, Junctions::X6(_, _, _, _, ref mut a, ..)) => a,
-			(4, Junctions::X7(_, _, _, _, ref mut a, ..)) => a,
-			(4, Junctions::X8(_, _, _, _, ref mut a, ..)) => a,
-			(5, Junctions::X6(_, _, _, _, _, ref mut a)) => a,
-			(5, Junctions::X7(_, _, _, _, _, ref mut a, ..)) => a,
-			(5, Junctions::X8(_, _, _, _, _, ref mut a, ..)) => a,
-			(6, Junctions::X7(_, _, _, _, _, _, ref mut a)) => a,
-			(6, Junctions::X8(_, _, _, _, _, _, ref mut a, ..)) => a,
-			(7, Junctions::X8(_, _, _, _, _, _, _, ref mut a)) => a,
-			_ => return None,
-		})
-	}
-
-	/// Returns a reference iterator over the junctions.
-	pub fn iter(&self) -> JunctionsRefIterator {
-		JunctionsRefIterator(&self, 0)
-	}
-
-	/// Returns a reference iterator over the junctions in reverse.
-	pub fn iter_rev(&self) -> JunctionsReverseRefIterator {
-		JunctionsReverseRefIterator(&self, 0)
-	}
-
-	/// Consumes `self` and returns an iterator over the junctions.
-	pub fn into_iter(self) -> JunctionsIterator {
-		JunctionsIterator(self)
-	}
-
-	/// Consumes `self` and returns an iterator over the junctions in reverse.
-	pub fn into_iter_rev(self) -> JunctionsReverseIterator {
-		JunctionsReverseIterator(self)
-	}
-
-	/// Ensures that self begins with `prefix` and that it has a single `Junction` item following.
-	/// If so, returns a reference to this `Junction` item.
-	///
-	/// # Example
-	/// ```rust
-	/// # use xcm::v1::{Junctions::*, Junction::*};
-	/// # fn main() {
-	/// let mut m = X3(Parachain(2), PalletInstance(3), OnlyChild);
-	/// assert_eq!(m.match_and_split(&X2(Parachain(2), PalletInstance(3))), Some(&OnlyChild));
-	/// assert_eq!(m.match_and_split(&X1(Parachain(2))), None);
-	/// # }
-	/// ```
-	pub fn match_and_split(&self, prefix: &Junctions) -> Option<&Junction> {
-		if prefix.len() + 1 != self.len() {
-			return None
-		}
-		for i in 0..prefix.len() {
-			if prefix.at(i) != self.at(i) {
-				return None
-			}
-		}
-		return self.at(prefix.len())
-	}
-}
-
-impl From<MultiLocation> for VersionedMultiLocation {
-	fn from(x: MultiLocation) -> Self {
-		VersionedMultiLocation::V1(x)
-	}
-}
-
-impl TryFrom<VersionedMultiLocation> for MultiLocation {
-	type Error = ();
-	fn try_from(x: VersionedMultiLocation) -> result::Result<Self, ()> {
-		match x {
-			VersionedMultiLocation::V1(x) => Ok(x),
-			_ => Err(()),
-		}
-	}
-}
-
-#[cfg(test)]
-mod tests {
-	use super::{Junctions::*, MultiLocation};
-	use crate::opaque::v1::{Junction::*, NetworkId::Any};
-
-	#[test]
-	fn match_and_split_works() {
-		let m = MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
-		assert_eq!(m.match_and_split(&MultiLocation { parents: 1, junctions: Null }), None);
-		assert_eq!(
-			m.match_and_split(&MultiLocation { parents: 1, junctions: X1(Parachain(42)) }),
-			Some(&AccountIndex64 { network: Any, index: 23 })
-		);
-		assert_eq!(m.match_and_split(&m), None);
-	}
-
-	#[test]
-	fn append_with_works() {
-		let acc = AccountIndex64 { network: Any, index: 23 };
-		let mut m = MultiLocation { parents: 1, junctions: X1(Parachain(42)) };
-		assert_eq!(m.append_with(MultiLocation::from(X2(PalletInstance(3), acc.clone()))), Ok(()));
-		assert_eq!(m, MultiLocation { parents: 1, junctions: X3(Parachain(42), PalletInstance(3), acc.clone()) });
-
-		// cannot append to create overly long multilocation
-		let acc = AccountIndex64 { network: Any, index: 23 };
-		let mut m = MultiLocation { parents: 6, junctions: X1(Parachain(42)) };
-		let suffix = MultiLocation::from(X2(PalletInstance(3), acc.clone()));
-		assert_eq!(m.append_with(suffix.clone()), Err(suffix));
-	}
-
-	#[test]
-	fn prepend_with_works() {
-		let mut m = MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
-		assert_eq!(m.prepend_with(MultiLocation { parents: 1, junctions: X1(OnlyChild) }), Ok(()));
-		assert_eq!(m, MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) });
-
-		// cannot prepend to create overly long multilocation
-		let mut m = MultiLocation { parents: 6, junctions: X1(Parachain(42)) };
-		let prefix = MultiLocation { parents: 2, junctions: Null };
-		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
-
-		let prefix = MultiLocation { parents: 1, junctions: Null };
-		assert_eq!(m.prepend_with(prefix), Ok(()));
-		assert_eq!(m, MultiLocation { parents: 7, junctions: X1(Parachain(42)) });
-	}
-}
diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
deleted file mode 100644
index f1e48c3b90c2..000000000000
--- a/xcm/src/v1/order.rs
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright 2021 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Version 1 of the Cross-Consensus Message format data structures.
-
-use alloc::vec::Vec;
-use derivative::Derivative;
-use parity_scale_codec::{self, Encode, Decode};
-use super::{MultiAsset, MultiLocation, Xcm};
-
-/// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
-#[derive(Derivative, Encode, Decode)]
-#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))]
-#[codec(encode_bound())]
-#[codec(decode_bound())]
-pub enum Order<Call> {
-	/// Do nothing. Not generally used.
-	#[codec(index = 0)]
-	Null,
-
-	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
-	/// this consensus system.
-	///
-	/// - `assets`: The asset(s) to remove from holding.
-	/// - `dest`: The new owner for the assets.
-	///
-	/// Errors:
-	#[codec(index = 1)]
-	DepositAsset { assets: Vec<MultiAsset>, dest: MultiLocation },
-
-	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
-	/// this consensus system.
-	///
-	/// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`.
-	///
-	/// - `assets`: The asset(s) to remove from holding.
-	/// - `dest`: The new owner for the assets.
-	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to
-	///   `dest.
-	///
-	/// Errors:
-	#[codec(index = 2)]
-	DepositReserveAsset { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
-
-	/// Remove the asset(s) (`give`) from holding and replace them with alternative assets.
-	///
-	/// The minimum amount of assets to be received into holding for the order not to fail may be stated.
-	///
-	/// - `give`: The asset(s) to remove from holding.
-	/// - `receive`: The minimum amount of assets(s) which `give` should be exchanged for. The meaning of wildcards
-	///   is undefined and they should be not be used.
-	///
-	/// Errors:
-	#[codec(index = 3)]
-	ExchangeAsset { give: Vec<MultiAsset>, receive: Vec<MultiAsset> },
-
-	/// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a reserve location.
-	///
-	/// - `assets`: The asset(s) to remove from holding.
-	/// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The sovereign account
-	///   of this consensus system *on the reserve location* will have appropriate assets withdrawn and `effects` will
-	///   be executed on them. There will typically be only one valid location on any given asset/chain combination.
-	/// - `effects`: The orders to execute on the assets once withdrawn *on the reserve location*.
-	///
-	/// Errors:
-	#[codec(index = 4)]
-	InitiateReserveWithdraw { assets: Vec<MultiAsset>, reserve: MultiLocation, effects: Vec<Order<()>> },
-
-	/// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location.
-	///
-	/// - `assets`: The asset(s) to remove from holding.
-	/// - `destination`: A valid location that has a bi-lateral teleportation arrangement.
-	/// - `effects`: The orders to execute on the assets once arrived *on the destination location*.
-	///
-	/// Errors:
-	#[codec(index = 5)]
-	InitiateTeleport { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
-
-	/// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a portion thereof.
-	///
-	/// - `query_id`: An identifier that will be replicated into the returned XCM message.
-	/// - `dest`: A valid destination for the returned XCM message. This may be limited to the current origin.
-	/// - `assets`: A filter for the assets that should be reported back. The assets reported back will be, asset-
-	///   wise, *the lesser of this value and the holding account*. No wildcards will be used when reporting assets
-	///   back.
-	///
-	/// Errors:
-	#[codec(index = 6)]
-	QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: Vec<MultiAsset> },
-
-	/// Pay for the execution of some Xcm with up to `weight` picoseconds of execution time, paying for this with
-	/// up to `fees` from the holding account.
-	///
-	/// Errors:
-	#[codec(index = 7)]
-	BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec<Xcm<Call>> },
-}
-
-pub mod opaque {
-	pub type Order = super::Order<()>;
-}
-
-impl<Call> Order<Call> {
-	pub fn into<C>(self) -> Order<C> { Order::from(self) }
-	pub fn from<C>(order: Order<C>) -> Self {
-		use Order::*;
-		match order {
-			Null => Null,
-			DepositAsset { assets, dest }
-				=> DepositAsset { assets, dest },
-			DepositReserveAsset { assets, dest, effects }
-				=> DepositReserveAsset { assets, dest, effects },
-			ExchangeAsset { give, receive }
-				=> ExchangeAsset { give, receive },
-			InitiateReserveWithdraw { assets, reserve, effects }
-				=> InitiateReserveWithdraw { assets, reserve, effects },
-			InitiateTeleport { assets, dest, effects }
-				=> InitiateTeleport { assets, dest, effects },
-			QueryHolding { query_id, dest, assets }
-				=> QueryHolding { query_id, dest, assets },
-			BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
-				let xcm = xcm.into_iter().map(Xcm::from).collect();
-				BuyExecution { fees, weight, debt, halt_on_error, xcm }
-			},
-		}
-	}
-}
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
deleted file mode 100644
index 6f3dccce1630..000000000000
--- a/xcm/src/v1/traits.rs
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2021 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Cross-Consensus Message format data structures.
-
-use core::result;
-use parity_scale_codec::{Encode, Decode};
-
-use super::{MultiLocation, Xcm};
-
-#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
-pub enum Error {
-	Undefined,
-	Overflow,
-	/// The operation is intentionally unsupported.
-	Unimplemented,
-	UnhandledXcmVersion,
-	UnhandledXcmMessage,
-	UnhandledEffect,
-	EscalationOfPrivilege,
-	UntrustedReserveLocation,
-	UntrustedTeleportLocation,
-	DestinationBufferOverflow,
-	/// The message and destination was recognized as being reachable but the operation could not be completed.
-	/// A human-readable explanation of the specific issue is provided.
-	SendFailed(#[codec(skip)] &'static str),
-	/// The message and destination combination was not recognized as being reachable.
-	CannotReachDestination(MultiLocation, Xcm<()>),
-	MultiLocationFull,
-	FailedToDecode,
-	BadOrigin,
-	ExceedsMaxMessageSize,
-	FailedToTransactAsset(#[codec(skip)] &'static str),
-	/// Execution of the XCM would potentially result in a greater weight used than the pre-specified
-	/// weight limit. The amount that is potentially required is the parameter.
-	WeightLimitReached(Weight),
-	Wildcard,
-	/// The case where an XCM message has specified a optional weight limit and the weight required for
-	/// processing is too great.
-	///
-	/// Used by:
-	/// - `Transact`
-	TooMuchWeightRequired,
-	/// The fees specified by the XCM message were not found in the holding account.
-	///
-	/// Used by:
-	/// - `BuyExecution`
-	NotHoldingFees,
-	/// The weight of an XCM message is not computable ahead of execution. This generally means at least part
-	/// of the message is invalid, which could be due to it containing overly nested structures or an invalid
-	/// nested data segment (e.g. for the call in `Transact`).
-	WeightNotComputable,
-	/// The XCM did not pass the barrier condition for execution. The barrier condition differs on different
-	/// chains and in different circumstances, but generally it means that the conditions surrounding the message
-	/// were not such that the chain considers the message worth spending time executing. Since most chains
-	/// lift the barrier to execution on appropriate payment, presentation of an NFT voucher, or based on the
-	/// message origin, it means that none of those were the case.
-	Barrier,
-	/// Indicates that it is not possible for a location to have an asset be withdrawn or transferred from its
-	/// ownership. This probably means it doesn't own (enough of) it, but may also indicate that it is under a
-	/// lock, hold, freeze or is otherwise unavailable.
-	NotWithdrawable,
-	/// Indicates that the consensus system cannot deposit an asset under the ownership of a particular location.
-	LocationCannotHold,
-	/// The assets given to purchase weight is are insufficient for the weight desired.
-	TooExpensive,
-	/// The given asset is not handled.
-	AssetNotFound,
-}
-
-impl From<()> for Error {
-	fn from(_: ()) -> Self {
-		Self::Undefined
-	}
-}
-
-pub type Result = result::Result<(), Error>;
-
-/// Local weight type; execution time in picoseconds.
-pub type Weight = u64;
-
-/// Outcome of an XCM execution.
-#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
-pub enum Outcome {
-	/// Execution completed successfully; given weight was used.
-	Complete(Weight),
-	/// Execution started, but did not complete successfully due to the given error; given weight was used.
-	Incomplete(Weight, Error),
-	/// Execution did not start due to the given error.
-	Error(Error),
-}
-
-impl Outcome {
-	pub fn ensure_complete(self) -> Result {
-		match self {
-			Outcome::Complete(_) => Ok(()),
-			Outcome::Incomplete(_, e) => Err(e),
-			Outcome::Error(e) => Err(e),
-		}
-	}
-	pub fn ensure_execution(self) -> result::Result<Weight, Error> {
-		match self {
-			Outcome::Complete(w) => Ok(w),
-			Outcome::Incomplete(w, _) => Ok(w),
-			Outcome::Error(e) => Err(e),
-		}
-	}
-	/// How much weight was used by the XCM execution attempt.
-	pub fn weight_used(&self) -> Weight {
-		match self {
-			Outcome::Complete(w) => *w,
-			Outcome::Incomplete(w, _) => *w,
-			Outcome::Error(_) => 0,
-		}
-	}
-}
-
-/// Type of XCM message executor.
-pub trait ExecuteXcm<Call> {
-	/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The weight limit is
-	/// a basic hard-limit and the implementation may place further restrictions or requirements on weight and
-	/// other aspects.
-	fn execute_xcm(origin: MultiLocation, message: Xcm<Call>, weight_limit: Weight) -> Outcome {
-		Self::execute_xcm_in_credit(origin, message, weight_limit, 0)
-	}
-
-	/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight.
-	///
-	/// Some amount of `weight_credit` may be provided which, depending on the implementation, may allow
-	/// execution without associated payment.
-	fn execute_xcm_in_credit(
-		origin: MultiLocation,
-		message: Xcm<Call>,
-		weight_limit: Weight,
-		weight_credit: Weight,
-	) -> Outcome;
-}
-
-impl<C> ExecuteXcm<C> for () {
-	fn execute_xcm_in_credit(
-		_origin: MultiLocation,
-		_message: Xcm<C>,
-		_weight_limit: Weight,
-		_weight_credit: Weight,
-	) -> Outcome {
-		Outcome::Error(Error::Unimplemented)
-	}
-}
-
-/// Utility for sending an XCM message.
-///
-/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each router might return
-/// `CannotReachDestination` to pass the execution to the next sender item. Note that each `CannotReachDestination`
-/// might alter the destination and the xcm message for to the next router.
-///
-///
-/// # Example
-/// ```rust
-/// # use xcm::v0::{MultiLocation, Xcm, Junction, Error, OriginKind, SendXcm, Result};
-/// # use parity_scale_codec::Encode;
-///
-/// /// A sender that only passes the message through and does nothing.
-/// struct Sender1;
-/// impl SendXcm for Sender1 {
-///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-///         return Err(Error::CannotReachDestination(destination, message))
-///     }
-/// }
-///
-/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing.
-/// struct Sender2;
-/// impl SendXcm for Sender2 {
-///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-///         if let MultiLocation::X2(j1, j2) = destination {
-///             Ok(())
-///         } else {
-///             Err(Error::Undefined)
-///         }
-///     }
-/// }
-///
-/// /// A sender that accepts a message from an X1 parent junction, passing through otherwise.
-/// struct Sender3;
-/// impl SendXcm for Sender3 {
-///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-///         match destination {
-///             MultiLocation::X1(j) if j == Junction::Parent => Ok(()),
-///             _ => Err(Error::CannotReachDestination(destination, message)),
-///         }
-///     }
-/// }
-///
-/// // A call to send via XCM. We don't really care about this.
-/// # fn main() {
-/// let call: Vec<u8> = ().encode();
-/// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
-/// let destination = MultiLocation::X1(Junction::Parent);
-///
-/// assert!(
-///     // Sender2 will block this.
-///     <(Sender1, Sender2, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
-///         .is_err()
-/// );
-///
-/// assert!(
-///     // Sender3 will catch this.
-///     <(Sender1, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
-///         .is_ok()
-/// );
-/// # }
-/// ```
-pub trait SendXcm {
-	/// Send an XCM `message` to a given `destination`.
-	///
-	/// If it is not a destination which can be reached with this type but possibly could by others, then it *MUST*
-	/// return `CannotReachDestination`. Any other error will cause the tuple implementation to exit early without
-	/// trying other type fields.
-	fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result;
-}
-
-#[impl_trait_for_tuples::impl_for_tuples(30)]
-impl SendXcm for Tuple {
-	fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-		for_tuples!( #(
-			// we shadow `destination` and `message` in each expansion for the next one.
-			let (destination, message) = match Tuple::send_xcm(destination, message) {
-				Err(Error::CannotReachDestination(d, m)) => (d, m),
-				o @ _ => return o,
-			};
-		)* );
-		Err(Error::CannotReachDestination(destination, message))
-	}
-}

From ee80e03f413a2a2076759a3fd0313daacc391347 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Fri, 30 Jul 2021 19:16:58 +0200
Subject: [PATCH 004/166] Draft next MultiAsset API.

---
 xcm/src/lib.rs                 |  15 +
 xcm/src/v0/mod.rs              |   6 +-
 xcm/src/v0/multi_asset.rs      |  43 +--
 xcm/src/v0/multiasset.rs       | 440 ++++++++++++++++++++++---
 xcm/src/v0/order.rs            |  21 +-
 xcm/xcm-builder/src/mock.rs    |   2 +-
 xcm/xcm-executor/src/assets.rs | 577 +++++++++++----------------------
 xcm/xcm-executor/src/lib.rs    |  14 +-
 8 files changed, 615 insertions(+), 503 deletions(-)

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index 1addc44bd552..8b459adc7185 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -63,3 +63,18 @@ pub enum VersionedMultiLocation {
 pub enum VersionedMultiAsset {
 	V0(v0::MultiAsset),
 }
+
+impl From<v0::MultiAsset> for VersionedMultiAsset {
+	fn from(x: v0::MultiAsset) -> Self {
+		VersionedMultiAsset::V0(x)
+	}
+}
+
+impl core::convert::TryFrom<VersionedMultiAsset> for v0::MultiAsset {
+	type Error = ();
+	fn try_from(x: VersionedMultiAsset) -> core::result::Result<Self, ()> {
+		match x {
+			VersionedMultiAsset::V0(x) => Ok(x),
+		}
+	}
+}
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 619e9b9bc75a..cc8044ea19d2 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -20,7 +20,7 @@ use core::{result, convert::TryFrom, fmt::Debug};
 use derivative::Derivative;
 use alloc::vec::Vec;
 use parity_scale_codec::{self, Encode, Decode};
-use crate::{VersionedMultiAsset, DoubleEncoded, VersionedXcm};
+use crate::{VersionedMultiAsset, VersionedWildMultiAsset, DoubleEncoded, VersionedXcm};
 
 mod junction;
 mod multi_asset;
@@ -30,7 +30,9 @@ mod traits;
 pub mod multiasset;	// the new multiasset.
 
 pub use junction::{Junction, NetworkId, BodyId, BodyPart};
-pub use multi_asset::{MultiAsset, AssetInstance};
+pub use multiasset::{
+	AssetId, AssetInstance, MultiAsset, MultiAssets, MultiAssetFilter, Fungibility, WildMultiAsset, WildFungibility
+};
 pub use multi_location::MultiLocation;
 pub use order::Order;
 pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
index dc682902df65..d7065d3e1d8e 100644
--- a/xcm/src/v0/multi_asset.rs
+++ b/xcm/src/v0/multi_asset.rs
@@ -20,33 +20,7 @@ use core::{result, convert::TryFrom};
 use alloc::vec::Vec;
 
 use parity_scale_codec::{self, Encode, Decode};
-use super::{MultiLocation, VersionedMultiAsset};
-
-/// A general identifier for an instance of a non-fungible asset class.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum AssetInstance {
-	/// Undefined - used if the NFA class has only one instance.
-	Undefined,
-
-	/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
-	/// values up to `2**128 - 1`.
-	Index { #[codec(compact)] id: u128 },
-
-	/// A 4-byte fixed-length datum.
-	Array4([u8; 4]),
-
-	/// An 8-byte fixed-length datum.
-	Array8([u8; 8]),
-
-	/// A 16-byte fixed-length datum.
-	Array16([u8; 16]),
-
-	/// A 32-byte fixed-length datum.
-	Array32([u8; 32]),
-
-	/// An arbitrary piece of data. Use only when necessary.
-	Blob(Vec<u8>),
-}
+use super::{MultiLocation, VersionedMultiAsset, AssetInstance};
 
 /// A single general identifier for an asset.
 ///
@@ -306,21 +280,6 @@ impl MultiAsset {
 	}
 }
 
-impl From<MultiAsset> for VersionedMultiAsset {
-	fn from(x: MultiAsset) -> Self {
-		VersionedMultiAsset::V0(x)
-	}
-}
-
-impl TryFrom<VersionedMultiAsset> for MultiAsset {
-	type Error = ();
-	fn try_from(x: VersionedMultiAsset) -> result::Result<Self, ()> {
-		match x {
-			VersionedMultiAsset::V0(x) => Ok(x),
-		}
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 8e1839719f09..010f1ce4c1da 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -12,13 +12,51 @@
 // GNU General Public License for more details.
 
 // You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-//! Cross-Consensus Message format asset data structure.
+//! Cross-Consensus Message format asset data structures.
+//!
+//! This encompasses four types for repesenting assets:
+//! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some amount of a fungible.
+//! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with fungibles first.
+//! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific kind.
+//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
+//!   account.
 
+use core::convert::{TryFrom, TryInto};
 use alloc::vec::Vec;
 use parity_scale_codec::{self as codec, Encode, Decode};
-use super::{MultiLocation, multi_asset::{AssetInstance, MultiAsset as OldMultiAsset}};
+use super::{
+	MultiLocation, multi_asset::MultiAsset as OldMultiAsset, VersionedMultiAsset,
+	VersionedWildMultiAsset,
+};
+use core::cmp::Ordering;
+
+/// A general identifier for an instance of a non-fungible asset class.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum AssetInstance {
+	/// Undefined - used if the NFA class has only one instance.
+	Undefined,
+
+	/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
+	/// values up to `2**128 - 1`.
+	Index { #[codec(compact)] id: u128 },
+
+	/// A 4-byte fixed-length datum.
+	Array4([u8; 4]),
+
+	/// An 8-byte fixed-length datum.
+	Array8([u8; 8]),
+
+	/// A 16-byte fixed-length datum.
+	Array16([u8; 16]),
+
+	/// A 32-byte fixed-length datum.
+	Array32([u8; 32]),
+
+	/// An arbitrary piece of data. Use only when necessary.
+	Blob(Vec<u8>),
+}
 
 /// Classification of an asset being concrete or abstract.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
@@ -28,44 +66,126 @@ pub enum AssetId {
 }
 
 impl AssetId {
-	/// Prepend a MultiLocation to a concrete asset, giving it a new root location.
+	/// Prepend a `MultiLocation` to a concrete asset, giving it a new root location.
 	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
 		if let AssetId::Concrete(ref mut l) = self {
 			l.prepend_with(prepend.clone()).map_err(|_| ())?;
 		}
 		Ok(())
 	}
+
+	/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `MultiAsset` value.
+	pub fn into_multiasset(self, fun: Fungibility) -> MultiAsset {
+		MultiAsset { fun, id: self }
+	}
+
+	/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `WildMultiAsset`
+	/// definite (`Asset`) value.
+	pub fn into_wild(self, fun: Fungibility) -> WildMultiAsset {
+		WildMultiAsset::Asset(fun, self)
+	}
+
+	/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `WildMultiAsset`
+	/// wildcard (`AllOf`) value.
+	pub fn into_allof(self, fun: WildFungibility) -> WildMultiAsset {
+		WildMultiAsset::AllOf(fun, self)
+	}
 }
 
-/// Classification of whether an asset is fungible or not, along with an optional amount or instance.
+/// Classification of whether an asset is fungible or not, along with an mandatory amount or instance.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
 pub enum Fungibility {
-	Fungible(Option<u128>),
-	NonFungible(Option<AssetInstance>),
+	Fungible(u128),
+	NonFungible(AssetInstance),
 }
 
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
-pub enum MultiAsset {
-	None,
-	Asset(Fungibility, Option<AssetId>),
-	All,
+impl Fungibility {
+	pub fn is_kind(&self, w: WildFungibility) -> bool {
+		use {Fungibility::*, WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}};
+		matches!((self, w), (Fungible(_), WildFungible) | (NonFungible(_), WildNonFungible))
+	}
+}
+
+impl From<u128> for Fungibility {
+	fn from(amount: u128) -> Fungibility {
+		debug_assert_ne!(amount, 0);
+		Fungibility::Fungible(amount)
+	}
+}
+
+impl From<AssetInstance> for Fungibility {
+	fn from(instance: AssetInstance) -> Fungibility {
+		Fungibility::NonFungible(instance)
+	}
+}
+
+
+
+
+#[derive(Clone, Eq, PartialEq, Debug)]
+pub struct MultiAsset {
+	pub id: AssetId,
+	pub fun: Fungibility,
+}
+
+impl PartialOrd for MultiAsset {
+	fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+		Some(self.cmp(other))
+	}
+}
+
+impl Ord for MultiAsset {
+	fn cmp(&self, other: &Self) -> Ordering {
+		match (&self.fun, &other.fun) {
+			(Fungibility::Fungible(..), Fungibility::NonFungible(..)) => return Ordering::Less,
+			(Fungibility::NonFungible(..), Fungibility::Fungible(..)) => return Ordering::Greater,
+		}
+		(&self.id, &self.fun).cmp((&other.id, &other.fun))
+	}
 }
 
 impl From<(AssetId, Fungibility)> for MultiAsset {
-	fn from((asset_id, fungibility): (AssetId, Fungibility)) -> MultiAsset {
-		MultiAsset::Asset(fungibility, Some(asset_id))
+	fn from((id, fun): (AssetId, Fungibility)) -> MultiAsset {
+		MultiAsset { fun, id }
 	}
 }
 
-impl From<Fungibility> for MultiAsset {
-	fn from(fungibility: Fungibility) -> MultiAsset {
-		MultiAsset::Asset(fungibility, None)
+impl From<(AssetId, u128)> for MultiAsset {
+	fn from((id, amount): (AssetId, u128)) -> MultiAsset {
+		MultiAsset { fun: amount.into(), id }
+	}
+}
+
+impl From<(AssetId, AssetInstance)> for MultiAsset {
+	fn from((id, instance): (AssetId, AssetInstance)) -> MultiAsset {
+		MultiAsset { fun: instance.into(), id }
+	}
+}
+
+impl From<MultiAsset> for OldMultiAsset {
+	fn from(a: MultiAsset) -> Self {
+		use {AssetId::*, Fungibility::*, OldMultiAsset::*};
+		match (a.fun, a.id) {
+			(Fungible(amount), Concrete(id)) => ConcreteFungible { id, amount },
+			(Fungible(amount), Abstract(id)) => AbstractFungible { id, amount },
+			(NonFungible(instance), Concrete(class)) => ConcreteNonFungible { class, instance },
+			(NonFungible(instance), Abstract(class)) => AbstractNonFungible { class, instance },
+		}
 	}
 }
 
-impl From<()> for MultiAsset {
-	fn from(_: ()) -> MultiAsset {
-		MultiAsset::None
+impl TryFrom<OldMultiAsset> for MultiAsset {
+	type Error = ();
+	fn try_from(a: OldMultiAsset) -> Result<Self, ()> {
+		use {AssetId::*, Fungibility::*, OldMultiAsset::*};
+		let (fun, id) = match a {
+			ConcreteFungible { id, amount } if amount > 0 => (Fungible(amount), Concrete(id)),
+			AbstractFungible { id, amount } if amount > 0 => (Fungible(amount), Abstract(id)),
+			ConcreteNonFungible { class, instance } => (NonFungible(instance), Concrete(class)),
+			AbstractNonFungible { class, instance } => (NonFungible(instance), Abstract(class)),
+			_ => return Err(()),
+		};
+		Ok(MultiAsset { fun, id })
 	}
 }
 
@@ -76,53 +196,273 @@ impl Encode for MultiAsset {
 }
 
 impl Decode for MultiAsset {
+	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
+		OldMultiAsset::decode(input)
+			.and_then(|r| TryInto::try_into(r).map_err(|_| "Unsupported wildcard".into()))?
+	}
+}
+
+impl MultiAsset {
+	fn is_fungible(&self, maybe_id: Option<AssetId>) -> bool {
+		use Fungibility::*;
+		matches!(self.fun, Fungible(..)) && maybe_id.map_or(true, |i| i == self.id)
+	}
+
+	fn is_non_fungible(&self, maybe_id: Option<AssetId>) -> bool {
+		use Fungibility::*;
+		matches!(self.fun, NonFungible(..)) && maybe_id.map_or(true, |i| i == self.id)
+	}
+
+	/// Prepend a `MultiLocation` to a concrete asset, giving it a new root location.
+	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
+		self.id.reanchor(prepend)
+	}
+
+	/// Returns true if `self` is a super-set of the given `inner`.
+	pub fn contains(&self, inner: &MultiAsset) -> bool {
+		use {MultiAsset::*, Fungibility::*};
+		if self.id == inner.id {
+			match (&self.fun, &inner.fun) {
+				(Fungible(a), Fungible(i)) if a >= i => return true,
+				(NonFungible(a), NonFungible(i)) if a == i => return true,
+				_ => (),
+			}
+		}
+		false
+	}
+}
+
+
+
+/// A vec of MultiAssets. There may be no duplicate fungible items in here and when decoding, they must be sorted.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode)]
+pub struct MultiAssets(Vec<MultiAsset>);
+
+impl Decode for MultiAssets {
+	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
+		let r = Vec::<MultiAsset>::decode(input)?;
+		if r.is_empty() { return Ok(Self(Vec::new())) }
+		r.iter().skip(1).try_fold(&r[0], |a, b| {
+			if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) {
+				Ok(b)
+			} else {
+				Err("Unsupported wildcard".into())
+			}
+		})?;
+		Ok(Self(r))
+	}
+}
+
+impl From<MultiAssets> for Vec<OldMultiAsset> {
+	fn from(a: MultiAssets) -> Self {
+		a.0.into_iter().map(OldMultiAsset::from).collect()
+	}
+}
+
+impl TryFrom<Vec<OldMultiAsset>> for MultiAssets {
+	type Error = ();
+	fn try_from(a: Vec<OldMultiAsset>) -> Result<Self, ()> {
+		a.0.into_iter().map(MultiAsset::try_from).collect()
+	}
+}
+
+impl MultiAssets {
+	/// A new (empty) value.
+	pub fn new() -> Self {
+		Self(Vec::new())
+	}
+
+	/// Add some asset onto the multiasset list. This is quite a laborious operation since it maintains the ordering.
+	pub fn push(&mut self, a: MultiAsset) {
+		if let Fungibility::Fungible(ref amount) = a.fun {
+			for asset in self.0.iter_mut().filter(|x| x.id == a.id) {
+				if let Fungibility::Fungible(ref mut balance) = asset.fun {
+					*balance += *amount;
+					return
+				}
+			}
+		}
+		self.0.push(a);
+		self.0.sort();
+	}
+
+	/// Returns `true` if this definitely represents no asset.
+	pub fn is_none(&self) -> bool {
+		self.0.is_empty()
+	}
+
+	/// Returns true if `self` is a super-set of the given `inner`.
+	pub fn contains(&self, inner: &MultiAsset) -> bool {
+		use {MultiAsset::*, Fungibility::*};
+		self.0.iter().any(|i| i.contains(inner))
+	}
+
+	/// Consume `self` and return the inner vec.
+	pub fn drain(self) -> Vec<MultiAsset> {
+		self.0
+	}
+
+	/// Return a reference to the inner vec.
+	pub fn inner(&self) -> &Vec<MultiAsset> {
+		&self.0
+	}
+
+	/// Prepend a `MultiLocation` to any concrete asset items, giving it a new root location.
+	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
+		self.0.iter_mut().try_for_each(|i| i.reanchor(prepend))
+	}
+}
+
+
+
+
+
+/// Classification of whether an asset is fungible or not, along with an optional amount or instance.
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+pub enum WildFungibility {
+	Fungible,
+	NonFungible,
+}
+
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+pub enum WildMultiAsset {
+	All,
+	// TODO: AllOf { fun: WildFungibility, id: AssetId }
+	AllOf(WildFungibility, AssetId),
+}
+
+impl Encode for WildMultiAsset {
+	fn encode(&self) -> Vec<u8> {
+		OldMultiAsset::from(self.clone()).encode()
+	}
+}
+
+impl Decode for WildMultiAsset {
 	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
 		OldMultiAsset::decode(input).map(Into::into)
 	}
 }
 
-impl From<MultiAsset> for OldMultiAsset {
-	fn from(a: MultiAsset) -> Self {
-		use {AssetId::*, Fungibility::*, OldMultiAsset::*, MultiAsset::Asset};
+impl From<WildMultiAsset> for OldMultiAsset {
+	fn from(a: WildMultiAsset) -> Self {
+		use {AssetId::*, Fungibility::*, OldMultiAsset::*, WildMultiAsset::AllOf};
 		match a {
-			MultiAsset::None => OldMultiAsset::None,
-			MultiAsset::All => All,
+			WildMultiAsset::All => All,
+			AllOf(WildFungibility::Fungible, Concrete(id)) => AllConcreteFungible { id },
+			AllOf(WildFungibility::Fungible, Abstract(id)) => AllAbstractFungible { id },
+			AllOf(WildFungibility::NonFungible, Concrete(class)) => AllConcreteNonFungible { class },
+			AllOf(WildFungibility::NonFungible, Abstract(class)) => AllAbstractNonFungible { class },
+		}
+	}
+}
 
-			Asset(Fungible(_), Option::None) => AllFungible,
-			Asset(NonFungible(_), Option::None) => AllNonFungible,
+impl TryFrom<OldMultiAsset> for WildMultiAsset {
+	type Error = ();
+	fn try_from(a: OldMultiAsset) -> Result<Self, ()> {
+		use {AssetId::*, Fungibility::*, OldMultiAsset::*, WildMultiAsset::AllOf};
+		Ok(match a {
+			All => WildMultiAsset::All,
+			AllConcreteFungible { id } => AllOf(WildFungibility::Fungible, Concrete(id)),
+			AllAbstractFungible { id } => AllOf(WildFungibility::Fungible, Abstract(id)),
+			AllConcreteNonFungible { class } => AllOf(WildFungibility::NonFungible, Concrete(class)),
+			AllAbstractNonFungible { class } => AllOf(WildFungibility::NonFungible, Abstract(class)),
+			_ => return Err(()),
+		})
+	}
+}
 
-			Asset(Fungible(Option::None), Some(Concrete(id))) => AllConcreteFungible { id },
-			Asset(Fungible(Option::None), Some(Abstract(id))) => AllAbstractFungible { id },
-			Asset(NonFungible(Option::None), Some(Concrete(class))) => AllConcreteNonFungible { class },
-			Asset(NonFungible(Option::None), Some(Abstract(class))) => AllAbstractNonFungible { class },
+impl WildMultiAsset {
+	/// Returns true if `self` is a super-set of the given `inner`.
+	///
+	/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
+	/// For more details, see the implementation and tests.
+	pub fn contains(&self, inner: &MultiAsset) -> bool {
+		use WildMultiAsset::*;
+		match self {
+			AllOf(fun, id) => inner.fun.is_kind(*fun) && inner.id == id,
+			All => true,
+		}
+	}
 
-			Asset(Fungible(Some(amount)), Some(Concrete(id))) => ConcreteFungible { id, amount },
-			Asset(Fungible(Some(amount)), Some(Abstract(id))) => AbstractFungible { id, amount },
-			Asset(NonFungible(Some(instance)), Some(Concrete(class))) => ConcreteNonFungible { class, instance },
-			Asset(NonFungible(Some(instance)), Some(Abstract(class))) => AbstractNonFungible { class, instance },
+	/// Prepend a `MultiLocation` to any concrete asset components, giving it a new root location.
+	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
+		use WildMultiAsset::*;
+		match self {
+			AllOf(_, ref mut id) => id.prepend_with(prepend.clone()).map_err(|_| ()),
+			_ => Ok(()),
 		}
 	}
 }
 
-impl From<OldMultiAsset> for MultiAsset {
-	fn from(a: OldMultiAsset) -> Self {
-		use {AssetId::*, Fungibility::*, OldMultiAsset::*, MultiAsset::Asset};
+
+
+
+
+/// `MultiAsset` collection, either `MultiAssets` or a single wildcard. Note: vectors of wildcards
+/// whose encoding is supported in XCM v0 are unsupported in this implementation and will result in a decode error.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+pub enum MultiAssetFilter {
+	Assets(MultiAssets),
+	Wild(WildMultiAsset),
+}
+
+impl From<MultiAssetFilter> for Vec<OldMultiAsset> {
+	fn from(a: MultiAssetFilter) -> Self {
+		use MultiAssetFilter::*;
 		match a {
-			None => MultiAsset::None,
-			All => MultiAsset::All,
+			Assets(assets) => assets.0.into_iter().map(OldMultiAsset::from).collect(),
+			Wild(wild) => vec![wild.into()],
+		}
+	}
+}
 
-			AllFungible => Asset(Fungible(Option::None), Option::None),
-			AllNonFungible => Asset(NonFungible(Option::None), Option::None),
+impl TryFrom<Vec<OldMultiAsset>> for MultiAssetFilter {
+	type Error = ();
+	fn try_from(old_assets: Vec<OldMultiAsset>) -> Result<Self, ()> {
+		use MultiAssetFilter::*;
+		if old_assets.is_empty() {
+			return Ok(Assets(MultiAssets::new()))
+		}
+		if let (1, Ok(wild)) = (old_assets.len(), old_assets[0].try_into()) {
+			return Ok(Wild(wild))
+		}
 
-			AllConcreteFungible { id } => Asset(Fungible(Option::None), Some(Concrete(id))),
-			AllAbstractFungible { id } => Asset(Fungible(Option::None), Some(Abstract(id))),
-			AllConcreteNonFungible { class } => Asset(NonFungible(Option::None), Some(Concrete(class))),
-			AllAbstractNonFungible { class } => Asset(NonFungible(Option::None), Some(Abstract(class))),
+		old_assets.into_iter().map(MultiAsset::try_from).collect()
+	}
+}
+
+impl MultiAssetFilter {
+	/// Returns `true` if the `MultiAsset` is a wildcard and refers to sets of assets, instead of just one.
+	pub fn is_wildcard(&self) -> bool {
+		matches!(self, MultiAssetFilter::Wild(..))
+	}
 
-			ConcreteFungible { id, amount } => Asset(Fungible(Some(amount)), Some(Concrete(id))),
-			AbstractFungible { id, amount } => Asset(Fungible(Some(amount)), Some(Abstract(id))),
-			ConcreteNonFungible { class, instance } => Asset(NonFungible(Some(instance)), Some(Concrete(class))),
-			AbstractNonFungible { class, instance } => Asset(NonFungible(Some(instance)), Some(Abstract(class))),
+	/// Returns `true` if the `MultiAsset` is not a wildcard.
+	pub fn is_definite(&self) -> bool {
+		!self.is_wildcard()
+	}
+
+	/// Returns `true` if this definitely represents no asset.
+	pub fn is_none(&self) -> bool {
+		matches!(self, MultiAssetFilter::Assets(a) if a.is_none())
+	}
+
+	/// Returns true if `self` is a super-set of the given `inner`.
+	///
+	/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
+	/// For more details, see the implementation and tests.
+	pub fn contains(&self, inner: &MultiAsset) -> bool {
+		match self {
+			MultiAssetFilter::Assets(ref assets) => assets.contains(inner),
+			MultiAssetFilter::Wild(ref wild) => wild.contains(inner),
+		}
+	}
+
+	/// Prepend a `MultiLocation` to any concrete asset components, giving it a new root location.
+	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
+		match self {
+			MultiAssetFilter::Assets(ref mut assets) => assets.reanchor(prepend),
+			MultiAssetFilter::Wild(ref mut wild) => wild.reanchor(prepend),
 		}
 	}
 }
diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index 776ac3691c74..fa8aa6df3393 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -19,7 +19,7 @@
 use alloc::vec::Vec;
 use derivative::Derivative;
 use parity_scale_codec::{self, Encode, Decode};
-use super::{MultiAsset, MultiLocation, Xcm};
+use super::{MultiAsset, WildMultiAsset, MultiAssetFilter, MultiLocation, Xcm};
 
 /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
 #[derive(Derivative, Encode, Decode)]
@@ -39,7 +39,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 1)]
-	DepositAsset { assets: Vec<MultiAsset>, dest: MultiLocation },
+	DepositAsset { assets: MultiAssetFilter, dest: MultiLocation },
 
 	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
 	/// this consensus system.
@@ -53,19 +53,18 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 2)]
-	DepositReserveAsset { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+	DepositReserveAsset { assets: MultiAssetFilter, dest: MultiLocation, effects: Vec<Order<()>> },
 
 	/// Remove the asset(s) (`give`) from holding and replace them with alternative assets.
 	///
 	/// The minimum amount of assets to be received into holding for the order not to fail may be stated.
 	///
 	/// - `give`: The asset(s) to remove from holding.
-	/// - `receive`: The minimum amount of assets(s) which `give` should be exchanged for. The meaning of wildcards
-	///   is undefined and they should be not be used.
+	/// - `receive`: The minimum amount of assets(s) which `give` should be exchanged for.
 	///
 	/// Errors:
 	#[codec(index = 3)]
-	ExchangeAsset { give: Vec<MultiAsset>, receive: Vec<MultiAsset> },
+	ExchangeAsset { give: MultiAssetFilter, receive: Vec<MultiAsset> },
 
 	/// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a reserve location.
 	///
@@ -77,7 +76,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 4)]
-	InitiateReserveWithdraw { assets: Vec<MultiAsset>, reserve: MultiLocation, effects: Vec<Order<()>> },
+	InitiateReserveWithdraw { assets: MultiAssetFilter, reserve: MultiLocation, effects: Vec<Order<()>> },
 
 	/// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location.
 	///
@@ -87,7 +86,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 5)]
-	InitiateTeleport { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+	InitiateTeleport { assets: MultiAssetFilter, dest: MultiLocation, effects: Vec<Order<()>> },
 
 	/// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a portion thereof.
 	///
@@ -99,14 +98,16 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 6)]
-	QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: Vec<MultiAsset> },
+	QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: MultiAssetFilter },
 
 	/// Pay for the execution of some XCM with up to `weight` picoseconds of execution time, paying for this with
 	/// up to `fees` from the holding account.
 	///
+	/// - `fees`: The asset(s) to remove from holding to pay for fees.
+	///
 	/// Errors:
 	#[codec(index = 7)]
-	BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec<Xcm<Call>> },
+	BuyExecution { fees: WildMultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec<Xcm<Call>> },
 }
 
 pub mod opaque {
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 56d7d753e49e..6e9b7ff5a322 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -122,7 +122,7 @@ pub fn add_asset(who: u64, what: MultiAsset) {
 	ASSETS.with(|a| a.borrow_mut()
 		.entry(who)
 		.or_insert(Assets::new())
-		.saturating_subsume(what)
+		.subsume(what)
 	);
 }
 
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index c0d35052482b..97c5fbbc15a5 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -15,44 +15,16 @@
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
 use sp_std::{prelude::*, mem, collections::{btree_map::BTreeMap, btree_set::BTreeSet}};
-use xcm::v0::{MultiAsset, MultiLocation, AssetInstance};
+use xcm::v0::{
+	MultiAsset, MultiAssets, MultiLocation, AssetInstance,
+	MultiAssetFilter::{self, Assets, Wild},
+	AssetId::{self, Concrete, Abstract},
+	WildMultiAsset::{self, All, AllOf},
+	Fungibility::{Fungible, NonFungible},
+	WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible},
+};
 use sp_runtime::RuntimeDebug;
 
-/// Classification of an asset being concrete or abstract.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, RuntimeDebug)]
-pub enum AssetId {
-	Concrete(MultiLocation),
-	Abstract(Vec<u8>),
-}
-
-impl AssetId {
-	/// Prepend a `MultiLocation` to a concrete asset, giving it a new root location.
-	pub fn prepend_location(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
-		if let AssetId::Concrete(ref mut l) = self {
-			l.prepend_with(prepend.clone()).map_err(|_| ())?;
-		}
-		Ok(())
-	}
-
-	/// Use the value of `self` along with an `amount to create the corresponding `MultiAsset` value for a
-	/// fungible asset.
-	pub fn into_fungible_multiasset(self, amount: u128) -> MultiAsset {
-		match self {
-			AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount },
-			AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount },
-		}
-	}
-
-	/// Use the value of `self` along with an `instance to create the corresponding `MultiAsset` value for a
-	/// non-fungible asset.
-	pub fn into_non_fungible_multiasset(self, instance: AssetInstance) -> MultiAsset {
-		match self {
-			AssetId::Concrete(class) => MultiAsset::ConcreteNonFungible { class, instance },
-			AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance },
-		}
-	}
-}
-
 /// List of non-wildcard fungible and non-fungible assets.
 #[derive(Default, Clone, RuntimeDebug, Eq, PartialEq)]
 pub struct Assets {
@@ -69,7 +41,7 @@ impl From<Vec<MultiAsset>> for Assets {
 	fn from(assets: Vec<MultiAsset>) -> Assets {
 		let mut result = Self::default();
 		for asset in assets.into_iter() {
-			result.saturating_subsume(asset)
+			result.subsume(asset)
 		}
 		result
 	}
@@ -84,181 +56,64 @@ impl From<Assets> for Vec<MultiAsset> {
 impl From<MultiAsset> for Assets {
 	fn from(asset: MultiAsset) -> Assets {
 		let mut result = Self::default();
-		result.saturating_subsume(asset);
+		result.subsume(asset);
 		result
 	}
 }
 
+/// An error emitted by `take` operations.
+pub enum TakeError {
+	/// There was an attempt to take an asset without saturating (enough of) which did not exist.
+	AssetUnderflow(MultiAsset),
+}
+
 impl Assets {
 	/// New value, containing no assets.
 	pub fn new() -> Self { Self::default() }
 
-	/// An iterator over the fungible assets.
+	/// A borrowing iterator over the fungible assets.
 	pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator<Item=MultiAsset> + 'a {
-		self.fungible.iter()
-			.map(|(id, &amount)| match id.clone() {
-				AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount },
-				AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount },
-			})
+		self.fungible.iter().map(|(id, &amount)| MultiAsset { fun: Fungible(amount), id: id.clone() })
 	}
 
-	/// An iterator over the non-fungible assets.
+	/// A borrowing iterator over the non-fungible assets.
 	pub fn non_fungible_assets_iter<'a>(&'a self) -> impl Iterator<Item=MultiAsset> + 'a {
-		self.non_fungible.iter()
-			.map(|&(ref class, ref instance)| match class.clone() {
-				AssetId::Concrete(class) => MultiAsset::ConcreteNonFungible { class, instance: instance.clone() },
-				AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance: instance.clone() },
-			})
+		self.non_fungible.iter().map(|(id, instance)| MultiAsset { fun: NonFungible(instance.clone()), id: id.clone() })
 	}
 
-	/// An iterator over all assets.
+	/// A consuming iterator over all assets.
 	pub fn into_assets_iter(self) -> impl Iterator<Item=MultiAsset> {
-		let fungible = self.fungible.into_iter()
-			.map(|(id, amount)| match id {
-				AssetId::Concrete(id) => MultiAsset::ConcreteFungible { id, amount },
-				AssetId::Abstract(id) => MultiAsset::AbstractFungible { id, amount },
-			});
-		let non_fungible = self.non_fungible.into_iter()
-			.map(|(id, instance)| match id {
-				AssetId::Concrete(class) => MultiAsset::ConcreteNonFungible { class, instance },
-				AssetId::Abstract(class) => MultiAsset::AbstractNonFungible { class, instance },
-			});
-		fungible.chain(non_fungible)
-	}
-
-	/// An iterator over all assets.
+		self.fungible.into_iter().map(|(id, amount)| MultiAsset { fun: Fungible(amount), id })
+			.chain(self.non_fungible.into_iter().map(|(id, instance)| MultiAsset { fun: NonFungible(instance), id }))
+	}
+
+	/// A borrowing iterator over all assets.
 	pub fn assets_iter<'a>(&'a self) -> impl Iterator<Item=MultiAsset> + 'a {
-		let fungible = self.fungible_assets_iter();
-		let non_fungible = self.non_fungible_assets_iter();
-		fungible.chain(non_fungible)
+		self.fungible_assets_iter().chain(self.non_fungible_assets_iter())
 	}
 
 	/// Mutate `self` to contain all given `assets`, saturating if necessary.
-	///
-	/// Wildcards in `assets` are ignored.
-	pub fn saturating_subsume_all(&mut self, assets: Assets) {
-		// OPTIMIZE: Could be done with a much faster btree entry merge and only sum the entries with the
-		// same key.
+	pub fn subsume_assets(&mut self, assets: Assets) {
+		// TODO: Could be done with a much faster btree entry merge and only sum the entries with the
+		//   same key.
 		for asset in assets.into_assets_iter() {
-			self.saturating_subsume(asset)
+			self.subsume(asset)
 		}
 	}
 
 	/// Mutate `self` to contain the given `asset`, saturating if necessary.
 	///
 	/// Wildcard values of `asset` do nothing.
-	pub fn saturating_subsume(&mut self, asset: MultiAsset) {
-		match asset {
-			MultiAsset::ConcreteFungible { id, amount } => {
-				self.saturating_subsume_fungible(AssetId::Concrete(id), amount);
-			}
-			MultiAsset::AbstractFungible { id, amount } => {
-				self.saturating_subsume_fungible(AssetId::Abstract(id), amount);
-			}
-			MultiAsset::ConcreteNonFungible { class, instance} => {
-				self.saturating_subsume_non_fungible(AssetId::Concrete(class), instance);
-			}
-			MultiAsset::AbstractNonFungible { class, instance} => {
-				self.saturating_subsume_non_fungible(AssetId::Abstract(class), instance);
-			}
-			_ => (),
+	pub fn subsume(&mut self, asset: MultiAsset) {
+		match asset.fun {
+			Fungible(amount) => self.fungible
+				.entry(asset.id)
+				.and_modify(|e| *e = e.saturating_add(amount))
+				.or_insert(amount),
+			NonFungible(instance) => self.non_fungible.insert((asset.id, instance)),
 		}
 	}
-
-	/// Consumes `self` and returns its original value excluding `asset` iff it contains at least `asset`.
-	///
-	/// Wildcard assets in `self` will result in an error.
-	///
-	/// `asset` may be a wildcard and are evaluated in the context of `self`.
-	///
-	/// Returns `Ok` with the `self` minus `asset` and the non-wildcard equivalence of `asset` taken if `self`
-	/// contains `asset`, and `Err` with `self` otherwise.
-	pub fn less(mut self, asset: MultiAsset) -> Result<(Self, Assets), Self> {
-		match self.try_take(asset) {
-			Ok(taken) => Ok((self, taken)),
-			Err(()) => Err(self),
-		}
-	}
-
-	/// Mutates `self` to its original value less `asset` and returns `true` iff it contains at least `asset`.
-	///
-	/// Wildcard assets in `self` will result in an error.
-	///
-	/// `asset` may be a wildcard and are evaluated in the context of `self`.
-	///
-	/// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus
-	/// `asset` if `self` contains `asset`, and return `Err` otherwise.
-	pub fn try_take(&mut self, asset: MultiAsset) -> Result<Assets, ()> {
-		match asset {
-			MultiAsset::None => Ok(Assets::new()),
-			MultiAsset::ConcreteFungible { id, amount } => self.try_take_fungible(AssetId::Concrete(id), amount),
-			MultiAsset::AbstractFungible { id, amount } => self.try_take_fungible(AssetId::Abstract(id), amount),
-			MultiAsset::ConcreteNonFungible { class, instance} => self.try_take_non_fungible(AssetId::Concrete(class), instance),
-			MultiAsset::AbstractNonFungible { class, instance} => self.try_take_non_fungible(AssetId::Abstract(class), instance),
-			MultiAsset::AllAbstractFungible { id } => Ok(self.take_fungible(&AssetId::Abstract(id))),
-			MultiAsset::AllConcreteFungible { id } => Ok(self.take_fungible(&AssetId::Concrete(id))),
-			MultiAsset::AllAbstractNonFungible { class } => Ok(self.take_non_fungible(&AssetId::Abstract(class))),
-			MultiAsset::AllConcreteNonFungible { class } => Ok(self.take_non_fungible(&AssetId::Concrete(class))),
-			MultiAsset::AllFungible => {
-				let mut taken = Assets::new();
-				mem::swap(&mut self.fungible, &mut taken.fungible);
-				Ok(taken)
-			},
-			MultiAsset::AllNonFungible => {
-				let mut taken = Assets::new();
-				mem::swap(&mut self.non_fungible, &mut taken.non_fungible);
-				Ok(taken)
-			},
-			MultiAsset::All => Ok(self.swapped(Assets::new())),
-		}
-	}
-
-	pub fn try_take_fungible(&mut self, id: AssetId, amount: u128) -> Result<Assets, ()> {
-		self.try_remove_fungible(&id, amount)?;
-		Ok(id.into_fungible_multiasset(amount).into())
-	}
-
-	pub fn try_take_non_fungible(&mut self, id: AssetId, instance: AssetInstance) -> Result<Assets, ()> {
-		let asset_id_instance = (id, instance);
-		self.try_remove_non_fungible(&asset_id_instance)?;
-		let (asset_id, instance) = asset_id_instance;
-		Ok(asset_id.into_non_fungible_multiasset(instance).into())
-	}
-
-	pub fn take_fungible(&mut self, id: &AssetId) -> Assets {
-		let mut taken = Assets::new();
-		if let Some((id, amount)) = self.fungible.remove_entry(&id) {
-			taken.fungible.insert(id, amount);
-		}
-		taken
-	}
-
-	pub fn take_non_fungible(&mut self, id: &AssetId) -> Assets {
-		let mut taken = Assets::new();
-		let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
-		non_fungible.into_iter().for_each(|(c, instance)| {
-			if &c == id {
-				taken.non_fungible.insert((c, instance));
-			} else {
-				self.non_fungible.insert((c, instance));
-			}
-		});
-		taken
-	}
-
-	pub fn try_remove_fungible(&mut self, id: &AssetId, amount: u128) -> Result<(), ()> {
-		let self_amount = self.fungible.get_mut(&id).ok_or(())?;
-		*self_amount = self_amount.checked_sub(amount).ok_or(())?;
-		Ok(())
-	}
-
-	pub fn try_remove_non_fungible(&mut self, class_instance: &(AssetId, AssetInstance)) -> Result<(), ()> {
-		match self.non_fungible.remove(class_instance) {
-			true => Ok(()),
-			false => Err(()),
-		}
-	}
-
+/*
 	/// Modify `self` to include a new fungible asset by `id` and `amount`,
 	/// saturating if necessary.
 	pub fn saturating_subsume_fungible(&mut self, id: AssetId, amount: u128) {
@@ -272,6 +127,12 @@ impl Assets {
 	pub fn saturating_subsume_non_fungible(&mut self, class: AssetId, instance: AssetInstance) {
 		self.non_fungible.insert((class, instance));
 	}
+*/
+	/// Swaps two mutable Assets, without deinitializing either one.
+	pub fn swapped(&mut self, mut with: Assets) -> Self {
+		mem::swap(&mut *self, &mut with);
+		with
+	}
 
 	/// Alter any concretely identified assets by prepending the given `MultiLocation`.
 	///
@@ -290,6 +151,122 @@ impl Assets {
 			.collect();
 	}
 
+	/// Returns an error unless all `assets` are contained in `self`. In the case of an error, the first asset in
+	/// `assets` which is not wholly in `self` is returned.
+	fn ensure_contains(&self, assets: &MultiAssets) -> Result<(), TakeError> {
+		for asset in assets.inner().iter() {
+			match asset {
+				MultiAsset { fun: Fungible(ref amount), ref id } => {
+					if self.fungible.get(id).map_or(true, |a| a < amount) {
+						return Err(TakeError((id.clone(), amount).into()))
+					}
+				}
+				MultiAsset { fun: NonFungible(ref instance), ref id } => {
+					let id_instance = (id.clone(), instance.clone());
+					if !self.non_fungible.contains(&id_instance) {
+						return Err(TakeError(id_instance.into()))
+					}
+				}
+			}
+		}
+		return Ok(())
+	}
+
+	/// Mutates `self` to its original value less `mask` and returns `true`.
+	///
+	/// If `saturate` is `true`, then `self` is considered to be masked by `mask`, thereby avoiding any attempt at
+	/// reducing it by assets it does not contain. In this case, the function is infallible. If `saturate` is `false`
+	/// and `asset` references a definite asset which `self` does not contain then an error is returned.
+	///
+	/// Returns `Ok` with the definite assets token from `self` and mutates `self` to its value minus
+	/// `asset`. Returns `Err` in the non-saturating case where `self` did not contain (enough of) a definite asset to
+	/// be removed.
+	fn general_take(&mut self, mask: MultiAssetFilter, saturate: bool) -> Result<Assets, TakeError> {
+		match mask {
+			Wild(All) => Ok(self.swapped(Assets::new())),
+			Wild(AllOf(WildFungible, id)) => {
+				let mut taken = Assets::new();
+				if let Some((id, amount)) = self.fungible.remove_entry(&id) {
+					taken.fungible.insert(id, amount);
+				}
+				Ok(taken)
+			}
+			Wild(AllOf(WildNonFungible, id)) => {
+				let mut taken = Assets::new();
+				let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
+				non_fungible.into_iter().for_each(|(c, instance)| {
+					if &c == id {
+						taken.non_fungible.insert((c, instance));
+					} else {
+						self.non_fungible.insert((c, instance));
+					}
+				});
+				Ok(taken)
+			}
+			Assets(assets) => {
+				if !saturate {
+					self.ensure_contains(&assets)?;
+				}
+				let mut taken = Assets::new();
+				for asset in assets.drain().into_iter() {
+					match asset {
+						MultiAsset { fun: Fungible(mut amount), id } => {
+							let (remove, amount) = match self.fungible.get_mut(&id) {
+								Some(self_amount) => {
+									let amount = amount.min(*self_amount);
+									*self_amount -= amount;
+									(self_amount == 0, amount)
+								}
+								None => (false, 0),
+							};
+							if remove {
+								self.fungible.remove(&id);
+							}
+							if amount > 0 {
+								taken.subsume(MultiAsset::from((id, amount)).into());
+							}
+						}
+						MultiAsset { fun: NonFungible(instance), id } => {
+							let id_instance = (id, instance);
+							if self.non_fungible.remove(&id_instance) {
+								taken.subsume(id_instance.into())
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	/// Mutates `self` to its original value less `asset` and returns `true` iff it contains at least `asset`.
+	///
+	/// `asset` is interpreted as being masked under `self`.
+	///
+	/// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus
+	/// `asset` if `self` contains `asset`, and return `Err` otherwise.
+	pub fn saturating_take(&mut self, asset: MultiAssetFilter) -> Assets {
+		self.general_take(asset, true).expect("general_take never results in error when saturating")
+	}
+
+	/// Mutates `self` to its original value less `asset` and returns `true` iff it contains at least `asset`.
+	///
+	/// `asset` is interpreted as being masked under `self`.
+	///
+	/// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus
+	/// `asset` if `self` contains `asset`, and return `Err` otherwise.
+	pub fn try_take(&mut self, asset: MultiAssetFilter) -> Result<Assets, TakeError> {
+		self.general_take(asset, false)
+	}
+
+	/// Consumes `self` and returns its original value excluding `asset` iff it contains at least `asset`, as well as
+	/// the assets excluded.
+	pub fn less(mut self, asset: WildMultiAsset) -> Result<(Assets, Assets), Self> {
+		match self.try_take(asset) {
+			Ok(taken) => Ok((self, taken)),
+			Err(_) => Err(self),
+		}
+	}
+
 	/// Return the assets in `self`, but (asset-wise) of no greater value than `assets`.
 	///
 	/// Result is undefined if `assets` includes elements which match to the same asset more than once.
@@ -314,223 +291,41 @@ impl Assets {
 	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 50 },
 	/// ]);
 	/// ```
-	pub fn min<'a, M, I>(&self, assets: I) -> Self
-	where
-		M: 'a + sp_std::borrow::Borrow<MultiAsset>,
-		I: IntoIterator<Item = M>,
-	{
-		let mut result = Assets::default();
-		for asset in assets.into_iter() {
-			match asset.borrow() {
-				MultiAsset::None => (),
-				MultiAsset::All => return self.clone(),
-				MultiAsset::AllFungible => {
-					// Replace `result.fungible` with all fungible assets,
-					// keeping `result.non_fungible` the same.
-					result = Assets {
-						fungible: self.fungible.clone(),
-						non_fungible: result.non_fungible,
-					}
-				},
-				MultiAsset::AllNonFungible => {
-					// Replace `result.non_fungible` with all non-fungible assets,
-					// keeping `result.fungible` the same.
-					result = Assets {
-						fungible: result.fungible,
-						non_fungible: self.non_fungible.clone(),
-					}
-				},
-				MultiAsset::AllAbstractFungible { id } => {
-					for asset in self.fungible_assets_iter() {
-						match &asset {
-							MultiAsset::AbstractFungible { id: identifier, .. } => {
-								if id == identifier { result.saturating_subsume(asset) }
-							},
-							_ => (),
-						}
-					}
-				},
-				MultiAsset::AllAbstractNonFungible { class } => {
-					for asset in self.non_fungible_assets_iter() {
-						match &asset {
-							MultiAsset::AbstractNonFungible { class: c, .. } => {
-								if class == c { result.saturating_subsume(asset) }
-							},
-							_ => (),
-						}
-					}
+	pub fn min(&self, mask: MultiAssetFilter) -> Assets {
+		let mut masked = Assets::new();
+		match mask {
+			Wild(All) => Ok(self.clone()),
+			Wild(AllOf(WildFungible, id)) => {
+				if let Some(&(ref id, amount)) = self.fungible.get(&id) {
+					masked.fungible.insert(id.clone(), amount);
 				}
-				MultiAsset::AllConcreteFungible { id } => {
-					for asset in self.fungible_assets_iter() {
-						match &asset {
-							MultiAsset::ConcreteFungible { id: identifier, .. } => {
-								if id == identifier { result.saturating_subsume(asset) }
-							},
-							_ => (),
-						}
-					}
-				},
-				MultiAsset::AllConcreteNonFungible { class } => {
-					for asset in self.non_fungible_assets_iter() {
-						match &asset {
-							MultiAsset::ConcreteNonFungible { class: c, .. } => {
-								if class == c { result.saturating_subsume(asset) }
-							},
-							_ => (),
-						}
-					}
-				}
-				x @ MultiAsset::ConcreteFungible { .. } | x @ MultiAsset::AbstractFungible { .. } => {
-					let (id, amount) = match x {
-						MultiAsset::ConcreteFungible { id, amount } => (AssetId::Concrete(id.clone()), *amount),
-						MultiAsset::AbstractFungible { id, amount } => (AssetId::Abstract(id.clone()), *amount),
-						_ => unreachable!(),
-					};
-					if let Some(v) = self.fungible.get(&id) {
-						result.saturating_subsume_fungible(id, amount.min(*v));
-					}
-				},
-				x @ MultiAsset::ConcreteNonFungible { .. } | x @ MultiAsset::AbstractNonFungible { .. } => {
-					let (class, instance) = match x {
-						MultiAsset::ConcreteNonFungible { class, instance } => (AssetId::Concrete(class.clone()), instance.clone()),
-						MultiAsset::AbstractNonFungible { class, instance } => (AssetId::Abstract(class.clone()), instance.clone()),
-						_ => unreachable!(),
-					};
-					let item = (class, instance);
-					if self.non_fungible.contains(&item) {
-						result.non_fungible.insert(item);
+			}
+			Wild(AllOf(WildNonFungible, id)) => {
+				self.non_fungible.iter().for_each(|(ref c, ref instance)| {
+					if c == id {
+						masked.non_fungible.insert((c.clone(), instance.clone()));
 					}
-				}
+				});
 			}
-		}
-		result
-	}
-
-	/// Take all possible assets up to `assets` from `self`, mutating `self` and returning the
-	/// assets taken.
-	///
-	/// Wildcards work.
-	///
-	/// Example:
-	///
-	/// ```
-	/// use xcm_executor::Assets;
-	/// use xcm::v0::{MultiAsset, MultiLocation};
-	/// let mut assets_i_have: Assets = vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 100 },
-	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 100 },
-	/// ].into();
-	/// let assets_they_want = vec![
-	/// 	MultiAsset::AllAbstractFungible { id: vec![0] },
-	/// ];
-	///
-	/// let assets_they_took: Assets = assets_i_have.saturating_take(assets_they_want);
-	/// assert_eq!(assets_they_took.into_assets_iter().collect::<Vec<_>>(), vec![
-	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 100 },
-	/// ]);
-	/// assert_eq!(assets_i_have.into_assets_iter().collect::<Vec<_>>(), vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 100 },
-	/// ]);
-	/// ```
-	pub fn saturating_take<I>(&mut self, assets: I) -> Assets
-	where
-		I: IntoIterator<Item = MultiAsset>,
-	{
-		let mut result = Assets::default();
-		for asset in assets.into_iter() {
-			match asset {
-				MultiAsset::None => (),
-				MultiAsset::All => return self.swapped(Assets::default()),
-				MultiAsset::AllFungible => {
-					// Remove all fungible assets, and copy them into `result`.
-					let fungible = mem::replace(&mut self.fungible, Default::default());
-					fungible.into_iter().for_each(|(id, amount)| {
-						result.saturating_subsume_fungible(id, amount);
-					})
-				},
-				MultiAsset::AllNonFungible => {
-					// Remove all non-fungible assets, and copy them into `result`.
-					let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
-					non_fungible.into_iter().for_each(|(class, instance)| {
-						result.saturating_subsume_non_fungible(class, instance);
-					});
-				},
-				x @ MultiAsset::AllAbstractFungible { .. } | x @ MultiAsset::AllConcreteFungible { .. } => {
-					let id = match x {
-						MultiAsset::AllConcreteFungible { id } => AssetId::Concrete(id),
-						MultiAsset::AllAbstractFungible { id } => AssetId::Abstract(id),
-						_ => unreachable!(),
-					};
-					// At the end of this block, we will be left with only the non-matching fungibles.
-					let mut non_matching_fungibles = BTreeMap::<AssetId, u128>::new();
-					let fungible = mem::replace(&mut self.fungible, Default::default());
-					fungible.into_iter().for_each(|(iden, amount)| {
-							if iden == id {
-								result.saturating_subsume_fungible(iden, amount);
-							} else {
-								non_matching_fungibles.insert(iden, amount);
+			Assets(assets) => {
+				for asset in assets.inner().iter() {
+					match asset {
+						MultiAsset { fun: Fungible(ref amount), ref id } => {
+							if let Some(m) = self.fungible.get(id) {
+								masked.subsume((id.clone(), Fungible(*amount.min(m))).into());
 							}
-						});
-					self.fungible = non_matching_fungibles;
-				},
-				x @ MultiAsset::AllAbstractNonFungible { .. } | x @ MultiAsset::AllConcreteNonFungible { .. } => {
-					let class = match x {
-						MultiAsset::AllConcreteNonFungible { class } => AssetId::Concrete(class),
-						MultiAsset::AllAbstractNonFungible { class } => AssetId::Abstract(class),
-						_ => unreachable!(),
-					};
-					// At the end of this block, we will be left with only the non-matching non-fungibles.
-					let mut non_matching_non_fungibles = BTreeSet::<(AssetId, AssetInstance)>::new();
-					let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
-					non_fungible.into_iter().for_each(|(c, instance)| {
-							if class == c {
-								result.saturating_subsume_non_fungible(c, instance);
-							} else {
-								non_matching_non_fungibles.insert((c, instance));
+						}
+						MultiAsset { fun: NonFungible(ref instance), ref id } => {
+							let id_instance = (id.clone(), instance.clone());
+							if self.non_fungible.contains(&id_instance) {
+								masked.subsume(id_instance.into());
 							}
-						});
-					self.non_fungible = non_matching_non_fungibles;
-				},
-				x @ MultiAsset::ConcreteFungible {..} | x @ MultiAsset::AbstractFungible {..} => {
-					let (id, amount) = match x {
-						MultiAsset::ConcreteFungible { id, amount } => (AssetId::Concrete(id), amount),
-						MultiAsset::AbstractFungible { id, amount } => (AssetId::Abstract(id), amount),
-						_ => unreachable!(),
-					};
-					// remove the maxmimum possible up to id/amount from self, add the removed onto
-					// result
-					let maybe_value = self.fungible.get(&id);
-					if let Some(&e) = maybe_value {
-						if e > amount {
-							self.fungible.insert(id.clone(), e - amount);
-							result.saturating_subsume_fungible(id, amount);
-						} else {
-							self.fungible.remove(&id);
-							result.saturating_subsume_fungible(id, e.clone());
 						}
 					}
 				}
-				x @ MultiAsset::ConcreteNonFungible {..} | x @ MultiAsset::AbstractNonFungible {..} => {
-					let (class, instance) = match x {
-						MultiAsset::ConcreteNonFungible { class, instance } => (AssetId::Concrete(class), instance),
-						MultiAsset::AbstractNonFungible { class, instance } => (AssetId::Abstract(class), instance),
-						_ => unreachable!(),
-					};
-					// remove the maxmimum possible up to id/amount from self, add the removed onto
-					// result
-					if let Some(entry) = self.non_fungible.take(&(class, instance)) {
-						result.non_fungible.insert(entry);
-					}
-				}
 			}
 		}
-		result
-	}
-
-	/// Swaps two mutable Assets, without deinitializing either one.
-	pub fn swapped(&mut self, mut with: Assets) -> Self {
-		mem::swap(&mut *self, &mut with);
-		with
+		masked
 	}
 }
 
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index 8f8a5c9ee617..87b770533db2 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -106,10 +106,10 @@ impl<Config: config::Config> XcmExecutor<Config> {
 		log::trace!(
 			target: "xcm::do_execute_xcm",
 			"origin: {:?}, top_level: {:?}, message: {:?}, weight_credit: {:?}, maybe_shallow_weight: {:?}",
-			origin, 
-			top_level, 
-			message, 
-			weight_credit, 
+			origin,
+			top_level,
+			message,
+			weight_credit,
 			maybe_shallow_weight,
 		);
 		// This is the weight of everything that cannot be paid for. This basically means all computation
@@ -133,7 +133,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				for asset in assets {
 					ensure!(!asset.is_wildcard(), XcmError::Wildcard);
 					let withdrawn = Config::AssetTransactor::withdraw_asset(&asset, &origin)?;
-					holding.saturating_subsume_all(withdrawn);
+					holding.subsume_assets(withdrawn);
 				}
 				Some((holding, effects))
 			}
@@ -288,7 +288,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				let purchasing_weight = Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?);
 				let max_fee = holding.try_take(fees).map_err(|()| XcmError::NotHoldingFees)?;
 				let unspent = trader.buy_weight(purchasing_weight, max_fee)?;
-				holding.saturating_subsume_all(unspent);
+				holding.subsume_assets(unspent);
 
 				let mut remaining_weight = weight;
 				for message in xcm.into_iter() {
@@ -298,7 +298,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 						Ok(surplus) => { total_surplus += surplus }
 					}
 				}
-				holding.saturating_subsume(trader.refund_weight(remaining_weight));
+				holding.subsume(trader.refund_weight(remaining_weight));
 			}
 			_ => return Err(XcmError::UnhandledEffect)?,
 		}

From 65b6fd4d6e12c58c8272a3a3328efc7e52903816 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 30 Jul 2021 10:18:36 -0700
Subject: [PATCH 005/166] Implement custom encoding/decoding scheme for
 MultiLocation

---
 xcm/src/v0/junction.rs       |   6 ++
 xcm/src/v0/multi_location.rs | 168 ++++++++++++++++++++++-------------
 2 files changed, 110 insertions(+), 64 deletions(-)

diff --git a/xcm/src/v0/junction.rs b/xcm/src/v0/junction.rs
index 3785e11b672c..d26cecf08b21 100644
--- a/xcm/src/v0/junction.rs
+++ b/xcm/src/v0/junction.rs
@@ -84,11 +84,17 @@ impl BodyPart {
 /// A single item in a path to describe the relative location of a consensus system.
 ///
 /// Each item assumes a pre-existing location as its context and is defined in terms of it.
+///
+/// NOTE: The codec index starts at 1, because a previous iteration of `Junction` has a `Parent`
+///       variant occupying index 0. We deprecate `Junction::Parent` now by having a custom
+///       Encode/Decode implementation for `MultiLocation`. Refer to [`MultiLocation`] for more
+///       details.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
 pub enum Junction {
 	/// An indexed parachain belonging to and operated by the context.
 	///
 	/// Generally used when the context is a Polkadot Relay-chain.
+	#[codec(index = 1)]
 	Parachain(#[codec(compact)] u32),
 	/// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
 	/// the context.
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index c92efd903a21..1ad12cc23759 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -18,7 +18,7 @@
 
 use core::{convert::TryFrom, mem, result};
 
-use parity_scale_codec::{self, Encode, Decode};
+use parity_scale_codec::{self, Decode, Encode, Input, Output};
 use super::Junction;
 use crate::VersionedMultiLocation;
 
@@ -44,10 +44,50 @@ use crate::VersionedMultiLocation;
 /// This specific `MultiLocation` implementation uses a Rust `enum` in order to make pattern matching easier.
 ///
 /// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
 pub struct MultiLocation {
 	parents: u8,
-	junctions: Junctions,
+	interior: Junctions,
+}
+
+impl Encode for MultiLocation {
+	fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
+		// 8 items max, but we cannot return an error, so we ap silently.
+		let parents = self.parents.min(
+			MAX_MULTILOCATION_LENGTH.saturating_sub(self.interior.len()) as u8,
+		);
+		let count = parents.saturating_add(self.interior.len() as u8);
+		dest.push_byte(count);
+		for _ in 0..parents {
+			dest.push_byte(0);
+		}
+		for j in self.interior.iter() {
+			j.encode_to(dest)
+		}
+	}
+}
+
+impl Decode for MultiLocation {
+	fn decode<I: Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
+		let count = input.read_byte()?;
+		let mut parents = 0u8;
+		let mut interior = Junctions::Null;
+		for i in 0..count {
+			let b = input.read_byte()?;
+			if b == 0 {
+				if i > parents {
+					// this would imply that there has been at least one non-parent junction, which
+					// further implies that this is non-canonical. we bail.
+					return Err(parity_scale_codec::Error::from("Parent after non-Parent forbidden"))
+				}
+				parents = parents.saturating_add(1);
+			} else {
+				interior = interior.pushed_with(Junction::decode(&mut &[b][..])?)
+					.map_err(|_| parity_scale_codec::Error::from("Interior too long"))?;
+			}
+		}
+		Ok(MultiLocation { parents, interior })
+	}
 }
 
 /// Maximum number of junctions a `MultiLocation` can contain.
@@ -62,18 +102,18 @@ impl MultiLocation {
 		}
 		Ok(MultiLocation {
 			parents,
-			junctions,
+			interior: junctions,
 		})
 	}
 
-	/// Return a reference to the junctions field.
+	/// Return a reference to the interior field.
 	pub fn junctions(&self) -> &Junctions {
-		&self.junctions
+		&self.interior
 	}
 
-	/// Return a mutable reference to the junctions field.
+	/// Return a mutable reference to the interior field.
 	pub fn junctions_mut(&mut self) -> &mut Junctions {
-		&mut self.junctions
+		&mut self.interior
 	}
 
 	/// Returns the number of `Parent` junctions at the beginning of `self`.
@@ -83,28 +123,28 @@ impl MultiLocation {
 
 	/// Returns the number of parents and junctions in `self`.
 	pub fn len(&self) -> usize {
-		self.parent_count() + self.junctions.len()
+		self.parent_count() + self.interior.len()
 	}
 
 	/// Returns first junction that is not a parent, or `None` if the location is empty or
 	/// contains only parents.
 	pub fn first_non_parent(&self) -> Option<&Junction> {
-		self.junctions.first()
+		self.interior.first()
 	}
 
 	/// Returns last junction, or `None` if the location is empty or contains only parents.
 	pub fn last(&self) -> Option<&Junction> {
-		self.junctions.last()
+		self.interior.last()
 	}
 
 	/// Splits off the first non-parent junction, returning the remaining suffix (first item in tuple)
 	/// and the first element (second item in tuple) or `None` if it was empty.
 	pub fn split_first_non_parent(self) -> (MultiLocation, Option<Junction>) {
-		let MultiLocation { parents, junctions } = self;
+		let MultiLocation { parents, interior: junctions } = self;
 		let (prefix, suffix) = junctions.split_first();
 		let multilocation = MultiLocation {
 			parents,
-			junctions: prefix,
+			interior: prefix,
 		};
 		(multilocation, suffix)
 	}
@@ -112,11 +152,11 @@ impl MultiLocation {
 	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
 	/// (second item in tuple) or `None` if it was empty or that `self` only contains parents.
 	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
-		let MultiLocation { parents, junctions } = self;
+		let MultiLocation { parents, interior: junctions } = self;
 		let (prefix, suffix) = junctions.split_last();
 		let multilocation = MultiLocation {
 			parents,
-			junctions: prefix,
+			interior: prefix,
 		};
 		(multilocation, suffix)
 	}
@@ -133,20 +173,20 @@ impl MultiLocation {
 	/// Mutates `self`, suffixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
 	pub fn push_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
 		let mut n = Junctions::Null;
-		mem::swap(&mut self.junctions, &mut n);
+		mem::swap(&mut self.interior, &mut n);
 		match n.pushed_with(new) {
-			Ok(result) => { self.junctions = result; Ok(()) }
-			Err(old) => { self.junctions = old; Err(()) }
+			Ok(result) => { self.interior = result; Ok(()) }
+			Err(old) => { self.interior = old; Err(()) }
 		}
 	}
 
 	/// Mutates `self`, prefixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
 	pub fn push_front_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
 		let mut n = Junctions::Null;
-		mem::swap(&mut self.junctions, &mut n);
+		mem::swap(&mut self.interior, &mut n);
 		match n.pushed_front_with(new) {
-			Ok(result) => { self.junctions = result; Ok(()) }
-			Err(old) => { self.junctions = old; Err(()) }
+			Ok(result) => { self.interior = result; Ok(()) }
+			Err(old) => { self.interior = old; Err(()) }
 		}
 	}
 
@@ -170,7 +210,7 @@ impl MultiLocation {
 		}
 		Ok(MultiLocation {
 			parents: self.parents,
-			junctions: self.junctions.pushed_with(new).expect("length is less than max length; qed"),
+			interior: self.interior.pushed_with(new).expect("length is less than max length; qed"),
 		})
 	}
 
@@ -182,7 +222,7 @@ impl MultiLocation {
 		}
 		Ok(MultiLocation {
 			parents: self.parents,
-			junctions: self.junctions.pushed_front_with(new).expect("length is less than max length; qed"),
+			interior: self.interior.pushed_front_with(new).expect("length is less than max length; qed"),
 		})
 	}
 
@@ -193,7 +233,7 @@ impl MultiLocation {
 		if i < num_parents {
 			return None
 		}
-		self.junctions.at(i - num_parents)
+		self.interior.at(i - num_parents)
 	}
 
 	/// Returns a mutable reference to the junction at index `i`, or `None` if the location is a
@@ -203,7 +243,7 @@ impl MultiLocation {
 		if i < num_parents {
 			return None
 		}
-		self.junctions.at_mut(i - num_parents)
+		self.interior.at_mut(i - num_parents)
 	}
 
 	/// Decrement the parent count by 1.
@@ -214,13 +254,13 @@ impl MultiLocation {
 	/// Removes the first non-parent element from `self`, returning it
 	/// (or `None` if it was empty or if `self` contains only parents).
 	pub fn take_first_non_parent(&mut self) -> Option<Junction> {
-		self.junctions.take_first()
+		self.interior.take_first()
 	}
 
 	/// Removes the last element from `junctions`, returning it (or `None` if it was empty or if
 	/// `self` only contains parents).
 	pub fn take_last(&mut self) -> Option<Junction> {
-		self.junctions.take_last()
+		self.interior.take_last()
 	}
 
 	/// Ensures that `self` has the same number of parents as `prefix`, its junctions begins with
@@ -243,7 +283,7 @@ impl MultiLocation {
 		if self.parents != prefix.parents {
 			return None
 		}
-		self.junctions.match_and_split(&prefix.junctions)
+		self.interior.match_and_split(&prefix.interior)
 	}
 
 	/// Mutate `self` so that it is suffixed with `suffix`. The correct normalized form is returned,
@@ -288,8 +328,8 @@ impl MultiLocation {
 	/// ```
 	pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> {
 		let self_parents = self.parent_count();
-		let prepend_len = (self_parents as isize - prefix.junctions.len() as isize).abs() as usize;
-		if self.junctions.len() + prefix.parent_count() + prepend_len > MAX_MULTILOCATION_LENGTH {
+		let prepend_len = (self_parents as isize - prefix.interior.len() as isize).abs() as usize;
+		if self.interior.len() + prefix.parent_count() + prepend_len > MAX_MULTILOCATION_LENGTH {
 			return Err(prefix)
 		}
 
@@ -305,7 +345,7 @@ impl MultiLocation {
 		}
 
 		self.parents = final_parent_count;
-		for j in prefix.junctions.into_iter_rev() {
+		for j in prefix.interior.into_iter_rev() {
 			self.push_front_non_parent(j).expect(
 				"self junctions len + prefix parent count + prepend len is less than max length; qed"
 			);
@@ -318,7 +358,7 @@ impl From<Junctions> for MultiLocation {
 	fn from(junctions: Junctions) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions,
+			interior: junctions,
 		}
 	}
 }
@@ -327,7 +367,7 @@ impl From<Junction> for MultiLocation {
 	fn from(x: Junction) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X1(x),
+			interior: Junctions::X1(x),
 		}
 	}
 }
@@ -336,7 +376,7 @@ impl From<()> for MultiLocation {
 	fn from(_: ()) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::Null,
+			interior: Junctions::Null,
 		}
 	}
 }
@@ -344,7 +384,7 @@ impl From<(Junction,)> for MultiLocation {
 	fn from(x: (Junction,)) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X1(x.0),
+			interior: Junctions::X1(x.0),
 		}
 	}
 }
@@ -352,7 +392,7 @@ impl From<(Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction)) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X2(x.0, x.1),
+			interior: Junctions::X2(x.0, x.1),
 		}
 	}
 }
@@ -360,7 +400,7 @@ impl From<(Junction, Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction, Junction)) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X3(x.0, x.1, x.2),
+			interior: Junctions::X3(x.0, x.1, x.2),
 		}
 	}
 }
@@ -368,7 +408,7 @@ impl From<(Junction, Junction, Junction, Junction)> for MultiLocation {
 	fn from(x: (Junction, Junction, Junction, Junction)) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X4(x.0, x.1, x.2, x.3),
+			interior: Junctions::X4(x.0, x.1, x.2, x.3),
 		}
 	}
 }
@@ -376,7 +416,7 @@ impl From<(Junction, Junction, Junction, Junction, Junction)> for MultiLocation
 	fn from(x: (Junction, Junction, Junction, Junction, Junction)) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X5(x.0, x.1, x.2, x.3, x.4),
+			interior: Junctions::X5(x.0, x.1, x.2, x.3, x.4),
 		}
 	}
 }
@@ -384,7 +424,7 @@ impl From<(Junction, Junction, Junction, Junction, Junction, Junction)> for Mult
 	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X6(x.0, x.1, x.2, x.3, x.4, x.5),
+			interior: Junctions::X6(x.0, x.1, x.2, x.3, x.4, x.5),
 		}
 	}
 }
@@ -392,7 +432,7 @@ impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction)
 	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X7(x.0, x.1, x.2, x.3, x.4, x.5, x.6),
+			interior: Junctions::X7(x.0, x.1, x.2, x.3, x.4, x.5, x.6),
 		}
 	}
 }
@@ -400,7 +440,7 @@ impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction,
 	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X8(x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7),
+			interior: Junctions::X8(x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7),
 		}
 	}
 }
@@ -409,7 +449,7 @@ impl From<[Junction; 0]> for MultiLocation {
 	fn from(_: [Junction; 0]) -> Self {
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::Null,
+			interior: Junctions::Null,
 		}
 	}
 }
@@ -418,7 +458,7 @@ impl From<[Junction; 1]> for MultiLocation {
 		let [x0] = x;
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X1(x0),
+			interior: Junctions::X1(x0),
 		}
 	}
 }
@@ -427,7 +467,7 @@ impl From<[Junction; 2]> for MultiLocation {
 		let [x0, x1] = x;
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X2(x0, x1),
+			interior: Junctions::X2(x0, x1),
 		}
 	}
 }
@@ -436,7 +476,7 @@ impl From<[Junction; 3]> for MultiLocation {
 		let [x0, x1, x2] = x;
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X3(x0, x1, x2),
+			interior: Junctions::X3(x0, x1, x2),
 		}
 	}
 }
@@ -445,7 +485,7 @@ impl From<[Junction; 4]> for MultiLocation {
 		let [x0, x1, x2, x3] = x;
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X4(x0, x1, x2, x3),
+			interior: Junctions::X4(x0, x1, x2, x3),
 		}
 	}
 }
@@ -454,7 +494,7 @@ impl From<[Junction; 5]> for MultiLocation {
 		let [x0, x1, x2, x3, x4] = x;
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X5(x0, x1, x2, x3, x4),
+			interior: Junctions::X5(x0, x1, x2, x3, x4),
 		}
 	}
 }
@@ -463,7 +503,7 @@ impl From<[Junction; 6]> for MultiLocation {
 		let [x0, x1, x2, x3, x4, x5] = x;
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X6(x0, x1, x2, x3, x4, x5),
+			interior: Junctions::X6(x0, x1, x2, x3, x4, x5),
 		}
 	}
 }
@@ -472,7 +512,7 @@ impl From<[Junction; 7]> for MultiLocation {
 		let [x0, x1, x2, x3, x4, x5, x6] = x;
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X7(x0, x1, x2, x3, x4, x5, x6),
+			interior: Junctions::X7(x0, x1, x2, x3, x4, x5, x6),
 		}
 	}
 }
@@ -481,7 +521,7 @@ impl From<[Junction; 8]> for MultiLocation {
 		let [x0, x1, x2, x3, x4, x5, x6, x7] = x;
 		MultiLocation {
 			parents: 0,
-			junctions: Junctions::X8(x0, x1, x2, x3, x4, x5, x6, x7),
+			interior: Junctions::X8(x0, x1, x2, x3, x4, x5, x6, x7),
 		}
 	}
 }
@@ -825,10 +865,10 @@ mod tests {
 
 	#[test]
 	fn match_and_split_works() {
-		let m = MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
-		assert_eq!(m.match_and_split(&MultiLocation { parents: 1, junctions: Null }), None);
+		let m = MultiLocation { parents: 1, interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
+		assert_eq!(m.match_and_split(&MultiLocation { parents: 1, interior: Null }), None);
 		assert_eq!(
-			m.match_and_split(&MultiLocation { parents: 1, junctions: X1(Parachain(42)) }),
+			m.match_and_split(&MultiLocation { parents: 1, interior: X1(Parachain(42)) }),
 			Some(&AccountIndex64 { network: Any, index: 23 })
 		);
 		assert_eq!(m.match_and_split(&m), None);
@@ -837,30 +877,30 @@ mod tests {
 	#[test]
 	fn append_with_works() {
 		let acc = AccountIndex64 { network: Any, index: 23 };
-		let mut m = MultiLocation { parents: 1, junctions: X1(Parachain(42)) };
+		let mut m = MultiLocation { parents: 1, interior: X1(Parachain(42)) };
 		assert_eq!(m.append_with(MultiLocation::from(X2(PalletInstance(3), acc.clone()))), Ok(()));
-		assert_eq!(m, MultiLocation { parents: 1, junctions: X3(Parachain(42), PalletInstance(3), acc.clone()) });
+		assert_eq!(m, MultiLocation { parents: 1, interior: X3(Parachain(42), PalletInstance(3), acc.clone()) });
 
 		// cannot append to create overly long multilocation
 		let acc = AccountIndex64 { network: Any, index: 23 };
-		let mut m = MultiLocation { parents: 6, junctions: X1(Parachain(42)) };
+		let mut m = MultiLocation { parents: 6, interior: X1(Parachain(42)) };
 		let suffix = MultiLocation::from(X2(PalletInstance(3), acc.clone()));
 		assert_eq!(m.append_with(suffix.clone()), Err(suffix));
 	}
 
 	#[test]
 	fn prepend_with_works() {
-		let mut m = MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
-		assert_eq!(m.prepend_with(MultiLocation { parents: 1, junctions: X1(OnlyChild) }), Ok(()));
-		assert_eq!(m, MultiLocation { parents: 1, junctions: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) });
+		let mut m = MultiLocation { parents: 1, interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
+		assert_eq!(m.prepend_with(MultiLocation { parents: 1, interior: X1(OnlyChild) }), Ok(()));
+		assert_eq!(m, MultiLocation { parents: 1, interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) });
 
 		// cannot prepend to create overly long multilocation
-		let mut m = MultiLocation { parents: 6, junctions: X1(Parachain(42)) };
-		let prefix = MultiLocation { parents: 2, junctions: Null };
+		let mut m = MultiLocation { parents: 6, interior: X1(Parachain(42)) };
+		let prefix = MultiLocation { parents: 2, interior: Null };
 		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
 
-		let prefix = MultiLocation { parents: 1, junctions: Null };
+		let prefix = MultiLocation { parents: 1, interior: Null };
 		assert_eq!(m.prepend_with(prefix), Ok(()));
-		assert_eq!(m, MultiLocation { parents: 7, junctions: X1(Parachain(42)) });
+		assert_eq!(m, MultiLocation { parents: 7, interior: X1(Parachain(42)) });
 	}
 }

From 16927cd11a5a6c14895efd2fade4d560bca63289 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 30 Jul 2021 10:24:21 -0700
Subject: [PATCH 006/166] Properly implement IntoIterator for Junctions

---
 xcm/src/v0/multi_location.rs | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 1ad12cc23759..3ea46cfd530a 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -61,7 +61,7 @@ impl Encode for MultiLocation {
 		for _ in 0..parents {
 			dest.push_byte(0);
 		}
-		for j in self.interior.iter() {
+		for j in &self.interior {
 			j.encode_to(dest)
 		}
 	}
@@ -583,6 +583,22 @@ impl<'a> Iterator for JunctionsReverseRefIterator<'a> {
 	}
 }
 
+impl<'a> IntoIterator for &'a Junctions {
+	type Item = &'a Junction;
+	type IntoIter = JunctionsRefIterator<'a>;
+	fn into_iter(self) -> Self::IntoIter {
+		JunctionsRefIterator(self, 0)
+	}
+}
+
+impl IntoIterator for Junctions {
+	type Item = Junction;
+	type IntoIter = JunctionsIterator;
+	fn into_iter(self) -> Self::IntoIter {
+		JunctionsIterator(self)
+	}
+}
+
 impl Junctions {
 	/// Returns first junction, or `None` if the location is empty.
 	pub fn first(&self) -> Option<&Junction> {
@@ -808,11 +824,6 @@ impl Junctions {
 		JunctionsReverseRefIterator(&self, 0)
 	}
 
-	/// Consumes `self` and returns an iterator over the junctions.
-	pub fn into_iter(self) -> JunctionsIterator {
-		JunctionsIterator(self)
-	}
-
 	/// Consumes `self` and returns an iterator over the junctions in reverse.
 	pub fn into_iter_rev(self) -> JunctionsReverseIterator {
 		JunctionsReverseIterator(self)

From 786fb460f318bb3547ae228eb9db071a2c1d30b5 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 30 Jul 2021 10:28:56 -0700
Subject: [PATCH 007/166] Implement TryFrom<MultiLocation> for Junctions

---
 xcm/src/v0/multi_location.rs | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 3ea46cfd530a..c683072264c8 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -854,6 +854,17 @@ impl Junctions {
 	}
 }
 
+impl TryFrom<MultiLocation> for Junctions {
+	type Error = ();
+	fn try_from(x: MultiLocation) -> result::Result<Self, ()> {
+		if x.parents > 0 {
+			Err(())
+		} else {
+			Ok(x.interior)
+		}
+	}
+}
+
 impl From<MultiLocation> for VersionedMultiLocation {
 	fn from(x: MultiLocation) -> Self {
 		VersionedMultiLocation::V0(x)

From 5b487a6721382072d6a2088774279b04715ce2e9 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 30 Jul 2021 10:30:44 -0700
Subject: [PATCH 008/166] Fix spelling mistakes

---
 xcm/src/v0/multi_location.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index c683072264c8..905d267bdf3b 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -94,7 +94,7 @@ impl Decode for MultiLocation {
 pub const MAX_MULTILOCATION_LENGTH: usize = 8;
 
 impl MultiLocation {
-	/// Creates a new MultiLocation, ensuring that the length of it does not exceed the maximum,
+	/// Creates a new `MultiLocation`, ensuring that the length of it does not exceed the maximum,
 	/// otherwise returns `Err`.
 	pub fn new(parents: u8, junctions: Junctions) -> result::Result<MultiLocation, ()> {
 		if parents as usize + junctions.len() > MAX_MULTILOCATION_LENGTH {
@@ -246,7 +246,7 @@ impl MultiLocation {
 		self.interior.at_mut(i - num_parents)
 	}
 
-	/// Decrement the parent count by 1.
+	/// Decrements the parent count by 1.
 	pub fn pop_parent(&mut self) {
 		self.parents = self.parents.saturating_sub(1);
 	}

From 5c23328a4558c352f70b14ad89e4b606642c457f Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 30 Jul 2021 10:51:31 -0700
Subject: [PATCH 009/166] Fix tests in xcm-executor

---
 xcm/src/v0/multi_location.rs                  |  9 ++++++++
 xcm/xcm-executor/src/assets.rs                | 22 +++++++++----------
 xcm/xcm-executor/src/lib.rs                   |  1 -
 xcm/xcm-executor/src/traits/conversion.rs     | 14 ++++++------
 xcm/xcm-executor/src/traits/transact_asset.rs |  8 +++----
 5 files changed, 31 insertions(+), 23 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 905d267bdf3b..ff2cb40c5a45 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -50,6 +50,15 @@ pub struct MultiLocation {
 	interior: Junctions,
 }
 
+impl Default for MultiLocation {
+	fn default() -> Self {
+		MultiLocation {
+			parents: 0,
+			interior: Junctions::Null,
+		}
+	}
+}
+
 impl Encode for MultiLocation {
 	fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
 		// 8 items max, but we cannot return an error, so we ap silently.
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index c0d35052482b..343ac28586eb 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -300,17 +300,17 @@ impl Assets {
 	/// use xcm_executor::Assets;
 	/// use xcm::v0::{MultiAsset, MultiLocation};
 	/// let assets_i_have: Assets = vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 100 },
+	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::default(), amount: 100 },
 	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 100 },
 	/// ].into();
 	/// let assets_they_want: Assets = vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 200 },
+	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::default(), amount: 200 },
 	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 50 },
 	/// ].into();
 	///
 	/// let assets_we_can_trade: Assets = assets_i_have.min(assets_they_want.assets_iter());
 	/// assert_eq!(assets_we_can_trade.into_assets_iter().collect::<Vec<_>>(), vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 100 },
+	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::default(), amount: 100 },
 	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 50 },
 	/// ]);
 	/// ```
@@ -417,7 +417,7 @@ impl Assets {
 	/// use xcm_executor::Assets;
 	/// use xcm::v0::{MultiAsset, MultiLocation};
 	/// let mut assets_i_have: Assets = vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 100 },
+	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::default(), amount: 100 },
 	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 100 },
 	/// ].into();
 	/// let assets_they_want = vec![
@@ -429,7 +429,7 @@ impl Assets {
 	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 100 },
 	/// ]);
 	/// assert_eq!(assets_i_have.into_assets_iter().collect::<Vec<_>>(), vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 100 },
+	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::default(), amount: 100 },
 	/// ]);
 	/// ```
 	pub fn saturating_take<I>(&mut self, assets: I) -> Assets
@@ -547,11 +547,11 @@ mod tests {
 	}
 	#[allow(non_snake_case)]
 	fn CF(amount: u128) -> MultiAsset {
-		MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount }
+		MultiAsset::ConcreteFungible { id: MultiLocation::default(), amount }
 	}
 	#[allow(non_snake_case)]
 	fn CNF(instance_id: u128) -> MultiAsset {
-		MultiAsset::ConcreteNonFungible { class: MultiLocation::Null, instance: AssetInstance::Index { id: instance_id } }
+		MultiAsset::ConcreteNonFungible { class: MultiLocation::default(), instance: AssetInstance::Index { id: instance_id } }
 	}
 
 	fn test_assets() -> Assets {
@@ -642,8 +642,8 @@ mod tests {
 	#[test]
 	fn min_all_concrete_works() {
 		let assets = test_assets();
-		let fungible = vec![MultiAsset::AllConcreteFungible { id: MultiLocation::Null }];
-		let non_fungible = vec![MultiAsset::AllConcreteNonFungible { class: MultiLocation::Null }];
+		let fungible = vec![MultiAsset::AllConcreteFungible { id: MultiLocation::default() }];
+		let non_fungible = vec![MultiAsset::AllConcreteNonFungible { class: MultiLocation::default() }];
 
 		let fungible = assets.min(fungible.iter());
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
@@ -724,8 +724,8 @@ mod tests {
 	#[test]
 	fn saturating_take_all_concrete_works() {
 		let mut assets = test_assets();
-		let fungible = vec![MultiAsset::AllConcreteFungible { id: MultiLocation::Null }];
-		let non_fungible = vec![MultiAsset::AllConcreteNonFungible { class: MultiLocation::Null }];
+		let fungible = vec![MultiAsset::AllConcreteFungible { id: MultiLocation::default() }];
+		let non_fungible = vec![MultiAsset::AllConcreteNonFungible { class: MultiLocation::default() }];
 
 		let fungible = assets.saturating_take(fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index 8f8a5c9ee617..b8a7eda909fa 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -218,7 +218,6 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				None
 			}
 			(origin, Xcm::RelayedFrom { who, message }) => {
-				ensure!(who.is_interior(), XcmError::EscalationOfPrivilege);
 				let mut origin = origin;
 				origin.append_with(who).map_err(|_| XcmError::MultiLocationFull)?;
 				let surplus = Self::do_execute_xcm(origin, top_level, *message, weight_credit, None, trader)?;
diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs
index 19b2de1a0076..72d9fd979672 100644
--- a/xcm/xcm-executor/src/traits/conversion.rs
+++ b/xcm/xcm-executor/src/traits/conversion.rs
@@ -125,15 +125,15 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
 /// which is passed to the next convert item.
 ///
 /// ```rust
-/// # use xcm::v0::{MultiLocation, Junction, OriginKind};
+/// # use xcm::v0::{MultiLocation, Junctions, Junction, OriginKind};
 /// # use xcm_executor::traits::ConvertOrigin;
 /// // A convertor that will bump the para id and pass it to the next one.
 /// struct BumpParaId;
 /// impl ConvertOrigin<u32> for BumpParaId {
 /// 	fn convert_origin(origin: MultiLocation, _: OriginKind) -> Result<u32, MultiLocation> {
-/// 		match origin {
-/// 			MultiLocation::X1(Junction::Parachain(id)) => {
-/// 				Err(MultiLocation::X1(Junction::Parachain(id + 1)))
+/// 		match origin.junctions() {
+/// 			Junctions::X1(Junction::Parachain(id)) if origin.parent_count() == 0 => {
+/// 				Err(Junctions::X1(Junction::Parachain(id + 1)).into())
 /// 			}
 /// 			_ => unreachable!()
 /// 		}
@@ -143,8 +143,8 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
 /// struct AcceptPara7;
 /// impl ConvertOrigin<u32> for AcceptPara7 {
 /// 	fn convert_origin(origin: MultiLocation, _: OriginKind) -> Result<u32, MultiLocation> {
-/// 		match origin {
-/// 			MultiLocation::X1(Junction::Parachain(id)) if id == 7 => {
+/// 		match origin.junctions() {
+/// 			Junctions::X1(Junction::Parachain(id)) if id == &7 && origin.parent_count() == 0 => {
 /// 				Ok(7)
 /// 			}
 /// 			_ => Err(origin)
@@ -152,7 +152,7 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
 /// 	}
 /// }
 /// # fn main() {
-/// let origin = MultiLocation::X1(Junction::Parachain(6));
+/// let origin: MultiLocation = Junctions::X1(Junction::Parachain(6)).into();
 /// assert!(
 /// 	<(BumpParaId, AcceptPara7) as ConvertOrigin<u32>>::convert_origin(origin, OriginKind::Native)
 /// 		.is_ok()
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index a967f1f6909a..08c13daaa818 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -246,27 +246,27 @@ mod tests {
 	fn defaults_to_asset_not_found() {
 		type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Err(XcmError::AssetNotFound));
+		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::default()), Err(XcmError::AssetNotFound));
 	}
 
 	#[test]
 	fn unimplemented_and_not_found_continue_iteration() {
 		type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, SuccessfulTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Ok(()));
+		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::default()), Ok(()));
 	}
 
 	#[test]
 	fn unexpected_error_stops_iteration() {
 		type MultiTransactor = (OverflowTransactor, SuccessfulTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Err(XcmError::Overflow));
+		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::default()), Err(XcmError::Overflow));
 	}
 
 	#[test]
 	fn success_stops_iteration() {
 		type MultiTransactor = (SuccessfulTransactor, OverflowTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Ok(()));
+		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::default()), Ok(()));
 	}
 }

From 2661b91a5cc1ea6721e067db71cd1e9bb000fcb3 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Fri, 30 Jul 2021 19:59:10 +0200
Subject: [PATCH 010/166] XCM core builds

---
 xcm/src/v0/mod.rs              | 11 ++++-
 xcm/src/v0/multi_asset.rs      |  3 +-
 xcm/src/v0/multiasset.rs       | 79 ++++++++++++++++++----------------
 xcm/xcm-executor/src/assets.rs | 14 ------
 4 files changed, 51 insertions(+), 56 deletions(-)

diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index cc8044ea19d2..8f16bee29b39 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -20,7 +20,7 @@ use core::{result, convert::TryFrom, fmt::Debug};
 use derivative::Derivative;
 use alloc::vec::Vec;
 use parity_scale_codec::{self, Encode, Decode};
-use crate::{VersionedMultiAsset, VersionedWildMultiAsset, DoubleEncoded, VersionedXcm};
+use crate::{DoubleEncoded, VersionedXcm};
 
 mod junction;
 mod multi_asset;
@@ -40,7 +40,14 @@ pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
 	pub use super::junction::{Junction::*, NetworkId, BodyId, BodyPart};
-	pub use super::multi_asset::{MultiAsset::{self, *}, AssetInstance::{self, *}};
+	pub use super::multiasset::{
+		AssetId, MultiAssets, MultiAsset,
+		AssetInstance::{self, *},
+		MultiAssetFilter::{self, *},
+		Fungibility::{self, *},
+		WildMultiAsset::{self, *},
+		WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible},
+	};
 	pub use super::multi_location::MultiLocation::{self, *};
 	pub use super::order::Order::{self, *};
 	pub use super::traits::{Error as XcmError, Result as XcmResult, SendXcm, ExecuteXcm, Outcome};
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
index d7065d3e1d8e..fe53f6905aa5 100644
--- a/xcm/src/v0/multi_asset.rs
+++ b/xcm/src/v0/multi_asset.rs
@@ -16,11 +16,10 @@
 
 //! Cross-Consensus Message format data structures.
 
-use core::{result, convert::TryFrom};
 use alloc::vec::Vec;
 
 use parity_scale_codec::{self, Encode, Decode};
-use super::{MultiLocation, VersionedMultiAsset, AssetInstance};
+use super::{MultiLocation, AssetInstance};
 
 /// A single general identifier for an asset.
 ///
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 010f1ce4c1da..45e19323e04a 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -24,11 +24,10 @@
 //!   account.
 
 use core::convert::{TryFrom, TryInto};
-use alloc::vec::Vec;
+use alloc::{vec, vec::Vec};
 use parity_scale_codec::{self as codec, Encode, Decode};
 use super::{
-	MultiLocation, multi_asset::MultiAsset as OldMultiAsset, VersionedMultiAsset,
-	VersionedWildMultiAsset,
+	MultiLocation, multi_asset::MultiAsset as OldMultiAsset,
 };
 use core::cmp::Ordering;
 
@@ -79,15 +78,9 @@ impl AssetId {
 		MultiAsset { fun, id: self }
 	}
 
-	/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `WildMultiAsset`
-	/// definite (`Asset`) value.
-	pub fn into_wild(self, fun: Fungibility) -> WildMultiAsset {
-		WildMultiAsset::Asset(fun, self)
-	}
-
 	/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `WildMultiAsset`
 	/// wildcard (`AllOf`) value.
-	pub fn into_allof(self, fun: WildFungibility) -> WildMultiAsset {
+	pub fn into_wild(self, fun: WildFungibility) -> WildMultiAsset {
 		WildMultiAsset::AllOf(fun, self)
 	}
 }
@@ -137,10 +130,10 @@ impl PartialOrd for MultiAsset {
 impl Ord for MultiAsset {
 	fn cmp(&self, other: &Self) -> Ordering {
 		match (&self.fun, &other.fun) {
-			(Fungibility::Fungible(..), Fungibility::NonFungible(..)) => return Ordering::Less,
-			(Fungibility::NonFungible(..), Fungibility::Fungible(..)) => return Ordering::Greater,
+			(Fungibility::Fungible(..), Fungibility::NonFungible(..)) => Ordering::Less,
+			(Fungibility::NonFungible(..), Fungibility::Fungible(..)) => Ordering::Greater,
+			_ => (&self.id, &self.fun).cmp(&(&other.id, &other.fun)),
 		}
-		(&self.id, &self.fun).cmp((&other.id, &other.fun))
 	}
 }
 
@@ -197,18 +190,17 @@ impl Encode for MultiAsset {
 
 impl Decode for MultiAsset {
 	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
-		OldMultiAsset::decode(input)
-			.and_then(|r| TryInto::try_into(r).map_err(|_| "Unsupported wildcard".into()))?
+		OldMultiAsset::decode(input)?.try_into().map_err(|_| "Unsupported wildcard".into())
 	}
 }
 
 impl MultiAsset {
-	fn is_fungible(&self, maybe_id: Option<AssetId>) -> bool {
+	pub fn is_fungible(&self, maybe_id: Option<AssetId>) -> bool {
 		use Fungibility::*;
 		matches!(self.fun, Fungible(..)) && maybe_id.map_or(true, |i| i == self.id)
 	}
 
-	fn is_non_fungible(&self, maybe_id: Option<AssetId>) -> bool {
+	pub fn is_non_fungible(&self, maybe_id: Option<AssetId>) -> bool {
 		use Fungibility::*;
 		matches!(self.fun, NonFungible(..)) && maybe_id.map_or(true, |i| i == self.id)
 	}
@@ -220,7 +212,7 @@ impl MultiAsset {
 
 	/// Returns true if `self` is a super-set of the given `inner`.
 	pub fn contains(&self, inner: &MultiAsset) -> bool {
-		use {MultiAsset::*, Fungibility::*};
+		use Fungibility::*;
 		if self.id == inner.id {
 			match (&self.fun, &inner.fun) {
 				(Fungible(a), Fungible(i)) if a >= i => return true,
@@ -242,7 +234,7 @@ impl Decode for MultiAssets {
 	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
 		let r = Vec::<MultiAsset>::decode(input)?;
 		if r.is_empty() { return Ok(Self(Vec::new())) }
-		r.iter().skip(1).try_fold(&r[0], |a, b| {
+		r.iter().skip(1).try_fold(&r[0], |a, b| -> Result<&MultiAsset, parity_scale_codec::Error> {
 			if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) {
 				Ok(b)
 			} else {
@@ -262,7 +254,7 @@ impl From<MultiAssets> for Vec<OldMultiAsset> {
 impl TryFrom<Vec<OldMultiAsset>> for MultiAssets {
 	type Error = ();
 	fn try_from(a: Vec<OldMultiAsset>) -> Result<Self, ()> {
-		a.0.into_iter().map(MultiAsset::try_from).collect()
+		a.into_iter().map(MultiAsset::try_from).collect::<Result<_, _>>().map(Self)
 	}
 }
 
@@ -293,7 +285,6 @@ impl MultiAssets {
 
 	/// Returns true if `self` is a super-set of the given `inner`.
 	pub fn contains(&self, inner: &MultiAsset) -> bool {
-		use {MultiAsset::*, Fungibility::*};
 		self.0.iter().any(|i| i.contains(inner))
 	}
 
@@ -339,19 +330,19 @@ impl Encode for WildMultiAsset {
 
 impl Decode for WildMultiAsset {
 	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
-		OldMultiAsset::decode(input).map(Into::into)
+		OldMultiAsset::decode(input)?.try_into().map_err(|()| "Invalid wildcard item".into())
 	}
 }
 
 impl From<WildMultiAsset> for OldMultiAsset {
 	fn from(a: WildMultiAsset) -> Self {
-		use {AssetId::*, Fungibility::*, OldMultiAsset::*, WildMultiAsset::AllOf};
+		use {AssetId::*, WildFungibility::*, OldMultiAsset::*, WildMultiAsset::AllOf};
 		match a {
 			WildMultiAsset::All => All,
-			AllOf(WildFungibility::Fungible, Concrete(id)) => AllConcreteFungible { id },
-			AllOf(WildFungibility::Fungible, Abstract(id)) => AllAbstractFungible { id },
-			AllOf(WildFungibility::NonFungible, Concrete(class)) => AllConcreteNonFungible { class },
-			AllOf(WildFungibility::NonFungible, Abstract(class)) => AllAbstractNonFungible { class },
+			AllOf(Fungible, Concrete(id)) => AllConcreteFungible { id },
+			AllOf(Fungible, Abstract(id)) => AllAbstractFungible { id },
+			AllOf(NonFungible, Concrete(class)) => AllConcreteNonFungible { class },
+			AllOf(NonFungible, Abstract(class)) => AllAbstractNonFungible { class },
 		}
 	}
 }
@@ -359,13 +350,13 @@ impl From<WildMultiAsset> for OldMultiAsset {
 impl TryFrom<OldMultiAsset> for WildMultiAsset {
 	type Error = ();
 	fn try_from(a: OldMultiAsset) -> Result<Self, ()> {
-		use {AssetId::*, Fungibility::*, OldMultiAsset::*, WildMultiAsset::AllOf};
+		use {AssetId::*, WildFungibility::*, OldMultiAsset::*, WildMultiAsset::AllOf};
 		Ok(match a {
 			All => WildMultiAsset::All,
-			AllConcreteFungible { id } => AllOf(WildFungibility::Fungible, Concrete(id)),
-			AllAbstractFungible { id } => AllOf(WildFungibility::Fungible, Abstract(id)),
-			AllConcreteNonFungible { class } => AllOf(WildFungibility::NonFungible, Concrete(class)),
-			AllAbstractNonFungible { class } => AllOf(WildFungibility::NonFungible, Abstract(class)),
+			AllConcreteFungible { id } => AllOf(Fungible, Concrete(id)),
+			AllAbstractFungible { id } => AllOf(Fungible, Abstract(id)),
+			AllConcreteNonFungible { class } => AllOf(NonFungible, Concrete(class)),
+			AllAbstractNonFungible { class } => AllOf(NonFungible, Abstract(class)),
 			_ => return Err(()),
 		})
 	}
@@ -379,7 +370,7 @@ impl WildMultiAsset {
 	pub fn contains(&self, inner: &MultiAsset) -> bool {
 		use WildMultiAsset::*;
 		match self {
-			AllOf(fun, id) => inner.fun.is_kind(*fun) && inner.id == id,
+			AllOf(fun, id) => inner.fun.is_kind(*fun) && &inner.id == id,
 			All => true,
 		}
 	}
@@ -388,7 +379,7 @@ impl WildMultiAsset {
 	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
 		use WildMultiAsset::*;
 		match self {
-			AllOf(_, ref mut id) => id.prepend_with(prepend.clone()).map_err(|_| ()),
+			AllOf(_, ref mut id) => id.reanchor(prepend).map_err(|_| ()),
 			_ => Ok(()),
 		}
 	}
@@ -418,16 +409,28 @@ impl From<MultiAssetFilter> for Vec<OldMultiAsset> {
 
 impl TryFrom<Vec<OldMultiAsset>> for MultiAssetFilter {
 	type Error = ();
-	fn try_from(old_assets: Vec<OldMultiAsset>) -> Result<Self, ()> {
+	fn try_from(mut old_assets: Vec<OldMultiAsset>) -> Result<Self, ()> {
 		use MultiAssetFilter::*;
 		if old_assets.is_empty() {
 			return Ok(Assets(MultiAssets::new()))
 		}
-		if let (1, Ok(wild)) = (old_assets.len(), old_assets[0].try_into()) {
-			return Ok(Wild(wild))
+		if old_assets.len() == 1 && old_assets[0].is_wildcard() {
+			return old_assets.pop().ok_or(()).and_then(|i| Ok(Wild(i.try_into()?)))
 		}
 
-		old_assets.into_iter().map(MultiAsset::try_from).collect()
+		MultiAssets::try_from(old_assets).map(Self::Assets)
+	}
+}
+
+impl Encode for MultiAssetFilter {
+	fn encode(&self) -> Vec<u8> {
+		Vec::<OldMultiAsset>::from(self.clone()).encode()
+	}
+}
+
+impl Decode for MultiAssetFilter {
+	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
+		Vec::<OldMultiAsset>::decode(input)?.try_into().map_err(|()| "Invalid items".into())
 	}
 }
 
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 97c5fbbc15a5..59a6b9fd81e6 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -113,21 +113,7 @@ impl Assets {
 			NonFungible(instance) => self.non_fungible.insert((asset.id, instance)),
 		}
 	}
-/*
-	/// Modify `self` to include a new fungible asset by `id` and `amount`,
-	/// saturating if necessary.
-	pub fn saturating_subsume_fungible(&mut self, id: AssetId, amount: u128) {
-		self.fungible
-			.entry(id)
-			.and_modify(|e| *e = e.saturating_add(amount))
-			.or_insert(amount);
-	}
 
-	/// Modify `self` to include a new non-fungible asset by `class` and `instance`.
-	pub fn saturating_subsume_non_fungible(&mut self, class: AssetId, instance: AssetInstance) {
-		self.non_fungible.insert((class, instance));
-	}
-*/
 	/// Swaps two mutable Assets, without deinitializing either one.
 	pub fn swapped(&mut self, mut with: Assets) -> Self {
 		mem::swap(&mut *self, &mut with);

From 6fc030eac3753c6519fa0a6f67e5e1b580a2c547 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Fri, 30 Jul 2021 21:13:15 +0200
Subject: [PATCH 011/166] XCM Executor builds

---
 xcm/src/v0/mod.rs                             |  14 +--
 xcm/src/v0/multiasset.rs                      |  12 ++
 xcm/xcm-builder/src/weight.rs                 |  13 +--
 xcm/xcm-executor/src/assets.rs                | 105 ++++++++++--------
 xcm/xcm-executor/src/lib.rs                   |  42 +++----
 xcm/xcm-executor/src/traits/transact_asset.rs |   8 +-
 xcm/xcm-executor/src/traits/weight.rs         |   2 +-
 7 files changed, 103 insertions(+), 93 deletions(-)

diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 8f16bee29b39..2d4c192d3ec0 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -54,7 +54,7 @@ pub mod prelude {
 	pub use super::{Xcm::{self, *}, OriginKind};
 }
 
-// TODO: #2841 #XCMENCODE Efficient encodings for Vec<MultiAsset>, Vec<Order>, using initial byte values 128+ to encode
+// TODO: #2841 #XCMENCODE Efficient encodings for MultiAssets, Vec<Order>, using initial byte values 128+ to encode
 //   the number of items in the vector.
 
 /// Basically just the XCM (more general) version of `ParachainDispatchOrigin`.
@@ -84,7 +84,7 @@ pub enum OriginKind {
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum Response {
 	/// Some assets.
-	Assets(Vec<MultiAsset>),
+	Assets(MultiAssets),
 }
 
 /// Cross-Consensus Message: A message from one consensus system to another.
@@ -110,7 +110,7 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 0)]
-	WithdrawAsset { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+	WithdrawAsset { assets: MultiAssets, effects: Vec<Order<Call>> },
 
 	/// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` system.
 	///
@@ -127,7 +127,7 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 1)]
-	ReserveAssetDeposit { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+	ReserveAssetDeposit { assets: MultiAssets, effects: Vec<Order<Call>> },
 
 	/// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be
 	/// created on this system.
@@ -145,7 +145,7 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 2)]
-	TeleportAsset { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+	TeleportAsset { assets: MultiAssets, effects: Vec<Order<Call>> },
 
 	/// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`.
 	///
@@ -172,7 +172,7 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 4)]
-	TransferAsset { assets: Vec<MultiAsset>, dest: MultiLocation },
+	TransferAsset { assets: MultiAssets, dest: MultiLocation },
 
 	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
 	/// ownership of `dest` within this consensus system.
@@ -190,7 +190,7 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 5)]
-	TransferReserveAsset { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+	TransferReserveAsset { assets: MultiAssets, dest: MultiLocation, effects: Vec<Order<()>> },
 
 	/// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed by the kind
 	/// of origin `origin_type`.
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 45e19323e04a..3d0ee0d2d00e 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -245,6 +245,12 @@ impl Decode for MultiAssets {
 	}
 }
 
+impl From<Vec<MultiAsset>> for MultiAssets {
+	fn from(x: Vec<MultiAsset>) -> Self {
+		Self(x)
+	}
+}
+
 impl From<MultiAssets> for Vec<OldMultiAsset> {
 	fn from(a: MultiAssets) -> Self {
 		a.0.into_iter().map(OldMultiAsset::from).collect()
@@ -397,6 +403,12 @@ pub enum MultiAssetFilter {
 	Wild(WildMultiAsset),
 }
 
+impl From<WildMultiAsset> for MultiAssetFilter {
+	fn from(x: WildMultiAsset) -> Self {
+		Self::Wild(x)
+	}
+}
+
 impl From<MultiAssetFilter> for Vec<OldMultiAsset> {
 	fn from(a: MultiAssetFilter) -> Self {
 		use MultiAssetFilter::*;
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index e2096afcaa30..26f282abfec7 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -110,14 +110,13 @@ impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader for FixedRateOf
 		Ok(unused)
 	}
 
-	fn refund_weight(&mut self, weight: Weight) -> MultiAsset {
+	fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
 		let (id, units_per_second) = T::get();
 		let weight = weight.min(self.0);
 		let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128;
 		self.0 -= weight;
 		self.1 = self.1.saturating_sub(amount);
-		let result = MultiAsset::ConcreteFungible { amount, id };
-		result
+		Some((id, amount).into())
 	}
 }
 
@@ -158,16 +157,12 @@ impl<
 		Ok(unused)
 	}
 
-	fn refund_weight(&mut self, weight: Weight) -> MultiAsset {
+	fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
 		let weight = weight.min(self.0);
 		let amount = WeightToFee::calc(&weight);
 		self.0 -= weight;
 		self.1 = self.1.saturating_sub(amount);
-		let result = MultiAsset::ConcreteFungible {
-			amount: amount.saturated_into(),
-			id: AssetId::get(),
-		};
-		result
+		Some(MultiAsset::from((AssetId::get(), amount.saturated_into())))
 	}
 
 }
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 59a6b9fd81e6..7c2b5410991c 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -16,10 +16,8 @@
 
 use sp_std::{prelude::*, mem, collections::{btree_map::BTreeMap, btree_set::BTreeSet}};
 use xcm::v0::{
-	MultiAsset, MultiAssets, MultiLocation, AssetInstance,
-	MultiAssetFilter::{self, Assets, Wild},
-	AssetId::{self, Concrete, Abstract},
-	WildMultiAsset::{self, All, AllOf},
+	MultiAsset, MultiAssets, MultiLocation, AssetInstance, MultiAssetFilter, AssetId,
+	WildMultiAsset::{All, AllOf},
 	Fungibility::{Fungible, NonFungible},
 	WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible},
 };
@@ -32,7 +30,7 @@ pub struct Assets {
 	pub fungible: BTreeMap<AssetId, u128>,
 
 	/// The non-fungible assets.
-	// OPTIMIZE: Consider BTreeMap<AssetId, BTreeSet<AssetInstance>>
+	// TODO: Consider BTreeMap<AssetId, BTreeSet<AssetInstance>>
 	//   or even BTreeMap<AssetId, SortedVec<AssetInstance>>
 	pub non_fungible: BTreeSet<(AssetId, AssetInstance)>,
 }
@@ -47,12 +45,24 @@ impl From<Vec<MultiAsset>> for Assets {
 	}
 }
 
+impl From<MultiAssets> for Assets {
+	fn from(assets: MultiAssets) -> Assets {
+		assets.drain().into()
+	}
+}
+
 impl From<Assets> for Vec<MultiAsset> {
 	fn from(a: Assets) -> Self {
 		a.into_assets_iter().collect()
 	}
 }
 
+impl From<Assets> for MultiAssets {
+	fn from(a: Assets) -> Self {
+		a.into_assets_iter().collect::<Vec<MultiAsset>>().into()
+	}
+}
+
 impl From<MultiAsset> for Assets {
 	fn from(asset: MultiAsset) -> Assets {
 		let mut result = Self::default();
@@ -62,6 +72,7 @@ impl From<MultiAsset> for Assets {
 }
 
 /// An error emitted by `take` operations.
+#[derive(Debug)]
 pub enum TakeError {
 	/// There was an attempt to take an asset without saturating (enough of) which did not exist.
 	AssetUnderflow(MultiAsset),
@@ -106,11 +117,15 @@ impl Assets {
 	/// Wildcard values of `asset` do nothing.
 	pub fn subsume(&mut self, asset: MultiAsset) {
 		match asset.fun {
-			Fungible(amount) => self.fungible
-				.entry(asset.id)
-				.and_modify(|e| *e = e.saturating_add(amount))
-				.or_insert(amount),
-			NonFungible(instance) => self.non_fungible.insert((asset.id, instance)),
+			Fungible(amount) => {
+				self.fungible
+					.entry(asset.id)
+					.and_modify(|e| *e = e.saturating_add(amount))
+					.or_insert(amount);
+			}
+			NonFungible(instance) => {
+				self.non_fungible.insert((asset.id, instance));
+			}
 		}
 	}
 
@@ -128,12 +143,12 @@ impl Assets {
 		let mut fungible = Default::default();
 		mem::swap(&mut self.fungible, &mut fungible);
 		self.fungible = fungible.into_iter()
-			.map(|(mut id, amount)| { let _ = id.prepend_location(prepend); (id, amount) })
+			.map(|(mut id, amount)| { let _ = id.reanchor(prepend); (id, amount) })
 			.collect();
 		let mut non_fungible = Default::default();
 		mem::swap(&mut self.non_fungible, &mut non_fungible);
 		self.non_fungible = non_fungible.into_iter()
-			.map(|(mut class, inst)| { let _ = class.prepend_location(prepend); (class, inst) })
+			.map(|(mut class, inst)| { let _ = class.reanchor(prepend); (class, inst) })
 			.collect();
 	}
 
@@ -144,13 +159,13 @@ impl Assets {
 			match asset {
 				MultiAsset { fun: Fungible(ref amount), ref id } => {
 					if self.fungible.get(id).map_or(true, |a| a < amount) {
-						return Err(TakeError((id.clone(), amount).into()))
+						return Err(TakeError::AssetUnderflow((id.clone(), *amount).into()))
 					}
 				}
 				MultiAsset { fun: NonFungible(ref instance), ref id } => {
 					let id_instance = (id.clone(), instance.clone());
 					if !self.non_fungible.contains(&id_instance) {
-						return Err(TakeError(id_instance.into()))
+						return Err(TakeError::AssetUnderflow(id_instance.into()))
 					}
 				}
 			}
@@ -162,46 +177,42 @@ impl Assets {
 	///
 	/// If `saturate` is `true`, then `self` is considered to be masked by `mask`, thereby avoiding any attempt at
 	/// reducing it by assets it does not contain. In this case, the function is infallible. If `saturate` is `false`
-	/// and `asset` references a definite asset which `self` does not contain then an error is returned.
+	/// and `mask` references a definite asset which `self` does not contain then an error is returned.
 	///
 	/// Returns `Ok` with the definite assets token from `self` and mutates `self` to its value minus
-	/// `asset`. Returns `Err` in the non-saturating case where `self` did not contain (enough of) a definite asset to
+	/// `mask`. Returns `Err` in the non-saturating case where `self` did not contain (enough of) a definite asset to
 	/// be removed.
 	fn general_take(&mut self, mask: MultiAssetFilter, saturate: bool) -> Result<Assets, TakeError> {
+		let mut taken = Assets::new();
 		match mask {
-			Wild(All) => Ok(self.swapped(Assets::new())),
-			Wild(AllOf(WildFungible, id)) => {
-				let mut taken = Assets::new();
+			MultiAssetFilter::Wild(All) => return Ok(self.swapped(Assets::new())),
+			MultiAssetFilter::Wild(AllOf(WildFungible, id)) => {
 				if let Some((id, amount)) = self.fungible.remove_entry(&id) {
 					taken.fungible.insert(id, amount);
 				}
-				Ok(taken)
 			}
-			Wild(AllOf(WildNonFungible, id)) => {
-				let mut taken = Assets::new();
+			MultiAssetFilter::Wild(AllOf(WildNonFungible, id)) => {
 				let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
 				non_fungible.into_iter().for_each(|(c, instance)| {
-					if &c == id {
+					if c == id {
 						taken.non_fungible.insert((c, instance));
 					} else {
 						self.non_fungible.insert((c, instance));
 					}
 				});
-				Ok(taken)
 			}
-			Assets(assets) => {
+			MultiAssetFilter::Assets(assets) => {
 				if !saturate {
 					self.ensure_contains(&assets)?;
 				}
-				let mut taken = Assets::new();
 				for asset in assets.drain().into_iter() {
 					match asset {
-						MultiAsset { fun: Fungible(mut amount), id } => {
+						MultiAsset { fun: Fungible(amount), id } => {
 							let (remove, amount) = match self.fungible.get_mut(&id) {
 								Some(self_amount) => {
 									let amount = amount.min(*self_amount);
 									*self_amount -= amount;
-									(self_amount == 0, amount)
+									(*self_amount == 0, amount)
 								}
 								None => (false, 0),
 							};
@@ -222,32 +233,30 @@ impl Assets {
 				}
 			}
 		}
+		Ok(taken)
 	}
 
-	/// Mutates `self` to its original value less `asset` and returns `true` iff it contains at least `asset`.
-	///
-	/// `asset` is interpreted as being masked under `self`.
+	/// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least `mask`.
 	///
-	/// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus
-	/// `asset` if `self` contains `asset`, and return `Err` otherwise.
+	/// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its value minus
+	/// `mask` if `self` contains `asset`, and return `Err` otherwise.
 	pub fn saturating_take(&mut self, asset: MultiAssetFilter) -> Assets {
-		self.general_take(asset, true).expect("general_take never results in error when saturating")
+		self.general_take(asset, true)
+			.expect("general_take never results in error when saturating")
 	}
 
-	/// Mutates `self` to its original value less `asset` and returns `true` iff it contains at least `asset`.
-	///
-	/// `asset` is interpreted as being masked under `self`.
+	/// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least `mask`.
 	///
 	/// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus
 	/// `asset` if `self` contains `asset`, and return `Err` otherwise.
-	pub fn try_take(&mut self, asset: MultiAssetFilter) -> Result<Assets, TakeError> {
-		self.general_take(asset, false)
+	pub fn try_take(&mut self, mask: MultiAssetFilter) -> Result<Assets, TakeError> {
+		self.general_take(mask, false)
 	}
 
-	/// Consumes `self` and returns its original value excluding `asset` iff it contains at least `asset`, as well as
+	/// Consumes `self` and returns its original value excluding `mask` iff it contains at least `mask`, as well as
 	/// the assets excluded.
-	pub fn less(mut self, asset: WildMultiAsset) -> Result<(Assets, Assets), Self> {
-		match self.try_take(asset) {
+	pub fn less(mut self, mask: MultiAssetFilter) -> Result<(Assets, Assets), Self> {
+		match self.try_take(mask) {
 			Ok(taken) => Ok((self, taken)),
 			Err(_) => Err(self),
 		}
@@ -277,23 +286,23 @@ impl Assets {
 	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 50 },
 	/// ]);
 	/// ```
-	pub fn min(&self, mask: MultiAssetFilter) -> Assets {
+	pub fn min(&self, mask: &MultiAssetFilter) -> Assets {
 		let mut masked = Assets::new();
 		match mask {
-			Wild(All) => Ok(self.clone()),
-			Wild(AllOf(WildFungible, id)) => {
-				if let Some(&(ref id, amount)) = self.fungible.get(&id) {
+			MultiAssetFilter::Wild(All) => return self.clone(),
+			MultiAssetFilter::Wild(AllOf(WildFungible, id)) => {
+				if let Some(&amount) = self.fungible.get(&id) {
 					masked.fungible.insert(id.clone(), amount);
 				}
 			}
-			Wild(AllOf(WildNonFungible, id)) => {
+			MultiAssetFilter::Wild(AllOf(WildNonFungible, id)) => {
 				self.non_fungible.iter().for_each(|(ref c, ref instance)| {
 					if c == id {
 						masked.non_fungible.insert((c.clone(), instance.clone()));
 					}
 				});
 			}
-			Assets(assets) => {
+			MultiAssetFilter::Assets(assets) => {
 				for asset in assets.inner().iter() {
 					match asset {
 						MultiAsset { fun: Fungible(ref amount), ref id } => {
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index 87b770533db2..b9ec7b4a6e92 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -21,10 +21,7 @@ use frame_support::{
 	ensure, weights::GetDispatchInfo,
 	dispatch::{Weight, Dispatchable}
 };
-use xcm::v0::{
-	ExecuteXcm, SendXcm, Error as XcmError, Outcome,
-	MultiLocation, MultiAsset, Xcm, Order, Response,
-};
+use xcm::v0::{ExecuteXcm, SendXcm, Error as XcmError, Outcome, MultiLocation, MultiAssets, Xcm, Order, Response};
 
 pub mod traits;
 use traits::{
@@ -33,7 +30,7 @@ use traits::{
 };
 
 mod assets;
-pub use assets::{Assets, AssetId};
+pub use assets::Assets;
 mod config;
 pub use config::Config;
 
@@ -86,10 +83,10 @@ impl<Config: config::Config> ExecuteXcm<Config::Call> for XcmExecutor<Config> {
 }
 
 impl<Config: config::Config> XcmExecutor<Config> {
-	fn reanchored(mut assets: Assets, dest: &MultiLocation) -> Vec<MultiAsset> {
+	fn reanchored(mut assets: Assets, dest: &MultiLocation) -> MultiAssets {
 		let inv_dest = Config::LocationInverter::invert_location(&dest);
 		assets.prepend_location(&inv_dest);
-		assets.into_assets_iter().collect::<Vec<_>>()
+		assets.into_assets_iter().collect::<Vec<_>>().into()
 	}
 
 	/// Execute the XCM and return the portion of weight of `shallow_weight + deep_weight` that `message` did not use.
@@ -130,8 +127,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 			(origin, Xcm::WithdrawAsset { assets, effects }) => {
 				// Take `assets` from the origin account (on-chain) and place in holding.
 				let mut holding = Assets::default();
-				for asset in assets {
-					ensure!(!asset.is_wildcard(), XcmError::Wildcard);
+				for asset in assets.inner() {
 					let withdrawn = Config::AssetTransactor::withdraw_asset(&asset, &origin)?;
 					holding.subsume_assets(withdrawn);
 				}
@@ -139,18 +135,16 @@ impl<Config: config::Config> XcmExecutor<Config> {
 			}
 			(origin, Xcm::ReserveAssetDeposit { assets, effects }) => {
 				// check whether we trust origin to be our reserve location for this asset.
-				for asset in assets.iter() {
-					ensure!(!asset.is_wildcard(), XcmError::Wildcard);
+				for asset in assets.inner() {
 					// We only trust the origin to send us assets that they identify as their
 					// sovereign assets.
 					ensure!(Config::IsReserve::filter_asset_location(asset, &origin), XcmError::UntrustedReserveLocation);
 				}
-				Some((Assets::from(assets), effects))
+				Some((assets.into(), effects))
 			}
 			(origin, Xcm::TransferAsset { assets, dest }) => {
 				// Take `assets` from the origin account (on-chain) and place into dest account.
-				for asset in assets {
-					ensure!(!asset.is_wildcard(), XcmError::Wildcard);
+				for asset in assets.inner() {
 					Config::AssetTransactor::teleport_asset(&asset, &origin, &dest)?;
 				}
 				None
@@ -158,18 +152,16 @@ impl<Config: config::Config> XcmExecutor<Config> {
 			(origin, Xcm::TransferReserveAsset { mut assets, dest, effects }) => {
 				// Take `assets` from the origin account (on-chain) and place into dest account.
 				let inv_dest = Config::LocationInverter::invert_location(&dest);
-				for asset in assets.iter_mut() {
-					ensure!(!asset.is_wildcard(), XcmError::Wildcard);
-					Config::AssetTransactor::teleport_asset(&asset, &origin, &dest)?;
-					asset.reanchor(&inv_dest)?;
+				for asset in assets.inner() {
+					Config::AssetTransactor::teleport_asset(asset, &origin, &dest)?;
 				}
+				assets.reanchor(&inv_dest)?;
 				Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?;
 				None
 			}
 			(origin, Xcm::TeleportAsset { assets, effects }) => {
 				// check whether we trust origin to teleport this asset to us via config trait.
-				for asset in assets.iter() {
-					ensure!(!asset.is_wildcard(), XcmError::Wildcard);
+				for asset in assets.inner() {
 					// We only trust the origin to send us assets that they identify as their
 					// sovereign assets.
 					ensure!(Config::IsTeleporter::filter_asset_location(asset, &origin), XcmError::UntrustedTeleportLocation);
@@ -178,7 +170,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 					// don't want to punish a possibly innocent chain/user).
 					Config::AssetTransactor::can_check_in(&origin, asset)?;
 				}
-				for asset in assets.iter() {
+				for asset in assets.inner() {
 					Config::AssetTransactor::check_in(&origin, asset);
 				}
 				Some((Assets::from(assets), effects))
@@ -280,13 +272,13 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				Config::XcmSender::send_xcm(dest, Xcm::TeleportAsset { assets, effects })?;
 			}
 			Order::QueryHolding { query_id, dest, assets } => {
-				let assets = Self::reanchored(holding.min(assets.iter()), &dest);
+				let assets = Self::reanchored(holding.min(&assets), &dest);
 				Config::XcmSender::send_xcm(dest, Xcm::QueryResponse { query_id, response: Response::Assets(assets) })?;
 			}
 			Order::BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
 				// pay for `weight` using up to `fees` of the holding account.
 				let purchasing_weight = Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?);
-				let max_fee = holding.try_take(fees).map_err(|()| XcmError::NotHoldingFees)?;
+				let max_fee = holding.try_take(fees.into()).map_err(|_| XcmError::NotHoldingFees)?;
 				let unspent = trader.buy_weight(purchasing_weight, max_fee)?;
 				holding.subsume_assets(unspent);
 
@@ -298,7 +290,9 @@ impl<Config: config::Config> XcmExecutor<Config> {
 						Ok(surplus) => { total_surplus += surplus }
 					}
 				}
-				holding.subsume(trader.refund_weight(remaining_weight));
+				if let Some(w) = trader.refund_weight(remaining_weight) {
+					holding.subsume(w);
+				}
 			}
 			_ => return Err(XcmError::UnhandledEffect)?,
 		}
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index a967f1f6909a..610f98977ca7 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -103,7 +103,7 @@ impl TransactAsset for Tuple {
 	fn can_check_in(origin: &MultiLocation, what: &MultiAsset) -> XcmResult {
 		for_tuples!( #(
 			match Tuple::can_check_in(origin, what) {
-				Err(XcmError::AssetNotFound | XcmError::Unimplemented) => (),
+				Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (),
 				r => return r,
 			}
 		)* );
@@ -131,7 +131,7 @@ impl TransactAsset for Tuple {
 	fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> XcmResult {
 		for_tuples!( #(
 			match Tuple::deposit_asset(what, who) {
-				Err(XcmError::AssetNotFound | XcmError::Unimplemented) => (),
+				Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (),
 				r => return r,
 			}
 		)* );
@@ -147,7 +147,7 @@ impl TransactAsset for Tuple {
 	fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result<Assets, XcmError> {
 		for_tuples!( #(
 			match Tuple::withdraw_asset(what, who) {
-				Err(XcmError::AssetNotFound | XcmError::Unimplemented) => (),
+				Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (),
 				r => return r,
 			}
 		)* );
@@ -163,7 +163,7 @@ impl TransactAsset for Tuple {
 	fn transfer_asset(what: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result<Assets, XcmError> {
 		for_tuples!( #(
 			match Tuple::transfer_asset(what, from, to) {
-				Err(XcmError::AssetNotFound | XcmError::Unimplemented) => (),
+				Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (),
 				r => return r,
 			}
 		)* );
diff --git a/xcm/xcm-executor/src/traits/weight.rs b/xcm/xcm-executor/src/traits/weight.rs
index dc9589803af5..1844f3b6c7f2 100644
--- a/xcm/xcm-executor/src/traits/weight.rs
+++ b/xcm/xcm-executor/src/traits/weight.rs
@@ -71,7 +71,7 @@ pub trait WeightTrader: Sized {
 	/// purchased using `buy_weight`.
 	///
 	/// Default implementation refunds nothing.
-	fn refund_weight(&mut self, _weight: Weight) -> MultiAsset { MultiAsset::None }
+	fn refund_weight(&mut self, _weight: Weight) -> Option<MultiAsset> { None }
 }
 
 impl WeightTrader for () {

From 8017453bf8ae1edb0c9a3b77c49d04187c079afe Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sat, 31 Jul 2021 11:39:28 +0200
Subject: [PATCH 012/166] XCM Builder builds

---
 xcm/src/v0/multiasset.rs                     | 42 +++++++++++++-------
 xcm/xcm-builder/src/filter_asset_location.rs |  4 +-
 xcm/xcm-builder/src/fungibles_adapter.rs     | 13 +++---
 xcm/xcm-builder/src/matches_fungible.rs      | 10 ++---
 xcm/xcm-builder/src/weight.rs                | 21 +++++-----
 xcm/xcm-executor/src/assets.rs               | 10 +++++
 6 files changed, 61 insertions(+), 39 deletions(-)

diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 3d0ee0d2d00e..c877f71a0dc6 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -64,6 +64,18 @@ pub enum AssetId {
 	Abstract(Vec<u8>),
 }
 
+impl From<MultiLocation> for AssetId {
+	fn from(x: MultiLocation) -> Self {
+		Self::Concrete(x)
+	}
+}
+
+impl From<Vec<u8>> for AssetId {
+	fn from(x: Vec<u8>) -> Self {
+		Self::Abstract(x)
+	}
+}
+
 impl AssetId {
 	/// Prepend a `MultiLocation` to a concrete asset, giving it a new root location.
 	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
@@ -137,21 +149,9 @@ impl Ord for MultiAsset {
 	}
 }
 
-impl From<(AssetId, Fungibility)> for MultiAsset {
-	fn from((id, fun): (AssetId, Fungibility)) -> MultiAsset {
-		MultiAsset { fun, id }
-	}
-}
-
-impl From<(AssetId, u128)> for MultiAsset {
-	fn from((id, amount): (AssetId, u128)) -> MultiAsset {
-		MultiAsset { fun: amount.into(), id }
-	}
-}
-
-impl From<(AssetId, AssetInstance)> for MultiAsset {
-	fn from((id, instance): (AssetId, AssetInstance)) -> MultiAsset {
-		MultiAsset { fun: instance.into(), id }
+impl<A: Into<AssetId>, B: Into<Fungibility>> From<(A, B)> for MultiAsset {
+	fn from((id, fun): (A, B)) -> MultiAsset {
+		MultiAsset { fun: fun.into(), id: id.into() }
 	}
 }
 
@@ -409,6 +409,18 @@ impl From<WildMultiAsset> for MultiAssetFilter {
 	}
 }
 
+impl From<MultiAsset> for MultiAssetFilter {
+	fn from(x: MultiAsset) -> Self {
+		Self::Assets(vec![x].into())
+	}
+}
+
+impl From<MultiAssets> for MultiAssetFilter {
+	fn from(x: MultiAssets) -> Self {
+		Self::Assets(x)
+	}
+}
+
 impl From<MultiAssetFilter> for Vec<OldMultiAsset> {
 	fn from(a: MultiAssetFilter) -> Self {
 		use MultiAssetFilter::*;
diff --git a/xcm/xcm-builder/src/filter_asset_location.rs b/xcm/xcm-builder/src/filter_asset_location.rs
index 9ad4f40aa71c..e095b9dbbc73 100644
--- a/xcm/xcm-builder/src/filter_asset_location.rs
+++ b/xcm/xcm-builder/src/filter_asset_location.rs
@@ -17,7 +17,7 @@
 //! Various implementations of `FilterAssetLocation`.
 
 use sp_std::marker::PhantomData;
-use xcm::v0::{MultiAsset, MultiLocation};
+use xcm::v0::{MultiAsset, MultiLocation, AssetId::Concrete};
 use frame_support::traits::Get;
 use xcm_executor::traits::FilterAssetLocation;
 
@@ -25,7 +25,7 @@ use xcm_executor::traits::FilterAssetLocation;
 pub struct NativeAsset;
 impl FilterAssetLocation for NativeAsset {
 	fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {
-		matches!(asset, MultiAsset::ConcreteFungible { ref id, .. } if id == origin)
+		matches!(asset.id, Concrete(ref id) if id == origin)
 	}
 }
 
diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs
index 80cd74c0124d..121d0828f165 100644
--- a/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -17,7 +17,10 @@
 //! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM.
 
 use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow};
-use xcm::v0::{Error as XcmError, Result, MultiAsset, MultiLocation, Junction};
+use xcm::v0::{
+	Error as XcmError, Result, MultiAsset, MultiLocation, Junction, Fungibility::Fungible,
+	AssetId::{Concrete, Abstract},
+};
 use frame_support::traits::{Get, tokens::fungibles, Contains};
 use xcm_executor::traits::{TransactAsset, Convert, MatchesFungibles, Error as MatchError};
 
@@ -61,8 +64,8 @@ impl<
 	ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
 {
 	fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
-		let (id, amount) = match a {
-			MultiAsset::ConcreteFungible { id, amount } => (id, amount),
+		let (amount, id) = match (&a.fun, &a.id) {
+			(Fungible(ref amount), Concrete(ref id)) => (amount, id),
 			_ => return Err(MatchError::AssetNotFound),
 		};
 		let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
@@ -83,8 +86,8 @@ impl<
 	ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
 {
 	fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
-		let (id, amount) = match a {
-			MultiAsset::AbstractFungible { id, amount } => (id, amount),
+		let (amount, id) = match (&a.fun, &a.id) {
+			(Fungible(ref amount), Abstract(ref id)) => (amount, id),
 			_ => return Err(MatchError::AssetNotFound),
 		};
 		let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 4d76a49b6bd8..8ec1893ee9df 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -18,7 +18,7 @@
 
 use sp_std::{marker::PhantomData, convert::TryFrom};
 use sp_runtime::traits::CheckedConversion;
-use xcm::v0::{MultiAsset, MultiLocation};
+use xcm::v0::{MultiAsset, MultiLocation, AssetId::{Abstract, Concrete}, Fungibility::Fungible};
 use frame_support::traits::Get;
 use xcm_executor::traits::MatchesFungible;
 
@@ -46,8 +46,8 @@ use xcm_executor::traits::MatchesFungible;
 pub struct IsConcrete<T>(PhantomData<T>);
 impl<T: Get<MultiLocation>, B: TryFrom<u128>> MatchesFungible<B> for IsConcrete<T> {
 	fn matches_fungible(a: &MultiAsset) -> Option<B> {
-		match a {
-			MultiAsset::ConcreteFungible { id, amount } if id == &T::get() =>
+		match (&a.id, &a.fun) {
+			(Concrete(ref id), Fungible(ref amount)) if id == &T::get() =>
 				CheckedConversion::checked_from(*amount),
 			_ => None,
 		}
@@ -76,8 +76,8 @@ impl<T: Get<MultiLocation>, B: TryFrom<u128>> MatchesFungible<B> for IsConcrete<
 pub struct IsAbstract<T>(PhantomData<T>);
 impl<T: Get<&'static [u8]>, B: TryFrom<u128>> MatchesFungible<B> for IsAbstract<T> {
 	fn matches_fungible(a: &MultiAsset) -> Option<B> {
-		match a {
-			MultiAsset::AbstractFungible { id, amount } if &id[..] == T::get() =>
+		match (&a.id, &a.fun) {
+			(Abstract(ref id), Fungible(ref amount)) if id == &T::get() =>
 				CheckedConversion::checked_from(*amount),
 			_ => None,
 		}
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index 26f282abfec7..77f28c73f571 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -16,7 +16,7 @@
 
 use sp_std::{result::Result, marker::PhantomData, convert::TryInto};
 use parity_scale_codec::Decode;
-use xcm::v0::{Xcm, Order, MultiAsset, MultiLocation, Error};
+use xcm::v0::{Xcm, Order, MultiAsset, MultiLocation, Error, AssetId::Concrete};
 use sp_runtime::traits::{Zero, Saturating, SaturatedConversion};
 use frame_support::traits::{Get, OnUnbalanced as OnUnbalancedT, tokens::currency::Currency as CurrencyT};
 use frame_support::weights::{Weight, GetDispatchInfo, WeightToFeePolynomial};
@@ -103,8 +103,7 @@ impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader for FixedRateOf
 		let (id, units_per_second) = T::get();
 		use frame_support::weights::constants::WEIGHT_PER_SECOND;
 		let amount = units_per_second * (weight as u128) / (WEIGHT_PER_SECOND as u128);
-		let required = MultiAsset::ConcreteFungible { amount, id };
-		let (unused, _) = payment.less(required).map_err(|_| Error::TooExpensive)?;
+		let unused = payment.checked_sub((id, amount).into()).map_err(|_| Error::TooExpensive)?;
 		self.0 = self.0.saturating_add(weight);
 		self.1 = self.1.saturating_add(amount);
 		Ok(unused)
@@ -116,14 +115,13 @@ impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader for FixedRateOf
 		let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128;
 		self.0 -= weight;
 		self.1 = self.1.saturating_sub(amount);
-		Some((id, amount).into())
+		Some((Concrete(id), amount).into())
 	}
 }
 
 impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> Drop for FixedRateOfConcreteFungible<T, R> {
 	fn drop(&mut self) {
-		let revenue = MultiAsset::ConcreteFungible { amount: self.1, id: T::get().0 };
-		R::take_revenue(revenue);
+		R::take_revenue((Concrete(T::get().0), self.1).into());
 	}
 }
 
@@ -147,11 +145,9 @@ impl<
 
 	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error> {
 		let amount = WeightToFee::calc(&weight);
-		let required = MultiAsset::ConcreteFungible {
-			amount: amount.try_into().map_err(|_| Error::Overflow)?,
-			id: AssetId::get(),
-		};
-		let (unused, _) = payment.less(required).map_err(|_| Error::TooExpensive)?;
+		let u128_amount: u128 = amount.try_into().map_err(|_| Error::Overflow)?;
+		let required = (Concrete(AssetId::get()), u128_amount).into();
+		let unused = payment.checked_sub(required).map_err(|_| Error::TooExpensive)?;
 		self.0 = self.0.saturating_add(weight);
 		self.1 = self.1.saturating_add(amount);
 		Ok(unused)
@@ -162,7 +158,8 @@ impl<
 		let amount = WeightToFee::calc(&weight);
 		self.0 -= weight;
 		self.1 = self.1.saturating_sub(amount);
-		Some(MultiAsset::from((AssetId::get(), amount.saturated_into())))
+		let amount: u128 = amount.saturated_into();
+		Some((AssetId::get(), amount).into())
 	}
 
 }
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 7c2b5410991c..b25b0b3e4637 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -253,6 +253,16 @@ impl Assets {
 		self.general_take(mask, false)
 	}
 
+	/// Consumes `self` and returns its original value excluding `asset` iff it contains at least `asset`.
+	pub fn checked_sub(mut self, asset: MultiAsset) -> Result<Assets, Self> {
+		// TODO: Optimize by doing this operation directly rather than converting into a MultiAssetFilter and
+		//   constructing the unused `_taken` return value.
+		match self.try_take(asset.into()) {
+			Ok(_taken) => Ok(self),
+			Err(_) => Err(self),
+		}
+	}
+
 	/// Consumes `self` and returns its original value excluding `mask` iff it contains at least `mask`, as well as
 	/// the assets excluded.
 	pub fn less(mut self, mask: MultiAssetFilter) -> Result<(Assets, Assets), Self> {

From 72c25814614b865b502681e2e7ab77c5df65bdd9 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 31 Jul 2021 04:13:15 -0700
Subject: [PATCH 013/166] Fix xcm-builder tests and compilation

---
 xcm/xcm-builder/src/barriers.rs            |   8 +-
 xcm/xcm-builder/src/currency_adapter.rs    |   4 +-
 xcm/xcm-builder/src/fungibles_adapter.rs   |  12 +-
 xcm/xcm-builder/src/location_conversion.rs | 111 +++++++++-------
 xcm/xcm-builder/src/matches_fungible.rs    |   6 +-
 xcm/xcm-builder/src/mock.rs                |  34 ++---
 xcm/xcm-builder/src/origin_conversion.rs   |  74 ++++++-----
 xcm/xcm-builder/src/tests.rs               | 144 +++++++++++----------
 8 files changed, 214 insertions(+), 179 deletions(-)

diff --git a/xcm/xcm-builder/src/barriers.rs b/xcm/xcm-builder/src/barriers.rs
index ea3d80660940..2d9db1e916f4 100644
--- a/xcm/xcm-builder/src/barriers.rs
+++ b/xcm/xcm-builder/src/barriers.rs
@@ -17,7 +17,7 @@
 //! Various implementations for `ShouldExecute`.
 
 use sp_std::{result::Result, marker::PhantomData};
-use xcm::v0::{Xcm, Order, MultiLocation, Junction};
+use xcm::v0::{Xcm, Order, MultiLocation, Junction, Junctions};
 use frame_support::{ensure, traits::Contains, weights::Weight};
 use xcm_executor::traits::{OnResponse, ShouldExecute};
 use polkadot_parachain::primitives::IsSystem;
@@ -86,7 +86,11 @@ impl<
 	ParaId: IsSystem + From<u32>,
 > Contains<MultiLocation> for IsChildSystemParachain<ParaId> {
 	fn contains(l: &MultiLocation) -> bool {
-		matches!(l, MultiLocation::X1(Junction::Parachain(id)) if ParaId::from(*id).is_system())
+		matches!(
+			l.junctions(),
+			Junctions::X1(Junction::Parachain(id))
+				if ParaId::from(*id).is_system() && l.parent_count() == 0,
+		)
 	}
 }
 
diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs
index 744835f08959..22a1c4c02a4d 100644
--- a/xcm/xcm-builder/src/currency_adapter.rs
+++ b/xcm/xcm-builder/src/currency_adapter.rs
@@ -50,7 +50,7 @@ impl From<Error> for XcmError {
 /// # Example
 /// ```
 /// use frame_support::parameter_types;
-/// use xcm::v0::{MultiLocation, Junction};
+/// use xcm::v0::{MultiLocation, Junction, Junctions::*};
 /// use xcm_builder::{ParentIsDefault, CurrencyAdapter, IsConcrete};
 ///
 /// /// Our chain's account id.
@@ -58,7 +58,7 @@ impl From<Error> for XcmError {
 ///
 /// /// Our relay chain's location.
 /// parameter_types! {
-///     RelayChain: MultiLocation = MultiLocation::X1(Junction::Parent);
+///     RelayChain: MultiLocation = MultiLocation::new(1, Null).unwrap();
 ///     CheckingAccount: AccountId = Default::default();
 /// }
 ///
diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs
index 80cd74c0124d..c39b4aa4eae1 100644
--- a/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -33,10 +33,16 @@ impl<
 	fn convert_ref(id: impl Borrow<MultiLocation>) -> result::Result<AssetId, ()> {
 		let prefix = Prefix::get();
 		let id = id.borrow();
-		if !prefix.iter().enumerate().all(|(index, item)| id.at(index) == Some(item)) {
+		if prefix.parent_count() != id.parent_count()
+			|| prefix
+				.junctions()
+				.iter()
+				.enumerate()
+				.any(|(index, junction)| id.junctions().at(index) != Some(junction))
+		{
 			return Err(())
 		}
-		match id.at(prefix.len()) {
+		match id.junctions().at(prefix.junctions().len()) {
 			Some(Junction::GeneralIndex { id }) => ConvertAssetId::convert_ref(id),
 			_ => Err(()),
 		}
@@ -44,7 +50,7 @@ impl<
 	fn reverse_ref(what: impl Borrow<AssetId>) -> result::Result<MultiLocation, ()> {
 		let mut location = Prefix::get();
 		let id = ConvertAssetId::reverse_ref(what)?;
-		location.push(Junction::GeneralIndex { id }).map_err(|_| ())?;
+		location.push_non_parent(Junction::GeneralIndex { id })?;
 		Ok(location)
 	}
 }
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index cdf0a2bf5171..7c6e9743fbcc 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -19,7 +19,7 @@ use sp_io::hashing::blake2_256;
 use sp_runtime::traits::AccountIdConversion;
 use frame_support::traits::Get;
 use parity_scale_codec::Encode;
-use xcm::v0::{MultiLocation, NetworkId, Junction};
+use xcm::v0::{Junctions, Junction, MultiLocation, NetworkId};
 use xcm_executor::traits::{InvertLocation, Convert};
 
 pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
@@ -43,7 +43,7 @@ impl<
 	AccountId: Default + Eq + Clone,
 > Convert<MultiLocation, AccountId> for ParentIsDefault<AccountId> {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-		if let &MultiLocation::X1(Junction::Parent) = location.borrow() {
+		if location.borrow().parent_count() == 1 {
 			Ok(AccountId::default())
 		} else {
 			Err(())
@@ -52,7 +52,7 @@ impl<
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if who.borrow() == &AccountId::default() {
-			Ok(Junction::Parent.into())
+			Ok(MultiLocation::new(1, Junctions::Null).expect("well-formed MultiLocation; qed"))
 		} else {
 			Err(())
 		}
@@ -65,10 +65,12 @@ impl<
 	AccountId: Clone,
 > Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId> {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-		if let &MultiLocation::X1(Junction::Parachain(id)) = location.borrow() {
-			Ok(ParaId::from(id).into_account())
-		} else {
-			Err(())
+		let location = location.borrow();
+		match location.junctions() {
+			Junctions::X1(Junction::Parachain(id)) if location.parent_count() == 0 => {
+				Ok(ParaId::from(*id).into_account())
+			},
+			_ => Err(()),
 		}
 	}
 
@@ -87,16 +89,22 @@ impl<
 	AccountId: Clone,
 > Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId> {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-		if let &MultiLocation::X2(Junction::Parent, Junction::Parachain(id)) = location.borrow() {
-			Ok(ParaId::from(id).into_account())
-		} else {
-			Err(())
+		let location = location.borrow();
+		match location.junctions() {
+			Junctions::X1(Junction::Parachain(id)) if location.parent_count() == 1 => {
+				Ok(ParaId::from(*id).into_account())
+			},
+			_ => Err(()),
 		}
 	}
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if let Some(id) = ParaId::try_from_account(who.borrow()) {
-			Ok([Junction::Parent, Junction::Parachain(id.into())].into())
+			Ok(MultiLocation::new(
+				1,
+				Junctions::X1(Junction::Parachain(id.into())))
+					.expect("well-formed MultiLocation; qed"),
+			)
 		} else {
 			Err(())
 		}
@@ -110,10 +118,14 @@ impl<
 	AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone,
 > Convert<MultiLocation, AccountId> for AccountId32Aliases<Network, AccountId> {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
-		let id = match location {
-			MultiLocation::X1(Junction::AccountId32 { id, network: NetworkId::Any }) => id,
-			MultiLocation::X1(Junction::AccountId32 { id, network }) if &network == &Network::get() => id,
-			l => return Err(l),
+		let id = match location.junctions() {
+			Junctions::X1(Junction::AccountId32 { id, network: NetworkId::Any })
+			if location.parent_count() == 0
+				=> *id,
+			Junctions::X1(Junction::AccountId32 { id, network })
+			if network == &Network::get() && location.parent_count() == 0
+				=> *id,
+			_ => return Err(location),
 		};
 		Ok(id.into())
 	}
@@ -129,10 +141,14 @@ impl<
 	AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone,
 > Convert<MultiLocation, AccountId> for AccountKey20Aliases<Network, AccountId> {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
-		let key = match location {
-			MultiLocation::X1(Junction::AccountKey20 { key, network: NetworkId::Any }) => key,
-			MultiLocation::X1(Junction::AccountKey20 { key, network }) if &network == &Network::get() => key,
-			l => return Err(l),
+		let key = match location.junctions() {
+			Junctions::X1(Junction::AccountKey20 { key, network: NetworkId::Any })
+			if location.parent_count() == 0
+				=> *key,
+			Junctions::X1(Junction::AccountKey20 { key, network })
+			if network == &Network::get() && location.parent_count() == 0
+				=> *key,
+			_ => return Err(location),
 		};
 		Ok(key.into())
 	}
@@ -156,7 +172,7 @@ impl<
 /// ```
 /// ```rust
 /// # use frame_support::parameter_types;
-/// # use xcm::v0::{MultiLocation::{self, *}, Junction::*, NetworkId::Any};
+/// # use xcm::v0::{MultiLocation, Junction::*, Junctions::{self, *}, NetworkId::Any};
 /// # use xcm_builder::LocationInverter;
 /// # use xcm_executor::traits::InvertLocation;
 /// # fn main() {
@@ -164,34 +180,31 @@ impl<
 ///     pub Ancestry: MultiLocation = X2(
 ///         Parachain(1),
 ///         AccountKey20 { network: Any, key: Default::default() },
-///     );
+///     ).into();
 /// }
 ///
-/// let input = X4(Parent, Parent, Parachain(2), AccountId32 { network: Any, id: Default::default() });
+/// let input = MultiLocation::new(2, X2(Parachain(2), AccountId32 { network: Any, id: Default::default() })).unwrap();
 /// let inverted = LocationInverter::<Ancestry>::invert_location(&input);
-/// assert_eq!(inverted, X4(
-///     Parent,
-///     Parent,
-///     Parachain(1),
-///     AccountKey20 { network: Any, key: Default::default() },
-/// ));
+/// assert_eq!(inverted, MultiLocation::new(
+///     2,
+///     X2(Parachain(1), AccountKey20 { network: Any, key: Default::default() }),
+/// ).unwrap());
 /// # }
 /// ```
 pub struct LocationInverter<Ancestry>(PhantomData<Ancestry>);
 impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry> {
 	fn invert_location(location: &MultiLocation) -> MultiLocation {
 		let mut ancestry = Ancestry::get();
-		let mut result = location.clone();
-		for (i, j) in location.iter_rev()
-			.map(|j| match j {
-				Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild),
-				_ => Junction::Parent,
-			})
-			.enumerate()
-		{
-			*result.at_mut(i).expect("location and result begin equal; same size; qed") = j;
+		let mut junctions = Junctions::Null;
+		for _ in 0..location.parent_count() {
+			junctions = junctions.pushed_with(
+				ancestry.take_first_non_parent().unwrap_or(Junction::OnlyChild),
+			)
+			.expect("ancestry is well-formed and has less than 8 non-parent junctions; qed");
 		}
-		result
+		let parents = location.junctions().len() as u8;
+		MultiLocation::new(parents, junctions)
+			.expect("parents + junctions len must equal location len; qed")
 	}
 }
 
@@ -200,7 +213,7 @@ mod tests {
 	use super::*;
 
 	use frame_support::parameter_types;
-	use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
+	use xcm::v0::{MultiLocation, Junction::*, Junctions::*, NetworkId::Any};
 
 	fn account20() -> Junction {
 		AccountKey20 { network: Any, key: Default::default() }
@@ -225,12 +238,12 @@ mod tests {
 	#[test]
 	fn inverter_works_in_tree() {
 		parameter_types!{
-			pub Ancestry: MultiLocation = X3(Parachain(1), account20(), account20());
+			pub Ancestry: MultiLocation = X3(Parachain(1), account20(), account20()).into();
 		}
 
-		let input = X5(Parent, Parent, Parent, Parachain(2), account32());
+		let input = MultiLocation::new(3, X2(Parachain(2), account32())).unwrap();
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
-		assert_eq!(inverted, X5(Parent, Parent, Parachain(1), account20(), account20()));
+		assert_eq!(inverted, MultiLocation::new(2, X3(Parachain(1), account20(), account20())).unwrap());
 	}
 
 	// Network Topology
@@ -240,12 +253,12 @@ mod tests {
 	#[test]
 	fn inverter_uses_ancestry_as_inverted_location() {
 		parameter_types!{
-			pub Ancestry: MultiLocation = X2(account20(), account20());
+			pub Ancestry: MultiLocation = X2(account20(), account20()).into();
 		}
 
-		let input = X2(Parent, Parent);
+		let input = MultiLocation::new(2, Null).unwrap();
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
-		assert_eq!(inverted, X2(account20(), account20()));
+		assert_eq!(inverted, X2(account20(), account20()).into());
 	}
 
 	// Network Topology
@@ -255,11 +268,11 @@ mod tests {
 	#[test]
 	fn inverter_uses_only_child_on_missing_ancestry() {
 		parameter_types!{
-			pub Ancestry: MultiLocation = X1(PalletInstance(5));
+			pub Ancestry: MultiLocation = X1(PalletInstance(5)).into();
 		}
 
-		let input = X2(Parent, Parent);
+		let input = MultiLocation::new(2, Null).unwrap();
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
-		assert_eq!(inverted, X2(PalletInstance(5), OnlyChild));
+		assert_eq!(inverted, X2(PalletInstance(5), OnlyChild).into());
 	}
 }
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 4d76a49b6bd8..b95725e6ceb0 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -28,16 +28,16 @@ use xcm_executor::traits::MatchesFungible;
 /// # Example
 ///
 /// ```
-/// use xcm::v0::{MultiAsset, MultiLocation, Junction};
+/// use xcm::v0::{MultiAsset, MultiLocation, Junction, Junctions::*};
 /// use xcm_builder::IsConcrete;
 /// use xcm_executor::traits::MatchesFungible;
 ///
 /// frame_support::parameter_types! {
-/// 	pub TargetLocation: MultiLocation = MultiLocation::X1(Junction::Parent);
+/// 	pub TargetLocation: MultiLocation = MultiLocation::new(1, Null).unwrap();
 /// }
 ///
 /// # fn main() {
-/// let id = MultiLocation::X1(Junction::Parent);
+/// let id = MultiLocation::new(1, Null).unwrap();
 /// let asset = MultiAsset::ConcreteFungible { id, amount: 999u128 };
 /// // match `asset` if it is a concrete asset in `TargetLocation`.
 /// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 56d7d753e49e..efe4f49ee5ce 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -18,8 +18,8 @@ pub use sp_std::{fmt::Debug, marker::PhantomData, cell::RefCell};
 pub use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
 pub use parity_scale_codec::{Encode, Decode};
 pub use xcm::v0::{
-	SendXcm, MultiLocation::*, Junction::*, MultiAsset, Xcm, Order, Result as XcmResult, Error as XcmError,
-	OriginKind, MultiLocation, Junction, opaque,
+	SendXcm, Junction::*, Junctions::*, MultiAsset, Xcm, Order, Result as XcmResult, Error as XcmError,
+	OriginKind, MultiLocation, Junction, Junctions, opaque,
 };
 pub use frame_support::{
 	ensure, parameter_types,
@@ -147,18 +147,18 @@ impl TransactAsset for TestAssetTransactor {
 
 
 pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
-	Ok(match l {
+	Ok(match l.junctions() {
 		// Siblings at 2000+id
-		X2(Parent, Parachain(id)) => 2000 + id as u64,
+		X1(Parachain(id)) if l.parent_count() == 1 => 2000 + *id as u64,
 		// Accounts are their number
-		X1(AccountIndex64 { index, .. }) => index,
+		X1(AccountIndex64 { index, .. }) if l.parent_count() == 0 => *index,
 		// Children at 1000+id
-		X1(Parachain(id)) => 1000 + id as u64,
+		X1(Parachain(id)) if l.parent_count() == 0 => 1000 + *id as u64,
 		// Self at 3000
-		Null => 3000,
+		Null if l.parent_count() == 0 => 3000,
 		// Parent at 3001
-		X1(Parent) => 3001,
-		l => return Err(l),
+		Null if l.parent_count() == 1 => 3001,
+		_ => return Err(l),
 	})
 }
 
@@ -166,13 +166,13 @@ pub struct TestOriginConverter;
 impl ConvertOrigin<TestOrigin> for TestOriginConverter {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<TestOrigin, MultiLocation> {
 		use OriginKind::*;
-		match (kind, origin) {
+		match (kind, origin.junctions()) {
 			(Superuser, _) => Ok(TestOrigin::Root),
-			(SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)),
-			(Native, X1(Parachain(id))) => Ok(TestOrigin::Parachain(id)),
-			(Native, X1(Parent)) => Ok(TestOrigin::Relay),
-			(Native, X1(AccountIndex64 {index, ..})) => Ok(TestOrigin::Signed(index)),
-			(_, origin) => Err(origin),
+			(SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)),
+			(Native, X1(Parachain(id))) if origin.parent_count() == 0 => Ok(TestOrigin::Parachain(*id)),
+			(Native, Null) if origin.parent_count() == 1 => Ok(TestOrigin::Relay),
+			(Native, X1(AccountIndex64 {index, ..})) if origin.parent_count() == 0 => Ok(TestOrigin::Signed(*index)),
+			_ => Err(origin),
 		}
 	}
 }
@@ -248,7 +248,7 @@ pub fn response(query_id: u64) -> Option<Response> {
 }
 
 parameter_types! {
-	pub TestAncestry: MultiLocation = X1(Parachain(42));
+	pub TestAncestry: MultiLocation = X1(Parachain(42)).into();
 	pub UnitWeightCost: Weight = 10;
 }
 parameter_types! {
@@ -256,7 +256,7 @@ parameter_types! {
 	pub static AllowUnpaidFrom: Vec<MultiLocation> = vec![];
 	pub static AllowPaidFrom: Vec<MultiLocation> = vec![];
 	// 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight.
-	pub static WeightPrice: (MultiLocation, u128) = (Null, 1_000_000_000_000);
+	pub static WeightPrice: (MultiLocation, u128) = (Null.into(), 1_000_000_000_000);
 }
 
 pub type TestBarrier = (
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index 79dbf957240c..e675a48274ba 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -17,7 +17,7 @@
 //! Various implementations for `ConvertOrigin`.
 
 use sp_std::{marker::PhantomData, convert::TryInto};
-use xcm::v0::{MultiLocation, OriginKind, NetworkId, Junction, BodyId, BodyPart};
+use xcm::v0::{MultiLocation, OriginKind, NetworkId, Junction, Junctions, BodyId, BodyPart};
 use xcm_executor::traits::{Convert, ConvertOrigin};
 use frame_support::traits::{EnsureOrigin, Get, OriginTrait, GetBacking};
 use frame_system::RawOrigin as SystemRawOrigin;
@@ -46,10 +46,10 @@ impl<
 	Origin: OriginTrait,
 > ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin) {
-			(OriginKind::Superuser, MultiLocation::X1(Junction::Parent)) =>
-				Ok(Origin::root()),
-			(_, origin) => Err(origin),
+		if kind == OriginKind::Superuser && origin.parent_count() == 1 {
+			Ok(Origin::root())
+		} else {
+			Err(origin)
 		}
 	}
 }
@@ -60,11 +60,11 @@ impl<
 	Origin: OriginTrait,
 > ConvertOrigin<Origin> for ChildSystemParachainAsSuperuser<ParaId, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin) {
-			(OriginKind::Superuser, MultiLocation::X1(Junction::Parachain(id)))
-			if ParaId::from(id).is_system() =>
+		match (kind, origin.junctions()) {
+			(OriginKind::Superuser, Junctions::X1(Junction::Parachain(id)))
+			if ParaId::from(*id).is_system() && origin.parent_count() == 0 =>
 				Ok(Origin::root()),
-			(_, origin) => Err(origin),
+			_ => Err(origin),
 		}
 	}
 }
@@ -75,11 +75,11 @@ impl<
 	Origin: OriginTrait
 > ConvertOrigin<Origin> for SiblingSystemParachainAsSuperuser<ParaId, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin) {
-			(OriginKind::Superuser, MultiLocation::X2(Junction::Parent, Junction::Parachain(id)))
-			if ParaId::from(id).is_system() =>
+		match (kind, origin.junctions()) {
+			(OriginKind::Superuser, Junctions::X1(Junction::Parachain(id)))
+			if ParaId::from(*id).is_system() && origin.parent_count() == 1 =>
 				Ok(Origin::root()),
-			(_, origin) => Err(origin),
+			_ => Err(origin),
 		}
 	}
 }
@@ -92,10 +92,10 @@ impl<
 	Origin: From<ParachainOrigin>,
 > ConvertOrigin<Origin> for ChildParachainAsNative<ParachainOrigin, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin) {
-			(OriginKind::Native, MultiLocation::X1(Junction::Parachain(id)))
-			=> Ok(Origin::from(ParachainOrigin::from(id))),
-			(_, origin) => Err(origin),
+		match (kind, origin.junctions()) {
+			(OriginKind::Native, Junctions::X1(Junction::Parachain(id)))
+			=> Ok(Origin::from(ParachainOrigin::from(*id))),
+			_ => Err(origin),
 		}
 	}
 }
@@ -108,10 +108,11 @@ impl<
 	Origin: From<ParachainOrigin>,
 > ConvertOrigin<Origin> for SiblingParachainAsNative<ParachainOrigin, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin) {
-			(OriginKind::Native, MultiLocation::X2(Junction::Parent, Junction::Parachain(id)))
-			=> Ok(Origin::from(ParachainOrigin::from(id))),
-			(_, origin) => Err(origin),
+		match (kind, origin.junctions()) {
+			(OriginKind::Native, Junctions::X1(Junction::Parachain(id)))
+			if origin.parent_count() == 1 =>
+				Ok(Origin::from(ParachainOrigin::from(*id))),
+			_ => Err(origin),
 		}
 	}
 }
@@ -125,9 +126,10 @@ impl<
 	Origin,
 > ConvertOrigin<Origin> for RelayChainAsNative<RelayOrigin, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin) {
-			(OriginKind::Native, MultiLocation::X1(Junction::Parent)) => Ok(RelayOrigin::get()),
-			(_, origin) => Err(origin),
+		if kind == OriginKind::Native && origin.parent_count() == 1 {
+			Ok(RelayOrigin::get())
+		} else {
+			Err(origin)
 		}
 	}
 }
@@ -142,11 +144,12 @@ impl<
 	Origin::AccountId: From<[u8; 32]>,
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin) {
-			(OriginKind::Native, MultiLocation::X1(Junction::AccountId32 { id, network }))
-			if matches!(network, NetworkId::Any) || network == Network::get()
-			=> Ok(Origin::signed(id.into())),
-			(_, origin) => Err(origin),
+		match (kind, origin.junctions()) {
+			(OriginKind::Native, Junctions::X1(Junction::AccountId32 { id, network }))
+			if (matches!(network, NetworkId::Any) || network == &Network::get())
+				&& origin.parent_count() == 0
+			=> Ok(Origin::signed((*id).into())),
+			_ => Err(origin),
 		}
 	}
 }
@@ -161,13 +164,14 @@ impl<
 	Origin::AccountId: From<[u8; 20]>,
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin) {
-			(OriginKind::Native, MultiLocation::X1(Junction::AccountKey20 { key, network }))
-				if matches!(network, NetworkId::Any) || network == Network::get() =>
+		match (kind, origin.junctions()) {
+			(OriginKind::Native, Junctions::X1(Junction::AccountKey20 { key, network }))
+				if (matches!(network, NetworkId::Any) || network == &Network::get())
+					&& origin.parent_count() == 0 =>
 			{
-				Ok(Origin::signed(key.into()))
+				Ok(Origin::signed((*key).into()))
 			}
-			(_, origin) => Err(origin),
+			_ => Err(origin),
 		}
 	}
 }
@@ -189,7 +193,7 @@ impl<
 		// We institute a root fallback so root can always represent the context. This
 		// guarantees that `successful_origin` will work.
 		if o.caller() == Origin::root().caller() {
-			Ok(MultiLocation::Null)
+			Ok(MultiLocation::default())
 		} else {
 			Err(o)
 		}
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 0f04b89285d1..073d580491ce 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -22,28 +22,31 @@ use xcm_executor::{XcmExecutor, Config, traits::*};
 
 #[test]
 fn basic_setup_works() {
-	add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) });
+	add_reserve(
+		MultiLocation::new(1, Null).unwrap(),
+		AllConcreteFungible { id: MultiLocation::new(1, Null).unwrap() },
+	);
 	assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
-		&ConcreteFungible { id: X1(Parent), amount: 100 },
-		&X1(Parent),
+		&ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 },
+		&MultiLocation::new(1, Null).unwrap(),
 	));
 
-	assert_eq!(to_account(X1(Parachain(1))), Ok(1001));
-	assert_eq!(to_account(X1(Parachain(50))), Ok(1050));
-	assert_eq!(to_account(X2(Parent, Parachain(1))), Ok(2001));
-	assert_eq!(to_account(X2(Parent, Parachain(50))), Ok(2050));
-	assert_eq!(to_account(X1(AccountIndex64{index:1, network:Any})), Ok(1));
-	assert_eq!(to_account(X1(AccountIndex64{index:42, network:Any})), Ok(42));
-	assert_eq!(to_account(Null), Ok(3000));
+	assert_eq!(to_account(X1(Parachain(1)).into()), Ok(1001));
+	assert_eq!(to_account(X1(Parachain(50)).into()), Ok(1050));
+	assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(1))).unwrap()), Ok(2001));
+	assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(50))).unwrap()), Ok(2050));
+	assert_eq!(to_account(X1(AccountIndex64{index:1, network:Any}).into()), Ok(1));
+	assert_eq!(to_account(X1(AccountIndex64{index:42, network:Any}).into()), Ok(42));
+	assert_eq!(to_account(Null.into()), Ok(3000));
 }
 
 #[test]
 fn weigher_should_work() {
 	let mut message = opaque::Xcm::ReserveAssetDeposit {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: vec![ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 }],
 		effects: vec![
 			Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: vec![All], dest: Null },
+			Order::DepositAsset { assets: vec![All], dest: Null.into() },
 		],
 	}.into();
 	assert_eq!(<TestConfig as Config>::Weigher::shallow(&mut message), Ok(30));
@@ -52,13 +55,13 @@ fn weigher_should_work() {
 #[test]
 fn take_weight_credit_barrier_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
-		dest: Null,
+		assets: vec![ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 }],
+		dest: Null.into(),
 	};
 
 	let mut weight_credit = 10;
 	let r = TakeWeightCredit::should_execute(
-		&X1(Parent),
+		&MultiLocation::new(1, Null).unwrap(),
 		true,
 		&mut message,
 		10,
@@ -68,7 +71,7 @@ fn take_weight_credit_barrier_should_work() {
 	assert_eq!(weight_credit, 0);
 
 	let r = TakeWeightCredit::should_execute(
-		&X1(Parent),
+		&MultiLocation::new(1, Null).unwrap(),
 		true,
 		&mut message,
 		10,
@@ -81,14 +84,14 @@ fn take_weight_credit_barrier_should_work() {
 #[test]
 fn allow_unpaid_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
-		dest: Null,
+		assets: vec![ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 }],
+		dest: Null.into(),
 	};
 
-	AllowUnpaidFrom::set(vec![ X1(Parent) ]);
+	AllowUnpaidFrom::set(vec![ MultiLocation::new(1, Null).unwrap() ]);
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
-		&X1(Parachain(1)),
+		&X1(Parachain(1)).into(),
 		true,
 		&mut message,
 		10,
@@ -97,7 +100,7 @@ fn allow_unpaid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
-		&X1(Parent),
+		&MultiLocation::new(1, Null).unwrap(),
 		true,
 		&mut message,
 		10,
@@ -108,15 +111,15 @@ fn allow_unpaid_should_work() {
 
 #[test]
 fn allow_paid_should_work() {
-	AllowPaidFrom::set(vec![ X1(Parent) ]);
+	AllowPaidFrom::set(vec![ MultiLocation::new(1, Null).unwrap() ]);
 
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
-		dest: Null,
+		assets: vec![ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 }],
+		dest: Null.into(),
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&X1(Parachain(1)),
+		&X1(Parachain(1)).into(),
 		true,
 		&mut message,
 		10,
@@ -125,15 +128,15 @@ fn allow_paid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposit {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: vec![ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 }],
 		effects: vec![
 			Order::BuyExecution { fees: All, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: vec![All], dest: Null },
+			Order::DepositAsset { assets: vec![All], dest: Null.into() },
 		],
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&X1(Parent),
+		&MultiLocation::new(1, Null).unwrap(),
 		true,
 		&mut underpaying_message,
 		30,
@@ -142,15 +145,15 @@ fn allow_paid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let mut paying_message = opaque::Xcm::ReserveAssetDeposit {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: vec![ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 }],
 		effects: vec![
 			Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: vec![All], dest: Null },
+			Order::DepositAsset { assets: vec![All], dest: Null.into() },
 		],
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&X1(Parachain(1)),
+		&X1(Parachain(1)).into(),
 		true,
 		&mut paying_message,
 		30,
@@ -159,7 +162,7 @@ fn allow_paid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&X1(Parent),
+		&MultiLocation::new(1, Null).unwrap(),
 		true,
 		&mut paying_message,
 		30,
@@ -170,71 +173,74 @@ fn allow_paid_should_work() {
 
 #[test]
 fn paying_reserve_deposit_should_work() {
-	AllowPaidFrom::set(vec![ X1(Parent) ]);
-	add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) });
-	WeightPrice::set((X1(Parent), 1_000_000_000_000));
+	AllowPaidFrom::set(vec![ MultiLocation::new(1, Null).unwrap() ]);
+	add_reserve(
+		MultiLocation::new(1, Null).unwrap(),
+		AllConcreteFungible { id: MultiLocation::new(1, Null).unwrap() },
+	);
+	WeightPrice::set((MultiLocation::new(1, Null).unwrap(), 1_000_000_000_000));
 
-	let origin = X1(Parent);
+	let origin = MultiLocation::new(1, Null).unwrap();
 	let message = Xcm::<TestCall>::ReserveAssetDeposit {
-		assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],
+		assets: vec![ ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 } ],
 		effects: vec![
 			Order::<TestCall>::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
-			Order::<TestCall>::DepositAsset { assets: vec![ All ], dest: Null },
+			Order::<TestCall>::DepositAsset { assets: vec![ All ], dest: Null.into() },
 		],
 	};
 	let weight_limit = 50;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(30));
-	assert_eq!(assets(3000), vec![ ConcreteFungible { id: X1(Parent), amount: 70 } ]);
+	assert_eq!(assets(3000), vec![ ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 70 } ]);
 }
 
 #[test]
 fn transfer_should_work() {
 	// we'll let them have message execution for free.
-	AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]);
+	AllowUnpaidFrom::set(vec![ X1(Parachain(1)).into() ]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, ConcreteFungible { id: Null, amount: 1000 });
+	add_asset(1001, ConcreteFungible { id: Null.into(), amount: 1000 });
 	// They want to transfer 100 of them to their sibling parachain #2
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
-		X1(Parachain(1)),
+		X1(Parachain(1)).into(),
 		Xcm::TransferAsset {
-			assets: vec![ ConcreteFungible { id: Null, amount: 100 } ],
-			dest: X1(AccountIndex64{index:3, network:Any}),
+			assets: vec![ ConcreteFungible { id: Null.into(), amount: 100 } ],
+			dest: X1(AccountIndex64{index:3, network:Any}).into(),
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
-	assert_eq!(assets(3), vec![ ConcreteFungible { id: Null, amount: 100 } ]);
-	assert_eq!(assets(1001), vec![ ConcreteFungible { id: Null, amount: 900 } ]);
+	assert_eq!(assets(3), vec![ ConcreteFungible { id: Null.into(), amount: 100 } ]);
+	assert_eq!(assets(1001), vec![ ConcreteFungible { id: Null.into(), amount: 900 } ]);
 	assert_eq!(sent_xcm(), vec![]);
 }
 
 #[test]
 fn reserve_transfer_should_work() {
-	AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]);
+	AllowUnpaidFrom::set(vec![ X1(Parachain(1)).into() ]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, ConcreteFungible { id: Null, amount: 1000 });
+	add_asset(1001, ConcreteFungible { id: Null.into(), amount: 1000 });
 	// The remote account owned by gav.
-	let three = X1(AccountIndex64{index:3, network:Any});
+	let three: MultiLocation = X1(AccountIndex64{index:3, network:Any}).into();
 
 	// They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2
 	// and let them know to hand it to account #3.
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
-		X1(Parachain(1)),
+		X1(Parachain(1)).into(),
 		Xcm::TransferReserveAsset {
-			assets: vec![ ConcreteFungible { id: Null, amount: 100 } ],
-			dest: X1(Parachain(2)),
+			assets: vec![ ConcreteFungible { id: Null.into(), amount: 100 } ],
+			dest: X1(Parachain(2)).into(),
 			effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three.clone() } ],
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
 
-	assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null, amount: 100 } ]);
+	assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null.into(), amount: 100 } ]);
 	assert_eq!(sent_xcm(), vec![(
-		X1(Parachain(2)),
+		X1(Parachain(2)).into(),
 		Xcm::ReserveAssetDeposit {
-			assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],
+			assets: vec![ ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 } ],
 			effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ],
 		})
 	]);
@@ -242,9 +248,9 @@ fn reserve_transfer_should_work() {
 
 #[test]
 fn transacting_should_work() {
-	AllowUnpaidFrom::set(vec![ X1(Parent) ]);
+	AllowUnpaidFrom::set(vec![ MultiLocation::new(1, Null).unwrap() ]);
 
-	let origin = X1(Parent);
+	let origin = MultiLocation::new(1, Null).unwrap();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -257,9 +263,9 @@ fn transacting_should_work() {
 
 #[test]
 fn transacting_should_respect_max_weight_requirement() {
-	AllowUnpaidFrom::set(vec![ X1(Parent) ]);
+	AllowUnpaidFrom::set(vec![ MultiLocation::new(1, Null).unwrap() ]);
 
-	let origin = X1(Parent);
+	let origin = MultiLocation::new(1, Null).unwrap();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 40,
@@ -272,9 +278,9 @@ fn transacting_should_respect_max_weight_requirement() {
 
 #[test]
 fn transacting_should_refund_weight() {
-	AllowUnpaidFrom::set(vec![ X1(Parent) ]);
+	AllowUnpaidFrom::set(vec![ MultiLocation::new(1, Null).unwrap() ]);
 
-	let origin = X1(Parent);
+	let origin = MultiLocation::new(1, Null).unwrap();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -287,14 +293,14 @@ fn transacting_should_refund_weight() {
 
 #[test]
 fn paid_transacting_should_refund_payment_for_unused_weight() {
-	let one = X1(AccountIndex64{index:1, network:Any});
+	let one: MultiLocation = X1(AccountIndex64{index:1, network:Any}).into();
 	AllowPaidFrom::set(vec![ one.clone() ]);
-	add_asset(1, ConcreteFungible { id: X1(Parent), amount: 100 });
-	WeightPrice::set((X1(Parent), 1_000_000_000_000));
+	add_asset(1, ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 });
+	WeightPrice::set((MultiLocation::new(1, Null).unwrap(), 1_000_000_000_000));
 
 	let origin = one.clone();
 	let message = Xcm::<TestCall>::WithdrawAsset {
-		assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],	// enough for 100 units of weight.
+		assets: vec![ ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 } ],	// enough for 100 units of weight.
 		effects: vec![
 			Order::<TestCall>::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![
 				Xcm::<TestCall>::Transact {
@@ -310,17 +316,19 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let weight_limit = 100;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(50));
-	assert_eq!(assets(1), vec![ ConcreteFungible { id: X1(Parent), amount: 50 } ]);
+	assert_eq!(assets(1), vec![ ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 50 } ]);
 }
 
 #[test]
 fn prepaid_result_of_query_should_get_free_execution() {
 	let query_id = 33;
-	let origin = X1(Parent);
+	let origin = MultiLocation::new(1, Null).unwrap();
 	// We put this in manually here, but normally this would be done at the point of crafting the message.
 	expect_response(query_id, origin.clone());
 
-	let the_response = Response::Assets(vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]);
+	let the_response = Response::Assets(
+		vec![ ConcreteFungible { id: MultiLocation::new(1, Null).unwrap(), amount: 100 } ],
+	);
 	let message = Xcm::<TestCall>::QueryResponse {
 		query_id,
 		response: the_response.clone(),

From c4a2d6853f906e39ce614fca2da79d642fcfcb38 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 31 Jul 2021 08:06:50 -0700
Subject: [PATCH 014/166] Make pallet-xcm compile

---
 xcm/pallet-xcm/src/lib.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index a99d630fefe3..f390f0bb60a4 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -250,9 +250,9 @@ pub mod pallet {
 		/// Relay an XCM `message` from a given `interior` location in this context to a given `dest`
 		/// location. A null `dest` is not handled.
 		pub fn send_xcm(interior: MultiLocation, dest: MultiLocation, message: Xcm<()>) -> Result<(), XcmError> {
-			let message = match interior {
-				MultiLocation::Null => message,
-				who => Xcm::<()>::RelayedFrom { who, message: Box::new(message) },
+			let message = match interior.junctions() {
+				Junctions::Null => message,
+				_ => Xcm::<()>::RelayedFrom { who: interior, message: Box::new(message) },
 			};
 			log::trace!(target: "xcm::send_xcm", "dest: {:?}, message: {:?}", &dest, &message);
 			T::XcmRouter::send_xcm(dest, message)

From 9f64f61226aed2421bea658ce47bed88c88a6109 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 31 Jul 2021 08:50:06 -0700
Subject: [PATCH 015/166] Use MultiLocation::default()

---
 xcm/pallet-xcm/src/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index f390f0bb60a4..0bbe0bff4b4a 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -323,7 +323,7 @@ impl<O: OriginTrait + From<Origin>, F: Filter<MultiLocation>> EnsureOrigin<O> fo
 
 	#[cfg(feature = "runtime-benchmarks")]
 	fn successful_origin() -> O {
-		O::from(Origin::Xcm(MultiLocation::Null))
+		O::from(Origin::Xcm(MultiLocation::default()))
 	}
 }
 

From 15b1ec99db524a2f50b6d44078e51fb9a6f952ac Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 31 Jul 2021 10:06:54 -0700
Subject: [PATCH 016/166] Make polkadot-runtime-common compile

---
 runtime/common/src/xcm_sender.rs | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs
index eb301a53ea30..2c93884e6b3e 100644
--- a/runtime/common/src/xcm_sender.rs
+++ b/runtime/common/src/xcm_sender.rs
@@ -18,7 +18,10 @@
 
 use parity_scale_codec::Encode;
 use sp_std::marker::PhantomData;
-use xcm::opaque::{VersionedXcm, v0::{SendXcm, MultiLocation, Junction, Xcm, Result, Error}};
+use xcm::opaque::{
+	VersionedXcm,
+	v0::{SendXcm, MultiLocation, Junction, Junctions, Xcm, Result, Error},
+};
 use runtime_parachains::{configuration, dmp};
 
 /// XCM sender for relay chain. It only sends downward message.
@@ -26,18 +29,18 @@ pub struct ChildParachainRouter<T>(PhantomData<T>);
 
 impl<T: configuration::Config + dmp::Config> SendXcm for ChildParachainRouter<T> {
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {
-		match dest {
-			MultiLocation::X1(Junction::Parachain(id)) => {
+		match dest.junctions() {
+			Junctions::X1(Junction::Parachain(id)) if dest.parent_count() == 0 => {
 				// Downward message passing.
 				let config = <configuration::Pallet<T>>::config();
 				<dmp::Pallet<T>>::queue_downward_message(
 					&config,
-					id.into(),
+					(*id).into(),
 					VersionedXcm::from(msg).encode(),
 				).map_err(Into::<Error>::into)?;
 				Ok(())
 			}
-			d => Err(Error::CannotReachDestination(d, msg)),
+			_ => Err(Error::CannotReachDestination(dest, msg)),
 		}
 	}
 }

From 2370c397a640b0d784747901f8d36da7ecb1c0a4 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 06:23:46 -0700
Subject: [PATCH 017/166] Make rococo-runtime compile

---
 runtime/rococo/src/lib.rs    | 38 ++++++++++++++++-------------
 xcm/src/v0/multi_location.rs | 47 ++++++++++++++++++++++++++++++------
 2 files changed, 60 insertions(+), 25 deletions(-)

diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 790248daf644..3afe89df664d 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -584,9 +584,9 @@ impl parachains_paras::Config for Runtime {
 }
 
 parameter_types! {
-	pub const RocLocation: MultiLocation = MultiLocation::Null;
+	pub const RocLocation: MultiLocation = MultiLocation::empty();
 	pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
-	pub const Ancestry: MultiLocation = MultiLocation::Null;
+	pub const Ancestry: MultiLocation = MultiLocation::empty();
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
 
@@ -627,16 +627,16 @@ pub type XcmRouter = (
 	xcm_sender::ChildParachainRouter<Runtime>,
 );
 
-use xcm::v0::{MultiAsset, MultiAsset::AllConcreteFungible, MultiLocation::{Null, X1}, Junction::Parachain};
+use xcm::v0::{MultiAsset, MultiAsset::AllConcreteFungible, Junctions::{Null, X1}, Junction::Parachain};
 parameter_types! {
 	pub const RococoForTick: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(100)));
+		(AllConcreteFungible { id: MultiLocation::empty() }, MultiLocation::with_parachain_interior(100));
 	pub const RococoForTrick: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(110)));
+		(AllConcreteFungible { id: MultiLocation::empty() }, MultiLocation::with_parachain_interior(110));
 	pub const RococoForTrack: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(120)));
+		(AllConcreteFungible { id: MultiLocation::empty() }, MultiLocation::with_parachain_interior(120));
 	pub const RococoForStatemint: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(1001)));
+		(AllConcreteFungible { id: MultiLocation::empty() }, MultiLocation::with_parachain_interior(1001));
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<RococoForTick>,
@@ -648,10 +648,10 @@ pub type TrustedTeleporters = (
 parameter_types! {
 	pub AllowUnpaidFrom: Vec<MultiLocation> =
 		vec![
-			X1(Parachain(100)),
-			X1(Parachain(110)),
-			X1(Parachain(120)),
-			X1(Parachain(1001))
+			MultiLocation::with_parachain_interior(100),
+			MultiLocation::with_parachain_interior(110),
+			MultiLocation::with_parachain_interior(120),
+			MultiLocation::with_parachain_interior(1001),
 		];
 }
 
@@ -698,10 +698,10 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
 			MultiAsset::{All, ConcreteFungible}, Junction::{AccountId32, Plurality},
 		};
-		match origin {
+		match origin.junctions() {
 			// Root and collective are allowed to execute anything.
-			Null | X1(Plurality { .. }) => true,
-			X1(AccountId32 { .. }) => {
+			Null | X1(Plurality { .. }) if origin.parent_count() == 0 => true,
+			X1(AccountId32 { .. }) if origin.parent_count() == 0 => {
 				// An account ID trying to send a message. We ensure that it's sensible.
 				// This checks that it's of the form:
 				// WithdrawAsset {
@@ -717,16 +717,20 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 				// }
 				matches!(msg, WithdrawAsset { ref assets, ref effects }
 					if assets.len() == 1
-					&& matches!(assets[0], ConcreteFungible { id: Null, .. })
+					&& matches!(assets[0], ConcreteFungible { ref id, .. } if id.is_empty())
 					&& effects.len() == 2
 					&& matches!(effects[0], BuyExecution { .. })
-					&& matches!(effects[1], InitiateTeleport { ref assets, dest: X1(Parachain(..)), ref effects }
+					&& matches!(effects[1], InitiateTeleport { ref assets, ref dest, ref effects }
 						if assets.len() == 1
+						&& matches!(dest.junctions(), X1(Parachain(..)))
+						&& dest.parent_count() == 0
 						&& matches!(assets[0], All)
 						&& effects.len() == 2
 						&& matches!(effects[0], BuyExecution { .. })
-						&& matches!(effects[1], DepositAsset { ref assets, dest: X1(AccountId32{..}) }
+						&& matches!(effects[1], DepositAsset { ref assets, ref dest }
 							if assets.len() == 1
+							&& matches!(dest.junctions(), X1(AccountId32{..}))
+							&& dest.parent_count() == 0
 							&& matches!(assets[0], All)
 						)
 					)
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index ff2cb40c5a45..cb7f7daa2c5d 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -52,10 +52,7 @@ pub struct MultiLocation {
 
 impl Default for MultiLocation {
 	fn default() -> Self {
-		MultiLocation {
-			parents: 0,
-			interior: Junctions::Null,
-		}
+		Self::empty()
 	}
 }
 
@@ -115,6 +112,40 @@ impl MultiLocation {
 		})
 	}
 
+	/// Creates a new `MultiLocation` with 0 parents and a `Null` interior.
+	pub const fn empty() -> MultiLocation {
+		MultiLocation {
+			parents: 0,
+			interior: Junctions::Null,
+		}
+	}
+
+	/// Creates a new `MultiLocation` with the specified number of parents and a `Null` interior.
+	/// Returns an error if `parents` is greater than `MAX_MULTILOCATION_LENGTH`.
+	pub const fn with_parents(parents: u8) -> result::Result<MultiLocation, ()> {
+		if parents as usize > MAX_MULTILOCATION_LENGTH {
+			return Err(())
+		}
+		Ok(MultiLocation {
+			parents,
+			interior: Junctions::Null,
+		})
+	}
+
+	/// Creates a new `MultiLocation` with no parents and a single `Parachain` interior junction
+	/// specified by `para_id`.
+	pub const fn with_parachain_interior(para_id: u32) -> MultiLocation {
+		MultiLocation {
+			parents: 0,
+			interior: Junctions::X1(Junction::Parachain(para_id)),
+		}
+	}
+
+	/// Whether or not the `MultiLocation` has no parents and has a `Null` interior.
+	pub const fn is_empty(&self) -> bool {
+		self.parents == 0 && self.interior.len() == 0
+	}
+
 	/// Return a reference to the interior field.
 	pub fn junctions(&self) -> &Junctions {
 		&self.interior
@@ -126,12 +157,12 @@ impl MultiLocation {
 	}
 
 	/// Returns the number of `Parent` junctions at the beginning of `self`.
-	pub fn parent_count(&self) -> usize {
+	pub const fn parent_count(&self) -> usize {
 		self.parents as usize
 	}
 
 	/// Returns the number of parents and junctions in `self`.
-	pub fn len(&self) -> usize {
+	pub const fn len(&self) -> usize {
 		self.parent_count() + self.interior.len()
 	}
 
@@ -159,7 +190,7 @@ impl MultiLocation {
 	}
 
 	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
-	/// (second item in tuple) or `None` if it was empty or that `self` only contains parents.
+	/// (second item in tuple) or `None` if it was empty or if `self` only contains parents.
 	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
 		let MultiLocation { parents, interior: junctions } = self;
 		let (prefix, suffix) = junctions.split_last();
@@ -722,7 +753,7 @@ impl Junctions {
 	}
 
 	/// Returns the number of junctions in `self`.
-	pub fn len(&self) -> usize {
+	pub const fn len(&self) -> usize {
 		match &self {
 			Junctions::Null => 0,
 			Junctions::X1(..) => 1,

From 6aaa81b1541c11ff5ed39dbee66616631358aaea Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 06:26:03 -0700
Subject: [PATCH 018/166] Change return type of parent_count to u8

---
 xcm/src/v0/multi_location.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index cb7f7daa2c5d..fce98efb3c20 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -157,13 +157,13 @@ impl MultiLocation {
 	}
 
 	/// Returns the number of `Parent` junctions at the beginning of `self`.
-	pub const fn parent_count(&self) -> usize {
-		self.parents as usize
+	pub const fn parent_count(&self) -> u8 {
+		self.parents
 	}
 
 	/// Returns the number of parents and junctions in `self`.
 	pub const fn len(&self) -> usize {
-		self.parent_count() + self.interior.len()
+		self.parent_count() as usize + self.interior.len()
 	}
 
 	/// Returns first junction that is not a parent, or `None` if the location is empty or
@@ -369,7 +369,7 @@ impl MultiLocation {
 	pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> {
 		let self_parents = self.parent_count();
 		let prepend_len = (self_parents as isize - prefix.interior.len() as isize).abs() as usize;
-		if self.interior.len() + prefix.parent_count() + prepend_len > MAX_MULTILOCATION_LENGTH {
+		if self.interior.len() + prefix.parent_count() as usize + prepend_len > MAX_MULTILOCATION_LENGTH {
 			return Err(prefix)
 		}
 

From 59e59357af8a252c75576df6f60ca31b56dcce86 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 06:32:44 -0700
Subject: [PATCH 019/166] Change MAX_MULTILOCATION_LENGTH to 255

---
 xcm/src/v0/multi_location.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index fce98efb3c20..9b5f83f5cc09 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -58,7 +58,7 @@ impl Default for MultiLocation {
 
 impl Encode for MultiLocation {
 	fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
-		// 8 items max, but we cannot return an error, so we ap silently.
+		// 255 items max, but we cannot return an error, so we truncate silently.
 		let parents = self.parents.min(
 			MAX_MULTILOCATION_LENGTH.saturating_sub(self.interior.len()) as u8,
 		);
@@ -97,7 +97,7 @@ impl Decode for MultiLocation {
 }
 
 /// Maximum number of junctions a `MultiLocation` can contain.
-pub const MAX_MULTILOCATION_LENGTH: usize = 8;
+pub const MAX_MULTILOCATION_LENGTH: usize = 255;
 
 impl MultiLocation {
 	/// Creates a new `MultiLocation`, ensuring that the length of it does not exceed the maximum,
@@ -945,7 +945,7 @@ mod tests {
 
 		// cannot append to create overly long multilocation
 		let acc = AccountIndex64 { network: Any, index: 23 };
-		let mut m = MultiLocation { parents: 6, interior: X1(Parachain(42)) };
+		let mut m = MultiLocation { parents: 254, interior: X1(Parachain(42)) };
 		let suffix = MultiLocation::from(X2(PalletInstance(3), acc.clone()));
 		assert_eq!(m.append_with(suffix.clone()), Err(suffix));
 	}
@@ -957,12 +957,12 @@ mod tests {
 		assert_eq!(m, MultiLocation { parents: 1, interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) });
 
 		// cannot prepend to create overly long multilocation
-		let mut m = MultiLocation { parents: 6, interior: X1(Parachain(42)) };
+		let mut m = MultiLocation { parents: 253, interior: X1(Parachain(42)) };
 		let prefix = MultiLocation { parents: 2, interior: Null };
 		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
 
 		let prefix = MultiLocation { parents: 1, interior: Null };
 		assert_eq!(m.prepend_with(prefix), Ok(()));
-		assert_eq!(m, MultiLocation { parents: 7, interior: X1(Parachain(42)) });
+		assert_eq!(m, MultiLocation { parents: 254, interior: X1(Parachain(42)) });
 	}
 }

From 85a61a52fc2e45e7b4912299b233d3f3fac885da Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 06:48:34 -0700
Subject: [PATCH 020/166] Make kusama-runtime compile

---
 runtime/kusama/src/lib.rs | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index 3d0ab1ebd099..6171a8c60df3 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -54,7 +54,7 @@ use runtime_parachains::scheduler as parachains_scheduler;
 use runtime_parachains::reward_points as parachains_reward_points;
 use runtime_parachains::runtime_api_impl::v1 as parachains_runtime_api_impl;
 
-use xcm::v0::{MultiLocation::{self, Null, X1}, NetworkId, BodyId, Xcm, Junction::Parachain};
+use xcm::v0::{MultiLocation, Junctions::{Null, X1}, NetworkId, BodyId, Xcm, Junction::Parachain};
 use xcm::v0::MultiAsset::{self, AllConcreteFungible};
 use xcm_builder::{
 	AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter,
@@ -1198,12 +1198,12 @@ parameter_types! {
 	/// The location of the KSM token, from the context of this chain. Since this token is native to this
 	/// chain, we make it synonymous with it and thus it is the `Null` location, which means "equivalent to
 	/// the context".
-	pub const KsmLocation: MultiLocation = MultiLocation::Null;
+	pub const KsmLocation: MultiLocation = MultiLocation::empty();
 	/// The Kusama network ID. This is named.
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	/// Our XCM location ancestry - i.e. what, if anything, `Parent` means evaluated in our context. Since
 	/// Kusama is a top-level relay-chain, there is no ancestry.
-	pub const Ancestry: MultiLocation = MultiLocation::Null;
+	pub const Ancestry: MultiLocation = MultiLocation::empty();
 	/// The check account, which holds any native assets that have been teleported out and not back in (yet).
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
@@ -1261,7 +1261,7 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const KusamaForStatemint: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(1000)));
+		(AllConcreteFungible { id: MultiLocation::empty() }, MultiLocation::with_parachain_interior(1000));
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<KusamaForStatemint>,
@@ -1314,10 +1314,10 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
 			MultiAsset::{All, ConcreteFungible}, Junction::{AccountId32, Plurality},
 		};
-		match origin {
+		match origin.junctions() {
 			// Root and council are are allowed to execute anything.
-			Null | X1(Plurality { .. }) => true,
-			X1(AccountId32 { .. }) => {
+			Null | X1(Plurality { .. }) if origin.parent_count() == 0 => true,
+			X1(AccountId32 { .. }) if origin.parent_count() == 0 => {
 				// An account ID trying to send a message. We ensure that it's sensible.
 				// This checks that it's of the form:
 				// WithdrawAsset {
@@ -1333,17 +1333,21 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 				// }
 				matches!(msg, WithdrawAsset { ref assets, ref effects }
 					if assets.len() == 1
-					&& matches!(assets[0], ConcreteFungible { id: Null, .. })
+					&& matches!(assets[0], ConcreteFungible { ref id, .. } if id.is_empty())
 					&& effects.len() == 2
 					&& matches!(effects[0], BuyExecution { .. })
-					&& matches!(effects[1], InitiateTeleport { ref assets, dest: X1(Parachain(..)), ref effects }
+					&& matches!(effects[1], InitiateTeleport { ref assets, ref dest, ref effects }
 						if assets.len() == 1
+						&& matches!(dest.junctions(), X1(Parachain(..)))
+						&& dest.parent_count() == 0
 						&& matches!(assets[0], All)
 						&& effects.len() == 2
 						&& matches!(effects[0], BuyExecution { .. })
-						&& matches!(effects[1], DepositAsset { ref assets, dest: X1(AccountId32{..}) }
+						&& matches!(effects[1], DepositAsset { ref assets, ref dest }
 							if assets.len() == 1
 							&& matches!(assets[0], All)
+							&& dest.parent_count() == 0
+							&& matches!(dest.junctions(), X1(AccountId32{..}))
 						)
 					)
 				)

From dba0ed9479052646126ad64152dae8c396455035 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 06:50:03 -0700
Subject: [PATCH 021/166] Fix logic in pallet-xcm

---
 xcm/pallet-xcm/src/lib.rs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 0bbe0bff4b4a..b13256639032 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -250,9 +250,10 @@ pub mod pallet {
 		/// Relay an XCM `message` from a given `interior` location in this context to a given `dest`
 		/// location. A null `dest` is not handled.
 		pub fn send_xcm(interior: MultiLocation, dest: MultiLocation, message: Xcm<()>) -> Result<(), XcmError> {
-			let message = match interior.junctions() {
-				Junctions::Null => message,
-				_ => Xcm::<()>::RelayedFrom { who: interior, message: Box::new(message) },
+			let message = if interior.is_empty() {
+				message
+			} else {
+				Xcm::<()>::RelayedFrom { who: interior, message: Box::new(message) }
 			};
 			log::trace!(target: "xcm::send_xcm", "dest: {:?}, message: {:?}", &dest, &message);
 			T::XcmRouter::send_xcm(dest, message)

From e1ec296e2afc4d7c9710e2105ae339417fb352fe Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 06:50:51 -0700
Subject: [PATCH 022/166] Use MultiLocation::empty()

---
 xcm/pallet-xcm/src/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index b13256639032..79dd9fece8b5 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -324,7 +324,7 @@ impl<O: OriginTrait + From<Origin>, F: Filter<MultiLocation>> EnsureOrigin<O> fo
 
 	#[cfg(feature = "runtime-benchmarks")]
 	fn successful_origin() -> O {
-		O::from(Origin::Xcm(MultiLocation::default()))
+		O::from(Origin::Xcm(MultiLocation::empty()))
 	}
 }
 

From 980763944272ef52d7862d1ac5a0156cbf54a735 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 06:55:57 -0700
Subject: [PATCH 023/166] Fix logic in location_conversion

---
 xcm/xcm-builder/src/location_conversion.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 7c6e9743fbcc..60bfde4da9fe 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -43,7 +43,7 @@ impl<
 	AccountId: Default + Eq + Clone,
 > Convert<MultiLocation, AccountId> for ParentIsDefault<AccountId> {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-		if location.borrow().parent_count() == 1 {
+		if location.borrow().parent_count() == 1 && location.borrow().junctions().len() == 0 {
 			Ok(AccountId::default())
 		} else {
 			Err(())
@@ -52,7 +52,7 @@ impl<
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if who.borrow() == &AccountId::default() {
-			Ok(MultiLocation::new(1, Junctions::Null).expect("well-formed MultiLocation; qed"))
+			Ok(MultiLocation::with_parents(1).expect("well-formed MultiLocation; qed"))
 		} else {
 			Err(())
 		}

From 57bd83ad534132c3c3374f13cc4d787da60687cd Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 07:02:06 -0700
Subject: [PATCH 024/166] Fix logic in origin_conversion.rs

---
 xcm/xcm-builder/src/origin_conversion.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index e675a48274ba..76782c6515a0 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -46,7 +46,7 @@ impl<
 	Origin: OriginTrait,
 > ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		if kind == OriginKind::Superuser && origin.parent_count() == 1 {
+		if kind == OriginKind::Superuser && origin.parent_count() == 1 && origin.junctions().len() == 0 {
 			Ok(Origin::root())
 		} else {
 			Err(origin)
@@ -126,7 +126,7 @@ impl<
 	Origin,
 > ConvertOrigin<Origin> for RelayChainAsNative<RelayOrigin, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		if kind == OriginKind::Native && origin.parent_count() == 1 {
+		if kind == OriginKind::Native && origin.parent_count() == 1 && origin.junctions().len() == 0 {
 			Ok(RelayOrigin::get())
 		} else {
 			Err(origin)
@@ -193,7 +193,7 @@ impl<
 		// We institute a root fallback so root can always represent the context. This
 		// guarantees that `successful_origin` will work.
 		if o.caller() == Origin::root().caller() {
-			Ok(MultiLocation::default())
+			Ok(MultiLocation::empty())
 		} else {
 			Err(o)
 		}

From 5a4dc4f76b7daa31e4257ad5924cf74c78e717ef Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 07:42:01 -0700
Subject: [PATCH 025/166] Make westend-runtime compile

---
 runtime/westend/src/lib.rs | 24 ++++++++++++++----------
 1 file changed, 14 insertions(+), 10 deletions(-)

diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index cdc849a10429..506e57f84584 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -53,7 +53,7 @@ use runtime_parachains::scheduler as parachains_scheduler;
 use runtime_parachains::reward_points as parachains_reward_points;
 use runtime_parachains::runtime_api_impl::v1 as parachains_runtime_api_impl;
 
-use xcm::v0::{MultiLocation::{self, Null, X1}, NetworkId, Xcm, Junction::Parachain};
+use xcm::v0::{MultiLocation, Junctions::{Null, X1}, NetworkId, Xcm, Junction::Parachain};
 use xcm::v0::MultiAsset::{self, AllConcreteFungible};
 use xcm_executor::XcmExecutor;
 use xcm_builder::{
@@ -863,8 +863,8 @@ impl auctions::Config for Runtime {
 }
 
 parameter_types! {
-	pub const WndLocation: MultiLocation = MultiLocation::Null;
-	pub const Ancestry: MultiLocation = MultiLocation::Null;
+	pub const WndLocation: MultiLocation = MultiLocation::empty();
+	pub const Ancestry: MultiLocation = MultiLocation::empty();
 	pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
@@ -908,7 +908,7 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const WestendForWestmint: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(1000)));
+		(AllConcreteFungible { id: MultiLocation::empty() }, MultiLocation::with_parachain_interior(1000));
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<WestendForWestmint>,
@@ -953,10 +953,10 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
 			MultiAsset::{All, ConcreteFungible}, Junction::AccountId32,
 		};
-		match origin {
+		match origin.junctions() {
 			// Root is allowed to execute anything.
-			Null => true,
-			X1(AccountId32 { .. }) => {
+			Null if origin.parent_count() == 0 => true,
+			X1(AccountId32 { .. }) if origin.parent_count() == 0 => {
 				// An account ID trying to send a message. We ensure that it's sensible.
 				// This checks that it's of the form:
 				// WithdrawAsset {
@@ -972,17 +972,21 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 				// }
 				matches!(msg, WithdrawAsset { ref assets, ref effects }
 					if assets.len() == 1
-					&& matches!(assets[0], ConcreteFungible { id: Null, .. })
+					&& matches!(assets[0], ConcreteFungible { ref id, .. } if id.is_empty())
 					&& effects.len() == 2
 					&& matches!(effects[0], BuyExecution { .. })
-					&& matches!(effects[1], InitiateTeleport { ref assets, dest: X1(Parachain(..)), ref effects }
+					&& matches!(effects[1], InitiateTeleport { ref assets, ref dest, ref effects }
 						if assets.len() == 1
 						&& matches!(assets[0], All)
+						&& dest.parent_count() == 0
+						&& matches!(dest.junctions(), X1(Parachain(..)))
 						&& effects.len() == 2
 						&& matches!(effects[0], BuyExecution { .. })
-						&& matches!(effects[1], DepositAsset { ref assets, dest: X1(AccountId32{..}) }
+						&& matches!(effects[1], DepositAsset { ref assets, ref dest }
 							if assets.len() == 1
 							&& matches!(assets[0], All)
+							&& dest.parent_count() == 0
+							&& matches!(dest.junctions(), X1(AccountId32{..}))
 						)
 					)
 				)

From f313fc4fc7cd91390c809c2ac709c59148d854d8 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 08:39:51 -0700
Subject: [PATCH 026/166] Rename prefixes and suffixes variables

---
 xcm/src/v0/multi_location.rs | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 9b5f83f5cc09..a76bae8f1dbc 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -181,24 +181,24 @@ impl MultiLocation {
 	/// and the first element (second item in tuple) or `None` if it was empty.
 	pub fn split_first_non_parent(self) -> (MultiLocation, Option<Junction>) {
 		let MultiLocation { parents, interior: junctions } = self;
-		let (prefix, suffix) = junctions.split_first();
+		let (suffix, first) = junctions.split_first();
 		let multilocation = MultiLocation {
 			parents,
-			interior: prefix,
+			interior: suffix,
 		};
-		(multilocation, suffix)
+		(multilocation, first)
 	}
 
 	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
 	/// (second item in tuple) or `None` if it was empty or if `self` only contains parents.
 	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
 		let MultiLocation { parents, interior: junctions } = self;
-		let (prefix, suffix) = junctions.split_last();
+		let (prefix, last) = junctions.split_last();
 		let multilocation = MultiLocation {
 			parents,
 			interior: prefix,
 		};
-		(multilocation, suffix)
+		(multilocation, last)
 	}
 
 	/// Bumps the parent count up by 1. Returns `Err` in case of overflow.

From 8cdf6c1ca17d169adde01f6b910fc3e70b407c85 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 08:41:27 -0700
Subject: [PATCH 027/166] Rename non_parent to interior

---
 xcm/src/v0/multi_location.rs | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index a76bae8f1dbc..1ad6f378535e 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -210,8 +210,8 @@ impl MultiLocation {
 		Ok(())
 	}
 
-	/// Mutates `self`, suffixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
-	pub fn push_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
+	/// Mutates `self`, suffixing its interior junctions with `new`. Returns `Err` in case of overflow.
+	pub fn push_interior(&mut self, new: Junction) -> result::Result<(), ()> {
 		let mut n = Junctions::Null;
 		mem::swap(&mut self.interior, &mut n);
 		match n.pushed_with(new) {
@@ -220,8 +220,8 @@ impl MultiLocation {
 		}
 	}
 
-	/// Mutates `self`, prefixing its non-parent junctions with `new`. Returns `Err` in case of overflow.
-	pub fn push_front_non_parent(&mut self, new: Junction) -> result::Result<(), ()> {
+	/// Mutates `self`, prefixing its interior junctions with `new`. Returns `Err` in case of overflow.
+	pub fn push_front_interior(&mut self, new: Junction) -> result::Result<(), ()> {
 		let mut n = Junctions::Null;
 		mem::swap(&mut self.interior, &mut n);
 		match n.pushed_front_with(new) {
@@ -244,7 +244,7 @@ impl MultiLocation {
 
 	/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with the original value of
 	/// `self` in case of overflow.
-	pub fn pushed_with_non_parent(self, new: Junction) -> result::Result<Self, Self> {
+	pub fn pushed_with_interior(self, new: Junction) -> result::Result<Self, Self> {
 		if self.len() >= MAX_MULTILOCATION_LENGTH {
 			return Err(self)
 		}
@@ -256,7 +256,7 @@ impl MultiLocation {
 
 	/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
 	/// `self` in case of overflow.
-	pub fn pushed_front_with_non_parent(self, new: Junction) -> result::Result<Self, Self> {
+	pub fn pushed_front_with_interior(self, new: Junction) -> result::Result<Self, Self> {
 		if self.len() >= MAX_MULTILOCATION_LENGTH {
 			return Err(self)
 		}
@@ -291,13 +291,13 @@ impl MultiLocation {
 		self.parents = self.parents.saturating_sub(1);
 	}
 
-	/// Removes the first non-parent element from `self`, returning it
+	/// Removes the first interior junction from `self`, returning it
 	/// (or `None` if it was empty or if `self` contains only parents).
-	pub fn take_first_non_parent(&mut self) -> Option<Junction> {
+	pub fn take_first_interior(&mut self) -> Option<Junction> {
 		self.interior.take_first()
 	}
 
-	/// Removes the last element from `junctions`, returning it (or `None` if it was empty or if
+	/// Removes the last element from `interior`, returning it (or `None` if it was empty or if
 	/// `self` only contains parents).
 	pub fn take_last(&mut self) -> Option<Junction> {
 		self.interior.take_last()
@@ -386,7 +386,7 @@ impl MultiLocation {
 
 		self.parents = final_parent_count;
 		for j in prefix.interior.into_iter_rev() {
-			self.push_front_non_parent(j).expect(
+			self.push_front_interior(j).expect(
 				"self junctions len + prefix parent count + prepend len is less than max length; qed"
 			);
 		}

From 595621635d25355a2ce10826b51807fe48c976c8 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 09:36:59 -0700
Subject: [PATCH 028/166] Rename non_parent to interior

---
 xcm/xcm-builder/src/fungibles_adapter.rs   | 2 +-
 xcm/xcm-builder/src/location_conversion.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs
index c39b4aa4eae1..99807f2098f8 100644
--- a/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -50,7 +50,7 @@ impl<
 	fn reverse_ref(what: impl Borrow<AssetId>) -> result::Result<MultiLocation, ()> {
 		let mut location = Prefix::get();
 		let id = ConvertAssetId::reverse_ref(what)?;
-		location.push_non_parent(Junction::GeneralIndex { id })?;
+		location.push_interior(Junction::GeneralIndex { id })?;
 		Ok(location)
 	}
 }
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 60bfde4da9fe..d3528eb275ae 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -198,7 +198,7 @@ impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry>
 		let mut junctions = Junctions::Null;
 		for _ in 0..location.parent_count() {
 			junctions = junctions.pushed_with(
-				ancestry.take_first_non_parent().unwrap_or(Junction::OnlyChild),
+				ancestry.take_first_interior().unwrap_or(Junction::OnlyChild),
 			)
 			.expect("ancestry is well-formed and has less than 8 non-parent junctions; qed");
 		}

From 46aea44a5056b7b7762f8382adb96ffbb38ebb5d Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 09:37:38 -0700
Subject: [PATCH 029/166] Add test for encode/decode roundtrip and fix decode
 algorithm

---
 xcm/src/v0/junction.rs       |  8 ++++++++
 xcm/src/v0/multi_location.rs | 24 ++++++++++++++++++++++--
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/xcm/src/v0/junction.rs b/xcm/src/v0/junction.rs
index d26cecf08b21..3aa98126b639 100644
--- a/xcm/src/v0/junction.rs
+++ b/xcm/src/v0/junction.rs
@@ -100,40 +100,48 @@ pub enum Junction {
 	/// the context.
 	///
 	/// Generally used when the context is a Substrate-based chain.
+	#[codec(index = 2)]
 	AccountId32 { network: NetworkId, id: [u8; 32] },
 	/// An 8-byte index for an account of a specific network that is respected as a sovereign endpoint within
 	/// the context.
 	///
 	/// May be used when the context is a Frame-based chain and includes e.g. an indices pallet.
+	#[codec(index = 3)]
 	AccountIndex64 { network: NetworkId, #[codec(compact)] index: u64 },
 	/// A 20-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
 	/// the context.
 	///
 	/// May be used when the context is an Ethereum or Bitcoin chain or smart-contract.
+	#[codec(index = 4)]
 	AccountKey20 { network: NetworkId, key: [u8; 20] },
 	/// An instanced, indexed pallet that forms a constituent part of the context.
 	///
 	/// Generally used when the context is a Frame-based chain.
+	#[codec(index = 5)]
 	PalletInstance(u8),
 	/// A non-descript index within the context location.
 	///
 	/// Usage will vary widely owing to its generality.
 	///
 	/// NOTE: Try to avoid using this and instead use a more specific item.
+	#[codec(index = 6)]
 	GeneralIndex { #[codec(compact)] id: u128 },
 	/// A nondescript datum acting as a key within the context location.
 	///
 	/// Usage will vary widely owing to its generality.
 	///
 	/// NOTE: Try to avoid using this and instead use a more specific item.
+	#[codec(index = 7)]
 	GeneralKey(Vec<u8>),
 	/// The unambiguous child.
 	///
 	/// Not currently used except as a fallback when deriving ancestry.
+	#[codec(index = 8)]
 	OnlyChild,
 	/// A pluralistic body existing within consensus.
 	///
 	/// Typical to be used to represent a governance origin of a chain, but could in principle be used to represent
 	/// things such as multisigs also.
+	#[codec(index = 9)]
 	Plurality { id: BodyId, part: BodyPart },
 }
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 1ad6f378535e..c44381713e83 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -88,8 +88,18 @@ impl Decode for MultiLocation {
 				}
 				parents = parents.saturating_add(1);
 			} else {
-				interior = interior.pushed_with(Junction::decode(&mut &[b][..])?)
-					.map_err(|_| parity_scale_codec::Error::from("Interior too long"))?;
+				let mut bytes = [b].to_vec();
+				loop {
+					if let Ok(junction) = Junction::decode(&mut &bytes[..]) {
+						interior = interior.pushed_with(junction)
+							.map_err(|_| parity_scale_codec::Error::from("Interior too long"))?;
+						break;
+					} else {
+						// a single byte may not be enough to decode a `Junction`, so keep reading
+						// the next byte until a `Junction` can successfully be decoded
+						bytes.push(input.read_byte()?);
+					}
+				}
 			}
 		}
 		Ok(MultiLocation { parents, interior })
@@ -922,9 +932,19 @@ impl TryFrom<VersionedMultiLocation> for MultiLocation {
 
 #[cfg(test)]
 mod tests {
+	use parity_scale_codec::{Decode, Encode};
 	use super::{Junctions::*, MultiLocation};
 	use crate::opaque::v0::{Junction::*, NetworkId::Any};
 
+	#[test]
+	fn encode_and_decode_works() {
+		let m = MultiLocation { parents: 1, interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };
+		let encoded = m.encode();
+		assert_eq!(encoded, [3, 0, 1, 168, 3, 0, 92].to_vec());
+		let decoded = MultiLocation::decode(&mut &encoded[..]);
+		assert_eq!(decoded, Ok(m));
+	}
+
 	#[test]
 	fn match_and_split_works() {
 		let m = MultiLocation { parents: 1, interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }) };

From 5445d0675c6fabbed58ef02e6db55b01ed81449a Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sun, 1 Aug 2021 20:00:31 +0200
Subject: [PATCH 030/166] API changes making their way throughout

---
 runtime/kusama/src/lib.rs                     |  51 +--
 runtime/rococo/src/lib.rs                     |  66 +---
 runtime/westend/src/lib.rs                    |  57 +--
 xcm/pallet-xcm/src/lib.rs                     |  20 +-
 xcm/src/v0/mod.rs                             |  22 +-
 xcm/src/v0/multi_asset.rs                     | 337 ------------------
 xcm/src/v0/multiasset.rs                      | 171 ++-------
 xcm/src/v0/order.rs                           |   8 +-
 xcm/src/v0/traits.rs                          |   2 +-
 xcm/xcm-builder/src/barriers.rs               |   8 +-
 xcm/xcm-builder/src/filter_asset_location.rs  |   4 +-
 xcm/xcm-builder/src/tests.rs                  |  10 +-
 xcm/xcm-builder/src/weight.rs                 |   4 +-
 xcm/xcm-executor/src/assets.rs                |  13 +-
 xcm/xcm-executor/src/lib.rs                   |  12 +-
 xcm/xcm-executor/src/traits/transact_asset.rs |   2 +-
 16 files changed, 88 insertions(+), 699 deletions(-)
 delete mode 100644 xcm/src/v0/multi_asset.rs

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index 3d0ab1ebd099..8b307d392843 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1307,61 +1307,14 @@ pub type LocalOriginToLocation = (
 	SignedToAccountId32<Origin, AccountId, KusamaNetwork>,
 );
 
-pub struct OnlyWithdrawTeleportForAccounts;
-impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdrawTeleportForAccounts {
-	fn contains((ref origin, ref msg): &(MultiLocation, Xcm<Call>)) -> bool {
-		use xcm::v0::{
-			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
-			MultiAsset::{All, ConcreteFungible}, Junction::{AccountId32, Plurality},
-		};
-		match origin {
-			// Root and council are are allowed to execute anything.
-			Null | X1(Plurality { .. }) => true,
-			X1(AccountId32 { .. }) => {
-				// An account ID trying to send a message. We ensure that it's sensible.
-				// This checks that it's of the form:
-				// WithdrawAsset {
-				//   assets: [ ConcreteFungible { id: Null } ],
-				//   effects: [ BuyExecution, InitiateTeleport {
-				//     assets: All,
-				//     dest: Parachain,
-				//     effects: [ BuyExecution, DepositAssets {
-				//       assets: All,
-				//       dest: AccountId32,
-				//     } ]
-				//   } ]
-				// }
-				matches!(msg, WithdrawAsset { ref assets, ref effects }
-					if assets.len() == 1
-					&& matches!(assets[0], ConcreteFungible { id: Null, .. })
-					&& effects.len() == 2
-					&& matches!(effects[0], BuyExecution { .. })
-					&& matches!(effects[1], InitiateTeleport { ref assets, dest: X1(Parachain(..)), ref effects }
-						if assets.len() == 1
-						&& matches!(assets[0], All)
-						&& effects.len() == 2
-						&& matches!(effects[0], BuyExecution { .. })
-						&& matches!(effects[1], DepositAsset { ref assets, dest: X1(AccountId32{..}) }
-							if assets.len() == 1
-							&& matches!(assets[0], All)
-						)
-					)
-				)
-			}
-			// Nobody else is allowed to execute anything.
-			_ => false,
-		}
-	}
-}
-
 impl pallet_xcm::Config for Runtime {
 	type Event = Event;
 	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
 	type XcmRouter = XcmRouter;
 	// Anyone can execute XCM messages locally...
 	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
-	// ...but they must match our filter, which requires them to be a simple withdraw + teleport.
-	type XcmExecuteFilter = OnlyWithdrawTeleportForAccounts;
+	// ...but they must match our filter, which rejects all.
+	type XcmExecuteFilter = ();
 	type XcmExecutor = XcmExecutor<XcmConfig>;
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 790248daf644..7000c291a1ff 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -627,16 +627,13 @@ pub type XcmRouter = (
 	xcm_sender::ChildParachainRouter<Runtime>,
 );
 
-use xcm::v0::{MultiAsset, MultiAsset::AllConcreteFungible, MultiLocation::{Null, X1}, Junction::Parachain};
+use xcm::v0::prelude::*;
 parameter_types! {
-	pub const RococoForTick: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(100)));
-	pub const RococoForTrick: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(110)));
-	pub const RococoForTrack: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(120)));
-	pub const RococoForStatemint: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(1001)));
+	pub const Rococo: MultiAssetFilter = Wild(AllOf(Concrete(RocLocation::get()), WildFungible));
+	pub const RococoForTick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(100)));
+	pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(110)));
+	pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(120)));
+	pub const RococoForStatemint: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(1001)));
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<RococoForTick>,
@@ -691,61 +688,14 @@ pub type LocalOriginToLocation = (
 	SignedToAccountId32<Origin, AccountId, RococoNetwork>,
 );
 
-pub struct OnlyWithdrawTeleportForAccounts;
-impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdrawTeleportForAccounts {
-	fn contains((ref origin, ref msg): &(MultiLocation, Xcm<Call>)) -> bool {
-		use xcm::v0::{
-			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
-			MultiAsset::{All, ConcreteFungible}, Junction::{AccountId32, Plurality},
-		};
-		match origin {
-			// Root and collective are allowed to execute anything.
-			Null | X1(Plurality { .. }) => true,
-			X1(AccountId32 { .. }) => {
-				// An account ID trying to send a message. We ensure that it's sensible.
-				// This checks that it's of the form:
-				// WithdrawAsset {
-				//   assets: [ ConcreteFungible { id: Null } ],
-				//   effects: [ BuyExecution, InitiateTeleport {
-				//     assets: All,
-				//     dest: Parachain,
-				//     effects: [ BuyExecution, DepositAssets {
-				//       assets: All,
-				//       dest: AccountId32,
-				//     } ]
-				//   } ]
-				// }
-				matches!(msg, WithdrawAsset { ref assets, ref effects }
-					if assets.len() == 1
-					&& matches!(assets[0], ConcreteFungible { id: Null, .. })
-					&& effects.len() == 2
-					&& matches!(effects[0], BuyExecution { .. })
-					&& matches!(effects[1], InitiateTeleport { ref assets, dest: X1(Parachain(..)), ref effects }
-						if assets.len() == 1
-						&& matches!(assets[0], All)
-						&& effects.len() == 2
-						&& matches!(effects[0], BuyExecution { .. })
-						&& matches!(effects[1], DepositAsset { ref assets, dest: X1(AccountId32{..}) }
-							if assets.len() == 1
-							&& matches!(assets[0], All)
-						)
-					)
-				)
-			}
-			// Nobody else is allowed to execute anything.
-			_ => false,
-		}
-	}
-}
-
 impl pallet_xcm::Config for Runtime {
 	type Event = Event;
 	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
 	type XcmRouter = XcmRouter;
 	// Anyone can execute XCM messages locally...
 	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
-	// ...but they must match our filter, which requires them to be a simple withdraw + teleport.
-	type XcmExecuteFilter = OnlyWithdrawTeleportForAccounts;
+	// ...but they must match our filter, which right now rejects everything.
+	type XcmExecuteFilter = ();
 	type XcmExecutor = XcmExecutor<XcmConfig>;
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index cdc849a10429..1e0f16918a72 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -53,8 +53,7 @@ use runtime_parachains::scheduler as parachains_scheduler;
 use runtime_parachains::reward_points as parachains_reward_points;
 use runtime_parachains::runtime_api_impl::v1 as parachains_runtime_api_impl;
 
-use xcm::v0::{MultiLocation::{self, Null, X1}, NetworkId, Xcm, Junction::Parachain};
-use xcm::v0::MultiAsset::{self, AllConcreteFungible};
+use xcm::v0::prelude::*;
 use xcm_executor::XcmExecutor;
 use xcm_builder::{
 	AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter,
@@ -907,8 +906,8 @@ pub type XcmRouter = (
 );
 
 parameter_types! {
-	pub const WestendForWestmint: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(1000)));
+	pub const WestendForWestmint: (MultiAssetFilter, MultiLocation) =
+		(Wild(AllOf(WildFungible, Concrete(WndLocation::get()))), X1(Parachain(1000)));
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<WestendForWestmint>,
@@ -946,52 +945,6 @@ pub type LocalOriginToLocation = (
 	SignedToAccountId32<Origin, AccountId, WestendNetwork>,
 );
 
-pub struct OnlyWithdrawTeleportForAccounts;
-impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdrawTeleportForAccounts {
-	fn contains((ref origin, ref msg): &(MultiLocation, Xcm<Call>)) -> bool {
-		use xcm::v0::{
-			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
-			MultiAsset::{All, ConcreteFungible}, Junction::AccountId32,
-		};
-		match origin {
-			// Root is allowed to execute anything.
-			Null => true,
-			X1(AccountId32 { .. }) => {
-				// An account ID trying to send a message. We ensure that it's sensible.
-				// This checks that it's of the form:
-				// WithdrawAsset {
-				//   assets: [ ConcreteFungible { id: Null } ],
-				//   effects: [ BuyExecution, InitiateTeleport {
-				//     assets: All,
-				//     dest: Parachain,
-				//     effects: [ BuyExecution, DepositAssets {
-				//       assets: All,
-				//       dest: AccountId32,
-				//     } ]
-				//   } ]
-				// }
-				matches!(msg, WithdrawAsset { ref assets, ref effects }
-					if assets.len() == 1
-					&& matches!(assets[0], ConcreteFungible { id: Null, .. })
-					&& effects.len() == 2
-					&& matches!(effects[0], BuyExecution { .. })
-					&& matches!(effects[1], InitiateTeleport { ref assets, dest: X1(Parachain(..)), ref effects }
-						if assets.len() == 1
-						&& matches!(assets[0], All)
-						&& effects.len() == 2
-						&& matches!(effects[0], BuyExecution { .. })
-						&& matches!(effects[1], DepositAsset { ref assets, dest: X1(AccountId32{..}) }
-							if assets.len() == 1
-							&& matches!(assets[0], All)
-						)
-					)
-				)
-			}
-			// Nobody else is allowed to execute anything.
-			_ => false,
-		}
-	}
-}
 
 impl pallet_xcm::Config for Runtime {
 	type Event = Event;
@@ -999,8 +952,8 @@ impl pallet_xcm::Config for Runtime {
 	type XcmRouter = XcmRouter;
 	// Anyone can execute XCM messages locally...
 	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
-	// ...but they must match our filter, which requires them to be a simple withdraw + teleport.
-	type XcmExecuteFilter = OnlyWithdrawTeleportForAccounts;
+	// ...but they must match our filter, which rejects everything.
+	type XcmExecuteFilter = ();
 	type XcmExecutor = XcmExecutor<XcmConfig>;
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index a99d630fefe3..77c004b58844 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -123,7 +123,7 @@ pub mod pallet {
 			let mut message = Xcm::WithdrawAsset {
 				assets: assets.clone(),
 				effects: sp_std::vec![ InitiateTeleport {
-					assets: sp_std::vec![ All ],
+					assets: Wild(All),
 					dest: dest.clone(),
 					effects: sp_std::vec![],
 				} ]
@@ -134,18 +134,19 @@ pub mod pallet {
 			origin: OriginFor<T>,
 			dest: MultiLocation,
 			beneficiary: MultiLocation,
-			assets: Vec<MultiAsset>,
+			assets: MultiAssets,
 			dest_weight: Weight,
 		) -> DispatchResult {
 			let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
-			let value = (origin_location, assets);
+			let value = (origin_location, assets.drain());
 			ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
 			let (origin_location, assets) = value;
+			let assets = assets.into();
 			let mut message = Xcm::WithdrawAsset {
 				assets,
 				effects: vec![
 					InitiateTeleport {
-						assets: vec![ All ],
+						assets: Wild(All),
 						dest,
 						effects: vec![
 							BuyExecution {
@@ -156,7 +157,7 @@ pub mod pallet {
 								halt_on_error: false,
 								xcm: vec![],
 							},
-							DepositAsset { assets: vec![ All ], dest: beneficiary },
+							DepositAsset { assets: Wild(All), dest: beneficiary },
 						],
 					},
 				],
@@ -179,7 +180,7 @@ pub mod pallet {
 		/// - `assets`: The assets to be withdrawn. This should include the assets used to pay the fee on the
 		///   `dest` side.
 		/// - `dest_weight`: Equal to the total weight on `dest` of the XCM message
-		///   `ReserveAssetDeposit { assets, effects: [ BuyExecution{..}, DepositAsset{..} ] }`.
+		///   `ReserveAssetDeposited { assets, effects: [ BuyExecution{..}, DepositAsset{..} ] }`.
 		#[pallet::weight({
 			let mut message = Xcm::TransferReserveAsset {
 				assets: assets.clone(),
@@ -192,13 +193,14 @@ pub mod pallet {
 			origin: OriginFor<T>,
 			dest: MultiLocation,
 			beneficiary: MultiLocation,
-			assets: Vec<MultiAsset>,
+			assets: MultiAssets,
 			dest_weight: Weight,
 		) -> DispatchResult {
 			let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
-			let value = (origin_location, assets);
+			let value = (origin_location, assets.drain());
 			ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
 			let (origin_location, assets) = value;
+			let assets = assets.into();
 			let mut message = Xcm::TransferReserveAsset {
 				assets,
 				dest,
@@ -211,7 +213,7 @@ pub mod pallet {
 						halt_on_error: false,
 						xcm: vec![],
 					},
-					DepositAsset { assets: vec![ All ], dest: beneficiary },
+					DepositAsset { assets: Wild(All), dest: beneficiary },
 				],
 			};
 			let weight = T::Weigher::weight(&mut message)
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 2d4c192d3ec0..38d940a16a19 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -23,7 +23,6 @@ use parity_scale_codec::{self, Encode, Decode};
 use crate::{DoubleEncoded, VersionedXcm};
 
 mod junction;
-mod multi_asset;
 mod multi_location;
 mod order;
 mod traits;
@@ -41,7 +40,8 @@ pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
 pub mod prelude {
 	pub use super::junction::{Junction::*, NetworkId, BodyId, BodyPart};
 	pub use super::multiasset::{
-		AssetId, MultiAssets, MultiAsset,
+		MultiAssets, MultiAsset,
+		AssetId::{self, *},
 		AssetInstance::{self, *},
 		MultiAssetFilter::{self, *},
 		Fungibility::{self, *},
@@ -104,7 +104,7 @@ pub enum Xcm<Call> {
 	/// orders (`effects`).
 	///
 	/// - `assets`: The asset(s) to be withdrawn into holding.
-	/// - `effects`: The order(s) to execute on the holding account.
+	/// - `effects`: The order(s) to execute on the holding register.
 	///
 	/// Kind: *Instruction*.
 	///
@@ -118,7 +118,7 @@ pub enum Xcm<Call> {
 	/// been placed into `holding`.
 	///
 	/// - `assets`: The asset(s) that are minted into holding.
-	/// - `effects`: The order(s) to execute on the holding account.
+	/// - `effects`: The order(s) to execute on the holding register.
 	///
 	/// Safety: `origin` must be trusted to have received and be storing `assets` such that they may later be
 	/// withdrawn should this system send a corresponding message.
@@ -127,7 +127,7 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 1)]
-	ReserveAssetDeposit { assets: MultiAssets, effects: Vec<Order<Call>> },
+	ReserveAssetDeposited { assets: MultiAssets, effects: Vec<Order<Call>> },
 
 	/// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be
 	/// created on this system.
@@ -136,7 +136,7 @@ pub enum Xcm<Call> {
 	/// been placed into `holding`.
 	///
 	/// - `assets`: The asset(s) that are minted into holding.
-	/// - `effects`: The order(s) to execute on the holding account.
+	/// - `effects`: The order(s) to execute on the holding register.
 	///
 	/// Safety: `origin` must be trusted to have irrevocably destroyed the `assets` prior as a consequence of
 	/// sending this message.
@@ -147,7 +147,7 @@ pub enum Xcm<Call> {
 	#[codec(index = 2)]
 	TeleportAsset { assets: MultiAssets, effects: Vec<Order<Call>> },
 
-	/// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`.
+	/// Indication of the contents of the holding register corresponding to the `QueryHolding` order of `query_id`.
 	///
 	/// - `query_id`: The identifier of the query that resulted in this message being sent.
 	/// - `assets`: The message content.
@@ -177,11 +177,11 @@ pub enum Xcm<Call> {
 	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
 	/// ownership of `dest` within this consensus system.
 	///
-	/// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`.
+	/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`.
 	///
 	/// - `assets`: The asset(s) to be withdrawn.
 	/// - `dest`: The new owner for the assets.
-	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to
+	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposited` which is sent onwards to
 	///   `dest`.
 	///
 	/// Safety: No concerns.
@@ -294,8 +294,8 @@ impl<Call> Xcm<Call> {
 		match xcm {
 			WithdrawAsset { assets, effects }
 			=> WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
-			ReserveAssetDeposit { assets, effects }
-			=> ReserveAssetDeposit { assets, effects: effects.into_iter().map(Order::into).collect() },
+			ReserveAssetDeposited { assets, effects }
+			=> ReserveAssetDeposited { assets, effects: effects.into_iter().map(Order::into).collect() },
 			TeleportAsset { assets, effects }
 			=> TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
 			QueryResponse { query_id: u64, response }
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
deleted file mode 100644
index fe53f6905aa5..000000000000
--- a/xcm/src/v0/multi_asset.rs
+++ /dev/null
@@ -1,337 +0,0 @@
-// Copyright 2020 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Cross-Consensus Message format data structures.
-
-use alloc::vec::Vec;
-
-use parity_scale_codec::{self, Encode, Decode};
-use super::{MultiLocation, AssetInstance};
-
-/// A single general identifier for an asset.
-///
-/// Represents both fungible and non-fungible assets. May only be used to represent a single asset class.
-///
-/// Wildcards may or may not be allowed by the interpreting context.
-///
-/// Assets classes may be identified in one of two ways: either an abstract identifier or a concrete identifier.
-/// Implementations may support only one of these. A single asset may be referenced from multiple asset identifiers,
-/// though will tend to have only a single *preferred* identifier.
-///
-/// ### Abstract identifiers
-///
-/// Abstract identifiers are absolute identifiers that represent a notional asset which can exist within multiple
-/// consensus systems. These tend to be simpler to deal with since their broad meaning is unchanged regardless stay of
-/// the consensus system in which it is interpreted.
-///
-/// However, in the attempt to provide uniformity across consensus systems, they may conflate different instantiations
-/// of some notional asset (e.g. the reserve asset and a local reserve-backed derivative of it) under the same name,
-/// leading to confusion. It also implies that one notional asset is accounted for locally in only one way. This may not
-/// be the case, e.g. where there are multiple bridge instances each providing a bridged "BTC" token yet none being
-/// fungible between the others.
-///
-/// Since they are meant to be absolute and universal, a global registry is needed to ensure that name collisions do not
-/// occur.
-///
-/// An abstract identifier is represented as a simple variable-size byte string. As of writing, no global registry
-/// exists and no proposals have been put forth for asset labeling.
-///
-/// ### Concrete identifiers
-///
-/// Concrete identifiers are *relative identifiers* that specifically identify a single asset through its location in a
-/// consensus system relative to the context interpreting. Use of a `MultiLocation` ensures that similar but non
-/// fungible variants of the same underlying asset can be properly distinguished, and obviates the need for any kind of
-/// central registry.
-///
-/// The limitation is that the asset identifier cannot be trivially copied between consensus systems and must instead be
-/// "re-anchored" whenever being moved to a new consensus system, using the two systems' relative paths.
-///
-/// Throughout XCM, messages are authored such that *when interpreted from the receiver's point of view* they will have
-/// the desired meaning/effect. This means that relative paths should always by constructed to be read from the point of
-/// view of the receiving system, *which may be have a completely different meaning in the authoring system*.
-///
-/// Concrete identifiers are the preferred way of identifying an asset since they are entirely unambiguous.
-///
-/// A concrete identifier is represented by a `MultiLocation`. If a system has an unambiguous primary asset (such as
-/// Bitcoin with BTC or Ethereum with ETH), then it will conventionally be identified as the chain itself. Alternative
-/// and more specific ways of referring to an asset within a system include:
-///
-/// - `<chain>/PalletInstance(<id>)` for a Frame chain with a single-asset pallet instance (such as an instance of the
-///   Balances pallet).
-/// - `<chain>/PalletInstance(<id>)/GeneralIndex(<index>)` for a Frame chain with an indexed multi-asset pallet instance
-///   (such as an instance of the Assets pallet).
-/// - `<chain>/AccountId32` for an ERC-20-style single-asset smart-contract on a Frame-based contracts chain.
-/// - `<chain>/AccountKey20` for an ERC-20-style single-asset smart-contract on an Ethereum-like chain.
-///
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum MultiAsset {
-	/// No assets. Rarely used.
-	None,
-
-	/// All assets. Typically used for the subset of assets to be used for an `Order`, and in that context means
-	/// "all assets currently in holding".
-	All,
-
-	/// All fungible assets. Typically used for the subset of assets to be used for an `Order`, and in that context
-	/// means "all fungible assets currently in holding".
-	AllFungible,
-
-	/// All non-fungible assets. Typically used for the subset of assets to be used for an `Order`, and in that
-	/// context means "all non-fungible assets currently in holding".
-	AllNonFungible,
-
-	/// All fungible assets of a given abstract asset `id`entifier.
-	AllAbstractFungible { id: Vec<u8> },
-
-	/// All non-fungible assets of a given abstract asset `class`.
-	AllAbstractNonFungible { class: Vec<u8> },
-
-	/// All fungible assets of a given concrete asset `id`entifier.
-	AllConcreteFungible { id: MultiLocation },
-
-	/// All non-fungible assets of a given concrete asset `class`.
-	AllConcreteNonFungible { class: MultiLocation },
-
-	/// Some specific `amount` of the fungible asset identified by an abstract `id`.
-	AbstractFungible { id: Vec<u8>, #[codec(compact)] amount: u128 },
-
-	/// Some specific `instance` of the non-fungible asset whose `class` is identified abstractly.
-	AbstractNonFungible { class: Vec<u8>, instance: AssetInstance },
-
-	/// Some specific `amount` of the fungible asset identified by an concrete `id`.
-	ConcreteFungible { id: MultiLocation, #[codec(compact)] amount: u128 },
-
-	/// Some specific `instance` of the non-fungible asset whose `class` is identified concretely.
-	ConcreteNonFungible { class: MultiLocation, instance: AssetInstance },
-}
-
-impl MultiAsset {
-	/// Returns `true` if the `MultiAsset` is a wildcard and can refer to classes of assets, instead of just one.
-	///
-	/// Typically can also be inferred by the name starting with `All`.
-	pub fn is_wildcard(&self) -> bool {
-		match self {
-			MultiAsset::None
-			| MultiAsset::AbstractFungible {..}
-			| MultiAsset::AbstractNonFungible {..}
-			| MultiAsset::ConcreteFungible {..}
-			| MultiAsset::ConcreteNonFungible {..}
-			=> false,
-
-			MultiAsset::All
-			| MultiAsset::AllFungible
-			| MultiAsset::AllNonFungible
-			| MultiAsset::AllAbstractFungible {..}
-			| MultiAsset::AllConcreteFungible {..}
-			| MultiAsset::AllAbstractNonFungible {..}
-			| MultiAsset::AllConcreteNonFungible {..}
-			=> true,
-		}
-	}
-
-	fn is_none(&self) -> bool {
-		match self {
-			MultiAsset::None
-			| MultiAsset::AbstractFungible { amount: 0, .. }
-			| MultiAsset::ConcreteFungible { amount: 0, .. }
-			=> true,
-
-			_ => false,
-		}
-	}
-
-	fn is_fungible(&self) -> bool {
-		match self {
-			MultiAsset::All
-			| MultiAsset::AllFungible
-			| MultiAsset::AllAbstractFungible {..}
-			| MultiAsset::AllConcreteFungible {..}
-			| MultiAsset::AbstractFungible {..}
-			| MultiAsset::ConcreteFungible {..}
-			=> true,
-
-			_ => false,
-		}
-	}
-
-	fn is_non_fungible(&self) -> bool {
-		match self {
-			MultiAsset::All
-			| MultiAsset::AllNonFungible
-			| MultiAsset::AllAbstractNonFungible {..}
-			| MultiAsset::AllConcreteNonFungible {..}
-			| MultiAsset::AbstractNonFungible {..}
-			| MultiAsset::ConcreteNonFungible {..}
-			=> true,
-
-			_ => false,
-		}
-	}
-
-	fn is_concrete_fungible(&self, id: &MultiLocation) -> bool {
-		match self {
-			MultiAsset::AllFungible => true,
-			MultiAsset::AllConcreteFungible { id: i }
-			| MultiAsset::ConcreteFungible { id: i, .. }
-			=> i == id,
-
-			_ => false,
-		}
-	}
-
-	fn is_abstract_fungible(&self, id: &[u8]) -> bool {
-		match self {
-			MultiAsset::AllFungible => true,
-			MultiAsset::AllAbstractFungible { id: i }
-			| MultiAsset::AbstractFungible { id: i, .. }
-			=> i == id,
-			_ => false,
-		}
-	}
-
-	fn is_concrete_non_fungible(&self, class: &MultiLocation) -> bool {
-		match self {
-			MultiAsset::AllNonFungible => true,
-			MultiAsset::AllConcreteNonFungible { class: i }
-			| MultiAsset::ConcreteNonFungible { class: i, .. }
-			=> i == class,
-			_ => false,
-		}
-	}
-
-	fn is_abstract_non_fungible(&self, class: &[u8]) -> bool {
-		match self {
-			MultiAsset::AllNonFungible => true,
-			MultiAsset::AllAbstractNonFungible { class: i }
-			| MultiAsset::AbstractNonFungible { class: i, .. }
-			=> i == class,
-			_ => false,
-		}
-	}
-
-	fn is_all(&self) -> bool { matches!(self, MultiAsset::All) }
-
-	/// Returns true if `self` is a super-set of the given `inner`.
-	///
-	/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
-	/// For more details, see the implementation and tests.
-	pub fn contains(&self, inner: &MultiAsset) -> bool {
-		use MultiAsset::*;
-
-		// Inner cannot be wild
-		if inner.is_wildcard() { return false }
-		// Everything contains nothing.
-		if inner.is_none() { return true }
-
-		// Everything contains anything.
-		if self.is_all() { return true }
-		// Nothing contains nothing.
-		if self.is_none() { return false }
-
-		match self {
-			// Anything fungible contains "all fungibles"
-			AllFungible => inner.is_fungible(),
-			// Anything non-fungible contains "all non-fungibles"
-			AllNonFungible => inner.is_non_fungible(),
-
-			AllConcreteFungible { id } => inner.is_concrete_fungible(id),
-			AllAbstractFungible { id } => inner.is_abstract_fungible(id),
-			AllConcreteNonFungible { class } => inner.is_concrete_non_fungible(class),
-			AllAbstractNonFungible { class } => inner.is_abstract_non_fungible(class),
-
-			ConcreteFungible { id, amount } => matches!(
-				inner,
-				ConcreteFungible { id: inner_id , amount: inner_amount } if inner_id == id && amount >= inner_amount
-			),
-			AbstractFungible { id, amount } => matches!(
-				inner,
-				AbstractFungible { id: inner_id , amount: inner_amount } if inner_id == id && amount >= inner_amount
-			),
-			ConcreteNonFungible { .. } => self == inner,
-			AbstractNonFungible { .. } => self == inner,
-			_ => false,
-		}
-	}
-
-	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
-		use MultiAsset::*;
-		match self {
-			AllConcreteFungible { ref mut id }
-			| AllConcreteNonFungible { class: ref mut id }
-			| ConcreteFungible { ref mut id, .. }
-			| ConcreteNonFungible { class: ref mut id, .. }
-			=> id.prepend_with(prepend.clone()).map_err(|_| ()),
-			_ => Ok(()),
-		}
-	}
-}
-
-#[cfg(test)]
-mod tests {
-	use super::*;
-
-	#[test]
-	fn contains_works() {
-		use alloc::vec;
-		use MultiAsset::*;
-		// trivial case: all contains any non-wildcard.
-		assert!(All.contains(&None));
-		assert!(All.contains(&AbstractFungible { id: alloc::vec![99u8], amount: 1 }));
-
-		// trivial case: none contains nothing, except itself.
-		assert!(None.contains(&None));
-		assert!(!None.contains(&AllFungible));
-		assert!(!None.contains(&All));
-
-		// A bit more sneaky: Nothing can contain wildcard, even All ir the thing itself.
-		assert!(!All.contains(&All));
-		assert!(!All.contains(&AllFungible));
-		assert!(!AllFungible.contains(&AllFungible));
-		assert!(!AllNonFungible.contains(&AllNonFungible));
-
-		// For fungibles, containing is basically equality, or equal id with higher amount.
-		assert!(
-			!AbstractFungible { id: vec![99u8], amount: 99 }
-			.contains(&AbstractFungible { id: vec![1u8], amount: 99 })
-		);
-		assert!(
-			AbstractFungible { id: vec![99u8], amount: 99 }
-			.contains(&AbstractFungible { id: vec![99u8], amount: 99 })
-		);
-		assert!(
-			AbstractFungible { id: vec![99u8], amount: 99 }
-			.contains(&AbstractFungible { id: vec![99u8], amount: 9 })
-		);
-		assert!(
-			!AbstractFungible { id: vec![99u8], amount: 99 }
-			.contains(&AbstractFungible { id: vec![99u8], amount: 100 })
-		);
-
-		// For non-fungibles, containing is equality.
-		assert!(
-			!AbstractNonFungible {class: vec![99u8], instance: AssetInstance::Index { id: 9 } }
-			.contains(&AbstractNonFungible { class: vec![98u8], instance: AssetInstance::Index { id: 9 } })
-		);
-		assert!(
-			!AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 8 } }
-			.contains(&AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } })
-		);
-		assert!(
-			AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } }
-			.contains(&AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index { id: 9 } })
-		);
-	}
-}
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index c877f71a0dc6..32b36f73a296 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -23,13 +23,10 @@
 //! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
 //!   account.
 
-use core::convert::{TryFrom, TryInto};
+use core::cmp::Ordering;
 use alloc::{vec, vec::Vec};
 use parity_scale_codec::{self as codec, Encode, Decode};
-use super::{
-	MultiLocation, multi_asset::MultiAsset as OldMultiAsset,
-};
-use core::cmp::Ordering;
+use super::MultiLocation;
 
 /// A general identifier for an instance of a non-fungible asset class.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
@@ -58,7 +55,7 @@ pub enum AssetInstance {
 }
 
 /// Classification of an asset being concrete or abstract.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum AssetId {
 	Concrete(MultiLocation),
 	Abstract(Vec<u8>),
@@ -98,7 +95,7 @@ impl AssetId {
 }
 
 /// Classification of whether an asset is fungible or not, along with an mandatory amount or instance.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum Fungibility {
 	Fungible(u128),
 	NonFungible(AssetInstance),
@@ -127,7 +124,7 @@ impl From<AssetInstance> for Fungibility {
 
 
 
-#[derive(Clone, Eq, PartialEq, Debug)]
+#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode)]
 pub struct MultiAsset {
 	pub id: AssetId,
 	pub fun: Fungibility,
@@ -155,45 +152,6 @@ impl<A: Into<AssetId>, B: Into<Fungibility>> From<(A, B)> for MultiAsset {
 	}
 }
 
-impl From<MultiAsset> for OldMultiAsset {
-	fn from(a: MultiAsset) -> Self {
-		use {AssetId::*, Fungibility::*, OldMultiAsset::*};
-		match (a.fun, a.id) {
-			(Fungible(amount), Concrete(id)) => ConcreteFungible { id, amount },
-			(Fungible(amount), Abstract(id)) => AbstractFungible { id, amount },
-			(NonFungible(instance), Concrete(class)) => ConcreteNonFungible { class, instance },
-			(NonFungible(instance), Abstract(class)) => AbstractNonFungible { class, instance },
-		}
-	}
-}
-
-impl TryFrom<OldMultiAsset> for MultiAsset {
-	type Error = ();
-	fn try_from(a: OldMultiAsset) -> Result<Self, ()> {
-		use {AssetId::*, Fungibility::*, OldMultiAsset::*};
-		let (fun, id) = match a {
-			ConcreteFungible { id, amount } if amount > 0 => (Fungible(amount), Concrete(id)),
-			AbstractFungible { id, amount } if amount > 0 => (Fungible(amount), Abstract(id)),
-			ConcreteNonFungible { class, instance } => (NonFungible(instance), Concrete(class)),
-			AbstractNonFungible { class, instance } => (NonFungible(instance), Abstract(class)),
-			_ => return Err(()),
-		};
-		Ok(MultiAsset { fun, id })
-	}
-}
-
-impl Encode for MultiAsset {
-	fn encode(&self) -> Vec<u8> {
-		OldMultiAsset::from(self.clone()).encode()
-	}
-}
-
-impl Decode for MultiAsset {
-	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
-		OldMultiAsset::decode(input)?.try_into().map_err(|_| "Unsupported wildcard".into())
-	}
-}
-
 impl MultiAsset {
 	pub fn is_fungible(&self, maybe_id: Option<AssetId>) -> bool {
 		use Fungibility::*;
@@ -238,7 +196,7 @@ impl Decode for MultiAssets {
 			if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) {
 				Ok(b)
 			} else {
-				Err("Unsupported wildcard".into())
+				Err("Out of order".into())
 			}
 		})?;
 		Ok(Self(r))
@@ -251,19 +209,6 @@ impl From<Vec<MultiAsset>> for MultiAssets {
 	}
 }
 
-impl From<MultiAssets> for Vec<OldMultiAsset> {
-	fn from(a: MultiAssets) -> Self {
-		a.0.into_iter().map(OldMultiAsset::from).collect()
-	}
-}
-
-impl TryFrom<Vec<OldMultiAsset>> for MultiAssets {
-	type Error = ();
-	fn try_from(a: Vec<OldMultiAsset>) -> Result<Self, ()> {
-		a.into_iter().map(MultiAsset::try_from).collect::<Result<_, _>>().map(Self)
-	}
-}
-
 impl MultiAssets {
 	/// A new (empty) value.
 	pub fn new() -> Self {
@@ -315,59 +260,23 @@ impl MultiAssets {
 
 
 /// Classification of whether an asset is fungible or not, along with an optional amount or instance.
-#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum WildFungibility {
 	Fungible,
 	NonFungible,
 }
 
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum WildMultiAsset {
+	/// All assets in the holding register, up to usize individual assets (different instances of non-fungibles could
+	/// as separate assets).
 	All,
 	// TODO: AllOf { fun: WildFungibility, id: AssetId }
+	/// All assets in the holding register of a given fungibility and ID. If operating on non-fungibles, then a limit
+	/// is provided for the maximum amount of matching instances.
 	AllOf(WildFungibility, AssetId),
 }
 
-impl Encode for WildMultiAsset {
-	fn encode(&self) -> Vec<u8> {
-		OldMultiAsset::from(self.clone()).encode()
-	}
-}
-
-impl Decode for WildMultiAsset {
-	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
-		OldMultiAsset::decode(input)?.try_into().map_err(|()| "Invalid wildcard item".into())
-	}
-}
-
-impl From<WildMultiAsset> for OldMultiAsset {
-	fn from(a: WildMultiAsset) -> Self {
-		use {AssetId::*, WildFungibility::*, OldMultiAsset::*, WildMultiAsset::AllOf};
-		match a {
-			WildMultiAsset::All => All,
-			AllOf(Fungible, Concrete(id)) => AllConcreteFungible { id },
-			AllOf(Fungible, Abstract(id)) => AllAbstractFungible { id },
-			AllOf(NonFungible, Concrete(class)) => AllConcreteNonFungible { class },
-			AllOf(NonFungible, Abstract(class)) => AllAbstractNonFungible { class },
-		}
-	}
-}
-
-impl TryFrom<OldMultiAsset> for WildMultiAsset {
-	type Error = ();
-	fn try_from(a: OldMultiAsset) -> Result<Self, ()> {
-		use {AssetId::*, WildFungibility::*, OldMultiAsset::*, WildMultiAsset::AllOf};
-		Ok(match a {
-			All => WildMultiAsset::All,
-			AllConcreteFungible { id } => AllOf(Fungible, Concrete(id)),
-			AllAbstractFungible { id } => AllOf(Fungible, Abstract(id)),
-			AllConcreteNonFungible { class } => AllOf(NonFungible, Concrete(class)),
-			AllAbstractNonFungible { class } => AllOf(NonFungible, Abstract(class)),
-			_ => return Err(()),
-		})
-	}
-}
-
 impl WildMultiAsset {
 	/// Returns true if `self` is a super-set of the given `inner`.
 	///
@@ -391,15 +300,20 @@ impl WildMultiAsset {
 	}
 }
 
+impl<A: Into<AssetId>, B: Into<WildFungibility>> From<(A, B)> for WildMultiAsset {
+	fn from((id, fun): (A, B)) -> WildMultiAsset {
+		WildMultiAsset::AllOf(fun.into(), id.into())
+	}
+}
 
 
 
 
 /// `MultiAsset` collection, either `MultiAssets` or a single wildcard. Note: vectors of wildcards
 /// whose encoding is supported in XCM v0 are unsupported in this implementation and will result in a decode error.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum MultiAssetFilter {
-	Assets(MultiAssets),
+	Definite(MultiAssets),
 	Wild(WildMultiAsset),
 }
 
@@ -411,50 +325,13 @@ impl From<WildMultiAsset> for MultiAssetFilter {
 
 impl From<MultiAsset> for MultiAssetFilter {
 	fn from(x: MultiAsset) -> Self {
-		Self::Assets(vec![x].into())
+		Self::Definite(vec![x].into())
 	}
 }
 
 impl From<MultiAssets> for MultiAssetFilter {
 	fn from(x: MultiAssets) -> Self {
-		Self::Assets(x)
-	}
-}
-
-impl From<MultiAssetFilter> for Vec<OldMultiAsset> {
-	fn from(a: MultiAssetFilter) -> Self {
-		use MultiAssetFilter::*;
-		match a {
-			Assets(assets) => assets.0.into_iter().map(OldMultiAsset::from).collect(),
-			Wild(wild) => vec![wild.into()],
-		}
-	}
-}
-
-impl TryFrom<Vec<OldMultiAsset>> for MultiAssetFilter {
-	type Error = ();
-	fn try_from(mut old_assets: Vec<OldMultiAsset>) -> Result<Self, ()> {
-		use MultiAssetFilter::*;
-		if old_assets.is_empty() {
-			return Ok(Assets(MultiAssets::new()))
-		}
-		if old_assets.len() == 1 && old_assets[0].is_wildcard() {
-			return old_assets.pop().ok_or(()).and_then(|i| Ok(Wild(i.try_into()?)))
-		}
-
-		MultiAssets::try_from(old_assets).map(Self::Assets)
-	}
-}
-
-impl Encode for MultiAssetFilter {
-	fn encode(&self) -> Vec<u8> {
-		Vec::<OldMultiAsset>::from(self.clone()).encode()
-	}
-}
-
-impl Decode for MultiAssetFilter {
-	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
-		Vec::<OldMultiAsset>::decode(input)?.try_into().map_err(|()| "Invalid items".into())
+		Self::Definite(x)
 	}
 }
 
@@ -471,7 +348,7 @@ impl MultiAssetFilter {
 
 	/// Returns `true` if this definitely represents no asset.
 	pub fn is_none(&self) -> bool {
-		matches!(self, MultiAssetFilter::Assets(a) if a.is_none())
+		matches!(self, MultiAssetFilter::Definite(a) if a.is_none())
 	}
 
 	/// Returns true if `self` is a super-set of the given `inner`.
@@ -480,7 +357,7 @@ impl MultiAssetFilter {
 	/// For more details, see the implementation and tests.
 	pub fn contains(&self, inner: &MultiAsset) -> bool {
 		match self {
-			MultiAssetFilter::Assets(ref assets) => assets.contains(inner),
+			MultiAssetFilter::Definite(ref assets) => assets.contains(inner),
 			MultiAssetFilter::Wild(ref wild) => wild.contains(inner),
 		}
 	}
@@ -488,7 +365,7 @@ impl MultiAssetFilter {
 	/// Prepend a `MultiLocation` to any concrete asset components, giving it a new root location.
 	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
 		match self {
-			MultiAssetFilter::Assets(ref mut assets) => assets.reanchor(prepend),
+			MultiAssetFilter::Definite(ref mut assets) => assets.reanchor(prepend),
 			MultiAssetFilter::Wild(ref mut wild) => wild.reanchor(prepend),
 		}
 	}
diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index fa8aa6df3393..6ee6eb20f9bc 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -44,11 +44,11 @@ pub enum Order<Call> {
 	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
 	/// this consensus system.
 	///
-	/// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`.
+	/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`.
 	///
 	/// - `assets`: The asset(s) to remove from holding.
 	/// - `dest`: The new owner for the assets.
-	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to
+	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposited` which is sent onwards to
 	///   `dest`.
 	///
 	/// Errors:
@@ -93,7 +93,7 @@ pub enum Order<Call> {
 	/// - `query_id`: An identifier that will be replicated into the returned XCM message.
 	/// - `dest`: A valid destination for the returned XCM message. This may be limited to the current origin.
 	/// - `assets`: A filter for the assets that should be reported back. The assets reported back will be, asset-
-	///   wise, *the lesser of this value and the holding account*. No wildcards will be used when reporting assets
+	///   wise, *the lesser of this value and the holding register*. No wildcards will be used when reporting assets
 	///   back.
 	///
 	/// Errors:
@@ -101,7 +101,7 @@ pub enum Order<Call> {
 	QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: MultiAssetFilter },
 
 	/// Pay for the execution of some XCM with up to `weight` picoseconds of execution time, paying for this with
-	/// up to `fees` from the holding account.
+	/// up to `fees` from the holding register.
 	///
 	/// - `fees`: The asset(s) to remove from holding to pay for fees.
 	///
diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs
index 9a01f227e766..24bfe84db853 100644
--- a/xcm/src/v0/traits.rs
+++ b/xcm/src/v0/traits.rs
@@ -62,7 +62,7 @@ pub enum Error {
 	/// Used by:
 	/// - `Transact`
 	TooMuchWeightRequired,
-	/// The fees specified by the XCM message were not found in the holding account.
+	/// The fees specified by the XCM message were not found in the holding register.
 	///
 	/// Used by:
 	/// - `BuyExecution`
diff --git a/xcm/xcm-builder/src/barriers.rs b/xcm/xcm-builder/src/barriers.rs
index ea3d80660940..0a48ad6c42e2 100644
--- a/xcm/xcm-builder/src/barriers.rs
+++ b/xcm/xcm-builder/src/barriers.rs
@@ -53,11 +53,11 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowTopLevelPaidExecutionFro
 		match message {
 			Xcm::TeleportAsset { effects, .. }
 			| Xcm::WithdrawAsset { effects, ..}
-			| Xcm::ReserveAssetDeposit { effects, ..}
+			| Xcm::ReserveAssetDeposited { effects, ..}
 			if matches!(
-					effects.first(),
-					Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight
-				)
+				effects.first(),
+				Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight
+			)
 			=> Ok(()),
 			_ => Err(()),
 		}
diff --git a/xcm/xcm-builder/src/filter_asset_location.rs b/xcm/xcm-builder/src/filter_asset_location.rs
index e095b9dbbc73..462b9421e35a 100644
--- a/xcm/xcm-builder/src/filter_asset_location.rs
+++ b/xcm/xcm-builder/src/filter_asset_location.rs
@@ -17,7 +17,7 @@
 //! Various implementations of `FilterAssetLocation`.
 
 use sp_std::marker::PhantomData;
-use xcm::v0::{MultiAsset, MultiLocation, AssetId::Concrete};
+use xcm::v0::{MultiAsset, MultiAssetFilter, MultiLocation, AssetId::Concrete};
 use frame_support::traits::Get;
 use xcm_executor::traits::FilterAssetLocation;
 
@@ -31,7 +31,7 @@ impl FilterAssetLocation for NativeAsset {
 
 /// Accepts an asset if it is contained in the given `T`'s `Get` implementation.
 pub struct Case<T>(PhantomData<T>);
-impl<T: Get<(MultiAsset, MultiLocation)>> FilterAssetLocation for Case<T> {
+impl<T: Get<(MultiAssetFilter, MultiLocation)>> FilterAssetLocation for Case<T> {
 	fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {
 		let (a, o) = T::get();
 		a.contains(asset) && &o == origin
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 0f04b89285d1..79235427be62 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -39,7 +39,7 @@ fn basic_setup_works() {
 
 #[test]
 fn weigher_should_work() {
-	let mut message = opaque::Xcm::ReserveAssetDeposit {
+	let mut message = opaque::Xcm::ReserveAssetDeposited {
 		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
 		effects: vec![
 			Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
@@ -124,7 +124,7 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposit {
+	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
 		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
 		effects: vec![
 			Order::BuyExecution { fees: All, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] },
@@ -141,7 +141,7 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let mut paying_message = opaque::Xcm::ReserveAssetDeposit {
+	let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
 		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
 		effects: vec![
 			Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
@@ -175,7 +175,7 @@ fn paying_reserve_deposit_should_work() {
 	WeightPrice::set((X1(Parent), 1_000_000_000_000));
 
 	let origin = X1(Parent);
-	let message = Xcm::<TestCall>::ReserveAssetDeposit {
+	let message = Xcm::<TestCall>::ReserveAssetDeposited {
 		assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],
 		effects: vec![
 			Order::<TestCall>::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
@@ -233,7 +233,7 @@ fn reserve_transfer_should_work() {
 	assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null, amount: 100 } ]);
 	assert_eq!(sent_xcm(), vec![(
 		X1(Parachain(2)),
-		Xcm::ReserveAssetDeposit {
+		Xcm::ReserveAssetDeposited {
 			assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],
 			effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ],
 		})
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index 77f28c73f571..ef18fcf99783 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -31,7 +31,7 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeigh
 			}
 			Xcm::RelayedFrom { ref mut message, .. } => T::get().saturating_add(Self::shallow(message.as_mut())?),
 			Xcm::WithdrawAsset { effects, .. }
-			| Xcm::ReserveAssetDeposit { effects, .. }
+			| Xcm::ReserveAssetDeposited { effects, .. }
 			| Xcm::TeleportAsset { effects, .. }
 			=> {
 				let inner: Weight = effects.iter_mut()
@@ -55,7 +55,7 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeigh
 		Ok(match message {
 			Xcm::RelayedFrom { ref mut message, .. } => Self::deep(message.as_mut())?,
 			Xcm::WithdrawAsset { effects, .. }
-			| Xcm::ReserveAssetDeposit { effects, .. }
+			| Xcm::ReserveAssetDeposited { effects, .. }
 			| Xcm::TeleportAsset { effects, .. }
 			=> {
 				let mut extra = 0;
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index b25b0b3e4637..5846185189f9 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -201,7 +201,7 @@ impl Assets {
 					}
 				});
 			}
-			MultiAssetFilter::Assets(assets) => {
+			MultiAssetFilter::Definite(assets) => {
 				if !saturate {
 					self.ensure_contains(&assets)?;
 				}
@@ -263,15 +263,6 @@ impl Assets {
 		}
 	}
 
-	/// Consumes `self` and returns its original value excluding `mask` iff it contains at least `mask`, as well as
-	/// the assets excluded.
-	pub fn less(mut self, mask: MultiAssetFilter) -> Result<(Assets, Assets), Self> {
-		match self.try_take(mask) {
-			Ok(taken) => Ok((self, taken)),
-			Err(_) => Err(self),
-		}
-	}
-
 	/// Return the assets in `self`, but (asset-wise) of no greater value than `assets`.
 	///
 	/// Result is undefined if `assets` includes elements which match to the same asset more than once.
@@ -312,7 +303,7 @@ impl Assets {
 					}
 				});
 			}
-			MultiAssetFilter::Assets(assets) => {
+			MultiAssetFilter::Definite(assets) => {
 				for asset in assets.inner().iter() {
 					match asset {
 						MultiAsset { fun: Fungible(ref amount), ref id } => {
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index b9ec7b4a6e92..a12d714cac6c 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -133,7 +133,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				}
 				Some((holding, effects))
 			}
-			(origin, Xcm::ReserveAssetDeposit { assets, effects }) => {
+			(origin, Xcm::ReserveAssetDeposited { assets, effects }) => {
 				// check whether we trust origin to be our reserve location for this asset.
 				for asset in assets.inner() {
 					// We only trust the origin to send us assets that they identify as their
@@ -145,7 +145,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 			(origin, Xcm::TransferAsset { assets, dest }) => {
 				// Take `assets` from the origin account (on-chain) and place into dest account.
 				for asset in assets.inner() {
-					Config::AssetTransactor::teleport_asset(&asset, &origin, &dest)?;
+					Config::AssetTransactor::beam_asset(&asset, &origin, &dest)?;
 				}
 				None
 			}
@@ -153,10 +153,10 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				// Take `assets` from the origin account (on-chain) and place into dest account.
 				let inv_dest = Config::LocationInverter::invert_location(&dest);
 				for asset in assets.inner() {
-					Config::AssetTransactor::teleport_asset(asset, &origin, &dest)?;
+					Config::AssetTransactor::beam_asset(asset, &origin, &dest)?;
 				}
 				assets.reanchor(&inv_dest)?;
-				Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?;
+				Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposited { assets, effects })?;
 				None
 			}
 			(origin, Xcm::TeleportAsset { assets, effects }) => {
@@ -256,7 +256,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 					Config::AssetTransactor::deposit_asset(&asset, &dest)?;
 				}
 				let assets = Self::reanchored(deposited, &dest);
-				Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposit { assets, effects })?;
+				Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposited { assets, effects })?;
 			},
 			Order::InitiateReserveWithdraw { assets, reserve, effects} => {
 				let assets = Self::reanchored(holding.saturating_take(assets), &reserve);
@@ -276,7 +276,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				Config::XcmSender::send_xcm(dest, Xcm::QueryResponse { query_id, response: Response::Assets(assets) })?;
 			}
 			Order::BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
-				// pay for `weight` using up to `fees` of the holding account.
+				// pay for `weight` using up to `fees` of the holding register.
 				let purchasing_weight = Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?);
 				let max_fee = holding.try_take(fees.into()).map_err(|_| XcmError::NotHoldingFees)?;
 				let unspent = trader.buy_weight(purchasing_weight, max_fee)?;
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index 610f98977ca7..736990775a23 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -85,7 +85,7 @@ pub trait TransactAsset {
 	/// Move an `asset` `from` one location in `to` another location.
 	///
 	/// Attempts to use `transfer_asset` and if not available then falls back to using a two-part withdraw/deposit.
-	fn teleport_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result<Assets, XcmError> {
+	fn beam_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result<Assets, XcmError> {
 		match Self::transfer_asset(asset, from, to) {
 			Err(XcmError::Unimplemented) => {
 				let assets = Self::withdraw_asset(asset, from)?;

From 958d79a2140b9b1040ba10aac85cf3c49a239438 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sun, 1 Aug 2021 20:03:10 +0200
Subject: [PATCH 031/166] Some TODOs

---
 xcm/src/v0/order.rs | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index 6ee6eb20f9bc..fbeb4a5c9608 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -39,6 +39,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 1)]
+	// TODO: https://github.com/paritytech/polkadot/issues/3547 introduce `, max_assets: u32`
 	DepositAsset { assets: MultiAssetFilter, dest: MultiLocation },
 
 	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
@@ -53,6 +54,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 2)]
+	// TODO: https://github.com/paritytech/polkadot/issues/3547 introduce `, max_assets: u32`
 	DepositReserveAsset { assets: MultiAssetFilter, dest: MultiLocation, effects: Vec<Order<()>> },
 
 	/// Remove the asset(s) (`give`) from holding and replace them with alternative assets.
@@ -107,7 +109,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 7)]
-	BuyExecution { fees: WildMultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec<Xcm<Call>> },
+	BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec<Xcm<Call>> },
 }
 
 pub mod opaque {

From 7d47d21bcc9f4948dc53de098fad34a15e811be0 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sun, 1 Aug 2021 20:26:39 +0200
Subject: [PATCH 032/166] Further build fixes

---
 runtime/kusama/src/lib.rs |  7 +++----
 runtime/rococo/src/lib.rs |  2 +-
 xcm/pallet-xcm/src/lib.rs | 12 ++++++++----
 xcm/src/v0/order.rs       |  2 +-
 4 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index 8b307d392843..a69e46f8ef8a 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -54,8 +54,7 @@ use runtime_parachains::scheduler as parachains_scheduler;
 use runtime_parachains::reward_points as parachains_reward_points;
 use runtime_parachains::runtime_api_impl::v1 as parachains_runtime_api_impl;
 
-use xcm::v0::{MultiLocation::{self, Null, X1}, NetworkId, BodyId, Xcm, Junction::Parachain};
-use xcm::v0::MultiAsset::{self, AllConcreteFungible};
+use xcm::v0::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation, CurrencyAdapter as XcmCurrencyAdapter,
 	ChildParachainAsNative, SignedAccountId32AsNative, ChildSystemParachainAsSuperuser, LocationInverter,
@@ -1260,8 +1259,8 @@ pub type XcmRouter = (
 );
 
 parameter_types! {
-	pub const KusamaForStatemint: (MultiAsset, MultiLocation) =
-		(AllConcreteFungible { id: Null }, X1(Parachain(1000)));
+	pub const Kusama: MultiAssetFilter = Wild(AllOf(WildFungible, Concrete(KsmLocation::get())));
+	pub const KusamaForStatemint: (MultiAssetFilter, MultiLocation) = (Kusama::get(), X1(Parachain(1000)));
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<KusamaForStatemint>,
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 7000c291a1ff..9d4dbdc1c53f 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -629,7 +629,7 @@ pub type XcmRouter = (
 
 use xcm::v0::prelude::*;
 parameter_types! {
-	pub const Rococo: MultiAssetFilter = Wild(AllOf(Concrete(RocLocation::get()), WildFungible));
+	pub const Rococo: MultiAssetFilter = Wild(AllOf(WildFungible, Concrete(RocLocation::get())));
 	pub const RococoForTick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(100)));
 	pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(110)));
 	pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(120)));
diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 77c004b58844..99341c2a0e85 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -89,6 +89,8 @@ pub mod pallet {
 		Filtered,
 		/// The message's weight could not be determined.
 		UnweighableMessage,
+		/// The assets to be sent are empty.
+		Empty,
 	}
 
 	#[pallet::hooks]
@@ -115,8 +117,8 @@ pub mod pallet {
 		///   from parachain to parachain, or `X1(Parachain(..))` to send from relay to parachain.
 		/// - `beneficiary`: A beneficiary location for the assets in the context of `dest`. Will generally be
 		///   an `AccountId32` value.
-		/// - `assets`: The assets to be withdrawn. This should include the assets used to pay the fee on the
-		///   `dest` side.
+		/// - `assets`: The assets to be withdrawn. The first item should be the currency used to to pay the fee on the
+		///   `dest` side. May not be empty.
 		/// - `dest_weight`: Equal to the total weight on `dest` of the XCM message
 		///   `Teleport { assets, effects: [ BuyExecution{..}, DepositAsset{..} ] }`.
 		#[pallet::weight({
@@ -141,6 +143,7 @@ pub mod pallet {
 			let value = (origin_location, assets.drain());
 			ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
 			let (origin_location, assets) = value;
+			let fees = assets.first().ok_or(Error::<T>::Empty)?.clone();
 			let assets = assets.into();
 			let mut message = Xcm::WithdrawAsset {
 				assets,
@@ -150,7 +153,7 @@ pub mod pallet {
 						dest,
 						effects: vec![
 							BuyExecution {
-								fees: All,
+								fees,
 								// Zero weight for additional XCM (since there are none to execute)
 								weight: 0,
 								debt: dest_weight,
@@ -200,13 +203,14 @@ pub mod pallet {
 			let value = (origin_location, assets.drain());
 			ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
 			let (origin_location, assets) = value;
+			let fees = assets.first().ok_or(Error::<T>::Empty)?.clone();
 			let assets = assets.into();
 			let mut message = Xcm::TransferReserveAsset {
 				assets,
 				dest,
 				effects: vec![
 					BuyExecution {
-						fees: All,
+						fees,
 						// Zero weight for additional XCM (since there are none to execute)
 						weight: 0,
 						debt: dest_weight,
diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index fbeb4a5c9608..6162581f7e28 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -19,7 +19,7 @@
 use alloc::vec::Vec;
 use derivative::Derivative;
 use parity_scale_codec::{self, Encode, Decode};
-use super::{MultiAsset, WildMultiAsset, MultiAssetFilter, MultiLocation, Xcm};
+use super::{MultiAsset, MultiAssetFilter, MultiLocation, Xcm};
 
 /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
 #[derive(Derivative, Encode, Decode)]

From 6ce9f1ddbf233a881564eb13ed6abb3d4eeb9e82 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 1 Aug 2021 11:59:36 -0700
Subject: [PATCH 033/166] Rename non_parent/junctions to interior

---
 runtime/common/src/xcm_sender.rs           |  2 +-
 runtime/kusama/src/lib.rs                  |  6 +++---
 runtime/rococo/src/lib.rs                  |  6 +++---
 runtime/westend/src/lib.rs                 |  6 +++---
 xcm/src/v0/multi_location.rs               | 14 +++++++-------
 xcm/src/v0/traits.rs                       |  4 ++--
 xcm/xcm-builder/src/barriers.rs            |  2 +-
 xcm/xcm-builder/src/fungibles_adapter.rs   |  6 +++---
 xcm/xcm-builder/src/location_conversion.rs | 12 ++++++------
 xcm/xcm-builder/src/mock.rs                |  4 ++--
 xcm/xcm-builder/src/origin_conversion.rs   | 16 ++++++++--------
 xcm/xcm-executor/src/traits/conversion.rs  |  4 ++--
 12 files changed, 41 insertions(+), 41 deletions(-)

diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs
index 2c93884e6b3e..21b3743a5560 100644
--- a/runtime/common/src/xcm_sender.rs
+++ b/runtime/common/src/xcm_sender.rs
@@ -29,7 +29,7 @@ pub struct ChildParachainRouter<T>(PhantomData<T>);
 
 impl<T: configuration::Config + dmp::Config> SendXcm for ChildParachainRouter<T> {
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {
-		match dest.junctions() {
+		match dest.interior() {
 			Junctions::X1(Junction::Parachain(id)) if dest.parent_count() == 0 => {
 				// Downward message passing.
 				let config = <configuration::Pallet<T>>::config();
diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index 6171a8c60df3..bad21bdd1fcc 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1314,7 +1314,7 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
 			MultiAsset::{All, ConcreteFungible}, Junction::{AccountId32, Plurality},
 		};
-		match origin.junctions() {
+		match origin.interior() {
 			// Root and council are are allowed to execute anything.
 			Null | X1(Plurality { .. }) if origin.parent_count() == 0 => true,
 			X1(AccountId32 { .. }) if origin.parent_count() == 0 => {
@@ -1338,7 +1338,7 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 					&& matches!(effects[0], BuyExecution { .. })
 					&& matches!(effects[1], InitiateTeleport { ref assets, ref dest, ref effects }
 						if assets.len() == 1
-						&& matches!(dest.junctions(), X1(Parachain(..)))
+						&& matches!(dest.interior(), X1(Parachain(..)))
 						&& dest.parent_count() == 0
 						&& matches!(assets[0], All)
 						&& effects.len() == 2
@@ -1347,7 +1347,7 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 							if assets.len() == 1
 							&& matches!(assets[0], All)
 							&& dest.parent_count() == 0
-							&& matches!(dest.junctions(), X1(AccountId32{..}))
+							&& matches!(dest.interior(), X1(AccountId32{..}))
 						)
 					)
 				)
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 3afe89df664d..3972c5adb2eb 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -698,7 +698,7 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
 			MultiAsset::{All, ConcreteFungible}, Junction::{AccountId32, Plurality},
 		};
-		match origin.junctions() {
+		match origin.interior() {
 			// Root and collective are allowed to execute anything.
 			Null | X1(Plurality { .. }) if origin.parent_count() == 0 => true,
 			X1(AccountId32 { .. }) if origin.parent_count() == 0 => {
@@ -722,14 +722,14 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 					&& matches!(effects[0], BuyExecution { .. })
 					&& matches!(effects[1], InitiateTeleport { ref assets, ref dest, ref effects }
 						if assets.len() == 1
-						&& matches!(dest.junctions(), X1(Parachain(..)))
+						&& matches!(dest.interior(), X1(Parachain(..)))
 						&& dest.parent_count() == 0
 						&& matches!(assets[0], All)
 						&& effects.len() == 2
 						&& matches!(effects[0], BuyExecution { .. })
 						&& matches!(effects[1], DepositAsset { ref assets, ref dest }
 							if assets.len() == 1
-							&& matches!(dest.junctions(), X1(AccountId32{..}))
+							&& matches!(dest.interior(), X1(AccountId32{..}))
 							&& dest.parent_count() == 0
 							&& matches!(assets[0], All)
 						)
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index 506e57f84584..4f877d533c11 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -953,7 +953,7 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 			Xcm::WithdrawAsset, Order::{BuyExecution, InitiateTeleport, DepositAsset},
 			MultiAsset::{All, ConcreteFungible}, Junction::AccountId32,
 		};
-		match origin.junctions() {
+		match origin.interior() {
 			// Root is allowed to execute anything.
 			Null if origin.parent_count() == 0 => true,
 			X1(AccountId32 { .. }) if origin.parent_count() == 0 => {
@@ -979,14 +979,14 @@ impl frame_support::traits::Contains<(MultiLocation, Xcm<Call>)> for OnlyWithdra
 						if assets.len() == 1
 						&& matches!(assets[0], All)
 						&& dest.parent_count() == 0
-						&& matches!(dest.junctions(), X1(Parachain(..)))
+						&& matches!(dest.interior(), X1(Parachain(..)))
 						&& effects.len() == 2
 						&& matches!(effects[0], BuyExecution { .. })
 						&& matches!(effects[1], DepositAsset { ref assets, ref dest }
 							if assets.len() == 1
 							&& matches!(assets[0], All)
 							&& dest.parent_count() == 0
-							&& matches!(dest.junctions(), X1(AccountId32{..}))
+							&& matches!(dest.interior(), X1(AccountId32{..}))
 						)
 					)
 				)
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index c44381713e83..56262195367e 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -157,12 +157,12 @@ impl MultiLocation {
 	}
 
 	/// Return a reference to the interior field.
-	pub fn junctions(&self) -> &Junctions {
+	pub fn interior(&self) -> &Junctions {
 		&self.interior
 	}
 
 	/// Return a mutable reference to the interior field.
-	pub fn junctions_mut(&mut self) -> &mut Junctions {
+	pub fn interior_mut(&mut self) -> &mut Junctions {
 		&mut self.interior
 	}
 
@@ -176,9 +176,9 @@ impl MultiLocation {
 		self.parent_count() as usize + self.interior.len()
 	}
 
-	/// Returns first junction that is not a parent, or `None` if the location is empty or
-	/// contains only parents.
-	pub fn first_non_parent(&self) -> Option<&Junction> {
+	/// Returns the first interior junction, or `None` if the location is empty or contains only
+	/// parents.
+	pub fn first_interior(&self) -> Option<&Junction> {
 		self.interior.first()
 	}
 
@@ -187,9 +187,9 @@ impl MultiLocation {
 		self.interior.last()
 	}
 
-	/// Splits off the first non-parent junction, returning the remaining suffix (first item in tuple)
+	/// Splits off the first interior junction, returning the remaining suffix (first item in tuple)
 	/// and the first element (second item in tuple) or `None` if it was empty.
-	pub fn split_first_non_parent(self) -> (MultiLocation, Option<Junction>) {
+	pub fn split_first_interior(self) -> (MultiLocation, Option<Junction>) {
 		let MultiLocation { parents, interior: junctions } = self;
 		let (suffix, first) = junctions.split_first();
 		let multilocation = MultiLocation {
diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs
index 9f8bab7f7d19..24362d8e3d31 100644
--- a/xcm/src/v0/traits.rs
+++ b/xcm/src/v0/traits.rs
@@ -199,7 +199,7 @@ impl<C> ExecuteXcm<C> for () {
 /// struct Sender2;
 /// impl SendXcm for Sender2 {
 ///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-///         if matches!(destination.junctions(), Junctions::X2(j1, j2))
+///         if matches!(destination.interior(), Junctions::X2(j1, j2))
 ///             && destination.parent_count() == 0
 ///         {
 ///             Ok(())
@@ -213,7 +213,7 @@ impl<C> ExecuteXcm<C> for () {
 /// struct Sender3;
 /// impl SendXcm for Sender3 {
 ///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-///         if matches!(destination.junctions(), Junctions::Null)
+///         if matches!(destination.interior(), Junctions::Null)
 ///             && destination.parent_count() == 1
 ///         {
 ///             Ok(())
diff --git a/xcm/xcm-builder/src/barriers.rs b/xcm/xcm-builder/src/barriers.rs
index 2d9db1e916f4..1e71cd497b67 100644
--- a/xcm/xcm-builder/src/barriers.rs
+++ b/xcm/xcm-builder/src/barriers.rs
@@ -87,7 +87,7 @@ impl<
 > Contains<MultiLocation> for IsChildSystemParachain<ParaId> {
 	fn contains(l: &MultiLocation) -> bool {
 		matches!(
-			l.junctions(),
+			l.interior(),
 			Junctions::X1(Junction::Parachain(id))
 				if ParaId::from(*id).is_system() && l.parent_count() == 0,
 		)
diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs
index 99807f2098f8..80ba164b70c9 100644
--- a/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -35,14 +35,14 @@ impl<
 		let id = id.borrow();
 		if prefix.parent_count() != id.parent_count()
 			|| prefix
-				.junctions()
+				.interior()
 				.iter()
 				.enumerate()
-				.any(|(index, junction)| id.junctions().at(index) != Some(junction))
+				.any(|(index, junction)| id.interior().at(index) != Some(junction))
 		{
 			return Err(())
 		}
-		match id.junctions().at(prefix.junctions().len()) {
+		match id.interior().at(prefix.interior().len()) {
 			Some(Junction::GeneralIndex { id }) => ConvertAssetId::convert_ref(id),
 			_ => Err(()),
 		}
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index d3528eb275ae..f30529b1cad6 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -43,7 +43,7 @@ impl<
 	AccountId: Default + Eq + Clone,
 > Convert<MultiLocation, AccountId> for ParentIsDefault<AccountId> {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-		if location.borrow().parent_count() == 1 && location.borrow().junctions().len() == 0 {
+		if location.borrow().parent_count() == 1 && location.borrow().interior().len() == 0 {
 			Ok(AccountId::default())
 		} else {
 			Err(())
@@ -66,7 +66,7 @@ impl<
 > Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId> {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
 		let location = location.borrow();
-		match location.junctions() {
+		match location.interior() {
 			Junctions::X1(Junction::Parachain(id)) if location.parent_count() == 0 => {
 				Ok(ParaId::from(*id).into_account())
 			},
@@ -90,7 +90,7 @@ impl<
 > Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId> {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
 		let location = location.borrow();
-		match location.junctions() {
+		match location.interior() {
 			Junctions::X1(Junction::Parachain(id)) if location.parent_count() == 1 => {
 				Ok(ParaId::from(*id).into_account())
 			},
@@ -118,7 +118,7 @@ impl<
 	AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone,
 > Convert<MultiLocation, AccountId> for AccountId32Aliases<Network, AccountId> {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
-		let id = match location.junctions() {
+		let id = match location.interior() {
 			Junctions::X1(Junction::AccountId32 { id, network: NetworkId::Any })
 			if location.parent_count() == 0
 				=> *id,
@@ -141,7 +141,7 @@ impl<
 	AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone,
 > Convert<MultiLocation, AccountId> for AccountKey20Aliases<Network, AccountId> {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
-		let key = match location.junctions() {
+		let key = match location.interior() {
 			Junctions::X1(Junction::AccountKey20 { key, network: NetworkId::Any })
 			if location.parent_count() == 0
 				=> *key,
@@ -202,7 +202,7 @@ impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry>
 			)
 			.expect("ancestry is well-formed and has less than 8 non-parent junctions; qed");
 		}
-		let parents = location.junctions().len() as u8;
+		let parents = location.interior().len() as u8;
 		MultiLocation::new(parents, junctions)
 			.expect("parents + junctions len must equal location len; qed")
 	}
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index efe4f49ee5ce..4f307d397ac5 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -147,7 +147,7 @@ impl TransactAsset for TestAssetTransactor {
 
 
 pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
-	Ok(match l.junctions() {
+	Ok(match l.interior() {
 		// Siblings at 2000+id
 		X1(Parachain(id)) if l.parent_count() == 1 => 2000 + *id as u64,
 		// Accounts are their number
@@ -166,7 +166,7 @@ pub struct TestOriginConverter;
 impl ConvertOrigin<TestOrigin> for TestOriginConverter {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<TestOrigin, MultiLocation> {
 		use OriginKind::*;
-		match (kind, origin.junctions()) {
+		match (kind, origin.interior()) {
 			(Superuser, _) => Ok(TestOrigin::Root),
 			(SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)),
 			(Native, X1(Parachain(id))) if origin.parent_count() == 0 => Ok(TestOrigin::Parachain(*id)),
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index 76782c6515a0..74a282f14b0a 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -46,7 +46,7 @@ impl<
 	Origin: OriginTrait,
 > ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		if kind == OriginKind::Superuser && origin.parent_count() == 1 && origin.junctions().len() == 0 {
+		if kind == OriginKind::Superuser && origin.parent_count() == 1 && origin.interior().len() == 0 {
 			Ok(Origin::root())
 		} else {
 			Err(origin)
@@ -60,7 +60,7 @@ impl<
 	Origin: OriginTrait,
 > ConvertOrigin<Origin> for ChildSystemParachainAsSuperuser<ParaId, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.junctions()) {
+		match (kind, origin.interior()) {
 			(OriginKind::Superuser, Junctions::X1(Junction::Parachain(id)))
 			if ParaId::from(*id).is_system() && origin.parent_count() == 0 =>
 				Ok(Origin::root()),
@@ -75,7 +75,7 @@ impl<
 	Origin: OriginTrait
 > ConvertOrigin<Origin> for SiblingSystemParachainAsSuperuser<ParaId, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.junctions()) {
+		match (kind, origin.interior()) {
 			(OriginKind::Superuser, Junctions::X1(Junction::Parachain(id)))
 			if ParaId::from(*id).is_system() && origin.parent_count() == 1 =>
 				Ok(Origin::root()),
@@ -92,7 +92,7 @@ impl<
 	Origin: From<ParachainOrigin>,
 > ConvertOrigin<Origin> for ChildParachainAsNative<ParachainOrigin, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.junctions()) {
+		match (kind, origin.interior()) {
 			(OriginKind::Native, Junctions::X1(Junction::Parachain(id)))
 			=> Ok(Origin::from(ParachainOrigin::from(*id))),
 			_ => Err(origin),
@@ -108,7 +108,7 @@ impl<
 	Origin: From<ParachainOrigin>,
 > ConvertOrigin<Origin> for SiblingParachainAsNative<ParachainOrigin, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.junctions()) {
+		match (kind, origin.interior()) {
 			(OriginKind::Native, Junctions::X1(Junction::Parachain(id)))
 			if origin.parent_count() == 1 =>
 				Ok(Origin::from(ParachainOrigin::from(*id))),
@@ -126,7 +126,7 @@ impl<
 	Origin,
 > ConvertOrigin<Origin> for RelayChainAsNative<RelayOrigin, Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		if kind == OriginKind::Native && origin.parent_count() == 1 && origin.junctions().len() == 0 {
+		if kind == OriginKind::Native && origin.parent_count() == 1 && origin.interior().len() == 0 {
 			Ok(RelayOrigin::get())
 		} else {
 			Err(origin)
@@ -144,7 +144,7 @@ impl<
 	Origin::AccountId: From<[u8; 32]>,
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.junctions()) {
+		match (kind, origin.interior()) {
 			(OriginKind::Native, Junctions::X1(Junction::AccountId32 { id, network }))
 			if (matches!(network, NetworkId::Any) || network == &Network::get())
 				&& origin.parent_count() == 0
@@ -164,7 +164,7 @@ impl<
 	Origin::AccountId: From<[u8; 20]>,
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.junctions()) {
+		match (kind, origin.interior()) {
 			(OriginKind::Native, Junctions::X1(Junction::AccountKey20 { key, network }))
 				if (matches!(network, NetworkId::Any) || network == &Network::get())
 					&& origin.parent_count() == 0 =>
diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs
index 72d9fd979672..467541cb2c3c 100644
--- a/xcm/xcm-executor/src/traits/conversion.rs
+++ b/xcm/xcm-executor/src/traits/conversion.rs
@@ -131,7 +131,7 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
 /// struct BumpParaId;
 /// impl ConvertOrigin<u32> for BumpParaId {
 /// 	fn convert_origin(origin: MultiLocation, _: OriginKind) -> Result<u32, MultiLocation> {
-/// 		match origin.junctions() {
+/// 		match origin.interior() {
 /// 			Junctions::X1(Junction::Parachain(id)) if origin.parent_count() == 0 => {
 /// 				Err(Junctions::X1(Junction::Parachain(id + 1)).into())
 /// 			}
@@ -143,7 +143,7 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
 /// struct AcceptPara7;
 /// impl ConvertOrigin<u32> for AcceptPara7 {
 /// 	fn convert_origin(origin: MultiLocation, _: OriginKind) -> Result<u32, MultiLocation> {
-/// 		match origin.junctions() {
+/// 		match origin.interior() {
 /// 			Junctions::X1(Junction::Parachain(id)) if id == &7 && origin.parent_count() == 0 => {
 /// 				Ok(7)
 /// 			}

From bb5bf44d6c89261b4e6d87603bd5c6c1dc1fff73 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sun, 1 Aug 2021 23:47:48 +0200
Subject: [PATCH 034/166] Basic compile builds

---
 runtime/rococo/src/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 9d4dbdc1c53f..f25ce35baa84 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -87,7 +87,7 @@ pub use pallet_balances::Call as BalancesCall;
 
 use polkadot_parachain::primitives::Id as ParaId;
 
-use xcm::v0::{Xcm, MultiLocation, NetworkId, BodyId};
+use xcm::v0::{MultiLocation, NetworkId, BodyId};
 use xcm_executor::XcmExecutor;
 use xcm_builder::{
 	AccountId32Aliases, ChildParachainConvertsVia, SovereignSignedViaLocation,

From acef3195286d12427d097bf6e104874ad6c51bdf Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 00:09:41 +0200
Subject: [PATCH 035/166] First test fixed

---
 xcm/src/v0/multiasset.rs                      | 12 +++++--
 xcm/xcm-executor/src/assets.rs                | 34 ++++++++++---------
 xcm/xcm-executor/src/traits/transact_asset.rs | 10 +++---
 3 files changed, 33 insertions(+), 23 deletions(-)

diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 32b36f73a296..88cfa8c75364 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -323,9 +323,15 @@ impl From<WildMultiAsset> for MultiAssetFilter {
 	}
 }
 
-impl From<MultiAsset> for MultiAssetFilter {
-	fn from(x: MultiAsset) -> Self {
-		Self::Definite(vec![x].into())
+impl<T: Into<MultiAsset>> From<T> for MultiAssetFilter {
+	fn from(x: T) -> Self {
+		Self::Definite(vec![x.into()].into())
+	}
+}
+
+impl From<Vec<MultiAsset>> for MultiAssetFilter {
+	fn from(x: Vec<MultiAsset>) -> Self {
+		Self::Definite(x.into())
 	}
 }
 
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 5846185189f9..13e7c209e9f9 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -328,30 +328,32 @@ impl Assets {
 #[cfg(test)]
 mod tests {
 	use super::*;
+	use xcm::v0::prelude::*;
+	use MultiLocation::Null;
 	#[allow(non_snake_case)]
 	fn AF(id: u8, amount: u128) -> MultiAsset {
-		MultiAsset::AbstractFungible { id: vec![id], amount }
+		(vec![id], amount).into()
 	}
 	#[allow(non_snake_case)]
 	fn ANF(class: u8, instance_id: u128) -> MultiAsset {
-		MultiAsset::AbstractNonFungible { class: vec![class], instance: AssetInstance::Index { id: instance_id } }
+		(vec![class], AssetInstance::Index { id: instance_id }).into()
 	}
 	#[allow(non_snake_case)]
 	fn CF(amount: u128) -> MultiAsset {
-		MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount }
+		(Null, amount).into()
 	}
 	#[allow(non_snake_case)]
 	fn CNF(instance_id: u128) -> MultiAsset {
-		MultiAsset::ConcreteNonFungible { class: MultiLocation::Null, instance: AssetInstance::Index { id: instance_id } }
+		(Null, AssetInstance::Index { id: instance_id }).into()
 	}
 
 	fn test_assets() -> Assets {
-		let mut assets_vec: Vec<MultiAsset> = Vec::new();
-		assets_vec.push(AF(1, 100));
-		assets_vec.push(ANF(2, 200));
-		assets_vec.push(CF(300));
-		assets_vec.push(CNF(400));
-		assets_vec.into()
+		let mut assets = Assets::new();
+		assets.subsume(AF(1, 100));
+		assets.subsume(ANF(2, 200));
+		assets.subsume(CF(300));
+		assets.subsume(CNF(400));
+		assets
 	}
 
 	#[test]
@@ -393,15 +395,15 @@ mod tests {
 	#[test]
 	fn min_all_and_none_works() {
 		let assets = test_assets();
-		let none = vec![MultiAsset::None];
-		let all = vec![MultiAsset::All];
+		let none = MultiAssets::new().into();
+		let all = All.into();
 
-		let none_min = assets.min(none.iter());
+		let none_min = assets.min(&none);
 		assert_eq!(None, none_min.assets_iter().next());
-		let all_min = assets.min(all.iter());
+		let all_min = assets.min(&all);
 		assert!(all_min.assets_iter().eq(assets.assets_iter()));
 	}
-
+/*
 	#[test]
 	fn min_all_fungible_and_all_non_fungible_works() {
 		let assets = test_assets();
@@ -549,5 +551,5 @@ mod tests {
 
 		let assets = assets1.into_assets_iter().collect::<Vec<_>>();
 		assert_eq!(assets, vec![AF(1, 50), ANF(2, 200)]);
-	}
+	}*/
 }
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index 736990775a23..d4ff17ce8496 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -181,6 +181,8 @@ impl TransactAsset for Tuple {
 #[cfg(test)]
 mod tests {
 	use super::*;
+	use xcm::v0::prelude::*;
+	use MultiLocation::Null;
 
 	pub struct UnimplementedTransactor;
 	impl TransactAsset for UnimplementedTransactor {}
@@ -246,27 +248,27 @@ mod tests {
 	fn defaults_to_asset_not_found() {
 		type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Err(XcmError::AssetNotFound));
+		assert_eq!(MultiTransactor::deposit_asset(&(Null, 1).into(), &Null), Err(XcmError::AssetNotFound));
 	}
 
 	#[test]
 	fn unimplemented_and_not_found_continue_iteration() {
 		type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, SuccessfulTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Ok(()));
+		assert_eq!(MultiTransactor::deposit_asset(&(Null, 1).into(), &Null), Ok(()));
 	}
 
 	#[test]
 	fn unexpected_error_stops_iteration() {
 		type MultiTransactor = (OverflowTransactor, SuccessfulTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Err(XcmError::Overflow));
+		assert_eq!(MultiTransactor::deposit_asset(&(Null, 1).into(), &Null), Err(XcmError::Overflow));
 	}
 
 	#[test]
 	fn success_stops_iteration() {
 		type MultiTransactor = (SuccessfulTransactor, OverflowTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&MultiAsset::All, &MultiLocation::Null), Ok(()));
+		assert_eq!(MultiTransactor::deposit_asset(&(Null, 1).into(), &Null), Ok(()));
 	}
 }

From 7d700b62fe409e19522b1546252328a444cafdf9 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 00:28:03 +0200
Subject: [PATCH 036/166] All executor tests fixed

---
 xcm/xcm-executor/src/assets.rs                | 89 ++++++-------------
 xcm/xcm-executor/src/traits/transact_asset.rs |  1 -
 2 files changed, 29 insertions(+), 61 deletions(-)

diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 13e7c209e9f9..3064a4a7312a 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -403,31 +403,17 @@ mod tests {
 		let all_min = assets.min(&all);
 		assert!(all_min.assets_iter().eq(assets.assets_iter()));
 	}
-/*
-	#[test]
-	fn min_all_fungible_and_all_non_fungible_works() {
-		let assets = test_assets();
-		let fungible = vec![MultiAsset::AllFungible];
-		let non_fungible = vec![MultiAsset::AllNonFungible];
-
-		let fungible = assets.min(fungible.iter());
-		let fungible = fungible.assets_iter().collect::<Vec<_>>();
-		assert_eq!(fungible, vec![CF(300), AF(1, 100)]);
-		let non_fungible = assets.min(non_fungible.iter());
-		let non_fungible = non_fungible.assets_iter().collect::<Vec<_>>();
-		assert_eq!(non_fungible, vec![CNF(400), ANF(2, 200)]);
-	}
 
 	#[test]
 	fn min_all_abstract_works() {
 		let assets = test_assets();
-		let fungible = vec![MultiAsset::AllAbstractFungible { id: vec![1] }];
-		let non_fungible = vec![MultiAsset::AllAbstractNonFungible { class: vec![2] }];
+		let fungible = Wild((vec![1], WildFungible).into());
+		let non_fungible = Wild((vec![2], WildNonFungible).into());
 
-		let fungible = assets.min(fungible.iter());
+		let fungible = assets.min(&fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
 		assert_eq!(fungible, vec![AF(1, 100)]);
-		let non_fungible = assets.min(non_fungible.iter());
+		let non_fungible = assets.min(&non_fungible);
 		let non_fungible = non_fungible.assets_iter().collect::<Vec<_>>();
 		assert_eq!(non_fungible, vec![ANF(2, 200)]);
 	}
@@ -435,13 +421,13 @@ mod tests {
 	#[test]
 	fn min_all_concrete_works() {
 		let assets = test_assets();
-		let fungible = vec![MultiAsset::AllConcreteFungible { id: MultiLocation::Null }];
-		let non_fungible = vec![MultiAsset::AllConcreteNonFungible { class: MultiLocation::Null }];
+		let fungible = Wild((Null, WildFungible).into());
+		let non_fungible = Wild((Null, WildNonFungible).into());
 
-		let fungible = assets.min(fungible.iter());
+		let fungible = assets.min(&fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
 		assert_eq!(fungible, vec![CF(300)]);
-		let non_fungible = assets.min(non_fungible.iter());
+		let non_fungible = assets.min(&non_fungible);
 		let non_fungible = non_fungible.assets_iter().collect::<Vec<_>>();
 		assert_eq!(non_fungible, vec![CNF(400)]);
 	}
@@ -450,18 +436,18 @@ mod tests {
 	fn min_basic_works() {
 		let assets1 = test_assets();
 
-		let mut assets2_vec: Vec<MultiAsset> = Vec::new();
+		let mut assets2 = Assets::new();
 		// This is less than 100, so it will decrease to 50
-		assets2_vec.push(AF(1, 50));
+		assets2.subsume(AF(1, 50));
 		// This asset does not exist, so not included
-		assets2_vec.push(ANF(2, 400));
+		assets2.subsume(ANF(2, 400));
 		// This is more then 300, so it should stay at 300
-		assets2_vec.push(CF(600));
+		assets2.subsume(CF(600));
 		// This asset should be included
-		assets2_vec.push(CNF(400));
-		let assets2: Assets = assets2_vec.into();
+		assets2.subsume(CNF(400));
+		let assets2: MultiAssets = assets2.into();
 
-		let assets_min = assets1.min(assets2.assets_iter());
+		let assets_min = assets1.min(&assets2.into());
 		let assets_min = assets_min.into_assets_iter().collect::<Vec<_>>();
 		assert_eq!(assets_min, vec![CF(300), AF(1, 50), CNF(400)]);
 	}
@@ -469,39 +455,21 @@ mod tests {
 	#[test]
 	fn saturating_take_all_and_none_works() {
 		let mut assets = test_assets();
-		let none = vec![MultiAsset::None];
-		let all = vec![MultiAsset::All];
 
-		let taken_none = assets.saturating_take(none);
+		let taken_none = assets.saturating_take(vec![].into());
 		assert_eq!(None, taken_none.assets_iter().next());
-		let taken_all = assets.saturating_take(all);
+		let taken_all = assets.saturating_take(All.into());
 		// Everything taken
 		assert_eq!(None, assets.assets_iter().next());
 		let all_iter = taken_all.assets_iter();
 		assert!(all_iter.eq(test_assets().assets_iter()));
 	}
 
-	#[test]
-	fn saturating_take_all_fungible_and_all_non_fungible_works() {
-		let mut assets = test_assets();
-		let fungible = vec![MultiAsset::AllFungible];
-		let non_fungible = vec![MultiAsset::AllNonFungible];
-
-		let fungible = assets.saturating_take(fungible);
-		let fungible = fungible.assets_iter().collect::<Vec<_>>();
-		assert_eq!(fungible, vec![CF(300), AF(1, 100)]);
-		let non_fungible = assets.saturating_take(non_fungible);
-		let non_fungible = non_fungible.assets_iter().collect::<Vec<_>>();
-		assert_eq!(non_fungible, [CNF(400), ANF(2, 200)]);
-		// Assets completely drained
-		assert_eq!(None, assets.assets_iter().next());
-	}
-
 	#[test]
 	fn saturating_take_all_abstract_works() {
 		let mut assets = test_assets();
-		let fungible = vec![MultiAsset::AllAbstractFungible { id: vec![1] }];
-		let non_fungible = vec![MultiAsset::AllAbstractNonFungible { class: vec![2] }];
+		let fungible = Wild((vec![1], WildFungible).into());
+		let non_fungible = Wild((vec![2], WildNonFungible).into());
 
 		let fungible = assets.saturating_take(fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
@@ -517,8 +485,8 @@ mod tests {
 	#[test]
 	fn saturating_take_all_concrete_works() {
 		let mut assets = test_assets();
-		let fungible = vec![MultiAsset::AllConcreteFungible { id: MultiLocation::Null }];
-		let non_fungible = vec![MultiAsset::AllConcreteNonFungible { class: MultiLocation::Null }];
+		let fungible = Wild((Null, WildFungible).into());
+		let non_fungible = Wild((Null, WildNonFungible).into());
 
 		let fungible = assets.saturating_take(fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
@@ -535,21 +503,22 @@ mod tests {
 	fn saturating_take_basic_works() {
 		let mut assets1 = test_assets();
 
-		let mut assets2_vec: Vec<MultiAsset> = Vec::new();
+		let mut assets2 = Assets::new();
 		// We should take 50
-		assets2_vec.push(AF(1, 50));
+		assets2.subsume(AF(1, 50));
 		// This asset should not be taken
-		assets2_vec.push(ANF(2, 400));
+		assets2.subsume(ANF(2, 400));
 		// This is more then 300, so it takes everything
-		assets2_vec.push(CF(600));
+		assets2.subsume(CF(600));
 		// This asset should be taken
-		assets2_vec.push(CNF(400));
+		assets2.subsume(CNF(400));
+		let assets2: MultiAssets = assets2.into();
 
-		let taken = assets1.saturating_take(assets2_vec);
+		let taken = assets1.saturating_take(assets2.into());
 		let taken = taken.into_assets_iter().collect::<Vec<_>>();
 		assert_eq!(taken, vec![CF(300), AF(1, 50), CNF(400)]);
 
 		let assets = assets1.into_assets_iter().collect::<Vec<_>>();
 		assert_eq!(assets, vec![AF(1, 50), ANF(2, 200)]);
-	}*/
+	}
 }
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index d4ff17ce8496..09cd94b19918 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -181,7 +181,6 @@ impl TransactAsset for Tuple {
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use xcm::v0::prelude::*;
 	use MultiLocation::Null;
 
 	pub struct UnimplementedTransactor;

From 3e62aa35b5945c786c5256baec10b3d701f5d4eb Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 00:32:23 +0200
Subject: [PATCH 037/166] Typo

---
 xcm/src/v0/multiasset.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 88cfa8c75364..c6fb07518578 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -94,7 +94,7 @@ impl AssetId {
 	}
 }
 
-/// Classification of whether an asset is fungible or not, along with an mandatory amount or instance.
+/// Classification of whether an asset is fungible or not, along with a mandatory amount or instance.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum Fungibility {
 	Fungible(u128),

From ca477f093f6e287cf3d7a3456327be8d8c7118f0 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 01:11:56 +0200
Subject: [PATCH 038/166] Optimize subsume_assets and add test

---
 xcm/xcm-executor/src/assets.rs | 44 ++++++++++++++++++++++++++++++----
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 3064a4a7312a..5cb8aac02a37 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -104,12 +104,32 @@ impl Assets {
 	}
 
 	/// Mutate `self` to contain all given `assets`, saturating if necessary.
-	pub fn subsume_assets(&mut self, assets: Assets) {
-		// TODO: Could be done with a much faster btree entry merge and only sum the entries with the
-		//   same key.
-		for asset in assets.into_assets_iter() {
-			self.subsume(asset)
+	pub fn subsume_assets(&mut self, mut assets: Assets) {
+		let mut f_iter = assets.fungible.iter_mut();
+		let mut g_iter = self.fungible.iter_mut();
+		if let (Some(mut f), Some(mut g)) = (f_iter.next(), g_iter.next()) {
+			loop {
+				if f.0 == g.0 {
+					// keys are equal. in this case, we add `swlf`'s balance for the asset onto `assets`, balance, knowing
+					// that the `append` operation which follows will clobber `self`'s value and only use `assets`'s.
+					*f.1 += *g.1;
+				}
+				if f.0 <= g.0 {
+					f = match f_iter.next() {
+						Some(x) => x,
+						None => break,
+					};
+				}
+				if f.0 >= g.0 {
+					g = match g_iter.next() {
+						Some(x) => x,
+						None => break,
+					};
+				}
+			}
 		}
+		self.fungible.append(&mut assets.fungible);
+		self.non_fungible.append(&mut assets.non_fungible);
 	}
 
 	/// Mutate `self` to contain the given `asset`, saturating if necessary.
@@ -356,6 +376,20 @@ mod tests {
 		assets
 	}
 
+	#[test]
+	fn subsume_assets_works() {
+		let t1 = test_assets();
+		let mut t2 = Assets::new();
+		t2.subsume(AF(1, 50));
+		t2.subsume(ANF(2, 100));
+		t2.subsume(CF(300));
+		t2.subsume(CNF(500));
+		let r1 = t1.clone().subsume_assets(t2.clone());
+		let mut r2 = t1.clone();
+		for a in t2.assets_iter() { r2.subsume(a) }
+		assert_eq!(r1, r2);
+	}
+
 	#[test]
 	fn into_assets_iter_works() {
 		let assets = test_assets();

From 3cc428fce5d734f41deb17c99bae76c51722f1c2 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 01:30:43 +0200
Subject: [PATCH 039/166] Optimize checked_sub

---
 xcm/xcm-executor/src/assets.rs | 52 +++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 7 deletions(-)

diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 5cb8aac02a37..bd499bd8ec62 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -274,12 +274,29 @@ impl Assets {
 	}
 
 	/// Consumes `self` and returns its original value excluding `asset` iff it contains at least `asset`.
-	pub fn checked_sub(mut self, asset: MultiAsset) -> Result<Assets, Self> {
-		// TODO: Optimize by doing this operation directly rather than converting into a MultiAssetFilter and
-		//   constructing the unused `_taken` return value.
-		match self.try_take(asset.into()) {
-			Ok(_taken) => Ok(self),
-			Err(_) => Err(self),
+	pub fn checked_sub(mut self, asset: MultiAsset) -> Result<Assets, Assets> {
+		match asset.fun {
+			Fungible(amount) => {
+				let remove = if let Some(balance) = self.fungible.get_mut(&asset.id) {
+					if *balance >= amount {
+						*balance -= amount;
+						*balance == 0
+					} else {
+						return Err(self)
+					}
+				} else {
+					return Err(self)
+				};
+				if remove {
+					self.fungible.remove(&asset.id);
+				}
+				Ok(self)
+			}
+			NonFungible(instance) => if self.non_fungible.remove(&(asset.id, instance)) {
+				Ok(self)
+			} else {
+				Err(self)
+			},
 		}
 	}
 
@@ -384,12 +401,33 @@ mod tests {
 		t2.subsume(ANF(2, 100));
 		t2.subsume(CF(300));
 		t2.subsume(CNF(500));
-		let r1 = t1.clone().subsume_assets(t2.clone());
+		let mut r1 = t1.clone();
+		r1.subsume_assets(t2.clone());
 		let mut r2 = t1.clone();
 		for a in t2.assets_iter() { r2.subsume(a) }
 		assert_eq!(r1, r2);
 	}
 
+	#[test]
+	fn checked_sub_works() {
+		let t = test_assets();
+		let t = t.checked_sub(AF(1, 50)).unwrap();
+		let t = t.checked_sub(AF(1, 51)).unwrap_err();
+		let t = t.checked_sub(AF(1, 50)).unwrap();
+		let t = t.checked_sub(AF(1, 1)).unwrap_err();
+		let t = t.checked_sub(CF(150)).unwrap();
+		let t = t.checked_sub(CF(151)).unwrap_err();
+		let t = t.checked_sub(CF(150)).unwrap();
+		let t = t.checked_sub(CF(1)).unwrap_err();
+		let t = t.checked_sub(ANF(2, 201)).unwrap_err();
+		let t = t.checked_sub(ANF(2, 200)).unwrap();
+		let t = t.checked_sub(ANF(2, 200)).unwrap_err();
+		let t = t.checked_sub(CNF(401)).unwrap_err();
+		let t = t.checked_sub(CNF(400)).unwrap();
+		let t = t.checked_sub(CNF(400)).unwrap_err();
+		assert_eq!(t, Assets::new());
+	}
+
 	#[test]
 	fn into_assets_iter_works() {
 		let assets = test_assets();

From 099aea73570a56bb07a26a07ffd34f99dc6e534c Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 01:43:54 +0200
Subject: [PATCH 040/166] XCM Builder first test fixed

---
 xcm/src/v0/mod.rs            |  3 ++-
 xcm/src/v0/multiasset.rs     | 12 ++++++------
 xcm/src/v0/order.rs          |  4 ++--
 xcm/xcm-builder/src/mock.rs  | 17 +++++++----------
 xcm/xcm-builder/src/tests.rs | 10 +++++-----
 5 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 38d940a16a19..473cc9f06b7b 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -38,7 +38,7 @@ pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
 
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
-	pub use super::junction::{Junction::*, NetworkId, BodyId, BodyPart};
+	pub use super::junction::{Junction::*, NetworkId::{self, *}, BodyId, BodyPart};
 	pub use super::multiasset::{
 		MultiAssets, MultiAsset,
 		AssetId::{self, *},
@@ -52,6 +52,7 @@ pub mod prelude {
 	pub use super::order::Order::{self, *};
 	pub use super::traits::{Error as XcmError, Result as XcmResult, SendXcm, ExecuteXcm, Outcome};
 	pub use super::{Xcm::{self, *}, OriginKind};
+	pub use super::opaque;
 }
 
 // TODO: #2841 #XCMENCODE Efficient encodings for MultiAssets, Vec<Order>, using initial byte values 128+ to encode
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index c6fb07518578..207b117b9ed6 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -317,15 +317,15 @@ pub enum MultiAssetFilter {
 	Wild(WildMultiAsset),
 }
 
-impl From<WildMultiAsset> for MultiAssetFilter {
-	fn from(x: WildMultiAsset) -> Self {
-		Self::Wild(x)
+impl<T: Into<WildMultiAsset>> From<T> for MultiAssetFilter {
+	fn from(x: T) -> Self {
+		Self::Wild(x.into())
 	}
 }
 
-impl<T: Into<MultiAsset>> From<T> for MultiAssetFilter {
-	fn from(x: T) -> Self {
-		Self::Definite(vec![x.into()].into())
+impl From<MultiAsset> for MultiAssetFilter {
+	fn from(x: MultiAsset) -> Self {
+		Self::Definite(vec![x].into())
 	}
 }
 
diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index 6162581f7e28..3917e6a01116 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -29,7 +29,7 @@ use super::{MultiAsset, MultiAssetFilter, MultiLocation, Xcm};
 pub enum Order<Call> {
 	/// Do nothing. Not generally used.
 	#[codec(index = 0)]
-	Null,
+	Noop,
 
 	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
 	/// this consensus system.
@@ -121,7 +121,7 @@ impl<Call> Order<Call> {
 	pub fn from<C>(order: Order<C>) -> Self {
 		use Order::*;
 		match order {
-			Null => Null,
+			Noop => Noop,
 			DepositAsset { assets, dest }
 				=> DepositAsset { assets, dest },
 			DepositReserveAsset { assets, dest, effects }
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 6e9b7ff5a322..81f926626829 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -17,10 +17,7 @@
 pub use sp_std::{fmt::Debug, marker::PhantomData, cell::RefCell};
 pub use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
 pub use parity_scale_codec::{Encode, Decode};
-pub use xcm::v0::{
-	SendXcm, MultiLocation::*, Junction::*, MultiAsset, Xcm, Order, Result as XcmResult, Error as XcmError,
-	OriginKind, MultiLocation, Junction, opaque,
-};
+pub use xcm::v0::prelude::*;
 pub use frame_support::{
 	ensure, parameter_types,
 	dispatch::{Dispatchable, Parameter, Weight, DispatchError, DispatchResultWithPostInfo, DispatchInfo},
@@ -139,8 +136,8 @@ impl TransactAsset for TestAssetTransactor {
 		ASSETS.with(|a| a.borrow_mut()
 			.get_mut(&who)
 			.ok_or(XcmError::NotWithdrawable)?
-			.try_take(what.clone())
-			.map_err(|()| XcmError::NotWithdrawable)
+			.try_take(what.clone().into())
+			.map_err(|_| XcmError::NotWithdrawable)
 		)
 	}
 }
@@ -178,14 +175,14 @@ impl ConvertOrigin<TestOrigin> for TestOriginConverter {
 }
 
 thread_local! {
-	pub static IS_RESERVE: RefCell<BTreeMap<MultiLocation, Vec<MultiAsset>>> = RefCell::new(BTreeMap::new());
-	pub static IS_TELEPORTER: RefCell<BTreeMap<MultiLocation, Vec<MultiAsset>>> = RefCell::new(BTreeMap::new());
+	pub static IS_RESERVE: RefCell<BTreeMap<MultiLocation, Vec<MultiAssetFilter>>> = RefCell::new(BTreeMap::new());
+	pub static IS_TELEPORTER: RefCell<BTreeMap<MultiLocation, Vec<MultiAssetFilter>>> = RefCell::new(BTreeMap::new());
 }
-pub fn add_reserve(from: MultiLocation, asset: MultiAsset) {
+pub fn add_reserve(from: MultiLocation, asset: MultiAssetFilter) {
 	IS_RESERVE.with(|r| r.borrow_mut().entry(from).or_default().push(asset));
 }
 #[allow(dead_code)]
-pub fn add_teleporter(from: MultiLocation, asset: MultiAsset) {
+pub fn add_teleporter(from: MultiLocation, asset: MultiAssetFilter) {
 	IS_TELEPORTER.with(|r| r.borrow_mut().entry(from).or_default().push(asset));
 }
 pub struct TestIsReserve;
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 79235427be62..a0af0893d6d2 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -16,15 +16,14 @@
 
 use super::*;
 use super::mock::*;
-use {MultiAsset::*, Option::None};
-use xcm::v0::{Order, NetworkId::Any, Outcome, Response, ExecuteXcm};
+use xcm::v0::prelude::*;
 use xcm_executor::{XcmExecutor, Config, traits::*};
 
 #[test]
 fn basic_setup_works() {
-	add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) });
+	add_reserve(X1(Parent), Wild((X1(Parent), WildFungible).into()));
 	assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
-		&ConcreteFungible { id: X1(Parent), amount: 100 },
+		&(X1(Parent), 100).into(),
 		&X1(Parent),
 	));
 
@@ -36,7 +35,7 @@ fn basic_setup_works() {
 	assert_eq!(to_account(X1(AccountIndex64{index:42, network:Any})), Ok(42));
 	assert_eq!(to_account(Null), Ok(3000));
 }
-
+/*
 #[test]
 fn weigher_should_work() {
 	let mut message = opaque::Xcm::ReserveAssetDeposited {
@@ -336,3 +335,4 @@ fn prepaid_result_of_query_should_get_free_execution() {
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin.clone(), message.clone(), weight_limit);
 	assert_eq!(r, Outcome::Incomplete(10, XcmError::Barrier));
 }
+*/

From 51584424df5ead86d25364b0e837cfb3db13deaf Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 08:55:57 +0200
Subject: [PATCH 041/166] Fix builder tests

---
 xcm/src/v0/mod.rs              |  2 +-
 xcm/src/v0/multiasset.rs       |  6 +++
 xcm/xcm-builder/src/lib.rs     |  4 +-
 xcm/xcm-builder/src/mock.rs    |  6 +--
 xcm/xcm-builder/src/tests.rs   | 77 ++++++++++++++++++----------------
 xcm/xcm-builder/src/weight.rs  | 65 +++++++++++++++++++++++++---
 xcm/xcm-executor/src/assets.rs | 16 +++----
 7 files changed, 121 insertions(+), 55 deletions(-)

diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 473cc9f06b7b..95bccfacf0b5 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -51,7 +51,7 @@ pub mod prelude {
 	pub use super::multi_location::MultiLocation::{self, *};
 	pub use super::order::Order::{self, *};
 	pub use super::traits::{Error as XcmError, Result as XcmResult, SendXcm, ExecuteXcm, Outcome};
-	pub use super::{Xcm::{self, *}, OriginKind};
+	pub use super::{Xcm::{self, *}, OriginKind, Response};
 	pub use super::opaque;
 }
 
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 207b117b9ed6..f00c73d8efee 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -209,6 +209,12 @@ impl From<Vec<MultiAsset>> for MultiAssets {
 	}
 }
 
+impl<T: Into<MultiAsset>> From<T> for MultiAssets {
+	fn from(x: T) -> Self {
+		Self(vec![x.into()])
+	}
+}
+
 impl MultiAssets {
 	/// A new (empty) value.
 	pub fn new() -> Self {
diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs
index 534261a9998d..339a9321e1ad 100644
--- a/xcm/xcm-builder/src/lib.rs
+++ b/xcm/xcm-builder/src/lib.rs
@@ -54,7 +54,9 @@ pub use fungibles_adapter::{
 };
 
 mod weight;
-pub use weight::{FixedRateOfConcreteFungible, FixedWeightBounds, UsingComponents, TakeRevenue};
+pub use weight::{FixedRateOfFungible, FixedWeightBounds, UsingComponents, TakeRevenue};
+#[allow(deprecated)]
+pub use weight::FixedRateOfConcreteFungible;
 
 mod matches_fungible;
 pub use matches_fungible::{IsAbstract, IsConcrete};
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 81f926626829..d036d2997df1 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -30,7 +30,7 @@ pub use xcm_executor::{
 };
 pub use crate::{
 	TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedWeightBounds,
-	FixedRateOfConcreteFungible, AllowKnownQueryResponses, LocationInverter,
+	FixedRateOfFungible, AllowKnownQueryResponses, LocationInverter,
 };
 
 pub enum TestOrigin {
@@ -253,7 +253,7 @@ parameter_types! {
 	pub static AllowUnpaidFrom: Vec<MultiLocation> = vec![];
 	pub static AllowPaidFrom: Vec<MultiLocation> = vec![];
 	// 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight.
-	pub static WeightPrice: (MultiLocation, u128) = (Null, 1_000_000_000_000);
+	pub static WeightPrice: (AssetId, u128) = (Null.into(), 1_000_000_000_000);
 }
 
 pub type TestBarrier = (
@@ -274,6 +274,6 @@ impl Config for TestConfig {
 	type LocationInverter = LocationInverter<TestAncestry>;
 	type Barrier = TestBarrier;
 	type Weigher = FixedWeightBounds<UnitWeightCost, TestCall>;
-	type Trader = FixedRateOfConcreteFungible<WeightPrice, ()>;
+	type Trader = FixedRateOfFungible<WeightPrice, ()>;
 	type ResponseHandler = TestResponseHandler;
 }
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index a0af0893d6d2..e23c262ea660 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -35,14 +35,14 @@ fn basic_setup_works() {
 	assert_eq!(to_account(X1(AccountIndex64{index:42, network:Any})), Ok(42));
 	assert_eq!(to_account(Null), Ok(3000));
 }
-/*
+
 #[test]
 fn weigher_should_work() {
 	let mut message = opaque::Xcm::ReserveAssetDeposited {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: vec![All], dest: Null },
+			Order::BuyExecution { fees: (X1(Parent), 1).into(), weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
+			Order::DepositAsset { assets: All.into(), dest: Null },
 		],
 	}.into();
 	assert_eq!(<TestConfig as Config>::Weigher::shallow(&mut message), Ok(30));
@@ -51,7 +51,7 @@ fn weigher_should_work() {
 #[test]
 fn take_weight_credit_barrier_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: (X1(Parent), 100).into(),
 		dest: Null,
 	};
 
@@ -80,7 +80,7 @@ fn take_weight_credit_barrier_should_work() {
 #[test]
 fn allow_unpaid_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: (X1(Parent), 100).into(),
 		dest: Null,
 	};
 
@@ -110,7 +110,7 @@ fn allow_paid_should_work() {
 	AllowPaidFrom::set(vec![ X1(Parent) ]);
 
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: (X1(Parent), 100).into(),
 		dest: Null,
 	};
 
@@ -123,11 +123,12 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
+	let fees = (X1(Parent), 1).into();
 	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::BuyExecution { fees: All, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: vec![All], dest: Null },
+			Order::BuyExecution { fees, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] },
+			Order::DepositAsset { assets: All.into(), dest: Null },
 		],
 	};
 
@@ -140,11 +141,12 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
+	let fees = (X1(Parent), 1).into();
 	let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: vec![ConcreteFungible { id: X1(Parent), amount: 100 }],
+		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: vec![All], dest: Null },
+			Order::BuyExecution { fees, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
+			Order::DepositAsset { assets: All.into(), dest: Null },
 		],
 	};
 
@@ -170,21 +172,22 @@ fn allow_paid_should_work() {
 #[test]
 fn paying_reserve_deposit_should_work() {
 	AllowPaidFrom::set(vec![ X1(Parent) ]);
-	add_reserve(X1(Parent), AllConcreteFungible { id: X1(Parent) });
-	WeightPrice::set((X1(Parent), 1_000_000_000_000));
+	add_reserve(X1(Parent), (X1(Parent), WildFungible).into());
+	WeightPrice::set((X1(Parent).into(), 1_000_000_000_000));
 
 	let origin = X1(Parent);
+	let fees = (X1(Parent), 30).into();
 	let message = Xcm::<TestCall>::ReserveAssetDeposited {
-		assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],
+		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::<TestCall>::BuyExecution { fees: All, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
-			Order::<TestCall>::DepositAsset { assets: vec![ All ], dest: Null },
+			Order::<TestCall>::BuyExecution { fees, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
+			Order::<TestCall>::DepositAsset { assets: All.into(), dest: Null },
 		],
 	};
 	let weight_limit = 50;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(30));
-	assert_eq!(assets(3000), vec![ ConcreteFungible { id: X1(Parent), amount: 70 } ]);
+	assert_eq!(assets(3000), vec![(X1(Parent), 70).into()]);
 }
 
 #[test]
@@ -192,19 +195,19 @@ fn transfer_should_work() {
 	// we'll let them have message execution for free.
 	AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, ConcreteFungible { id: Null, amount: 1000 });
+	add_asset(1001, (Null, 1000).into());
 	// They want to transfer 100 of them to their sibling parachain #2
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
 		X1(Parachain(1)),
 		Xcm::TransferAsset {
-			assets: vec![ ConcreteFungible { id: Null, amount: 100 } ],
+			assets: (Null, 100).into(),
 			dest: X1(AccountIndex64{index:3, network:Any}),
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
-	assert_eq!(assets(3), vec![ ConcreteFungible { id: Null, amount: 100 } ]);
-	assert_eq!(assets(1001), vec![ ConcreteFungible { id: Null, amount: 900 } ]);
+	assert_eq!(assets(3), vec![(Null, 100).into()]);
+	assert_eq!(assets(1001), vec![(Null, 900).into()]);
 	assert_eq!(sent_xcm(), vec![]);
 }
 
@@ -212,7 +215,7 @@ fn transfer_should_work() {
 fn reserve_transfer_should_work() {
 	AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, ConcreteFungible { id: Null, amount: 1000 });
+	add_asset(1001, (Null, 1000).into());
 	// The remote account owned by gav.
 	let three = X1(AccountIndex64{index:3, network:Any});
 
@@ -221,20 +224,20 @@ fn reserve_transfer_should_work() {
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
 		X1(Parachain(1)),
 		Xcm::TransferReserveAsset {
-			assets: vec![ ConcreteFungible { id: Null, amount: 100 } ],
+			assets: (Null, 100).into(),
 			dest: X1(Parachain(2)),
-			effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three.clone() } ],
+			effects: vec![ Order::DepositAsset { assets: All.into(), dest: three.clone() } ],
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
 
-	assert_eq!(assets(1002), vec![ ConcreteFungible { id: Null, amount: 100 } ]);
+	assert_eq!(assets(1002), vec![(Null, 100).into()]);
 	assert_eq!(sent_xcm(), vec![(
 		X1(Parachain(2)),
 		Xcm::ReserveAssetDeposited {
-			assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],
-			effects: vec![ Order::DepositAsset { assets: vec![ All ], dest: three } ],
+			assets: (X1(Parent), 100).into(),
+			effects: vec![ Order::DepositAsset { assets: All.into(), dest: three } ],
 		})
 	]);
 }
@@ -288,14 +291,15 @@ fn transacting_should_refund_weight() {
 fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let one = X1(AccountIndex64{index:1, network:Any});
 	AllowPaidFrom::set(vec![ one.clone() ]);
-	add_asset(1, ConcreteFungible { id: X1(Parent), amount: 100 });
-	WeightPrice::set((X1(Parent), 1_000_000_000_000));
+	add_asset(1, (X1(Parent), 100).into());
+	WeightPrice::set((X1(Parent).into(), 1_000_000_000_000));
 
 	let origin = one.clone();
+	let fees = (X1(Parent), 100).into();
 	let message = Xcm::<TestCall>::WithdrawAsset {
-		assets: vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ],	// enough for 100 units of weight.
+		assets: (X1(Parent), 100).into(),	// enough for 100 units of weight.
 		effects: vec![
-			Order::<TestCall>::BuyExecution { fees: All, weight: 70, debt: 30, halt_on_error: true, xcm: vec![
+			Order::<TestCall>::BuyExecution { fees, weight: 70, debt: 30, halt_on_error: true, xcm: vec![
 				Xcm::<TestCall>::Transact {
 					origin_type: OriginKind::Native,
 					require_weight_at_most: 60,
@@ -303,13 +307,13 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 					call: TestCall::Any(60, Some(10)).encode().into(),
 				}
 			] },
-			Order::<TestCall>::DepositAsset { assets: vec![ All ], dest: one.clone() },
+			Order::<TestCall>::DepositAsset { assets: All.into(), dest: one.clone() },
 		],
 	};
 	let weight_limit = 100;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(50));
-	assert_eq!(assets(1), vec![ ConcreteFungible { id: X1(Parent), amount: 50 } ]);
+	assert_eq!(assets(1), vec![(X1(Parent), 50).into()]);
 }
 
 #[test]
@@ -319,7 +323,7 @@ fn prepaid_result_of_query_should_get_free_execution() {
 	// We put this in manually here, but normally this would be done at the point of crafting the message.
 	expect_response(query_id, origin.clone());
 
-	let the_response = Response::Assets(vec![ ConcreteFungible { id: X1(Parent), amount: 100 } ]);
+	let the_response = Response::Assets((X1(Parent), 100).into());
 	let message = Xcm::<TestCall>::QueryResponse {
 		query_id,
 		response: the_response.clone(),
@@ -335,4 +339,3 @@ fn prepaid_result_of_query_should_get_free_execution() {
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin.clone(), message.clone(), weight_limit);
 	assert_eq!(r, Outcome::Incomplete(10, XcmError::Barrier));
 }
-*/
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index ef18fcf99783..500db2a393c1 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -16,7 +16,7 @@
 
 use sp_std::{result::Result, marker::PhantomData, convert::TryInto};
 use parity_scale_codec::Decode;
-use xcm::v0::{Xcm, Order, MultiAsset, MultiLocation, Error, AssetId::Concrete};
+use xcm::v0::{Xcm, Order, MultiAsset, AssetId, MultiLocation, Error, AssetId::Concrete};
 use sp_runtime::traits::{Zero, Saturating, SaturatedConversion};
 use frame_support::traits::{Get, OnUnbalanced as OnUnbalancedT, tokens::currency::Currency as CurrencyT};
 use frame_support::weights::{Weight, GetDispatchInfo, WeightToFeePolynomial};
@@ -92,10 +92,12 @@ impl TakeRevenue for () {
 ///
 /// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for
 /// one second of weight.
+#[deprecated = "Use `FixedRateOfFungible` instead"]
 pub struct FixedRateOfConcreteFungible<
 	T: Get<(MultiLocation, u128)>,
 	R: TakeRevenue,
 >(Weight, u128, PhantomData<(T, R)>);
+#[allow(deprecated)]
 impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader for FixedRateOfConcreteFungible<T, R> {
 	fn new() -> Self { Self(0, 0, PhantomData) }
 
@@ -115,13 +117,62 @@ impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader for FixedRateOf
 		let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128;
 		self.0 -= weight;
 		self.1 = self.1.saturating_sub(amount);
-		Some((Concrete(id), amount).into())
+		if amount > 0 {
+			Some((Concrete(id), amount).into())
+		} else {
+			None
+		}
 	}
 }
-
+#[allow(deprecated)]
 impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> Drop for FixedRateOfConcreteFungible<T, R> {
 	fn drop(&mut self) {
-		R::take_revenue((Concrete(T::get().0), self.1).into());
+		if self.1 > 0 {
+			R::take_revenue((Concrete(T::get().0), self.1).into());
+		}
+	}
+}
+
+/// Simple fee calculator that requires payment in a single fungible at a fixed rate.
+///
+/// The constant `Get` type parameter should be the fungible ID and the amount of it required for
+/// one second of weight.
+pub struct FixedRateOfFungible<
+	T: Get<(AssetId, u128)>,
+	R: TakeRevenue,
+>(Weight, u128, PhantomData<(T, R)>);
+impl<T: Get<(AssetId, u128)>, R: TakeRevenue> WeightTrader for FixedRateOfFungible<T, R> {
+	fn new() -> Self { Self(0, 0, PhantomData) }
+
+	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error> {
+		let (id, units_per_second) = T::get();
+		use frame_support::weights::constants::WEIGHT_PER_SECOND;
+		let amount = units_per_second * (weight as u128) / (WEIGHT_PER_SECOND as u128);
+		let unused = payment.checked_sub((id, amount).into()).map_err(|_| Error::TooExpensive)?;
+		self.0 = self.0.saturating_add(weight);
+		self.1 = self.1.saturating_add(amount);
+		Ok(unused)
+	}
+
+	fn refund_weight(&mut self, weight: Weight) -> Option<MultiAsset> {
+		let (id, units_per_second) = T::get();
+		let weight = weight.min(self.0);
+		let amount = units_per_second * (weight as u128) / 1_000_000_000_000u128;
+		self.0 -= weight;
+		self.1 = self.1.saturating_sub(amount);
+		if amount > 0 {
+			Some((id, amount).into())
+		} else {
+			None
+		}
+	}
+}
+
+impl<T: Get<(AssetId, u128)>, R: TakeRevenue> Drop for FixedRateOfFungible<T, R> {
+	fn drop(&mut self) {
+		if self.1 > 0 {
+			R::take_revenue((T::get().0, self.1).into());
+		}
 	}
 }
 
@@ -159,7 +210,11 @@ impl<
 		self.0 -= weight;
 		self.1 = self.1.saturating_sub(amount);
 		let amount: u128 = amount.saturated_into();
-		Some((AssetId::get(), amount).into())
+		if amount > 0 {
+			Some((AssetId::get(), amount).into())
+		} else {
+			None
+		}
 	}
 
 }
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index bd499bd8ec62..23e576a35a9b 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -35,6 +35,14 @@ pub struct Assets {
 	pub non_fungible: BTreeSet<(AssetId, AssetInstance)>,
 }
 
+impl From<MultiAsset> for Assets {
+	fn from(asset: MultiAsset) -> Assets {
+		let mut result = Self::default();
+		result.subsume(asset);
+		result
+	}
+}
+
 impl From<Vec<MultiAsset>> for Assets {
 	fn from(assets: Vec<MultiAsset>) -> Assets {
 		let mut result = Self::default();
@@ -63,14 +71,6 @@ impl From<Assets> for MultiAssets {
 	}
 }
 
-impl From<MultiAsset> for Assets {
-	fn from(asset: MultiAsset) -> Assets {
-		let mut result = Self::default();
-		result.subsume(asset);
-		result
-	}
-}
-
 /// An error emitted by `take` operations.
 #[derive(Debug)]
 pub enum TakeError {

From 6814aa8db13f4a64ce133fadc44811f36c7faa3b Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 11:15:53 +0200
Subject: [PATCH 042/166] Fix doc test

---
 xcm/xcm-executor/src/assets.rs | 17 +++++------------
 1 file changed, 5 insertions(+), 12 deletions(-)

diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 23e576a35a9b..41fafbf67c40 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -308,20 +308,13 @@ impl Assets {
 	///
 	/// ```
 	/// use xcm_executor::Assets;
-	/// use xcm::v0::{MultiAsset, MultiLocation};
-	/// let assets_i_have: Assets = vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 100 },
-	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 100 },
-	/// ].into();
-	/// let assets_they_want: Assets = vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 200 },
-	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 50 },
-	/// ].into();
+	/// use xcm::v0::prelude::*;
+	/// let assets_i_have: Assets = vec![ (Null, 100).into(), (vec![0], 100).into() ].into();
+	/// let assets_they_want: MultiAssetFilter = vec![ (Null, 200).into(), (vec![0], 50).into() [.into();
 	///
-	/// let assets_we_can_trade: Assets = assets_i_have.min(assets_they_want.assets_iter());
+	/// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want);
 	/// assert_eq!(assets_we_can_trade.into_assets_iter().collect::<Vec<_>>(), vec![
-	/// 	MultiAsset::ConcreteFungible { id: MultiLocation::Null, amount: 100 },
-	/// 	MultiAsset::AbstractFungible { id: vec![0], amount: 50 },
+	/// 	(Null, 100).into(), (vec![0], 50).into(),
 	/// ]);
 	/// ```
 	pub fn min(&self, mask: &MultiAssetFilter) -> Assets {

From 8d8aa5cfead7d1d772728e86fcdfd466fe35db71 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Mon, 2 Aug 2021 04:41:34 -0700
Subject: [PATCH 043/166] Make xcm-simulator compile

---
 xcm/xcm-simulator/example/src/parachain.rs   |  2 +-
 xcm/xcm-simulator/example/src/relay_chain.rs |  4 ++--
 xcm/xcm-simulator/src/lib.rs                 | 10 +++++-----
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index f4ad471ff697..e8cb7021bd3f 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -110,7 +110,7 @@ parameter_types! {
 }
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = MultiLocation::X1(Parent);
+	pub const KsmLocation: MultiLocation = MultiLocation::with_parents(1).expect("well-formed XCM; qed");
 	pub const RelayNetwork: NetworkId = NetworkId::Kusama;
 	pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
 }
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index c69f20d05eaf..26a9af806c54 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -92,10 +92,10 @@ impl shared::Config for Runtime {}
 impl configuration::Config for Runtime {}
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = MultiLocation::Null;
+	pub const KsmLocation: MultiLocation = MultiLocation::empty();
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = MultiLocation::Null;
+	pub Ancestry: MultiLocation = MultiLocation::empty();
 	pub UnitWeightCost: Weight = 1_000;
 }
 
diff --git a/xcm/xcm-simulator/src/lib.rs b/xcm/xcm-simulator/src/lib.rs
index 096d62b61695..c875141c401c 100644
--- a/xcm/xcm-simulator/src/lib.rs
+++ b/xcm/xcm-simulator/src/lib.rs
@@ -194,8 +194,8 @@ macro_rules! decl_test_network {
 			fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::XcmResult {
 				use $crate::{UmpSink, XcmpMessageHandlerT};
 
-				match destination {
-					$crate::X1($crate::Parent) => {
+				match destination.interior() {
+					Null if destination.parent_count() == 1 => {
 						let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump);
 						let _ = <$relay_chain>::process_upward_message(
 							T::get(), &encoded[..],
@@ -204,7 +204,7 @@ macro_rules! decl_test_network {
 						Ok(())
 					},
 					$(
-						$crate::X2($crate::Parent, $crate::Parachain(id)) if id == $para_id => {
+						$crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 1 => {
 							let encoded = $crate::encode_xcm(message, $crate::MessageKind::Xcmp);
 							let messages = vec![(T::get(), 1, &encoded[..])];
 							let _ = <$parachain>::handle_xcmp_messages(
@@ -225,9 +225,9 @@ macro_rules! decl_test_network {
 			fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::XcmResult {
 				use $crate::DmpMessageHandlerT;
 
-				match destination {
+				match destination.interior() {
 					$(
-						$crate::X1($crate::Parachain(id)) if id == $para_id => {
+						$crate::X1($crate::Parachain(id)) if *id == $para_id && destination.parent_count() == 0 => {
 							let encoded = $crate::encode_xcm(message, $crate::MessageKind::Dmp);
 							let messages = vec![(1, encoded)];
 							let _ = <$parachain>::handle_dmp_messages(

From 825a2aa0712eb582a0df3a1787b305d07f5f5b34 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Mon, 2 Aug 2021 06:13:49 -0700
Subject: [PATCH 044/166] Make xcm-simulator-example compile

---
 xcm/src/v0/multi_location.rs               |  9 ++++++++
 xcm/xcm-simulator/example/src/lib.rs       | 24 +++++++++++-----------
 xcm/xcm-simulator/example/src/parachain.rs | 19 ++++++++++-------
 3 files changed, 33 insertions(+), 19 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 7c1efaa5e893..3ce4aeabe190 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -125,6 +125,15 @@ impl MultiLocation {
 		MultiLocation { parents: 0, interior: Junctions::Null }
 	}
 
+	/// Creates a new `MultiLocation` with the specified number of parents in the `P` const generic
+	/// parameter and a `Null` interior.
+	pub const fn with_parents_const<const P: u8>() -> MultiLocation {
+		MultiLocation {
+			parents: P,
+			interior: Junctions::Null,
+		}
+	}
+
 	/// Creates a new `MultiLocation` with the specified number of parents and a `Null` interior.
 	/// Returns an error if `parents` is greater than `MAX_MULTILOCATION_LENGTH`.
 	pub const fn with_parents(parents: u8) -> result::Result<MultiLocation, ()> {
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index f318409bf187..032cbd8c8674 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -101,10 +101,10 @@ mod tests {
 	use codec::Encode;
 	use frame_support::assert_ok;
 	use xcm::v0::{
-		Junction::{self, Parachain, Parent},
+		Junction::{self, Parachain},
+		Junctions::*,
 		MultiAsset::*,
-		MultiLocation::*,
-		NetworkId, OriginKind,
+		MultiLocation, NetworkId, OriginKind,
 		Xcm::*,
 	};
 	use xcm_simulator::TestExt;
@@ -118,8 +118,8 @@ mod tests {
 		);
 		Relay::execute_with(|| {
 			assert_ok!(RelayChainPalletXcm::send_xcm(
-				Null,
-				X1(Parachain(1)),
+				MultiLocation::empty(),
+				X1(Parachain(1)).into(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,
@@ -145,8 +145,8 @@ mod tests {
 		);
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
-				Null,
-				X1(Parent),
+				MultiLocation::empty(),
+				MultiLocation::with_parents(1).unwrap(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,
@@ -172,8 +172,8 @@ mod tests {
 		);
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
-				Null,
-				X2(Parent, Parachain(2)),
+				MultiLocation::empty(),
+				MultiLocation::new(1, X1(Parachain(2))).unwrap(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,
@@ -197,9 +197,9 @@ mod tests {
 		Relay::execute_with(|| {
 			assert_ok!(RelayChainPalletXcm::reserve_transfer_assets(
 				relay_chain::Origin::signed(ALICE),
-				X1(Parachain(1)),
-				X1(Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }),
-				vec![ConcreteFungible { id: Null, amount: 123 }],
+				X1(Parachain(1)).into(),
+				X1(Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }).into(),
+				vec![ConcreteFungible { id: MultiLocation::empty(), amount: 123 }],
 				123,
 			));
 		});
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index e8cb7021bd3f..cd92bdd80d44 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -38,9 +38,10 @@ use polkadot_parachain::primitives::{
 use xcm::{
 	v0::{
 		Error as XcmError, ExecuteXcm,
-		Junction::{Parachain, Parent},
+		Junction::Parachain,
+		Junctions::X1,
 		MultiAsset,
-		MultiLocation::{self, X1},
+		MultiLocation,
 		NetworkId, Outcome, Xcm,
 	},
 	VersionedXcm,
@@ -110,7 +111,7 @@ parameter_types! {
 }
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = MultiLocation::with_parents(1).expect("well-formed XCM; qed");
+	pub const KsmLocation: MultiLocation = MultiLocation::with_parents_const::<1>();
 	pub const RelayNetwork: NetworkId = NetworkId::Kusama;
 	pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
 }
@@ -129,7 +130,7 @@ pub type XcmOriginToCallOrigin = (
 
 parameter_types! {
 	pub const UnitWeightCost: Weight = 1;
-	pub KsmPerSecond: (MultiLocation, u128) = (X1(Parent), 1);
+	pub KsmPerSecond: (MultiLocation, u128) = (MultiLocation::with_parents(1).unwrap(), 1);
 }
 
 pub type LocalAssetTransactor =
@@ -219,8 +220,8 @@ pub mod mock_msg_queue {
 			let hash = Encode::using_encoded(&xcm, T::Hashing::hash);
 			let (result, event) = match Xcm::<T::Call>::try_from(xcm) {
 				Ok(xcm) => {
-					let location = (Parent, Parachain(sender.into()));
-					match T::XcmExecutor::execute_xcm(location.into(), xcm, max_weight) {
+					let location = MultiLocation::new(1, X1(Parachain(sender.into()))).unwrap();
+					match T::XcmExecutor::execute_xcm(location, xcm, max_weight) {
 						Outcome::Error(e) => (Err(e.clone()), Event::Fail(Some(hash), e)),
 						Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))),
 						// As far as the caller is concerned, this was dispatched without error, so
@@ -275,7 +276,11 @@ pub mod mock_msg_queue {
 						Self::deposit_event(Event::UnsupportedVersion(id));
 					},
 					Ok(Ok(x)) => {
-						let outcome = T::XcmExecutor::execute_xcm(Parent.into(), x, limit);
+						let outcome = T::XcmExecutor::execute_xcm(
+							MultiLocation::with_parents(1).unwrap(),
+							x,
+							limit,
+						);
 						Self::deposit_event(Event::ExecutedDownward(id, outcome));
 					},
 				}

From 4f4693a249f85fe992b1c9ba762e11084c62d912 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Mon, 2 Aug 2021 06:14:53 -0700
Subject: [PATCH 045/166] Make spellcheck happy

---
 xcm/xcm-simulator/example/src/parachain.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index cd92bdd80d44..363b82eea558 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -188,7 +188,7 @@ pub mod mock_msg_queue {
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
 		// XCMP
-		/// Some XCM was executed ok.
+		/// Some XCM was executed successfully.
 		Success(Option<T::Hash>),
 		/// Some XCM failed.
 		Fail(Option<T::Hash>, XcmError),

From 8178647599162373d6b9d997b967640ac69f64b5 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Mon, 2 Aug 2021 06:38:23 -0700
Subject: [PATCH 046/166] cargo fmt

---
 runtime/westend/src/lib.rs                 | 2 +-
 xcm/src/v0/multi_location.rs               | 5 +----
 xcm/xcm-simulator/example/src/parachain.rs | 8 ++------
 3 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index 5d436af6b8af..b1b9d58721f1 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -46,7 +46,7 @@ use runtime_parachains::{
 
 use xcm::v0::{
 	Junction::Parachain,
-    Junctions::{Null, X1},
+	Junctions::{Null, X1},
 	MultiAsset::{self, AllConcreteFungible},
 	MultiLocation, NetworkId, Xcm,
 };
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 3ce4aeabe190..68e1761e7c00 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -128,10 +128,7 @@ impl MultiLocation {
 	/// Creates a new `MultiLocation` with the specified number of parents in the `P` const generic
 	/// parameter and a `Null` interior.
 	pub const fn with_parents_const<const P: u8>() -> MultiLocation {
-		MultiLocation {
-			parents: P,
-			interior: Junctions::Null,
-		}
+		MultiLocation { parents: P, interior: Junctions::Null }
 	}
 
 	/// Creates a new `MultiLocation` with the specified number of parents and a `Null` interior.
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 363b82eea558..569abf5dc6b0 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -37,12 +37,8 @@ use polkadot_parachain::primitives::{
 };
 use xcm::{
 	v0::{
-		Error as XcmError, ExecuteXcm,
-		Junction::Parachain,
-		Junctions::X1,
-		MultiAsset,
-		MultiLocation,
-		NetworkId, Outcome, Xcm,
+		Error as XcmError, ExecuteXcm, Junction::Parachain, Junctions::X1, MultiAsset,
+		MultiLocation, NetworkId, Outcome, Xcm,
 	},
 	VersionedXcm,
 };

From 529a931a1f3058855b3ccc51274552cc4852f1cb Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 16:12:19 +0200
Subject: [PATCH 047/166] fix some doc tests

---
 xcm/xcm-builder/src/matches_fungible.rs | 11 +++++------
 1 file changed, 5 insertions(+), 6 deletions(-)

diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 8ec1893ee9df..6b80994d1989 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -28,17 +28,16 @@ use xcm_executor::traits::MatchesFungible;
 /// # Example
 ///
 /// ```
-/// use xcm::v0::{MultiAsset, MultiLocation, Junction};
+/// use xcm::v0::prelude::*;
 /// use xcm_builder::IsConcrete;
 /// use xcm_executor::traits::MatchesFungible;
 ///
 /// frame_support::parameter_types! {
-/// 	pub TargetLocation: MultiLocation = MultiLocation::X1(Junction::Parent);
+/// 	pub TargetLocation: MultiLocation = X1(Parent);
 /// }
 ///
 /// # fn main() {
-/// let id = MultiLocation::X1(Junction::Parent);
-/// let asset = MultiAsset::ConcreteFungible { id, amount: 999u128 };
+/// let asset = (X1(Parent), 999).into();
 /// // match `asset` if it is a concrete asset in `TargetLocation`.
 /// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
 /// # }
@@ -59,7 +58,7 @@ impl<T: Get<MultiLocation>, B: TryFrom<u128>> MatchesFungible<B> for IsConcrete<
 /// # Example
 ///
 /// ```
-/// use xcm::v0::{MultiAsset};
+/// use xcm::v0::prelude::*;
 /// use xcm_builder::IsAbstract;
 /// use xcm_executor::traits::MatchesFungible;
 ///
@@ -68,7 +67,7 @@ impl<T: Get<MultiLocation>, B: TryFrom<u128>> MatchesFungible<B> for IsConcrete<
 /// }
 ///
 /// # fn main() {
-/// let asset = MultiAsset::AbstractFungible { id: vec![7u8], amount: 999u128 };
+/// let asset = (vec![7u8], 999).into();
 /// // match `asset` if it is a concrete asset in `TargetLocation`.
 /// assert_eq!(<IsAbstract<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
 /// # }

From 3e93d54d0217b271f553d299e3314852f5c6701e Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 16:17:15 +0200
Subject: [PATCH 048/166] spelling

---
 scripts/gitlab/lingua.dic | 1 +
 xcm/src/v0/multiasset.rs  | 8 ++++----
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/scripts/gitlab/lingua.dic b/scripts/gitlab/lingua.dic
index a532700e3a5d..c0fc608a45b5 100644
--- a/scripts/gitlab/lingua.dic
+++ b/scripts/gitlab/lingua.dic
@@ -68,6 +68,7 @@ extrinsics
 fedora/M
 FRAME/MS
 FSMs
+fungibility
 gameable
 getter/MS
 GiB/S
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index f00c73d8efee..9356e258d1fc 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -16,7 +16,7 @@
 
 //! Cross-Consensus Message format asset data structures.
 //!
-//! This encompasses four types for repesenting assets:
+//! This encompasses four types for representing assets:
 //! - `MultiAsset`: A description of a single asset, either an instance of a non-fungible or some amount of a fungible.
 //! - `MultiAssets`: A collection of `MultiAsset`s. These are stored in a `Vec` and sorted with fungibles first.
 //! - `Wild`: A single asset wildcard, this can either be "all" assets, or all assets of a specific kind.
@@ -184,7 +184,7 @@ impl MultiAsset {
 
 
 
-/// A vec of MultiAssets. There may be no duplicate fungible items in here and when decoding, they must be sorted.
+/// A `Vec` of `MultiAsset`s. There may be no duplicate fungible items in here and when decoding, they must be sorted.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode)]
 pub struct MultiAssets(Vec<MultiAsset>);
 
@@ -221,7 +221,7 @@ impl MultiAssets {
 		Self(Vec::new())
 	}
 
-	/// Add some asset onto the multiasset list. This is quite a laborious operation since it maintains the ordering.
+	/// Add some asset onto the list. This is quite a laborious operation since it maintains the ordering.
 	pub fn push(&mut self, a: MultiAsset) {
 		if let Fungibility::Fungible(ref amount) = a.fun {
 			for asset in self.0.iter_mut().filter(|x| x.id == a.id) {
@@ -274,7 +274,7 @@ pub enum WildFungibility {
 
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum WildMultiAsset {
-	/// All assets in the holding register, up to usize individual assets (different instances of non-fungibles could
+	/// All assets in the holding register, up to `usize` individual assets (different instances of non-fungibles could
 	/// as separate assets).
 	All,
 	// TODO: AllOf { fun: WildFungibility, id: AssetId }

From f42b3abca40d6ada00321c21ece7793bb6d846b8 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 2 Aug 2021 16:22:32 +0200
Subject: [PATCH 049/166] named fields for AllOf

---
 runtime/kusama/src/lib.rs      |  2 +-
 runtime/rococo/src/lib.rs      |  2 +-
 runtime/westend/src/lib.rs     |  2 +-
 xcm/src/v0/multiasset.rs       | 11 +++++------
 xcm/xcm-executor/src/assets.rs |  8 ++++----
 5 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index a69e46f8ef8a..e72b7ed1b5e1 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1259,7 +1259,7 @@ pub type XcmRouter = (
 );
 
 parameter_types! {
-	pub const Kusama: MultiAssetFilter = Wild(AllOf(WildFungible, Concrete(KsmLocation::get())));
+	pub const Kusama: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(KsmLocation::get()) });
 	pub const KusamaForStatemint: (MultiAssetFilter, MultiLocation) = (Kusama::get(), X1(Parachain(1000)));
 }
 pub type TrustedTeleporters = (
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index f25ce35baa84..292de1b633cf 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -629,7 +629,7 @@ pub type XcmRouter = (
 
 use xcm::v0::prelude::*;
 parameter_types! {
-	pub const Rococo: MultiAssetFilter = Wild(AllOf(WildFungible, Concrete(RocLocation::get())));
+	pub const Rococo: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(RocLocation::get()) });
 	pub const RococoForTick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(100)));
 	pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(110)));
 	pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(120)));
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index 1e0f16918a72..860b3f1bc851 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -907,7 +907,7 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const WestendForWestmint: (MultiAssetFilter, MultiLocation) =
-		(Wild(AllOf(WildFungible, Concrete(WndLocation::get()))), X1(Parachain(1000)));
+		(Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), X1(Parachain(1000)));
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<WestendForWestmint>,
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 9356e258d1fc..351665baaa0c 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -90,7 +90,7 @@ impl AssetId {
 	/// Use the value of `self` along with a `fun` fungibility specifier to create the corresponding `WildMultiAsset`
 	/// wildcard (`AllOf`) value.
 	pub fn into_wild(self, fun: WildFungibility) -> WildMultiAsset {
-		WildMultiAsset::AllOf(fun, self)
+		WildMultiAsset::AllOf { fun, id: self }
 	}
 }
 
@@ -277,10 +277,9 @@ pub enum WildMultiAsset {
 	/// All assets in the holding register, up to `usize` individual assets (different instances of non-fungibles could
 	/// as separate assets).
 	All,
-	// TODO: AllOf { fun: WildFungibility, id: AssetId }
 	/// All assets in the holding register of a given fungibility and ID. If operating on non-fungibles, then a limit
 	/// is provided for the maximum amount of matching instances.
-	AllOf(WildFungibility, AssetId),
+	AllOf { fun: WildFungibility, id: AssetId },
 }
 
 impl WildMultiAsset {
@@ -291,7 +290,7 @@ impl WildMultiAsset {
 	pub fn contains(&self, inner: &MultiAsset) -> bool {
 		use WildMultiAsset::*;
 		match self {
-			AllOf(fun, id) => inner.fun.is_kind(*fun) && &inner.id == id,
+			AllOf { fun, id } => inner.fun.is_kind(*fun) && &inner.id == id,
 			All => true,
 		}
 	}
@@ -300,7 +299,7 @@ impl WildMultiAsset {
 	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
 		use WildMultiAsset::*;
 		match self {
-			AllOf(_, ref mut id) => id.reanchor(prepend).map_err(|_| ()),
+			AllOf { ref mut id, .. } => id.reanchor(prepend).map_err(|_| ()),
 			_ => Ok(()),
 		}
 	}
@@ -308,7 +307,7 @@ impl WildMultiAsset {
 
 impl<A: Into<AssetId>, B: Into<WildFungibility>> From<(A, B)> for WildMultiAsset {
 	fn from((id, fun): (A, B)) -> WildMultiAsset {
-		WildMultiAsset::AllOf(fun.into(), id.into())
+		WildMultiAsset::AllOf { fun: fun.into(), id: id.into() }
 	}
 }
 
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 41fafbf67c40..85ab40a8eb9b 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -206,12 +206,12 @@ impl Assets {
 		let mut taken = Assets::new();
 		match mask {
 			MultiAssetFilter::Wild(All) => return Ok(self.swapped(Assets::new())),
-			MultiAssetFilter::Wild(AllOf(WildFungible, id)) => {
+			MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => {
 				if let Some((id, amount)) = self.fungible.remove_entry(&id) {
 					taken.fungible.insert(id, amount);
 				}
 			}
-			MultiAssetFilter::Wild(AllOf(WildNonFungible, id)) => {
+			MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => {
 				let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
 				non_fungible.into_iter().for_each(|(c, instance)| {
 					if c == id {
@@ -321,12 +321,12 @@ impl Assets {
 		let mut masked = Assets::new();
 		match mask {
 			MultiAssetFilter::Wild(All) => return self.clone(),
-			MultiAssetFilter::Wild(AllOf(WildFungible, id)) => {
+			MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => {
 				if let Some(&amount) = self.fungible.get(&id) {
 					masked.fungible.insert(id.clone(), amount);
 				}
 			}
-			MultiAssetFilter::Wild(AllOf(WildNonFungible, id)) => {
+			MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => {
 				self.non_fungible.iter().for_each(|(ref c, ref instance)| {
 					if c == id {
 						masked.non_fungible.insert((c.clone(), instance.clone()));

From 260f8a42421a51b034836c759942b1246a8b1941 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Tue, 3 Aug 2021 02:23:27 -0700
Subject: [PATCH 050/166] Fix subtle bug where Null is treated as an identifier

---
 xcm/xcm-simulator/src/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-simulator/src/lib.rs b/xcm/xcm-simulator/src/lib.rs
index 64edb2000160..22fb3e57a1f4 100644
--- a/xcm/xcm-simulator/src/lib.rs
+++ b/xcm/xcm-simulator/src/lib.rs
@@ -196,7 +196,7 @@ macro_rules! decl_test_network {
 				use $crate::{UmpSink, XcmpMessageHandlerT};
 
 				match destination.interior() {
-					Null if destination.parent_count() == 1 => {
+					$crate::Junctions::Null if destination.parent_count() == 1 => {
 						let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump);
 						let _ = <$relay_chain>::process_upward_message(
 							T::get(), &encoded[..],

From 2a2af5becce51ecd251ff24461ef76e3b0befa8e Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Tue, 3 Aug 2021 02:55:57 -0700
Subject: [PATCH 051/166] Add FIXME comment awaiting for const generics eval
 stabilization

---
 xcm/src/v0/multi_location.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 68e1761e7c00..77d30bc7fb5a 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -127,6 +127,8 @@ impl MultiLocation {
 
 	/// Creates a new `MultiLocation` with the specified number of parents in the `P` const generic
 	/// parameter and a `Null` interior.
+	// #FIXME: Use a where clause to evaluate P for well-formedness once const eval of const
+	//         generics is possible.
 	pub const fn with_parents_const<const P: u8>() -> MultiLocation {
 		MultiLocation { parents: P, interior: Junctions::Null }
 	}

From 97051b283461f486d00fd59842c79b7161d33684 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 17:47:03 +0200
Subject: [PATCH 052/166] Update xcm/src/v0/multiasset.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
---
 xcm/src/v0/multiasset.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 351665baaa0c..944e449b60f9 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -272,6 +272,7 @@ pub enum WildFungibility {
 	NonFungible,
 }
 
+/// A wildcard representing a set of assets.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum WildMultiAsset {
 	/// All assets in the holding register, up to `usize` individual assets (different instances of non-fungibles could

From 84b79cf71ad03191e5f9c62cc863c265f9d70e70 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 17:49:07 +0200
Subject: [PATCH 053/166] Update xcm/src/v0/multiasset.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
---
 xcm/src/v0/multiasset.rs | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 944e449b60f9..dcd1d9f905c6 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -315,8 +315,10 @@ impl<A: Into<AssetId>, B: Into<WildFungibility>> From<(A, B)> for WildMultiAsset
 
 
 
-/// `MultiAsset` collection, either `MultiAssets` or a single wildcard. Note: vectors of wildcards
-/// whose encoding is supported in XCM v0 are unsupported in this implementation and will result in a decode error.
+/// `MultiAsset` collection, either `MultiAssets` or a single wildcard.
+/// 
+/// Note: Vectors of wildcards whose encoding is supported in XCM v0 are unsupported
+/// in this implementation and will result in a decode error.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum MultiAssetFilter {
 	Definite(MultiAssets),

From 1f988728108b30ecf893b716bd0406546f578b76 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 17:49:27 +0200
Subject: [PATCH 054/166] Update xcm/src/v0/multiasset.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
---
 xcm/src/v0/multiasset.rs | 5 -----
 1 file changed, 5 deletions(-)

diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index dcd1d9f905c6..0f3ea7f1ec8e 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -260,11 +260,6 @@ impl MultiAssets {
 		self.0.iter_mut().try_for_each(|i| i.reanchor(prepend))
 	}
 }
-
-
-
-
-
 /// Classification of whether an asset is fungible or not, along with an optional amount or instance.
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum WildFungibility {

From 0cc61debb05c30e394c1179b8a514f433c8ca325 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 17:49:32 +0200
Subject: [PATCH 055/166] Update xcm/src/v0/multiasset.rs

Co-authored-by: Alexander Popiak <alexander.popiak@parity.io>
---
 xcm/src/v0/multiasset.rs | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 0f3ea7f1ec8e..02c43fc1d205 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -306,10 +306,6 @@ impl<A: Into<AssetId>, B: Into<WildFungibility>> From<(A, B)> for WildMultiAsset
 		WildMultiAsset::AllOf { fun: fun.into(), id: id.into() }
 	}
 }
-
-
-
-
 /// `MultiAsset` collection, either `MultiAssets` or a single wildcard.
 /// 
 /// Note: Vectors of wildcards whose encoding is supported in XCM v0 are unsupported

From 723990cb50154b8b09a9a21a05c9b0c164bb945d Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 20:06:27 +0200
Subject: [PATCH 056/166] Reformat

---
 runtime/westend/src/lib.rs                    |   1 -
 xcm/pallet-xcm/src/lib.rs                     | 109 ++++++----
 xcm/src/v0/mod.rs                             | 136 +++++++-----
 xcm/src/v0/multiasset.rs                      |  60 +++---
 xcm/src/v0/order.rs                           |  52 +++--
 xcm/xcm-builder/src/barriers.rs               |  31 ++-
 xcm/xcm-builder/src/filter_asset_location.rs  |   4 +-
 xcm/xcm-builder/src/fungibles_adapter.rs      | 201 ++++++++++++------
 xcm/xcm-builder/src/lib.rs                    |  19 +-
 xcm/xcm-builder/src/matches_fungible.rs       |  10 +-
 xcm/xcm-builder/src/mock.rs                   | 116 +++++-----
 xcm/xcm-builder/src/tests.rs                  | 123 ++++++-----
 xcm/xcm-builder/src/weight.rs                 | 127 ++++++-----
 xcm/xcm-executor/src/assets.rs                | 115 ++++++----
 xcm/xcm-executor/src/lib.rs                   | 109 ++++++----
 xcm/xcm-executor/src/traits/transact_asset.rs |  57 +++--
 xcm/xcm-executor/src/traits/weight.rs         |  14 +-
 17 files changed, 753 insertions(+), 531 deletions(-)

diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index 2255f4194c87..12efa280771d 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -944,7 +944,6 @@ pub type LocalOriginToLocation = (
 	SignedToAccountId32<Origin, AccountId, WestendNetwork>,
 );
 
-
 impl pallet_xcm::Config for Runtime {
 	type Event = Event;
 	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 99341c2a0e85..95d5c867e781 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -18,23 +18,28 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use sp_std::{prelude::*, marker::PhantomData, convert::TryInto, boxed::Box, vec};
-use codec::{Encode, Decode};
+#[cfg(test)]
+mod mock;
+#[cfg(test)]
+mod tests;
+
+use codec::{Decode, Encode};
+use frame_support::traits::{Contains, EnsureOrigin, Filter, Get, OriginTrait};
+use sp_runtime::{traits::BadOrigin, RuntimeDebug};
+use sp_std::{boxed::Box, convert::TryInto, marker::PhantomData, prelude::*, vec};
 use xcm::v0::prelude::*;
 use xcm_executor::traits::ConvertOrigin;
-use sp_runtime::{RuntimeDebug, traits::BadOrigin};
-use frame_support::traits::{EnsureOrigin, OriginTrait, Filter, Get, Contains};
 
-pub use pallet::*;
 use frame_support::PalletId;
+pub use pallet::*;
 
 #[frame_support::pallet]
 pub mod pallet {
 	use super::*;
 	use frame_support::pallet_prelude::*;
 	use frame_system::pallet_prelude::*;
-	use xcm_executor::traits::WeightBounds;
 	use sp_runtime::traits::AccountIdConversion;
+	use xcm_executor::traits::WeightBounds;
 
 	#[pallet::pallet]
 	#[pallet::generate_store(pub(super) trait Store)]
@@ -48,7 +53,7 @@ pub mod pallet {
 
 		/// Required origin for sending XCM messages. If successful, the it resolves to `MultiLocation`
 		/// which exists as an interior location within this chain's XCM context.
-		type SendXcmOrigin: EnsureOrigin<Self::Origin, Success=MultiLocation>;
+		type SendXcmOrigin: EnsureOrigin<Self::Origin, Success = MultiLocation>;
 
 		/// The type used to actually dispatch an XCM to its destination.
 		type XcmRouter: SendXcm;
@@ -56,7 +61,7 @@ pub mod pallet {
 		/// Required origin for executing XCM messages, including the teleport functionality. If successful,
 		/// then it resolves to `MultiLocation` which exists as an interior location within this chain's XCM
 		/// context.
-		type ExecuteXcmOrigin: EnsureOrigin<Self::Origin, Success=MultiLocation>;
+		type ExecuteXcmOrigin: EnsureOrigin<Self::Origin, Success = MultiLocation>;
 
 		/// Our XCM filter which messages to be executed using `XcmExecutor` must pass.
 		type XcmExecuteFilter: Contains<(MultiLocation, Xcm<Self::Call>)>;
@@ -101,11 +106,12 @@ pub mod pallet {
 		#[pallet::weight(100_000_000)]
 		pub fn send(origin: OriginFor<T>, dest: MultiLocation, message: Xcm<()>) -> DispatchResult {
 			let origin_location = T::SendXcmOrigin::ensure_origin(origin)?;
-			Self::send_xcm(origin_location.clone(), dest.clone(), message.clone())
-				.map_err(|e| match e {
+			Self::send_xcm(origin_location.clone(), dest.clone(), message.clone()).map_err(
+				|e| match e {
 					XcmError::CannotReachDestination(..) => Error::<T>::Unreachable,
 					_ => Error::<T>::SendFailure,
-				})?;
+				},
+			)?;
 			Self::deposit_event(Event::Sent(origin_location, dest, message));
 			Ok(())
 		}
@@ -147,27 +153,26 @@ pub mod pallet {
 			let assets = assets.into();
 			let mut message = Xcm::WithdrawAsset {
 				assets,
-				effects: vec![
-					InitiateTeleport {
-						assets: Wild(All),
-						dest,
-						effects: vec![
-							BuyExecution {
-								fees,
-								// Zero weight for additional XCM (since there are none to execute)
-								weight: 0,
-								debt: dest_weight,
-								halt_on_error: false,
-								xcm: vec![],
-							},
-							DepositAsset { assets: Wild(All), dest: beneficiary },
-						],
-					},
-				],
+				effects: vec![InitiateTeleport {
+					assets: Wild(All),
+					dest,
+					effects: vec![
+						BuyExecution {
+							fees,
+							// Zero weight for additional XCM (since there are none to execute)
+							weight: 0,
+							debt: dest_weight,
+							halt_on_error: false,
+							xcm: vec![],
+						},
+						DepositAsset { assets: Wild(All), dest: beneficiary },
+					],
+				}],
 			};
-			let weight = T::Weigher::weight(&mut message)
-				.map_err(|()| Error::<T>::UnweighableMessage)?;
-			let outcome = T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight);
+			let weight =
+				T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;
+			let outcome =
+				T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight);
 			Self::deposit_event(Event::Attempted(outcome));
 			Ok(())
 		}
@@ -220,9 +225,10 @@ pub mod pallet {
 					DepositAsset { assets: Wild(All), dest: beneficiary },
 				],
 			};
-			let weight = T::Weigher::weight(&mut message)
-				.map_err(|()| Error::<T>::UnweighableMessage)?;
-			let outcome = T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight);
+			let weight =
+				T::Weigher::weight(&mut message).map_err(|()| Error::<T>::UnweighableMessage)?;
+			let outcome =
+				T::XcmExecutor::execute_xcm_in_credit(origin_location, message, weight, weight);
 			Self::deposit_event(Event::Attempted(outcome));
 			Ok(())
 		}
@@ -239,9 +245,11 @@ pub mod pallet {
 		/// NOTE: A successful return to this does *not* imply that the `msg` was executed successfully
 		/// to completion; only that *some* of it was executed.
 		#[pallet::weight(max_weight.saturating_add(100_000_000u64))]
-		pub fn execute(origin: OriginFor<T>, message: Box<Xcm<T::Call>>, max_weight: Weight)
-			-> DispatchResult
-		{
+		pub fn execute(
+			origin: OriginFor<T>,
+			message: Box<Xcm<T::Call>>,
+			max_weight: Weight,
+		) -> DispatchResult {
 			let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
 			let value = (origin_location, *message);
 			ensure!(T::XcmExecuteFilter::contains(&value), Error::<T>::Filtered);
@@ -255,7 +263,11 @@ pub mod pallet {
 	impl<T: Config> Pallet<T> {
 		/// Relay an XCM `message` from a given `interior` location in this context to a given `dest`
 		/// location. A null `dest` is not handled.
-		pub fn send_xcm(interior: MultiLocation, dest: MultiLocation, message: Xcm<()>) -> Result<(), XcmError> {
+		pub fn send_xcm(
+			interior: MultiLocation,
+			dest: MultiLocation,
+			message: Xcm<()>,
+		) -> Result<(), XcmError> {
 			let message = match interior {
 				MultiLocation::Null => message,
 				who => Xcm::<()>::RelayedFrom { who, message: Box::new(message) },
@@ -288,7 +300,8 @@ pub mod pallet {
 /// Ensure that the origin `o` represents a sibling parachain.
 /// Returns `Ok` with the parachain ID of the sibling or an `Err` otherwise.
 pub fn ensure_xcm<OuterOrigin>(o: OuterOrigin) -> Result<MultiLocation, BadOrigin>
-	where OuterOrigin: Into<Result<Origin, OuterOrigin>>
+where
+	OuterOrigin: Into<Result<Origin, OuterOrigin>>,
 {
 	match o.into() {
 		Ok(Origin::Xcm(location)) => Ok(location),
@@ -301,7 +314,9 @@ pub fn ensure_xcm<OuterOrigin>(o: OuterOrigin) -> Result<MultiLocation, BadOrigi
 ///
 /// May reasonably be used with `EnsureXcm`.
 pub struct IsMajorityOfBody<Prefix, Body>(PhantomData<(Prefix, Body)>);
-impl<Prefix: Get<MultiLocation>, Body: Get<BodyId>> Filter<MultiLocation> for IsMajorityOfBody<Prefix, Body> {
+impl<Prefix: Get<MultiLocation>, Body: Get<BodyId>> Filter<MultiLocation>
+	for IsMajorityOfBody<Prefix, Body>
+{
 	fn filter(l: &MultiLocation) -> bool {
 		let maybe_suffix = l.match_and_split(&Prefix::get());
 		matches!(maybe_suffix, Some(Plurality { id, part }) if id == &Body::get() && part.is_majority())
@@ -312,19 +327,21 @@ impl<Prefix: Get<MultiLocation>, Body: Get<BodyId>> Filter<MultiLocation> for Is
 /// `Origin::Xcm` item.
 pub struct EnsureXcm<F>(PhantomData<F>);
 impl<O: OriginTrait + From<Origin>, F: Filter<MultiLocation>> EnsureOrigin<O> for EnsureXcm<F>
-	where O::PalletsOrigin: From<Origin> + TryInto<Origin, Error=O::PalletsOrigin>
+where
+	O::PalletsOrigin: From<Origin> + TryInto<Origin, Error = O::PalletsOrigin>,
 {
 	type Success = MultiLocation;
 
 	fn try_origin(outer: O) -> Result<Self::Success, O> {
-		outer.try_with_caller(|caller| caller.try_into()
-			.and_then(|Origin::Xcm(location)|
+		outer.try_with_caller(|caller| {
+			caller.try_into().and_then(|Origin::Xcm(location)| {
 				if F::filter(&location) {
 					Ok(location)
 				} else {
 					Err(Origin::Xcm(location).into())
 				}
-			))
+			})
+		})
 	}
 
 	#[cfg(feature = "runtime-benchmarks")]
@@ -336,9 +353,7 @@ impl<O: OriginTrait + From<Origin>, F: Filter<MultiLocation>> EnsureOrigin<O> fo
 /// A simple passthrough where we reuse the `MultiLocation`-typed XCM origin as the inner value of
 /// this crate's `Origin::Xcm` value.
 pub struct XcmPassthrough<Origin>(PhantomData<Origin>);
-impl<
-	Origin: From<crate::Origin>,
-> ConvertOrigin<Origin> for XcmPassthrough<Origin> {
+impl<Origin: From<crate::Origin>> ConvertOrigin<Origin> for XcmPassthrough<Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
 		match (kind, origin) {
 			(OriginKind::Xcm, l) => Ok(crate::Origin::Xcm(l).into()),
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 95bccfacf0b5..2bd568e60194 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -16,43 +16,52 @@
 
 //! Version 0 of the Cross-Consensus Message format data structures.
 
-use core::{result, convert::TryFrom, fmt::Debug};
-use derivative::Derivative;
-use alloc::vec::Vec;
-use parity_scale_codec::{self, Encode, Decode};
 use crate::{DoubleEncoded, VersionedXcm};
+use alloc::vec::Vec;
+use core::{convert::TryFrom, fmt::Debug, result};
+use derivative::Derivative;
+use parity_scale_codec::{self, Decode, Encode};
 
 mod junction;
 mod multi_location;
+pub mod multiasset;
 mod order;
-mod traits;
-pub mod multiasset;	// the new multiasset.
+mod traits; // the new multiasset.
 
-pub use junction::{Junction, NetworkId, BodyId, BodyPart};
+pub use junction::{BodyId, BodyPart, Junction, NetworkId};
+pub use multi_location::MultiLocation;
 pub use multiasset::{
-	AssetId, AssetInstance, MultiAsset, MultiAssets, MultiAssetFilter, Fungibility, WildMultiAsset, WildFungibility
+	AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
+	WildFungibility, WildMultiAsset,
 };
-pub use multi_location::MultiLocation;
 pub use order::Order;
-pub use traits::{Error, Result, SendXcm, ExecuteXcm, Outcome};
+pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
-	pub use super::junction::{Junction::*, NetworkId::{self, *}, BodyId, BodyPart};
-	pub use super::multiasset::{
-		MultiAssets, MultiAsset,
-		AssetId::{self, *},
-		AssetInstance::{self, *},
-		MultiAssetFilter::{self, *},
-		Fungibility::{self, *},
-		WildMultiAsset::{self, *},
-		WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible},
+	pub use super::{
+		junction::{
+			BodyId, BodyPart,
+			Junction::*,
+			NetworkId::{self, *},
+		},
+		multi_location::MultiLocation::{self, *},
+		multiasset::{
+			AssetId::{self, *},
+			AssetInstance::{self, *},
+			Fungibility::{self, *},
+			MultiAsset,
+			MultiAssetFilter::{self, *},
+			MultiAssets,
+			WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible},
+			WildMultiAsset::{self, *},
+		},
+		opaque,
+		order::Order::{self, *},
+		traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
+		OriginKind, Response,
+		Xcm::{self, *},
 	};
-	pub use super::multi_location::MultiLocation::{self, *};
-	pub use super::order::Order::{self, *};
-	pub use super::traits::{Error as XcmError, Result as XcmResult, SendXcm, ExecuteXcm, Outcome};
-	pub use super::{Xcm::{self, *}, OriginKind, Response};
-	pub use super::opaque;
 }
 
 // TODO: #2841 #XCMENCODE Efficient encodings for MultiAssets, Vec<Order>, using initial byte values 128+ to encode
@@ -159,7 +168,11 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 3)]
-	QueryResponse { #[codec(compact)] query_id: u64, response: Response },
+	QueryResponse {
+		#[codec(compact)]
+		query_id: u64,
+		response: Response,
+	},
 
 	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
 	/// ownership of `dest` within this consensus system.
@@ -221,9 +234,12 @@ pub enum Xcm<Call> {
 	/// Kind: *System Notification*
 	#[codec(index = 7)]
 	HrmpNewChannelOpenRequest {
-		#[codec(compact)] sender: u32,
-		#[codec(compact)] max_message_size: u32,
-		#[codec(compact)] max_capacity: u32,
+		#[codec(compact)]
+		sender: u32,
+		#[codec(compact)]
+		max_message_size: u32,
+		#[codec(compact)]
+		max_capacity: u32,
 	},
 
 	/// A message to notify about that a previously sent open channel request has been accepted by
@@ -237,7 +253,8 @@ pub enum Xcm<Call> {
 	/// Errors:
 	#[codec(index = 8)]
 	HrmpChannelAccepted {
-		#[codec(compact)] recipient: u32,
+		#[codec(compact)]
+		recipient: u32,
 	},
 
 	/// A message to notify that the other party in an open channel decided to close it. In particular,
@@ -252,9 +269,12 @@ pub enum Xcm<Call> {
 	/// Errors:
 	#[codec(index = 9)]
 	HrmpChannelClosing {
-		#[codec(compact)] initiator: u32,
-		#[codec(compact)] sender: u32,
-		#[codec(compact)] recipient: u32,
+		#[codec(compact)]
+		initiator: u32,
+		#[codec(compact)]
+		sender: u32,
+		#[codec(compact)]
+		recipient: u32,
 	},
 
 	/// A message to indicate that the embedded XCM is actually arriving on behalf of some consensus
@@ -267,10 +287,7 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 10)]
-	RelayedFrom {
-		who: MultiLocation,
-		message: alloc::boxed::Box<Xcm<Call>>,
-	},
+	RelayedFrom { who: MultiLocation, message: alloc::boxed::Box<Xcm<Call>> },
 }
 
 impl<Call> From<Xcm<Call>> for VersionedXcm<Call> {
@@ -289,32 +306,33 @@ impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
 }
 
 impl<Call> Xcm<Call> {
-	pub fn into<C>(self) -> Xcm<C> { Xcm::from(self) }
+	pub fn into<C>(self) -> Xcm<C> {
+		Xcm::from(self)
+	}
 	pub fn from<C>(xcm: Xcm<C>) -> Self {
 		use Xcm::*;
 		match xcm {
-			WithdrawAsset { assets, effects }
-			=> WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
-			ReserveAssetDeposited { assets, effects }
-			=> ReserveAssetDeposited { assets, effects: effects.into_iter().map(Order::into).collect() },
-			TeleportAsset { assets, effects }
-			=> TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
-			QueryResponse { query_id: u64, response }
-			=> QueryResponse { query_id: u64, response },
-			TransferAsset { assets, dest }
-			=> TransferAsset { assets, dest },
-			TransferReserveAsset { assets, dest, effects }
-			=> TransferReserveAsset { assets, dest, effects },
-			HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity}
-			=> HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity},
-			HrmpChannelAccepted { recipient}
-			=> HrmpChannelAccepted { recipient},
-			HrmpChannelClosing { initiator, sender, recipient}
-			=> HrmpChannelClosing { initiator, sender, recipient},
-			Transact { origin_type, require_weight_at_most, call}
-			=> Transact { origin_type, require_weight_at_most, call: call.into() },
-			RelayedFrom { who, message }
-			=> RelayedFrom { who, message: alloc::boxed::Box::new((*message).into()) },
+			WithdrawAsset { assets, effects } =>
+				WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
+			ReserveAssetDeposited { assets, effects } => ReserveAssetDeposited {
+				assets,
+				effects: effects.into_iter().map(Order::into).collect(),
+			},
+			TeleportAsset { assets, effects } =>
+				TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
+			QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response },
+			TransferAsset { assets, dest } => TransferAsset { assets, dest },
+			TransferReserveAsset { assets, dest, effects } =>
+				TransferReserveAsset { assets, dest, effects },
+			HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } =>
+				HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity },
+			HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient },
+			HrmpChannelClosing { initiator, sender, recipient } =>
+				HrmpChannelClosing { initiator, sender, recipient },
+			Transact { origin_type, require_weight_at_most, call } =>
+				Transact { origin_type, require_weight_at_most, call: call.into() },
+			RelayedFrom { who, message } =>
+				RelayedFrom { who, message: alloc::boxed::Box::new((*message).into()) },
 		}
 	}
 }
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v0/multiasset.rs
index 02c43fc1d205..c11110ed571c 100644
--- a/xcm/src/v0/multiasset.rs
+++ b/xcm/src/v0/multiasset.rs
@@ -1,5 +1,5 @@
 // Copyright 2020 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
+// This file is part of Polkadot.
 
 // Substrate is free software: you can redistribute it and/or modify
 // it under the terms of the GNU General Public License as published by
@@ -23,10 +23,10 @@
 //! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
 //!   account.
 
-use core::cmp::Ordering;
-use alloc::{vec, vec::Vec};
-use parity_scale_codec::{self as codec, Encode, Decode};
 use super::MultiLocation;
+use alloc::{vec, vec::Vec};
+use core::cmp::Ordering;
+use parity_scale_codec::{self as codec, Decode, Encode};
 
 /// A general identifier for an instance of a non-fungible asset class.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
@@ -36,7 +36,10 @@ pub enum AssetInstance {
 
 	/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
 	/// values up to `2**128 - 1`.
-	Index { #[codec(compact)] id: u128 },
+	Index {
+		#[codec(compact)]
+		id: u128,
+	},
 
 	/// A 4-byte fixed-length datum.
 	Array4([u8; 4]),
@@ -103,7 +106,8 @@ pub enum Fungibility {
 
 impl Fungibility {
 	pub fn is_kind(&self, w: WildFungibility) -> bool {
-		use {Fungibility::*, WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible}};
+		use Fungibility::*;
+		use WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible};
 		matches!((self, w), (Fungible(_), WildFungible) | (NonFungible(_), WildNonFungible))
 	}
 }
@@ -121,9 +125,6 @@ impl From<AssetInstance> for Fungibility {
 	}
 }
 
-
-
-
 #[derive(Clone, Eq, PartialEq, Debug, Encode, Decode)]
 pub struct MultiAsset {
 	pub id: AssetId,
@@ -182,8 +183,6 @@ impl MultiAsset {
 	}
 }
 
-
-
 /// A `Vec` of `MultiAsset`s. There may be no duplicate fungible items in here and when decoding, they must be sorted.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode)]
 pub struct MultiAssets(Vec<MultiAsset>);
@@ -191,14 +190,19 @@ pub struct MultiAssets(Vec<MultiAsset>);
 impl Decode for MultiAssets {
 	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
 		let r = Vec::<MultiAsset>::decode(input)?;
-		if r.is_empty() { return Ok(Self(Vec::new())) }
-		r.iter().skip(1).try_fold(&r[0], |a, b| -> Result<&MultiAsset, parity_scale_codec::Error> {
-			if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) {
-				Ok(b)
-			} else {
-				Err("Out of order".into())
-			}
-		})?;
+		if r.is_empty() {
+			return Ok(Self(Vec::new()))
+		}
+		r.iter().skip(1).try_fold(
+			&r[0],
+			|a, b| -> Result<&MultiAsset, parity_scale_codec::Error> {
+				if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) {
+					Ok(b)
+				} else {
+					Err("Out of order".into())
+				}
+			},
+		)?;
 		Ok(Self(r))
 	}
 }
@@ -306,8 +310,9 @@ impl<A: Into<AssetId>, B: Into<WildFungibility>> From<(A, B)> for WildMultiAsset
 		WildMultiAsset::AllOf { fun: fun.into(), id: id.into() }
 	}
 }
+
 /// `MultiAsset` collection, either `MultiAssets` or a single wildcard.
-/// 
+///
 /// Note: Vectors of wildcards whose encoding is supported in XCM v0 are unsupported
 /// in this implementation and will result in a decode error.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
@@ -341,21 +346,6 @@ impl From<MultiAssets> for MultiAssetFilter {
 }
 
 impl MultiAssetFilter {
-	/// Returns `true` if the `MultiAsset` is a wildcard and refers to sets of assets, instead of just one.
-	pub fn is_wildcard(&self) -> bool {
-		matches!(self, MultiAssetFilter::Wild(..))
-	}
-
-	/// Returns `true` if the `MultiAsset` is not a wildcard.
-	pub fn is_definite(&self) -> bool {
-		!self.is_wildcard()
-	}
-
-	/// Returns `true` if this definitely represents no asset.
-	pub fn is_none(&self) -> bool {
-		matches!(self, MultiAssetFilter::Definite(a) if a.is_none())
-	}
-
 	/// Returns true if `self` is a super-set of the given `inner`.
 	///
 	/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index 3917e6a01116..aed5a6ff3634 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -16,14 +16,14 @@
 
 //! Version 0 of the Cross-Consensus Message format data structures.
 
+use super::{MultiAsset, MultiAssetFilter, MultiLocation, Xcm};
 use alloc::vec::Vec;
 use derivative::Derivative;
-use parity_scale_codec::{self, Encode, Decode};
-use super::{MultiAsset, MultiAssetFilter, MultiLocation, Xcm};
+use parity_scale_codec::{self, Decode, Encode};
 
 /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
 #[derive(Derivative, Encode, Decode)]
-#[derivative(Clone(bound=""), Eq(bound=""), PartialEq(bound=""), Debug(bound=""))]
+#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
 #[codec(encode_bound())]
 #[codec(decode_bound())]
 pub enum Order<Call> {
@@ -78,7 +78,11 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 4)]
-	InitiateReserveWithdraw { assets: MultiAssetFilter, reserve: MultiLocation, effects: Vec<Order<()>> },
+	InitiateReserveWithdraw {
+		assets: MultiAssetFilter,
+		reserve: MultiLocation,
+		effects: Vec<Order<()>>,
+	},
 
 	/// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location.
 	///
@@ -100,7 +104,12 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 6)]
-	QueryHolding { #[codec(compact)] query_id: u64, dest: MultiLocation, assets: MultiAssetFilter },
+	QueryHolding {
+		#[codec(compact)]
+		query_id: u64,
+		dest: MultiLocation,
+		assets: MultiAssetFilter,
+	},
 
 	/// Pay for the execution of some XCM with up to `weight` picoseconds of execution time, paying for this with
 	/// up to `fees` from the holding register.
@@ -109,7 +118,13 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 7)]
-	BuyExecution { fees: MultiAsset, weight: u64, debt: u64, halt_on_error: bool, xcm: Vec<Xcm<Call>> },
+	BuyExecution {
+		fees: MultiAsset,
+		weight: u64,
+		debt: u64,
+		halt_on_error: bool,
+		xcm: Vec<Xcm<Call>>,
+	},
 }
 
 pub mod opaque {
@@ -117,23 +132,22 @@ pub mod opaque {
 }
 
 impl<Call> Order<Call> {
-	pub fn into<C>(self) -> Order<C> { Order::from(self) }
+	pub fn into<C>(self) -> Order<C> {
+		Order::from(self)
+	}
 	pub fn from<C>(order: Order<C>) -> Self {
 		use Order::*;
 		match order {
 			Noop => Noop,
-			DepositAsset { assets, dest }
-				=> DepositAsset { assets, dest },
-			DepositReserveAsset { assets, dest, effects }
-				=> DepositReserveAsset { assets, dest, effects },
-			ExchangeAsset { give, receive }
-				=> ExchangeAsset { give, receive },
-			InitiateReserveWithdraw { assets, reserve, effects }
-				=> InitiateReserveWithdraw { assets, reserve, effects },
-			InitiateTeleport { assets, dest, effects }
-				=> InitiateTeleport { assets, dest, effects },
-			QueryHolding { query_id, dest, assets }
-				=> QueryHolding { query_id, dest, assets },
+			DepositAsset { assets, dest } => DepositAsset { assets, dest },
+			DepositReserveAsset { assets, dest, effects } =>
+				DepositReserveAsset { assets, dest, effects },
+			ExchangeAsset { give, receive } => ExchangeAsset { give, receive },
+			InitiateReserveWithdraw { assets, reserve, effects } =>
+				InitiateReserveWithdraw { assets, reserve, effects },
+			InitiateTeleport { assets, dest, effects } =>
+				InitiateTeleport { assets, dest, effects },
+			QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest, assets },
 			BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
 				let xcm = xcm.into_iter().map(Xcm::from).collect();
 				BuyExecution { fees, weight, debt, halt_on_error, xcm }
diff --git a/xcm/xcm-builder/src/barriers.rs b/xcm/xcm-builder/src/barriers.rs
index 0a48ad6c42e2..2d870d7525c2 100644
--- a/xcm/xcm-builder/src/barriers.rs
+++ b/xcm/xcm-builder/src/barriers.rs
@@ -16,11 +16,11 @@
 
 //! Various implementations for `ShouldExecute`.
 
-use sp_std::{result::Result, marker::PhantomData};
-use xcm::v0::{Xcm, Order, MultiLocation, Junction};
 use frame_support::{ensure, traits::Contains, weights::Weight};
-use xcm_executor::traits::{OnResponse, ShouldExecute};
 use polkadot_parachain::primitives::IsSystem;
+use sp_std::{marker::PhantomData, result::Result};
+use xcm::v0::{Junction, MultiLocation, Order, Xcm};
+use xcm_executor::traits::{OnResponse, ShouldExecute};
 
 /// Execution barrier that just takes `shallow_weight` from `weight_credit`.
 pub struct TakeWeightCredit;
@@ -51,14 +51,14 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowTopLevelPaidExecutionFro
 		ensure!(T::contains(origin), ());
 		ensure!(top_level, ());
 		match message {
-			Xcm::TeleportAsset { effects, .. }
-			| Xcm::WithdrawAsset { effects, ..}
-			| Xcm::ReserveAssetDeposited { effects, ..}
-			if matches!(
-				effects.first(),
-				Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight
-			)
-			=> Ok(()),
+			Xcm::TeleportAsset { effects, .. } |
+			Xcm::WithdrawAsset { effects, .. } |
+			Xcm::ReserveAssetDeposited { effects, .. }
+				if matches!(
+					effects.first(),
+					Some(Order::BuyExecution { debt, ..}) if *debt >= shallow_weight
+				) =>
+				Ok(()),
 			_ => Err(()),
 		}
 	}
@@ -82,9 +82,7 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowUnpaidExecutionFrom<T> {
 
 /// Allows a message only if it is from a system-level child parachain.
 pub struct IsChildSystemParachain<ParaId>(PhantomData<ParaId>);
-impl<
-	ParaId: IsSystem + From<u32>,
-> Contains<MultiLocation> for IsChildSystemParachain<ParaId> {
+impl<ParaId: IsSystem + From<u32>> Contains<MultiLocation> for IsChildSystemParachain<ParaId> {
 	fn contains(l: &MultiLocation) -> bool {
 		matches!(l, MultiLocation::X1(Junction::Parachain(id)) if ParaId::from(*id).is_system())
 	}
@@ -101,8 +99,9 @@ impl<ResponseHandler: OnResponse> ShouldExecute for AllowKnownQueryResponses<Res
 		_weight_credit: &mut Weight,
 	) -> Result<(), ()> {
 		match message {
-			Xcm::QueryResponse { query_id, .. } if ResponseHandler::expecting_response(origin, *query_id)
-			=> Ok(()),
+			Xcm::QueryResponse { query_id, .. }
+				if ResponseHandler::expecting_response(origin, *query_id) =>
+				Ok(()),
 			_ => Err(()),
 		}
 	}
diff --git a/xcm/xcm-builder/src/filter_asset_location.rs b/xcm/xcm-builder/src/filter_asset_location.rs
index 462b9421e35a..cb2fa80be734 100644
--- a/xcm/xcm-builder/src/filter_asset_location.rs
+++ b/xcm/xcm-builder/src/filter_asset_location.rs
@@ -16,9 +16,9 @@
 
 //! Various implementations of `FilterAssetLocation`.
 
-use sp_std::marker::PhantomData;
-use xcm::v0::{MultiAsset, MultiAssetFilter, MultiLocation, AssetId::Concrete};
 use frame_support::traits::Get;
+use sp_std::marker::PhantomData;
+use xcm::v0::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation};
 use xcm_executor::traits::FilterAssetLocation;
 
 /// Accepts an asset iff it is a native asset.
diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs
index 121d0828f165..d81ddd5a575d 100644
--- a/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -16,23 +16,25 @@
 
 //! Adapters to work with `frame_support::traits::tokens::fungibles` through XCM.
 
-use sp_std::{prelude::*, result, marker::PhantomData, borrow::Borrow};
+use frame_support::traits::{tokens::fungibles, Contains, Get};
+use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result};
 use xcm::v0::{
-	Error as XcmError, Result, MultiAsset, MultiLocation, Junction, Fungibility::Fungible,
-	AssetId::{Concrete, Abstract},
+	AssetId::{Abstract, Concrete},
+	Error as XcmError,
+	Fungibility::Fungible,
+	Junction, MultiAsset, MultiLocation, Result,
 };
-use frame_support::traits::{Get, tokens::fungibles, Contains};
-use xcm_executor::traits::{TransactAsset, Convert, MatchesFungibles, Error as MatchError};
+use xcm_executor::traits::{Convert, Error as MatchError, MatchesFungibles, TransactAsset};
 
 /// Converter struct implementing `AssetIdConversion` converting a numeric asset ID (must be `TryFrom/TryInto<u128>`) into
 /// a `GeneralIndex` junction, prefixed by some `MultiLocation` value. The `MultiLocation` value will typically be a
 /// `PalletInstance` junction.
-pub struct AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>(PhantomData<(Prefix, AssetId, ConvertAssetId)>);
-impl<
-	Prefix: Get<MultiLocation>,
-	AssetId: Clone,
-	ConvertAssetId: Convert<u128, AssetId>,
-> Convert<MultiLocation, AssetId> for AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId> {
+pub struct AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>(
+	PhantomData<(Prefix, AssetId, ConvertAssetId)>,
+);
+impl<Prefix: Get<MultiLocation>, AssetId: Clone, ConvertAssetId: Convert<u128, AssetId>>
+	Convert<MultiLocation, AssetId> for AsPrefixedGeneralIndex<Prefix, AssetId, ConvertAssetId>
+{
 	fn convert_ref(id: impl Borrow<MultiLocation>) -> result::Result<AssetId, ()> {
 		let prefix = Prefix::get();
 		let id = id.borrow();
@@ -53,58 +55,63 @@ impl<
 }
 
 pub struct ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>(
-	PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>
+	PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>,
 );
 impl<
-	AssetId: Clone,
-	Balance: Clone,
-	ConvertAssetId: Convert<MultiLocation, AssetId>,
-	ConvertBalance: Convert<u128, Balance>,
-> MatchesFungibles<AssetId, Balance> for
-	ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
+		AssetId: Clone,
+		Balance: Clone,
+		ConvertAssetId: Convert<MultiLocation, AssetId>,
+		ConvertBalance: Convert<u128, Balance>,
+	> MatchesFungibles<AssetId, Balance>
+	for ConvertedConcreteAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
 {
 	fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
 		let (amount, id) = match (&a.fun, &a.id) {
 			(Fungible(ref amount), Concrete(ref id)) => (amount, id),
 			_ => return Err(MatchError::AssetNotFound),
 		};
-		let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
-		let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
+		let what =
+			ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
+		let amount = ConvertBalance::convert_ref(amount)
+			.map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
 		Ok((what, amount))
 	}
 }
 
 pub struct ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>(
-	PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>
+	PhantomData<(AssetId, Balance, ConvertAssetId, ConvertBalance)>,
 );
 impl<
-	AssetId: Clone,
-	Balance: Clone,
-	ConvertAssetId: Convert<Vec<u8>, AssetId>,
-	ConvertBalance: Convert<u128, Balance>,
-> MatchesFungibles<AssetId, Balance> for
-	ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
+		AssetId: Clone,
+		Balance: Clone,
+		ConvertAssetId: Convert<Vec<u8>, AssetId>,
+		ConvertBalance: Convert<u128, Balance>,
+	> MatchesFungibles<AssetId, Balance>
+	for ConvertedAbstractAssetId<AssetId, Balance, ConvertAssetId, ConvertBalance>
 {
 	fn matches_fungibles(a: &MultiAsset) -> result::Result<(AssetId, Balance), MatchError> {
 		let (amount, id) = match (&a.fun, &a.id) {
 			(Fungible(ref amount), Abstract(ref id)) => (amount, id),
 			_ => return Err(MatchError::AssetNotFound),
 		};
-		let what = ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
-		let amount = ConvertBalance::convert_ref(amount).map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
+		let what =
+			ConvertAssetId::convert_ref(id).map_err(|_| MatchError::AssetIdConversionFailed)?;
+		let amount = ConvertBalance::convert_ref(amount)
+			.map_err(|_| MatchError::AmountToBalanceConversionFailed)?;
 		Ok((what, amount))
 	}
 }
 
 pub struct FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId>(
-	PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>
+	PhantomData<(Assets, Matcher, AccountIdConverter, AccountId)>,
 );
 impl<
-	Assets: fungibles::Transfer<AccountId>,
-	Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
-	AccountIdConverter: Convert<MultiLocation, AccountId>,
-	AccountId: Clone,	// can't get away without it since Currency is generic over it.
-> TransactAsset for FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId> {
+		Assets: fungibles::Transfer<AccountId>,
+		Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
+		AccountIdConverter: Convert<MultiLocation, AccountId>,
+		AccountId: Clone, // can't get away without it since Currency is generic over it.
+	> TransactAsset for FungiblesTransferAdapter<Assets, Matcher, AccountIdConverter, AccountId>
+{
 	fn transfer_asset(
 		what: &MultiAsset,
 		from: &MultiLocation,
@@ -122,17 +129,31 @@ impl<
 	}
 }
 
-pub struct FungiblesMutateAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>(
-	PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>
-);
+pub struct FungiblesMutateAdapter<
+	Assets,
+	Matcher,
+	AccountIdConverter,
+	AccountId,
+	CheckAsset,
+	CheckingAccount,
+>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>);
 impl<
-	Assets: fungibles::Mutate<AccountId>,
-	Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
-	AccountIdConverter: Convert<MultiLocation, AccountId>,
-	AccountId: Clone,	// can't get away without it since Currency is generic over it.
-	CheckAsset: Contains<Assets::AssetId>,
-	CheckingAccount: Get<AccountId>,
-> TransactAsset for FungiblesMutateAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount> {
+		Assets: fungibles::Mutate<AccountId>,
+		Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
+		AccountIdConverter: Convert<MultiLocation, AccountId>,
+		AccountId: Clone, // can't get away without it since Currency is generic over it.
+		CheckAsset: Contains<Assets::AssetId>,
+		CheckingAccount: Get<AccountId>,
+	> TransactAsset
+	for FungiblesMutateAdapter<
+		Assets,
+		Matcher,
+		AccountIdConverter,
+		AccountId,
+		CheckAsset,
+		CheckingAccount,
+	>
+{
 	fn can_check_in(_origin: &MultiLocation, what: &MultiAsset) -> Result {
 		// Check we handle this asset.
 		let (asset_id, amount) = Matcher::matches_fungibles(what)?;
@@ -151,7 +172,10 @@ impl<
 			if CheckAsset::contains(&asset_id) {
 				let checking_account = CheckingAccount::get();
 				let ok = Assets::burn_from(asset_id, &checking_account, amount).is_ok();
-				debug_assert!(ok, "`can_check_in` must have returned `true` immediately prior; qed");
+				debug_assert!(
+					ok,
+					"`can_check_in` must have returned `true` immediately prior; qed"
+				);
 			}
 		}
 	}
@@ -177,7 +201,7 @@ impl<
 
 	fn withdraw_asset(
 		what: &MultiAsset,
-		who: &MultiLocation
+		who: &MultiLocation,
 	) -> result::Result<xcm_executor::Assets, XcmError> {
 		// Check we handle this asset.
 		let (asset_id, amount) = Matcher::matches_fungibles(what)?;
@@ -189,43 +213,80 @@ impl<
 	}
 }
 
-pub struct FungiblesAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>(
-	PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>
-);
+pub struct FungiblesAdapter<
+	Assets,
+	Matcher,
+	AccountIdConverter,
+	AccountId,
+	CheckAsset,
+	CheckingAccount,
+>(PhantomData<(Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount)>);
 impl<
-	Assets: fungibles::Mutate<AccountId> + fungibles::Transfer<AccountId>,
-	Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
-	AccountIdConverter: Convert<MultiLocation, AccountId>,
-	AccountId: Clone,	// can't get away without it since Currency is generic over it.
-	CheckAsset: Contains<Assets::AssetId>,
-	CheckingAccount: Get<AccountId>,
-> TransactAsset for FungiblesAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount> {
+		Assets: fungibles::Mutate<AccountId> + fungibles::Transfer<AccountId>,
+		Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
+		AccountIdConverter: Convert<MultiLocation, AccountId>,
+		AccountId: Clone, // can't get away without it since Currency is generic over it.
+		CheckAsset: Contains<Assets::AssetId>,
+		CheckingAccount: Get<AccountId>,
+	> TransactAsset
+	for FungiblesAdapter<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
+{
 	fn can_check_in(origin: &MultiLocation, what: &MultiAsset) -> Result {
-		FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
-			::can_check_in(origin, what)
+		FungiblesMutateAdapter::<
+			Assets,
+			Matcher,
+			AccountIdConverter,
+			AccountId,
+			CheckAsset,
+			CheckingAccount,
+		>::can_check_in(origin, what)
 	}
 
 	fn check_in(origin: &MultiLocation, what: &MultiAsset) {
-		FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
-			::check_in(origin, what)
+		FungiblesMutateAdapter::<
+			Assets,
+			Matcher,
+			AccountIdConverter,
+			AccountId,
+			CheckAsset,
+			CheckingAccount,
+		>::check_in(origin, what)
 	}
 
 	fn check_out(dest: &MultiLocation, what: &MultiAsset) {
-		FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
-			::check_out(dest, what)
+		FungiblesMutateAdapter::<
+			Assets,
+			Matcher,
+			AccountIdConverter,
+			AccountId,
+			CheckAsset,
+			CheckingAccount,
+		>::check_out(dest, what)
 	}
 
 	fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result {
-		FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
-			::deposit_asset(what, who)
+		FungiblesMutateAdapter::<
+			Assets,
+			Matcher,
+			AccountIdConverter,
+			AccountId,
+			CheckAsset,
+			CheckingAccount,
+		>::deposit_asset(what, who)
 	}
 
 	fn withdraw_asset(
 		what: &MultiAsset,
-		who: &MultiLocation
+		who: &MultiLocation,
 	) -> result::Result<xcm_executor::Assets, XcmError> {
-		FungiblesMutateAdapter::<Assets, Matcher, AccountIdConverter, AccountId, CheckAsset, CheckingAccount>
-			::withdraw_asset(what, who)
+		FungiblesMutateAdapter::<
+			Assets,
+			Matcher,
+			AccountIdConverter,
+			AccountId,
+			CheckAsset,
+			CheckingAccount,
+		>::withdraw_asset(what, who)
 	}
 
 	fn transfer_asset(
@@ -233,6 +294,8 @@ impl<
 		from: &MultiLocation,
 		to: &MultiLocation,
 	) -> result::Result<xcm_executor::Assets, XcmError> {
-		FungiblesTransferAdapter::<Assets, Matcher, AccountIdConverter, AccountId>::transfer_asset(what, from, to)
+		FungiblesTransferAdapter::<Assets, Matcher, AccountIdConverter, AccountId>::transfer_asset(
+			what, from, to,
+		)
 	}
 }
diff --git a/xcm/xcm-builder/src/lib.rs b/xcm/xcm-builder/src/lib.rs
index 339a9321e1ad..d2e2d2e23f38 100644
--- a/xcm/xcm-builder/src/lib.rs
+++ b/xcm/xcm-builder/src/lib.rs
@@ -27,21 +27,22 @@ mod tests;
 
 mod location_conversion;
 pub use location_conversion::{
-	Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases,
-	AccountKey20Aliases, LocationInverter,
+	Account32Hash, AccountId32Aliases, AccountKey20Aliases, ChildParachainConvertsVia,
+	LocationInverter, ParentIsDefault, SiblingParachainConvertsVia,
 };
 
 mod origin_conversion;
 pub use origin_conversion::{
-	SovereignSignedViaLocation, ParentAsSuperuser, ChildSystemParachainAsSuperuser, SiblingSystemParachainAsSuperuser,
-	ChildParachainAsNative, SiblingParachainAsNative, RelayChainAsNative, SignedAccountId32AsNative,
-	SignedAccountKey20AsNative, EnsureXcmOrigin, SignedToAccountId32, BackingToPlurality,
+	BackingToPlurality, ChildParachainAsNative, ChildSystemParachainAsSuperuser, EnsureXcmOrigin,
+	ParentAsSuperuser, RelayChainAsNative, SiblingParachainAsNative,
+	SiblingSystemParachainAsSuperuser, SignedAccountId32AsNative, SignedAccountKey20AsNative,
+	SignedToAccountId32, SovereignSignedViaLocation,
 };
 
 mod barriers;
 pub use barriers::{
-	TakeWeightCredit, AllowUnpaidExecutionFrom, AllowTopLevelPaidExecutionFrom, AllowKnownQueryResponses,
-	IsChildSystemParachain,
+	AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
+	IsChildSystemParachain, TakeWeightCredit,
 };
 
 mod currency_adapter;
@@ -50,13 +51,13 @@ pub use currency_adapter::CurrencyAdapter;
 mod fungibles_adapter;
 pub use fungibles_adapter::{
 	AsPrefixedGeneralIndex, ConvertedAbstractAssetId, ConvertedConcreteAssetId, FungiblesAdapter,
-	FungiblesMutateAdapter, FungiblesTransferAdapter
+	FungiblesMutateAdapter, FungiblesTransferAdapter,
 };
 
 mod weight;
-pub use weight::{FixedRateOfFungible, FixedWeightBounds, UsingComponents, TakeRevenue};
 #[allow(deprecated)]
 pub use weight::FixedRateOfConcreteFungible;
+pub use weight::{FixedRateOfFungible, FixedWeightBounds, TakeRevenue, UsingComponents};
 
 mod matches_fungible;
 pub use matches_fungible::{IsAbstract, IsConcrete};
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 6b80994d1989..0b635f3c1cb8 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -16,10 +16,14 @@
 
 //! Various implementations for the `MatchesFungible` trait.
 
-use sp_std::{marker::PhantomData, convert::TryFrom};
-use sp_runtime::traits::CheckedConversion;
-use xcm::v0::{MultiAsset, MultiLocation, AssetId::{Abstract, Concrete}, Fungibility::Fungible};
 use frame_support::traits::Get;
+use sp_runtime::traits::CheckedConversion;
+use sp_std::{convert::TryFrom, marker::PhantomData};
+use xcm::v0::{
+	AssetId::{Abstract, Concrete},
+	Fungibility::Fungible,
+	MultiAsset, MultiLocation,
+};
 use xcm_executor::traits::MatchesFungible;
 
 /// Converts a `MultiAsset` into balance `B` if it is a concrete fungible with an id equal to that
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index d036d2997df1..6adc5b478343 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -14,23 +14,30 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-pub use sp_std::{fmt::Debug, marker::PhantomData, cell::RefCell};
-pub use sp_std::collections::{btree_map::BTreeMap, btree_set::BTreeSet};
-pub use parity_scale_codec::{Encode, Decode};
-pub use xcm::v0::prelude::*;
+pub use crate::{
+	AllowKnownQueryResponses, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
+	FixedRateOfFungible, FixedWeightBounds, LocationInverter, TakeWeightCredit,
+};
 pub use frame_support::{
+	dispatch::{
+		DispatchError, DispatchInfo, DispatchResultWithPostInfo, Dispatchable, Parameter, Weight,
+	},
 	ensure, parameter_types,
-	dispatch::{Dispatchable, Parameter, Weight, DispatchError, DispatchResultWithPostInfo, DispatchInfo},
-	weights::{PostDispatchInfo, GetDispatchInfo},
 	sp_runtime::DispatchErrorWithPostInfo,
-	traits::{Get, Contains, IsInVec},
+	traits::{Contains, Get, IsInVec},
+	weights::{GetDispatchInfo, PostDispatchInfo},
 };
-pub use xcm_executor::{
-	Assets, Config, traits::{TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse}
+pub use parity_scale_codec::{Decode, Encode};
+pub use sp_std::{
+	cell::RefCell,
+	collections::{btree_map::BTreeMap, btree_set::BTreeSet},
+	fmt::Debug,
+	marker::PhantomData,
 };
-pub use crate::{
-	TakeWeightCredit, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom, FixedWeightBounds,
-	FixedRateOfFungible, AllowKnownQueryResponses, LocationInverter,
+pub use xcm::v0::prelude::*;
+pub use xcm_executor::{
+	traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset},
+	Assets, Config,
 };
 
 pub enum TestOrigin {
@@ -59,20 +66,18 @@ impl Dispatchable for TestCall {
 	fn dispatch(self, origin: Self::Origin) -> DispatchResultWithPostInfo {
 		let mut post_info = PostDispatchInfo::default();
 		post_info.actual_weight = match self {
-			TestCall::OnlyRoot(_, maybe_actual)
-			| TestCall::OnlySigned(_, maybe_actual, _)
-			| TestCall::OnlyParachain(_, maybe_actual, _)
-			| TestCall::Any(_, maybe_actual)
-			=> maybe_actual,
+			TestCall::OnlyRoot(_, maybe_actual) |
+			TestCall::OnlySigned(_, maybe_actual, _) |
+			TestCall::OnlyParachain(_, maybe_actual, _) |
+			TestCall::Any(_, maybe_actual) => maybe_actual,
 		};
 		if match (&origin, &self) {
 			(TestOrigin::Parachain(i), TestCall::OnlyParachain(_, _, Some(j))) => i == j,
 			(TestOrigin::Signed(i), TestCall::OnlySigned(_, _, Some(j))) => i == j,
-			(TestOrigin::Root, TestCall::OnlyRoot(..))
-			| (TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None))
-			| (TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None))
-			| (_, TestCall::Any(..))
-			=> true,
+			(TestOrigin::Root, TestCall::OnlyRoot(..)) |
+			(TestOrigin::Parachain(_), TestCall::OnlyParachain(_, _, None)) |
+			(TestOrigin::Signed(_), TestCall::OnlySigned(_, _, None)) |
+			(_, TestCall::Any(..)) => true,
 			_ => false,
 		} {
 			Ok(post_info)
@@ -85,13 +90,12 @@ impl Dispatchable for TestCall {
 impl GetDispatchInfo for TestCall {
 	fn get_dispatch_info(&self) -> DispatchInfo {
 		let weight = *match self {
-			TestCall::OnlyRoot(estimate, ..)
-			| TestCall::OnlyParachain(estimate, ..)
-			| TestCall::OnlySigned(estimate, ..)
-			| TestCall::Any(estimate, ..)
-			=> estimate,
+			TestCall::OnlyRoot(estimate, ..) |
+			TestCall::OnlyParachain(estimate, ..) |
+			TestCall::OnlySigned(estimate, ..) |
+			TestCall::Any(estimate, ..) => estimate,
 		};
-		DispatchInfo { weight, .. Default::default() }
+		DispatchInfo { weight, ..Default::default() }
 	}
 }
 
@@ -116,11 +120,7 @@ pub fn assets(who: u64) -> Vec<MultiAsset> {
 	ASSETS.with(|a| a.borrow().get(&who).map_or(vec![], |a| a.clone().into()))
 }
 pub fn add_asset(who: u64, what: MultiAsset) {
-	ASSETS.with(|a| a.borrow_mut()
-		.entry(who)
-		.or_insert(Assets::new())
-		.subsume(what)
-	);
+	ASSETS.with(|a| a.borrow_mut().entry(who).or_insert(Assets::new()).subsume(what));
 }
 
 pub struct TestAssetTransactor;
@@ -133,16 +133,16 @@ impl TransactAsset for TestAssetTransactor {
 
 	fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> Result<Assets, XcmError> {
 		let who = to_account(who.clone()).map_err(|_| XcmError::LocationCannotHold)?;
-		ASSETS.with(|a| a.borrow_mut()
-			.get_mut(&who)
-			.ok_or(XcmError::NotWithdrawable)?
-			.try_take(what.clone().into())
-			.map_err(|_| XcmError::NotWithdrawable)
-		)
+		ASSETS.with(|a| {
+			a.borrow_mut()
+				.get_mut(&who)
+				.ok_or(XcmError::NotWithdrawable)?
+				.try_take(what.clone().into())
+				.map_err(|_| XcmError::NotWithdrawable)
+		})
 	}
 }
 
-
 pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
 	Ok(match l {
 		// Siblings at 2000+id
@@ -161,14 +161,17 @@ pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
 
 pub struct TestOriginConverter;
 impl ConvertOrigin<TestOrigin> for TestOriginConverter {
-	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<TestOrigin, MultiLocation> {
+	fn convert_origin(
+		origin: MultiLocation,
+		kind: OriginKind,
+	) -> Result<TestOrigin, MultiLocation> {
 		use OriginKind::*;
 		match (kind, origin) {
 			(Superuser, _) => Ok(TestOrigin::Root),
 			(SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)),
 			(Native, X1(Parachain(id))) => Ok(TestOrigin::Parachain(id)),
 			(Native, X1(Parent)) => Ok(TestOrigin::Relay),
-			(Native, X1(AccountIndex64 {index, ..})) => Ok(TestOrigin::Signed(index)),
+			(Native, X1(AccountIndex64 { index, .. })) => Ok(TestOrigin::Signed(index)),
 			(_, origin) => Err(origin),
 		}
 	}
@@ -188,17 +191,15 @@ pub fn add_teleporter(from: MultiLocation, asset: MultiAssetFilter) {
 pub struct TestIsReserve;
 impl FilterAssetLocation for TestIsReserve {
 	fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {
-		IS_RESERVE.with(|r| r.borrow().get(origin)
-			.map_or(false, |v| v.iter().any(|a| a.contains(asset)))
-		)
+		IS_RESERVE
+			.with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.contains(asset))))
 	}
 }
 pub struct TestIsTeleporter;
 impl FilterAssetLocation for TestIsTeleporter {
 	fn filter_asset_location(asset: &MultiAsset, origin: &MultiLocation) -> bool {
-		IS_TELEPORTER.with(|r| r.borrow().get(origin)
-			.map_or(false, |v| v.iter().any(|a| a.contains(asset)))
-		)
+		IS_TELEPORTER
+			.with(|r| r.borrow().get(origin).map_or(false, |v| v.iter().any(|a| a.contains(asset))))
 	}
 }
 
@@ -220,28 +221,25 @@ impl OnResponse for TestResponseHandler {
 	}
 	fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::v0::Response) -> Weight {
 		QUERIES.with(|q| {
-			q.borrow_mut()
-				.entry(query_id)
-				.and_modify(|v| if matches!(*v, ResponseSlot::Expecting(..)) {
+			q.borrow_mut().entry(query_id).and_modify(|v| {
+				if matches!(*v, ResponseSlot::Expecting(..)) {
 					*v = ResponseSlot::Received(response);
-				});
+				}
+			});
 		});
 		10
 	}
 }
 pub fn expect_response(query_id: u64, from: MultiLocation) {
-	QUERIES.with(|q| q.borrow_mut()
-		.insert(query_id, ResponseSlot::Expecting(from))
-	);
+	QUERIES.with(|q| q.borrow_mut().insert(query_id, ResponseSlot::Expecting(from)));
 }
 pub fn response(query_id: u64) -> Option<Response> {
-	QUERIES.with(|q| q.borrow()
-		.get(&query_id)
-		.and_then(|v| match v {
+	QUERIES.with(|q| {
+		q.borrow().get(&query_id).and_then(|v| match v {
 			ResponseSlot::Received(r) => Some(r.clone()),
 			_ => None,
 		})
-	)
+	})
 }
 
 parameter_types! {
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index e23c262ea660..5c7465440b29 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -14,10 +14,9 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use super::*;
-use super::mock::*;
+use super::{mock::*, *};
 use xcm::v0::prelude::*;
-use xcm_executor::{XcmExecutor, Config, traits::*};
+use xcm_executor::{traits::*, Config, XcmExecutor};
 
 #[test]
 fn basic_setup_works() {
@@ -31,8 +30,8 @@ fn basic_setup_works() {
 	assert_eq!(to_account(X1(Parachain(50))), Ok(1050));
 	assert_eq!(to_account(X2(Parent, Parachain(1))), Ok(2001));
 	assert_eq!(to_account(X2(Parent, Parachain(50))), Ok(2050));
-	assert_eq!(to_account(X1(AccountIndex64{index:1, network:Any})), Ok(1));
-	assert_eq!(to_account(X1(AccountIndex64{index:42, network:Any})), Ok(42));
+	assert_eq!(to_account(X1(AccountIndex64 { index: 1, network: Any })), Ok(1));
+	assert_eq!(to_account(X1(AccountIndex64 { index: 42, network: Any })), Ok(42));
 	assert_eq!(to_account(Null), Ok(3000));
 }
 
@@ -41,50 +40,41 @@ fn weigher_should_work() {
 	let mut message = opaque::Xcm::ReserveAssetDeposited {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::BuyExecution { fees: (X1(Parent), 1).into(), weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
+			Order::BuyExecution {
+				fees: (X1(Parent), 1).into(),
+				weight: 0,
+				debt: 30,
+				halt_on_error: true,
+				xcm: vec![],
+			},
 			Order::DepositAsset { assets: All.into(), dest: Null },
 		],
-	}.into();
+	}
+	.into();
 	assert_eq!(<TestConfig as Config>::Weigher::shallow(&mut message), Ok(30));
 }
 
 #[test]
 fn take_weight_credit_barrier_should_work() {
-	let mut message = opaque::Xcm::TransferAsset {
-		assets: (X1(Parent), 100).into(),
-		dest: Null,
-	};
+	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), dest: Null };
 
 	let mut weight_credit = 10;
-	let r = TakeWeightCredit::should_execute(
-		&X1(Parent),
-		true,
-		&mut message,
-		10,
-		&mut weight_credit,
-	);
+	let r =
+		TakeWeightCredit::should_execute(&X1(Parent), true, &mut message, 10, &mut weight_credit);
 	assert_eq!(r, Ok(()));
 	assert_eq!(weight_credit, 0);
 
-	let r = TakeWeightCredit::should_execute(
-		&X1(Parent),
-		true,
-		&mut message,
-		10,
-		&mut weight_credit,
-	);
+	let r =
+		TakeWeightCredit::should_execute(&X1(Parent), true, &mut message, 10, &mut weight_credit);
 	assert_eq!(r, Err(()));
 	assert_eq!(weight_credit, 0);
 }
 
 #[test]
 fn allow_unpaid_should_work() {
-	let mut message = opaque::Xcm::TransferAsset {
-		assets: (X1(Parent), 100).into(),
-		dest: Null,
-	};
+	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), dest: Null };
 
-	AllowUnpaidFrom::set(vec![ X1(Parent) ]);
+	AllowUnpaidFrom::set(vec![X1(Parent)]);
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
 		&X1(Parachain(1)),
@@ -107,12 +97,9 @@ fn allow_unpaid_should_work() {
 
 #[test]
 fn allow_paid_should_work() {
-	AllowPaidFrom::set(vec![ X1(Parent) ]);
+	AllowPaidFrom::set(vec![X1(Parent)]);
 
-	let mut message = opaque::Xcm::TransferAsset {
-		assets: (X1(Parent), 100).into(),
-		dest: Null,
-	};
+	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), dest: Null };
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
 		&X1(Parachain(1)),
@@ -171,7 +158,7 @@ fn allow_paid_should_work() {
 
 #[test]
 fn paying_reserve_deposit_should_work() {
-	AllowPaidFrom::set(vec![ X1(Parent) ]);
+	AllowPaidFrom::set(vec![X1(Parent)]);
 	add_reserve(X1(Parent), (X1(Parent), WildFungible).into());
 	WeightPrice::set((X1(Parent).into(), 1_000_000_000_000));
 
@@ -180,7 +167,13 @@ fn paying_reserve_deposit_should_work() {
 	let message = Xcm::<TestCall>::ReserveAssetDeposited {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::<TestCall>::BuyExecution { fees, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
+			Order::<TestCall>::BuyExecution {
+				fees,
+				weight: 0,
+				debt: 30,
+				halt_on_error: true,
+				xcm: vec![],
+			},
 			Order::<TestCall>::DepositAsset { assets: All.into(), dest: Null },
 		],
 	};
@@ -193,7 +186,7 @@ fn paying_reserve_deposit_should_work() {
 #[test]
 fn transfer_should_work() {
 	// we'll let them have message execution for free.
-	AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]);
+	AllowUnpaidFrom::set(vec![X1(Parachain(1))]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
 	add_asset(1001, (Null, 1000).into());
 	// They want to transfer 100 of them to their sibling parachain #2
@@ -201,7 +194,7 @@ fn transfer_should_work() {
 		X1(Parachain(1)),
 		Xcm::TransferAsset {
 			assets: (Null, 100).into(),
-			dest: X1(AccountIndex64{index:3, network:Any}),
+			dest: X1(AccountIndex64 { index: 3, network: Any }),
 		},
 		50,
 	);
@@ -213,11 +206,11 @@ fn transfer_should_work() {
 
 #[test]
 fn reserve_transfer_should_work() {
-	AllowUnpaidFrom::set(vec![ X1(Parachain(1)) ]);
+	AllowUnpaidFrom::set(vec![X1(Parachain(1))]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
 	add_asset(1001, (Null, 1000).into());
 	// The remote account owned by gav.
-	let three = X1(AccountIndex64{index:3, network:Any});
+	let three = X1(AccountIndex64 { index: 3, network: Any });
 
 	// They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2
 	// and let them know to hand it to account #3.
@@ -226,25 +219,28 @@ fn reserve_transfer_should_work() {
 		Xcm::TransferReserveAsset {
 			assets: (Null, 100).into(),
 			dest: X1(Parachain(2)),
-			effects: vec![ Order::DepositAsset { assets: All.into(), dest: three.clone() } ],
+			effects: vec![Order::DepositAsset { assets: All.into(), dest: three.clone() }],
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
 
 	assert_eq!(assets(1002), vec![(Null, 100).into()]);
-	assert_eq!(sent_xcm(), vec![(
-		X1(Parachain(2)),
-		Xcm::ReserveAssetDeposited {
-			assets: (X1(Parent), 100).into(),
-			effects: vec![ Order::DepositAsset { assets: All.into(), dest: three } ],
-		})
-	]);
+	assert_eq!(
+		sent_xcm(),
+		vec![(
+			X1(Parachain(2)),
+			Xcm::ReserveAssetDeposited {
+				assets: (X1(Parent), 100).into(),
+				effects: vec![Order::DepositAsset { assets: All.into(), dest: three }],
+			}
+		)]
+	);
 }
 
 #[test]
 fn transacting_should_work() {
-	AllowUnpaidFrom::set(vec![ X1(Parent) ]);
+	AllowUnpaidFrom::set(vec![X1(Parent)]);
 
 	let origin = X1(Parent);
 	let message = Xcm::<TestCall>::Transact {
@@ -259,7 +255,7 @@ fn transacting_should_work() {
 
 #[test]
 fn transacting_should_respect_max_weight_requirement() {
-	AllowUnpaidFrom::set(vec![ X1(Parent) ]);
+	AllowUnpaidFrom::set(vec![X1(Parent)]);
 
 	let origin = X1(Parent);
 	let message = Xcm::<TestCall>::Transact {
@@ -274,7 +270,7 @@ fn transacting_should_respect_max_weight_requirement() {
 
 #[test]
 fn transacting_should_refund_weight() {
-	AllowUnpaidFrom::set(vec![ X1(Parent) ]);
+	AllowUnpaidFrom::set(vec![X1(Parent)]);
 
 	let origin = X1(Parent);
 	let message = Xcm::<TestCall>::Transact {
@@ -289,24 +285,28 @@ fn transacting_should_refund_weight() {
 
 #[test]
 fn paid_transacting_should_refund_payment_for_unused_weight() {
-	let one = X1(AccountIndex64{index:1, network:Any});
-	AllowPaidFrom::set(vec![ one.clone() ]);
+	let one = X1(AccountIndex64 { index: 1, network: Any });
+	AllowPaidFrom::set(vec![one.clone()]);
 	add_asset(1, (X1(Parent), 100).into());
 	WeightPrice::set((X1(Parent).into(), 1_000_000_000_000));
 
 	let origin = one.clone();
 	let fees = (X1(Parent), 100).into();
 	let message = Xcm::<TestCall>::WithdrawAsset {
-		assets: (X1(Parent), 100).into(),	// enough for 100 units of weight.
+		assets: (X1(Parent), 100).into(), // enough for 100 units of weight.
 		effects: vec![
-			Order::<TestCall>::BuyExecution { fees, weight: 70, debt: 30, halt_on_error: true, xcm: vec![
-				Xcm::<TestCall>::Transact {
+			Order::<TestCall>::BuyExecution {
+				fees,
+				weight: 70,
+				debt: 30,
+				halt_on_error: true,
+				xcm: vec![Xcm::<TestCall>::Transact {
 					origin_type: OriginKind::Native,
 					require_weight_at_most: 60,
 					// call estimated at 70 but only takes 10.
 					call: TestCall::Any(60, Some(10)).encode().into(),
-				}
-			] },
+				}],
+			},
 			Order::<TestCall>::DepositAsset { assets: All.into(), dest: one.clone() },
 		],
 	};
@@ -324,10 +324,7 @@ fn prepaid_result_of_query_should_get_free_execution() {
 	expect_response(query_id, origin.clone());
 
 	let the_response = Response::Assets((X1(Parent), 100).into());
-	let message = Xcm::<TestCall>::QueryResponse {
-		query_id,
-		response: the_response.clone(),
-	};
+	let message = Xcm::<TestCall>::QueryResponse { query_id, response: the_response.clone() };
 	let weight_limit = 10;
 
 	// First time the response gets through since we're expecting it...
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index 500db2a393c1..faee6a08f23c 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -14,27 +14,32 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use sp_std::{result::Result, marker::PhantomData, convert::TryInto};
+use frame_support::{
+	traits::{tokens::currency::Currency as CurrencyT, Get, OnUnbalanced as OnUnbalancedT},
+	weights::{GetDispatchInfo, Weight, WeightToFeePolynomial},
+};
 use parity_scale_codec::Decode;
-use xcm::v0::{Xcm, Order, MultiAsset, AssetId, MultiLocation, Error, AssetId::Concrete};
-use sp_runtime::traits::{Zero, Saturating, SaturatedConversion};
-use frame_support::traits::{Get, OnUnbalanced as OnUnbalancedT, tokens::currency::Currency as CurrencyT};
-use frame_support::weights::{Weight, GetDispatchInfo, WeightToFeePolynomial};
-use xcm_executor::{Assets, traits::{WeightBounds, WeightTrader}};
+use sp_runtime::traits::{SaturatedConversion, Saturating, Zero};
+use sp_std::{convert::TryInto, marker::PhantomData, result::Result};
+use xcm::v0::{AssetId, AssetId::Concrete, Error, MultiAsset, MultiLocation, Order, Xcm};
+use xcm_executor::{
+	traits::{WeightBounds, WeightTrader},
+	Assets,
+};
 
 pub struct FixedWeightBounds<T, C>(PhantomData<(T, C)>);
 impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeightBounds<T, C> {
 	fn shallow(message: &mut Xcm<C>) -> Result<Weight, ()> {
 		Ok(match message {
-			Xcm::Transact { call, .. } => {
-				call.ensure_decoded()?.get_dispatch_info().weight.saturating_add(T::get())
-			}
-			Xcm::RelayedFrom { ref mut message, .. } => T::get().saturating_add(Self::shallow(message.as_mut())?),
-			Xcm::WithdrawAsset { effects, .. }
-			| Xcm::ReserveAssetDeposited { effects, .. }
-			| Xcm::TeleportAsset { effects, .. }
-			=> {
-				let inner: Weight = effects.iter_mut()
+			Xcm::Transact { call, .. } =>
+				call.ensure_decoded()?.get_dispatch_info().weight.saturating_add(T::get()),
+			Xcm::RelayedFrom { ref mut message, .. } =>
+				T::get().saturating_add(Self::shallow(message.as_mut())?),
+			Xcm::WithdrawAsset { effects, .. } |
+			Xcm::ReserveAssetDeposited { effects, .. } |
+			Xcm::TeleportAsset { effects, .. } => {
+				let inner: Weight = effects
+					.iter_mut()
 					.map(|effect| match effect {
 						Order::BuyExecution { .. } => {
 							// On success, execution of this will result in more weight being consumed but
@@ -45,28 +50,29 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeigh
 							T::get()
 						},
 						_ => T::get(),
-					}).sum();
+					})
+					.sum();
 				T::get().saturating_add(inner)
-			}
+			},
 			_ => T::get(),
 		})
 	}
 	fn deep(message: &mut Xcm<C>) -> Result<Weight, ()> {
 		Ok(match message {
 			Xcm::RelayedFrom { ref mut message, .. } => Self::deep(message.as_mut())?,
-			Xcm::WithdrawAsset { effects, .. }
-			| Xcm::ReserveAssetDeposited { effects, .. }
-			| Xcm::TeleportAsset { effects, .. }
-			=> {
+			Xcm::WithdrawAsset { effects, .. } |
+			Xcm::ReserveAssetDeposited { effects, .. } |
+			Xcm::TeleportAsset { effects, .. } => {
 				let mut extra = 0;
 				for effect in effects.iter_mut() {
 					match effect {
-						Order::BuyExecution { xcm, .. } => {
+						Order::BuyExecution { xcm, .. } =>
 							for message in xcm.iter_mut() {
-								extra.saturating_accrue(Self::shallow(message)?.saturating_add(Self::deep(message)?));
-							}
-						},
-						_ => {}
+								extra.saturating_accrue(
+									Self::shallow(message)?.saturating_add(Self::deep(message)?),
+								);
+							},
+						_ => {},
 					}
 				}
 				extra
@@ -93,13 +99,18 @@ impl TakeRevenue for () {
 /// The constant `Get` type parameter should be the concrete fungible ID and the amount of it required for
 /// one second of weight.
 #[deprecated = "Use `FixedRateOfFungible` instead"]
-pub struct FixedRateOfConcreteFungible<
-	T: Get<(MultiLocation, u128)>,
-	R: TakeRevenue,
->(Weight, u128, PhantomData<(T, R)>);
+pub struct FixedRateOfConcreteFungible<T: Get<(MultiLocation, u128)>, R: TakeRevenue>(
+	Weight,
+	u128,
+	PhantomData<(T, R)>,
+);
 #[allow(deprecated)]
-impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader for FixedRateOfConcreteFungible<T, R> {
-	fn new() -> Self { Self(0, 0, PhantomData) }
+impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> WeightTrader
+	for FixedRateOfConcreteFungible<T, R>
+{
+	fn new() -> Self {
+		Self(0, 0, PhantomData)
+	}
 
 	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error> {
 		let (id, units_per_second) = T::get();
@@ -137,12 +148,15 @@ impl<T: Get<(MultiLocation, u128)>, R: TakeRevenue> Drop for FixedRateOfConcrete
 ///
 /// The constant `Get` type parameter should be the fungible ID and the amount of it required for
 /// one second of weight.
-pub struct FixedRateOfFungible<
-	T: Get<(AssetId, u128)>,
-	R: TakeRevenue,
->(Weight, u128, PhantomData<(T, R)>);
+pub struct FixedRateOfFungible<T: Get<(AssetId, u128)>, R: TakeRevenue>(
+	Weight,
+	u128,
+	PhantomData<(T, R)>,
+);
 impl<T: Get<(AssetId, u128)>, R: TakeRevenue> WeightTrader for FixedRateOfFungible<T, R> {
-	fn new() -> Self { Self(0, 0, PhantomData) }
+	fn new() -> Self {
+		Self(0, 0, PhantomData)
+	}
 
 	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error> {
 		let (id, units_per_second) = T::get();
@@ -179,20 +193,27 @@ impl<T: Get<(AssetId, u128)>, R: TakeRevenue> Drop for FixedRateOfFungible<T, R>
 /// Weight trader which uses the `TransactionPayment` pallet to set the right price for weight and then
 /// places any weight bought into the right account.
 pub struct UsingComponents<
-	WeightToFee: WeightToFeePolynomial<Balance=Currency::Balance>,
+	WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
 	AssetId: Get<MultiLocation>,
 	AccountId,
 	Currency: CurrencyT<AccountId>,
 	OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
->(Weight, Currency::Balance, PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>);
+>(
+	Weight,
+	Currency::Balance,
+	PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,
+);
 impl<
-	WeightToFee: WeightToFeePolynomial<Balance=Currency::Balance>,
-	AssetId: Get<MultiLocation>,
-	AccountId,
-	Currency: CurrencyT<AccountId>,
-	OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
-> WeightTrader for UsingComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced> {
-	fn new() -> Self { Self(0, Zero::zero(), PhantomData) }
+		WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+		AssetId: Get<MultiLocation>,
+		AccountId,
+		Currency: CurrencyT<AccountId>,
+		OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+	> WeightTrader for UsingComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
+{
+	fn new() -> Self {
+		Self(0, Zero::zero(), PhantomData)
+	}
 
 	fn buy_weight(&mut self, weight: Weight, payment: Assets) -> Result<Assets, Error> {
 		let amount = WeightToFee::calc(&weight);
@@ -216,15 +237,15 @@ impl<
 			None
 		}
 	}
-
 }
 impl<
-	WeightToFee: WeightToFeePolynomial<Balance=Currency::Balance>,
-	AssetId: Get<MultiLocation>,
-	AccountId,
-	Currency: CurrencyT<AccountId>,
-	OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
-> Drop for UsingComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced> {
+		WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,
+		AssetId: Get<MultiLocation>,
+		AccountId,
+		Currency: CurrencyT<AccountId>,
+		OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,
+	> Drop for UsingComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>
+{
 	fn drop(&mut self) {
 		OnUnbalanced::on_unbalanced(Currency::issue(self.1));
 	}
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 85ab40a8eb9b..a7e48662e719 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -14,14 +14,19 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use sp_std::{prelude::*, mem, collections::{btree_map::BTreeMap, btree_set::BTreeSet}};
+use sp_runtime::RuntimeDebug;
+use sp_std::{
+	collections::{btree_map::BTreeMap, btree_set::BTreeSet},
+	mem,
+	prelude::*,
+};
 use xcm::v0::{
-	MultiAsset, MultiAssets, MultiLocation, AssetInstance, MultiAssetFilter, AssetId,
-	WildMultiAsset::{All, AllOf},
+	AssetId, AssetInstance,
 	Fungibility::{Fungible, NonFungible},
+	MultiAsset, MultiAssetFilter, MultiAssets, MultiLocation,
 	WildFungibility::{Fungible as WildFungible, NonFungible as WildNonFungible},
+	WildMultiAsset::{All, AllOf},
 };
-use sp_runtime::RuntimeDebug;
 
 /// List of non-wildcard fungible and non-fungible assets.
 #[derive(Default, Clone, RuntimeDebug, Eq, PartialEq)]
@@ -80,26 +85,38 @@ pub enum TakeError {
 
 impl Assets {
 	/// New value, containing no assets.
-	pub fn new() -> Self { Self::default() }
+	pub fn new() -> Self {
+		Self::default()
+	}
 
 	/// A borrowing iterator over the fungible assets.
-	pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator<Item=MultiAsset> + 'a {
-		self.fungible.iter().map(|(id, &amount)| MultiAsset { fun: Fungible(amount), id: id.clone() })
+	pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator<Item = MultiAsset> + 'a {
+		self.fungible
+			.iter()
+			.map(|(id, &amount)| MultiAsset { fun: Fungible(amount), id: id.clone() })
 	}
 
 	/// A borrowing iterator over the non-fungible assets.
-	pub fn non_fungible_assets_iter<'a>(&'a self) -> impl Iterator<Item=MultiAsset> + 'a {
-		self.non_fungible.iter().map(|(id, instance)| MultiAsset { fun: NonFungible(instance.clone()), id: id.clone() })
+	pub fn non_fungible_assets_iter<'a>(&'a self) -> impl Iterator<Item = MultiAsset> + 'a {
+		self.non_fungible
+			.iter()
+			.map(|(id, instance)| MultiAsset { fun: NonFungible(instance.clone()), id: id.clone() })
 	}
 
 	/// A consuming iterator over all assets.
-	pub fn into_assets_iter(self) -> impl Iterator<Item=MultiAsset> {
-		self.fungible.into_iter().map(|(id, amount)| MultiAsset { fun: Fungible(amount), id })
-			.chain(self.non_fungible.into_iter().map(|(id, instance)| MultiAsset { fun: NonFungible(instance), id }))
+	pub fn into_assets_iter(self) -> impl Iterator<Item = MultiAsset> {
+		self.fungible
+			.into_iter()
+			.map(|(id, amount)| MultiAsset { fun: Fungible(amount), id })
+			.chain(
+				self.non_fungible
+					.into_iter()
+					.map(|(id, instance)| MultiAsset { fun: NonFungible(instance), id }),
+			)
 	}
 
 	/// A borrowing iterator over all assets.
-	pub fn assets_iter<'a>(&'a self) -> impl Iterator<Item=MultiAsset> + 'a {
+	pub fn assets_iter<'a>(&'a self) -> impl Iterator<Item = MultiAsset> + 'a {
 		self.fungible_assets_iter().chain(self.non_fungible_assets_iter())
 	}
 
@@ -110,7 +127,7 @@ impl Assets {
 		if let (Some(mut f), Some(mut g)) = (f_iter.next(), g_iter.next()) {
 			loop {
 				if f.0 == g.0 {
-					// keys are equal. in this case, we add `swlf`'s balance for the asset onto `assets`, balance, knowing
+					// keys are equal. in this case, we add `self`'s balance for the asset onto `assets`, balance, knowing
 					// that the `append` operation which follows will clobber `self`'s value and only use `assets`'s.
 					*f.1 += *g.1;
 				}
@@ -142,10 +159,10 @@ impl Assets {
 					.entry(asset.id)
 					.and_modify(|e| *e = e.saturating_add(amount))
 					.or_insert(amount);
-			}
+			},
 			NonFungible(instance) => {
 				self.non_fungible.insert((asset.id, instance));
-			}
+			},
 		}
 	}
 
@@ -162,13 +179,21 @@ impl Assets {
 	pub fn prepend_location(&mut self, prepend: &MultiLocation) {
 		let mut fungible = Default::default();
 		mem::swap(&mut self.fungible, &mut fungible);
-		self.fungible = fungible.into_iter()
-			.map(|(mut id, amount)| { let _ = id.reanchor(prepend); (id, amount) })
+		self.fungible = fungible
+			.into_iter()
+			.map(|(mut id, amount)| {
+				let _ = id.reanchor(prepend);
+				(id, amount)
+			})
 			.collect();
 		let mut non_fungible = Default::default();
 		mem::swap(&mut self.non_fungible, &mut non_fungible);
-		self.non_fungible = non_fungible.into_iter()
-			.map(|(mut class, inst)| { let _ = class.reanchor(prepend); (class, inst) })
+		self.non_fungible = non_fungible
+			.into_iter()
+			.map(|(mut class, inst)| {
+				let _ = class.reanchor(prepend);
+				(class, inst)
+			})
 			.collect();
 	}
 
@@ -181,13 +206,13 @@ impl Assets {
 					if self.fungible.get(id).map_or(true, |a| a < amount) {
 						return Err(TakeError::AssetUnderflow((id.clone(), *amount).into()))
 					}
-				}
+				},
 				MultiAsset { fun: NonFungible(ref instance), ref id } => {
 					let id_instance = (id.clone(), instance.clone());
 					if !self.non_fungible.contains(&id_instance) {
 						return Err(TakeError::AssetUnderflow(id_instance.into()))
 					}
-				}
+				},
 			}
 		}
 		return Ok(())
@@ -202,7 +227,11 @@ impl Assets {
 	/// Returns `Ok` with the definite assets token from `self` and mutates `self` to its value minus
 	/// `mask`. Returns `Err` in the non-saturating case where `self` did not contain (enough of) a definite asset to
 	/// be removed.
-	fn general_take(&mut self, mask: MultiAssetFilter, saturate: bool) -> Result<Assets, TakeError> {
+	fn general_take(
+		&mut self,
+		mask: MultiAssetFilter,
+		saturate: bool,
+	) -> Result<Assets, TakeError> {
 		let mut taken = Assets::new();
 		match mask {
 			MultiAssetFilter::Wild(All) => return Ok(self.swapped(Assets::new())),
@@ -210,7 +239,7 @@ impl Assets {
 				if let Some((id, amount)) = self.fungible.remove_entry(&id) {
 					taken.fungible.insert(id, amount);
 				}
-			}
+			},
 			MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => {
 				let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
 				non_fungible.into_iter().for_each(|(c, instance)| {
@@ -220,7 +249,7 @@ impl Assets {
 						self.non_fungible.insert((c, instance));
 					}
 				});
-			}
+			},
 			MultiAssetFilter::Definite(assets) => {
 				if !saturate {
 					self.ensure_contains(&assets)?;
@@ -233,7 +262,7 @@ impl Assets {
 									let amount = amount.min(*self_amount);
 									*self_amount -= amount;
 									(*self_amount == 0, amount)
-								}
+								},
 								None => (false, 0),
 							};
 							if remove {
@@ -242,16 +271,16 @@ impl Assets {
 							if amount > 0 {
 								taken.subsume(MultiAsset::from((id, amount)).into());
 							}
-						}
+						},
 						MultiAsset { fun: NonFungible(instance), id } => {
 							let id_instance = (id, instance);
 							if self.non_fungible.remove(&id_instance) {
 								taken.subsume(id_instance.into())
 							}
-						}
+						},
 					}
 				}
-			}
+			},
 		}
 		Ok(taken)
 	}
@@ -291,12 +320,13 @@ impl Assets {
 					self.fungible.remove(&asset.id);
 				}
 				Ok(self)
-			}
-			NonFungible(instance) => if self.non_fungible.remove(&(asset.id, instance)) {
-				Ok(self)
-			} else {
-				Err(self)
 			},
+			NonFungible(instance) =>
+				if self.non_fungible.remove(&(asset.id, instance)) {
+					Ok(self)
+				} else {
+					Err(self)
+				},
 		}
 	}
 
@@ -325,31 +355,30 @@ impl Assets {
 				if let Some(&amount) = self.fungible.get(&id) {
 					masked.fungible.insert(id.clone(), amount);
 				}
-			}
+			},
 			MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => {
 				self.non_fungible.iter().for_each(|(ref c, ref instance)| {
 					if c == id {
 						masked.non_fungible.insert((c.clone(), instance.clone()));
 					}
 				});
-			}
-			MultiAssetFilter::Definite(assets) => {
+			},
+			MultiAssetFilter::Definite(assets) =>
 				for asset in assets.inner().iter() {
 					match asset {
 						MultiAsset { fun: Fungible(ref amount), ref id } => {
 							if let Some(m) = self.fungible.get(id) {
 								masked.subsume((id.clone(), Fungible(*amount.min(m))).into());
 							}
-						}
+						},
 						MultiAsset { fun: NonFungible(ref instance), ref id } => {
 							let id_instance = (id.clone(), instance.clone());
 							if self.non_fungible.contains(&id_instance) {
 								masked.subsume(id_instance.into());
 							}
-						}
+						},
 					}
-				}
-			}
+				},
 		}
 		masked
 	}
@@ -397,7 +426,9 @@ mod tests {
 		let mut r1 = t1.clone();
 		r1.subsume_assets(t2.clone());
 		let mut r2 = t1.clone();
-		for a in t2.assets_iter() { r2.subsume(a) }
+		for a in t2.assets_iter() {
+			r2.subsume(a)
+		}
 		assert_eq!(r1, r2);
 	}
 
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index a12d714cac6c..d6dcbd1f93fd 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -16,17 +16,21 @@
 
 #![cfg_attr(not(feature = "std"), no_std)]
 
-use sp_std::{prelude::*, marker::PhantomData};
 use frame_support::{
-	ensure, weights::GetDispatchInfo,
-	dispatch::{Weight, Dispatchable}
+	dispatch::{Dispatchable, Weight},
+	ensure,
+	weights::GetDispatchInfo,
+};
+use sp_std::{marker::PhantomData, prelude::*};
+use xcm::v0::{
+	Error as XcmError, ExecuteXcm, MultiAssets, MultiLocation, Order, Outcome, Response, SendXcm,
+	Xcm,
 };
-use xcm::v0::{ExecuteXcm, SendXcm, Error as XcmError, Outcome, MultiLocation, MultiAssets, Xcm, Order, Response};
 
 pub mod traits;
 use traits::{
-	TransactAsset, ConvertOrigin, FilterAssetLocation, InvertLocation, WeightBounds, WeightTrader,
-	ShouldExecute, OnResponse
+	ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, ShouldExecute, TransactAsset,
+	WeightBounds, WeightTrader,
 };
 
 mod assets;
@@ -67,10 +71,17 @@ impl<Config: config::Config> ExecuteXcm<Config::Call> for XcmExecutor<Config> {
 			None => return Outcome::Error(XcmError::Overflow),
 		};
 		if maximum_weight > weight_limit {
-			return Outcome::Error(XcmError::WeightLimitReached(maximum_weight));
+			return Outcome::Error(XcmError::WeightLimitReached(maximum_weight))
 		}
 		let mut trader = Config::Trader::new();
-		let result = Self::do_execute_xcm(origin, true, message, &mut weight_credit, Some(shallow_weight), &mut trader);
+		let result = Self::do_execute_xcm(
+			origin,
+			true,
+			message,
+			&mut weight_credit,
+			Some(shallow_weight),
+			&mut trader,
+		);
 		drop(trader);
 		log::trace!(target: "xcm::execute_xcm", "result: {:?}", &result);
 		match result {
@@ -115,8 +126,14 @@ impl<Config: config::Config> XcmExecutor<Config> {
 			.or_else(|| Config::Weigher::shallow(&mut message).ok())
 			.ok_or(XcmError::WeightNotComputable)?;
 
-		Config::Barrier::should_execute(&origin, top_level, &message, shallow_weight, weight_credit)
-			.map_err(|()| XcmError::Barrier)?;
+		Config::Barrier::should_execute(
+			&origin,
+			top_level,
+			&message,
+			shallow_weight,
+			weight_credit,
+		)
+		.map_err(|()| XcmError::Barrier)?;
 
 		// The surplus weight, defined as the amount by which `shallow_weight` plus all nested
 		// `shallow_weight` values (ensuring no double-counting and also known as `deep_weight`) is an
@@ -132,23 +149,26 @@ impl<Config: config::Config> XcmExecutor<Config> {
 					holding.subsume_assets(withdrawn);
 				}
 				Some((holding, effects))
-			}
+			},
 			(origin, Xcm::ReserveAssetDeposited { assets, effects }) => {
 				// check whether we trust origin to be our reserve location for this asset.
 				for asset in assets.inner() {
 					// We only trust the origin to send us assets that they identify as their
 					// sovereign assets.
-					ensure!(Config::IsReserve::filter_asset_location(asset, &origin), XcmError::UntrustedReserveLocation);
+					ensure!(
+						Config::IsReserve::filter_asset_location(asset, &origin),
+						XcmError::UntrustedReserveLocation
+					);
 				}
 				Some((assets.into(), effects))
-			}
+			},
 			(origin, Xcm::TransferAsset { assets, dest }) => {
 				// Take `assets` from the origin account (on-chain) and place into dest account.
 				for asset in assets.inner() {
 					Config::AssetTransactor::beam_asset(&asset, &origin, &dest)?;
 				}
 				None
-			}
+			},
 			(origin, Xcm::TransferReserveAsset { mut assets, dest, effects }) => {
 				// Take `assets` from the origin account (on-chain) and place into dest account.
 				let inv_dest = Config::LocationInverter::invert_location(&dest);
@@ -158,13 +178,16 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				assets.reanchor(&inv_dest)?;
 				Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposited { assets, effects })?;
 				None
-			}
+			},
 			(origin, Xcm::TeleportAsset { assets, effects }) => {
 				// check whether we trust origin to teleport this asset to us via config trait.
 				for asset in assets.inner() {
 					// We only trust the origin to send us assets that they identify as their
 					// sovereign assets.
-					ensure!(Config::IsTeleporter::filter_asset_location(asset, &origin), XcmError::UntrustedTeleportLocation);
+					ensure!(
+						Config::IsTeleporter::filter_asset_location(asset, &origin),
+						XcmError::UntrustedTeleportLocation
+					);
 					// We should check that the asset can actually be teleported in (for this to be in error, there
 					// would need to be an accounting violation by one of the trusted chains, so it's unlikely, but we
 					// don't want to punish a possibly innocent chain/user).
@@ -174,7 +197,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 					Config::AssetTransactor::check_in(&origin, asset);
 				}
 				Some((Assets::from(assets), effects))
-			}
+			},
 			(origin, Xcm::Transact { origin_type, require_weight_at_most, mut call }) => {
 				// We assume that the Relay-chain is allowed to use transact on this parachain.
 
@@ -190,8 +213,9 @@ impl<Config: config::Config> XcmExecutor<Config> {
 						// Not much to do with the result as it is. It's up to the parachain to ensure that the
 						// message makes sense.
 						error_and_info.post_info.actual_weight
-					}
-				}.unwrap_or(weight);
+					},
+				}
+				.unwrap_or(weight);
 				let surplus = weight.saturating_sub(actual_weight);
 				// Credit any surplus weight that we bought. This should be safe since it's work we
 				// didn't realise that we didn't have to do.
@@ -204,20 +228,21 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				// Return the overestimated amount so we can adjust our expectations on how much this entire
 				// execution has taken.
 				None
-			}
+			},
 			(origin, Xcm::QueryResponse { query_id, response }) => {
 				Config::ResponseHandler::on_response(origin, query_id, response);
 				None
-			}
+			},
 			(origin, Xcm::RelayedFrom { who, message }) => {
 				ensure!(who.is_interior(), XcmError::EscalationOfPrivilege);
 				let mut origin = origin;
 				origin.append_with(who).map_err(|_| XcmError::MultiLocationFull)?;
-				let surplus = Self::do_execute_xcm(origin, top_level, *message, weight_credit, None, trader)?;
+				let surplus =
+					Self::do_execute_xcm(origin, top_level, *message, weight_credit, None, trader)?;
 				total_surplus = total_surplus.saturating_add(surplus);
 				None
-			}
-			_ => Err(XcmError::UnhandledXcmMessage)?,	// Unhandled XCM message.
+			},
+			_ => Err(XcmError::UnhandledXcmMessage)?, // Unhandled XCM message.
 		};
 
 		if let Some((mut holding, effects)) = maybe_holding_effects {
@@ -258,11 +283,11 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				let assets = Self::reanchored(deposited, &dest);
 				Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposited { assets, effects })?;
 			},
-			Order::InitiateReserveWithdraw { assets, reserve, effects} => {
+			Order::InitiateReserveWithdraw { assets, reserve, effects } => {
 				let assets = Self::reanchored(holding.saturating_take(assets), &reserve);
 				Config::XcmSender::send_xcm(reserve, Xcm::WithdrawAsset { assets, effects })?;
-			}
-			Order::InitiateTeleport { assets, dest, effects} => {
+			},
+			Order::InitiateTeleport { assets, dest, effects } => {
 				// We must do this first in order to resolve wildcards.
 				let assets = holding.saturating_take(assets);
 				for asset in assets.assets_iter() {
@@ -270,30 +295,42 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				}
 				let assets = Self::reanchored(assets, &dest);
 				Config::XcmSender::send_xcm(dest, Xcm::TeleportAsset { assets, effects })?;
-			}
+			},
 			Order::QueryHolding { query_id, dest, assets } => {
 				let assets = Self::reanchored(holding.min(&assets), &dest);
-				Config::XcmSender::send_xcm(dest, Xcm::QueryResponse { query_id, response: Response::Assets(assets) })?;
-			}
+				Config::XcmSender::send_xcm(
+					dest,
+					Xcm::QueryResponse { query_id, response: Response::Assets(assets) },
+				)?;
+			},
 			Order::BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
 				// pay for `weight` using up to `fees` of the holding register.
-				let purchasing_weight = Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?);
-				let max_fee = holding.try_take(fees.into()).map_err(|_| XcmError::NotHoldingFees)?;
+				let purchasing_weight =
+					Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?);
+				let max_fee =
+					holding.try_take(fees.into()).map_err(|_| XcmError::NotHoldingFees)?;
 				let unspent = trader.buy_weight(purchasing_weight, max_fee)?;
 				holding.subsume_assets(unspent);
 
 				let mut remaining_weight = weight;
 				for message in xcm.into_iter() {
-					match Self::do_execute_xcm(origin.clone(), false, message, &mut remaining_weight, None, trader) {
+					match Self::do_execute_xcm(
+						origin.clone(),
+						false,
+						message,
+						&mut remaining_weight,
+						None,
+						trader,
+					) {
 						Err(e) if halt_on_error => return Err(e),
-						Err(_) => {}
-						Ok(surplus) => { total_surplus += surplus }
+						Err(_) => {},
+						Ok(surplus) => total_surplus += surplus,
 					}
 				}
 				if let Some(w) = trader.refund_weight(remaining_weight) {
 					holding.subsume(w);
 				}
-			}
+			},
 			_ => return Err(XcmError::UnhandledEffect)?,
 		}
 		Ok(total_surplus)
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index 09cd94b19918..d6114efbe09c 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -14,9 +14,9 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use sp_std::result::Result;
-use xcm::v0::{Error as XcmError, Result as XcmResult, MultiAsset, MultiLocation};
 use crate::Assets;
+use sp_std::result::Result;
+use xcm::v0::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult};
 
 /// Facility for asset transacting.
 ///
@@ -78,22 +78,30 @@ pub trait TransactAsset {
 	/// Move an `asset` `from` one location in `to` another location.
 	///
 	/// Returns `XcmError::FailedToTransactAsset` if transfer failed.
-	fn transfer_asset(_asset: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result<Assets, XcmError> {
+	fn transfer_asset(
+		_asset: &MultiAsset,
+		_from: &MultiLocation,
+		_to: &MultiLocation,
+	) -> Result<Assets, XcmError> {
 		Err(XcmError::Unimplemented)
 	}
 
 	/// Move an `asset` `from` one location in `to` another location.
 	///
 	/// Attempts to use `transfer_asset` and if not available then falls back to using a two-part withdraw/deposit.
-	fn beam_asset(asset: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result<Assets, XcmError> {
+	fn beam_asset(
+		asset: &MultiAsset,
+		from: &MultiLocation,
+		to: &MultiLocation,
+	) -> Result<Assets, XcmError> {
 		match Self::transfer_asset(asset, from, to) {
 			Err(XcmError::Unimplemented) => {
 				let assets = Self::withdraw_asset(asset, from)?;
 				// Not a very forgiving attitude; once we implement roll-backs then it'll be nicer.
 				Self::deposit_asset(asset, to)?;
 				Ok(assets)
-			}
-			result => result
+			},
+			result => result,
 		}
 	}
 }
@@ -160,7 +168,11 @@ impl TransactAsset for Tuple {
 		Err(XcmError::AssetNotFound)
 	}
 
-	fn transfer_asset(what: &MultiAsset, from: &MultiLocation, to: &MultiLocation) -> Result<Assets, XcmError> {
+	fn transfer_asset(
+		what: &MultiAsset,
+		from: &MultiLocation,
+		to: &MultiLocation,
+	) -> Result<Assets, XcmError> {
 		for_tuples!( #(
 			match Tuple::transfer_asset(what, from, to) {
 				Err(XcmError::AssetNotFound) | Err(XcmError::Unimplemented) => (),
@@ -200,7 +212,11 @@ mod tests {
 			Err(XcmError::AssetNotFound)
 		}
 
-		fn transfer_asset(_what: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result<Assets, XcmError> {
+		fn transfer_asset(
+			_what: &MultiAsset,
+			_from: &MultiLocation,
+			_to: &MultiLocation,
+		) -> Result<Assets, XcmError> {
 			Err(XcmError::AssetNotFound)
 		}
 	}
@@ -219,7 +235,11 @@ mod tests {
 			Err(XcmError::Overflow)
 		}
 
-		fn transfer_asset(_what: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result<Assets, XcmError> {
+		fn transfer_asset(
+			_what: &MultiAsset,
+			_from: &MultiLocation,
+			_to: &MultiLocation,
+		) -> Result<Assets, XcmError> {
 			Err(XcmError::Overflow)
 		}
 	}
@@ -238,16 +258,24 @@ mod tests {
 			Ok(Assets::default())
 		}
 
-		fn transfer_asset(_what: &MultiAsset, _from: &MultiLocation, _to: &MultiLocation) -> Result<Assets, XcmError> {
+		fn transfer_asset(
+			_what: &MultiAsset,
+			_from: &MultiLocation,
+			_to: &MultiLocation,
+		) -> Result<Assets, XcmError> {
 			Ok(Assets::default())
 		}
 	}
 
 	#[test]
 	fn defaults_to_asset_not_found() {
-		type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
+		type MultiTransactor =
+			(UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&(Null, 1).into(), &Null), Err(XcmError::AssetNotFound));
+		assert_eq!(
+			MultiTransactor::deposit_asset(&(Null, 1).into(), &Null),
+			Err(XcmError::AssetNotFound)
+		);
 	}
 
 	#[test]
@@ -261,7 +289,10 @@ mod tests {
 	fn unexpected_error_stops_iteration() {
 		type MultiTransactor = (OverflowTransactor, SuccessfulTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&(Null, 1).into(), &Null), Err(XcmError::Overflow));
+		assert_eq!(
+			MultiTransactor::deposit_asset(&(Null, 1).into(), &Null),
+			Err(XcmError::Overflow)
+		);
 	}
 
 	#[test]
diff --git a/xcm/xcm-executor/src/traits/weight.rs b/xcm/xcm-executor/src/traits/weight.rs
index 1844f3b6c7f2..4e9c805edfbd 100644
--- a/xcm/xcm-executor/src/traits/weight.rs
+++ b/xcm/xcm-executor/src/traits/weight.rs
@@ -14,10 +14,10 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use sp_std::result::Result;
-use xcm::v0::{Xcm, MultiAsset, MultiLocation, Error};
-use frame_support::weights::Weight;
 use crate::Assets;
+use frame_support::weights::Weight;
+use sp_std::result::Result;
+use xcm::v0::{Error, MultiAsset, MultiLocation, Xcm};
 
 /// Determine the weight of an XCM message.
 pub trait WeightBounds<Call> {
@@ -71,11 +71,15 @@ pub trait WeightTrader: Sized {
 	/// purchased using `buy_weight`.
 	///
 	/// Default implementation refunds nothing.
-	fn refund_weight(&mut self, _weight: Weight) -> Option<MultiAsset> { None }
+	fn refund_weight(&mut self, _weight: Weight) -> Option<MultiAsset> {
+		None
+	}
 }
 
 impl WeightTrader for () {
-	fn new() -> Self { () }
+	fn new() -> Self {
+		()
+	}
 	fn buy_weight(&mut self, _: Weight, _: Assets) -> Result<Assets, Error> {
 		Err(Error::Unimplemented)
 	}

From 9e2e009e4ba12f663b45f10563a2b80e7043d287 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 20:21:54 +0200
Subject: [PATCH 057/166] Move to XCM version 1

---
 runtime/kusama/src/lib.rs                     |  2 +-
 runtime/parachains/src/dmp.rs                 |  2 +-
 runtime/parachains/src/ump.rs                 |  4 +-
 runtime/rococo/src/lib.rs                     |  2 +-
 runtime/westend/src/lib.rs                    |  2 +-
 xcm/pallet-xcm/src/lib.rs                     |  4 +-
 xcm/pallet-xcm/src/mock.rs                    |  2 +-
 xcm/src/lib.rs                                | 66 +++++++++++++++----
 xcm/src/{v0 => v1}/junction.rs                |  0
 xcm/src/{v0 => v1}/mod.rs                     | 21 +-----
 xcm/src/{v0 => v1}/multiasset.rs              |  0
 .../multi_location.rs => v1/multilocation.rs} | 23 ++-----
 xcm/src/{v0 => v1}/order.rs                   |  0
 xcm/src/{v0 => v1}/traits.rs                  |  2 +-
 xcm/xcm-builder/src/barriers.rs               |  2 +-
 xcm/xcm-builder/src/currency_adapter.rs       |  4 +-
 xcm/xcm-builder/src/filter_asset_location.rs  |  2 +-
 xcm/xcm-builder/src/fungibles_adapter.rs      |  2 +-
 xcm/xcm-builder/src/location_conversion.rs    |  6 +-
 xcm/xcm-builder/src/matches_fungible.rs       |  6 +-
 xcm/xcm-builder/src/mock.rs                   |  6 +-
 xcm/xcm-builder/src/origin_conversion.rs      |  2 +-
 xcm/xcm-builder/src/tests.rs                  |  2 +-
 xcm/xcm-builder/src/weight.rs                 |  2 +-
 xcm/xcm-executor/src/assets.rs                |  6 +-
 xcm/xcm-executor/src/config.rs                |  2 +-
 xcm/xcm-executor/src/lib.rs                   |  2 +-
 xcm/xcm-executor/src/traits/conversion.rs     |  4 +-
 .../src/traits/filter_asset_location.rs       |  2 +-
 .../src/traits/matches_fungible.rs            |  2 +-
 .../src/traits/matches_fungibles.rs           |  2 +-
 xcm/xcm-executor/src/traits/on_response.rs    |  2 +-
 xcm/xcm-executor/src/traits/should_execute.rs |  2 +-
 xcm/xcm-executor/src/traits/transact_asset.rs |  2 +-
 xcm/xcm-executor/src/traits/weight.rs         |  2 +-
 xcm/xcm-simulator/example/src/lib.rs          |  2 +-
 xcm/xcm-simulator/example/src/relay_chain.rs  |  2 +-
 37 files changed, 105 insertions(+), 91 deletions(-)
 rename xcm/src/{v0 => v1}/junction.rs (100%)
 rename xcm/src/{v0 => v1}/mod.rs (96%)
 rename xcm/src/{v0 => v1}/multiasset.rs (100%)
 rename xcm/src/{v0/multi_location.rs => v1/multilocation.rs} (98%)
 rename xcm/src/{v0 => v1}/order.rs (100%)
 rename xcm/src/{v0 => v1}/traits.rs (99%)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index 705bd319efae..c2720c8deed1 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -75,7 +75,7 @@ use sp_staking::SessionIndex;
 use sp_version::NativeVersion;
 use sp_version::RuntimeVersion;
 use static_assertions::const_assert;
-use xcm::v0::prelude::*;
+use xcm::v1::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
 	BackingToPlurality, ChildParachainAsNative, ChildParachainConvertsVia,
diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs
index 7982424800e5..1ff8fed4528d 100644
--- a/runtime/parachains/src/dmp.rs
+++ b/runtime/parachains/src/dmp.rs
@@ -22,7 +22,7 @@ use frame_support::pallet_prelude::*;
 use primitives::v1::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage};
 use sp_runtime::traits::{BlakeTwo256, Hash as HashT, SaturatedConversion};
 use sp_std::{fmt, prelude::*};
-use xcm::v0::Error as XcmError;
+use xcm::v1::Error as XcmError;
 
 pub use pallet::*;
 
diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs
index c64123537b02..32e7edadaf79 100644
--- a/runtime/parachains/src/ump.rs
+++ b/runtime/parachains/src/ump.rs
@@ -27,7 +27,7 @@ use sp_std::{
 	marker::PhantomData,
 	prelude::*,
 };
-use xcm::v0::Outcome;
+use xcm::v1::Outcome;
 
 pub use pallet::*;
 
@@ -78,7 +78,7 @@ pub type MessageId = [u8; 32];
 /// and will be forwarded to the XCM Executor.
 pub struct XcmSink<XcmExecutor, Config>(PhantomData<(XcmExecutor, Config)>);
 
-impl<XcmExecutor: xcm::v0::ExecuteXcm<C::Call>, C: Config> UmpSink for XcmSink<XcmExecutor, C> {
+impl<XcmExecutor: xcm::v1::ExecuteXcm<C::Call>, C: Config> UmpSink for XcmSink<XcmExecutor, C> {
 	fn process_upward_message(
 		origin: ParaId,
 		data: &[u8],
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 4086d38ca814..88e6072003ff 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -80,7 +80,7 @@ use polkadot_parachain::primitives::Id as ParaId;
 
 use constants::{currency::*, fee::*, time::*};
 use frame_support::traits::InstanceFilter;
-use xcm::v0::prelude::*;
+use xcm::v1::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, BackingToPlurality, ChildParachainAsNative, ChildParachainConvertsVia,
 	ChildSystemParachainAsSuperuser, CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds,
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index 12efa280771d..a578ff548afc 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -44,7 +44,7 @@ use runtime_parachains::{
 	session_info as parachains_session_info, shared as parachains_shared, ump as parachains_ump,
 };
 
-use xcm::v0::prelude::*;
+use xcm::v1::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
 	ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 95d5c867e781..ece2590f4d53 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -27,7 +27,7 @@ use codec::{Decode, Encode};
 use frame_support::traits::{Contains, EnsureOrigin, Filter, Get, OriginTrait};
 use sp_runtime::{traits::BadOrigin, RuntimeDebug};
 use sp_std::{boxed::Box, convert::TryInto, marker::PhantomData, prelude::*, vec};
-use xcm::v0::prelude::*;
+use xcm::v1::prelude::*;
 use xcm_executor::traits::ConvertOrigin;
 
 use frame_support::PalletId;
@@ -82,7 +82,7 @@ pub mod pallet {
 	#[pallet::event]
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
-		Attempted(xcm::v0::Outcome),
+		Attempted(xcm::v1::Outcome),
 		Sent(MultiLocation, MultiLocation, Xcm<()>),
 	}
 
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index bd8375dec3b8..eb9136b4ed03 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -181,7 +181,7 @@ impl pallet_xcm::Config for Test {
 	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
 	type XcmRouter = (TestSendXcmErrX8, TestSendXcm);
 	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
-	type XcmExecuteFilter = All<(MultiLocation, xcm::v0::Xcm<Call>)>;
+	type XcmExecuteFilter = All<(MultiLocation, xcm::v1::Xcm<Call>)>;
 	type XcmExecutor = XcmExecutor<XcmConfig>;
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index 4a275d61c4e3..705b4d34933b 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -23,25 +23,50 @@
 #![no_std]
 extern crate alloc;
 
+use core::{result::Result, convert::TryFrom};
 use derivative::Derivative;
-use parity_scale_codec::{Decode, Encode};
+use parity_scale_codec::{Decode, Encode, Input, Error as CodecError};
 
-pub mod v0;
+pub mod v1;
 
 mod double_encoded;
 pub use double_encoded::DoubleEncoded;
 
+pub enum Unsupported {}
+impl Decode for Unsupported {
+	fn decode<I: Input>(_: &mut I) -> Result<Self, CodecError> {
+		Err("Not decodable".into())
+	}
+}
+
 /// A single XCM message, together with its version code.
 #[derive(Derivative, Encode, Decode)]
 #[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
 #[codec(encode_bound())]
 #[codec(decode_bound())]
 pub enum VersionedXcm<Call> {
-	V0(v0::Xcm<Call>),
+	V0(Unsupported),
+	V1(v1::Xcm<Call>),
+}
+
+impl<Call> From<v1::Xcm<Call>> for VersionedXcm<Call> {
+	fn from(x: v1::Xcm<Call>) -> Self {
+		VersionedXcm::V0(x)
+	}
+}
+
+impl<Call> TryFrom<VersionedXcm<Call>> for v1::Xcm<Call> {
+	type Error = ();
+	fn try_from(x: VersionedXcm<Call>) -> Result<Self, ()> {
+		match x {
+			VersionedXcm::V1(x) => Ok(x),
+			_ => Err(()),
+		}
+	}
 }
 
 pub mod opaque {
-	pub mod v0 {
+	pub mod v1 {
 		// Everything from v0
 		pub use crate::v0::*;
 		// Then override with the opaque types in v0
@@ -55,26 +80,45 @@ pub mod opaque {
 /// A versioned multi-location, a relative location of a cross-consensus system identifier.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum VersionedMultiLocation {
-	V0(v0::MultiLocation),
+	V0(v1::MultiLocation),
+	V1(v1::MultiLocation),
+}
+
+impl From<v1::MultiLocation> for VersionedMultiLocation {
+	fn from(x: v1::MultiLocation) -> Self {
+		VersionedMultiLocation::V1(x)
+	}
+}
+
+impl TryFrom<VersionedMultiLocation> for v1::MultiLocation {
+	type Error = ();
+	fn try_from(x: VersionedMultiLocation) -> Result<Self, ()> {
+		match x {
+			VersionedMultiLocation::V0(x) => Ok(x),
+			VersionedMultiLocation::V1(x) => Ok(x),
+		}
+	}
 }
 
 /// A versioned multi-asset, an identifier for an asset within a consensus system.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum VersionedMultiAsset {
-	V0(v0::MultiAsset),
+	V0(Unsupported),
+	V1(v1::MultiAsset),
 }
 
-impl From<v0::MultiAsset> for VersionedMultiAsset {
-	fn from(x: v0::MultiAsset) -> Self {
-		VersionedMultiAsset::V0(x)
+impl From<v1::MultiAsset> for VersionedMultiAsset {
+	fn from(x: v1::MultiAsset) -> Self {
+		VersionedMultiAsset::V1(x)
 	}
 }
 
-impl core::convert::TryFrom<VersionedMultiAsset> for v0::MultiAsset {
+impl core::convert::TryFrom<VersionedMultiAsset> for v1::MultiAsset {
 	type Error = ();
 	fn try_from(x: VersionedMultiAsset) -> core::result::Result<Self, ()> {
 		match x {
-			VersionedMultiAsset::V0(x) => Ok(x),
+			VersionedMultiAsset::V1(x) => Ok(x),
+			_ => Err(()),
 		}
 	}
 }
diff --git a/xcm/src/v0/junction.rs b/xcm/src/v1/junction.rs
similarity index 100%
rename from xcm/src/v0/junction.rs
rename to xcm/src/v1/junction.rs
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v1/mod.rs
similarity index 96%
rename from xcm/src/v0/mod.rs
rename to xcm/src/v1/mod.rs
index 2bd568e60194..eb97acdeebde 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -23,13 +23,13 @@ use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
 mod junction;
-mod multi_location;
+mod multilocation;
 pub mod multiasset;
 mod order;
 mod traits; // the new multiasset.
 
 pub use junction::{BodyId, BodyPart, Junction, NetworkId};
-pub use multi_location::MultiLocation;
+pub use multilocation::MultiLocation;
 pub use multiasset::{
 	AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
 	WildFungibility, WildMultiAsset,
@@ -45,7 +45,7 @@ pub mod prelude {
 			Junction::*,
 			NetworkId::{self, *},
 		},
-		multi_location::MultiLocation::{self, *},
+		multilocation::MultiLocation::{self, *},
 		multiasset::{
 			AssetId::{self, *},
 			AssetInstance::{self, *},
@@ -290,21 +290,6 @@ pub enum Xcm<Call> {
 	RelayedFrom { who: MultiLocation, message: alloc::boxed::Box<Xcm<Call>> },
 }
 
-impl<Call> From<Xcm<Call>> for VersionedXcm<Call> {
-	fn from(x: Xcm<Call>) -> Self {
-		VersionedXcm::V0(x)
-	}
-}
-
-impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
-	type Error = ();
-	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
-		match x {
-			VersionedXcm::V0(x) => Ok(x),
-		}
-	}
-}
-
 impl<Call> Xcm<Call> {
 	pub fn into<C>(self) -> Xcm<C> {
 		Xcm::from(self)
diff --git a/xcm/src/v0/multiasset.rs b/xcm/src/v1/multiasset.rs
similarity index 100%
rename from xcm/src/v0/multiasset.rs
rename to xcm/src/v1/multiasset.rs
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v1/multilocation.rs
similarity index 98%
rename from xcm/src/v0/multi_location.rs
rename to xcm/src/v1/multilocation.rs
index e45df25a0ff6..af1b289702b2 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -460,7 +460,7 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v0::{MultiLocation::*, Junction::*};
+	/// # use xcm::v1::{MultiLocation::*, Junction::*};
 	/// # fn main() {
 	/// let mut m = X3(Parent, PalletInstance(3), OnlyChild);
 	/// assert_eq!(m.match_and_split(&X2(Parent, PalletInstance(3))), Some(&OnlyChild));
@@ -600,7 +600,7 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v0::{MultiLocation::*, Junction::*};
+	/// # use xcm::v1::{MultiLocation::*, Junction::*};
 	/// # fn main() {
 	/// let mut m = X3(Parent, Parachain(21), OnlyChild);
 	/// assert_eq!(m.append_with(X2(Parent, PalletInstance(3))), Ok(()));
@@ -627,7 +627,7 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
+	/// # use xcm::v1::{MultiLocation::*, Junction::*, NetworkId::Any};
 	/// # fn main() {
 	/// let mut m = X3(Parent, Parent, PalletInstance(3));
 	/// assert_eq!(m.prepend_with(X3(Parent, Parachain(21), OnlyChild)), Ok(()));
@@ -684,7 +684,7 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
+	/// # use xcm::v1::{MultiLocation::*, Junction::*, NetworkId::Any};
 	/// # fn main() {
 	/// let parent = X1(Parent);
 	/// assert_eq!(parent.is_interior(), false);
@@ -697,21 +697,6 @@ impl MultiLocation {
 	}
 }
 
-impl From<MultiLocation> for VersionedMultiLocation {
-	fn from(x: MultiLocation) -> Self {
-		VersionedMultiLocation::V0(x)
-	}
-}
-
-impl TryFrom<VersionedMultiLocation> for MultiLocation {
-	type Error = ();
-	fn try_from(x: VersionedMultiLocation) -> result::Result<Self, ()> {
-		match x {
-			VersionedMultiLocation::V0(x) => Ok(x),
-		}
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::MultiLocation::*;
diff --git a/xcm/src/v0/order.rs b/xcm/src/v1/order.rs
similarity index 100%
rename from xcm/src/v0/order.rs
rename to xcm/src/v1/order.rs
diff --git a/xcm/src/v0/traits.rs b/xcm/src/v1/traits.rs
similarity index 99%
rename from xcm/src/v0/traits.rs
rename to xcm/src/v1/traits.rs
index d6ce316726c8..fc1c3ce88b57 100644
--- a/xcm/src/v0/traits.rs
+++ b/xcm/src/v1/traits.rs
@@ -184,7 +184,7 @@ impl<C> ExecuteXcm<C> for () {
 ///
 /// # Example
 /// ```rust
-/// # use xcm::v0::{MultiLocation, Xcm, Junction, Error, OriginKind, SendXcm, Result};
+/// # use xcm::v1::{MultiLocation, Xcm, Junction, Error, OriginKind, SendXcm, Result};
 /// # use parity_scale_codec::Encode;
 ///
 /// /// A sender that only passes the message through and does nothing.
diff --git a/xcm/xcm-builder/src/barriers.rs b/xcm/xcm-builder/src/barriers.rs
index 2d870d7525c2..f253be18026f 100644
--- a/xcm/xcm-builder/src/barriers.rs
+++ b/xcm/xcm-builder/src/barriers.rs
@@ -19,7 +19,7 @@
 use frame_support::{ensure, traits::Contains, weights::Weight};
 use polkadot_parachain::primitives::IsSystem;
 use sp_std::{marker::PhantomData, result::Result};
-use xcm::v0::{Junction, MultiLocation, Order, Xcm};
+use xcm::v1::{Junction, MultiLocation, Order, Xcm};
 use xcm_executor::traits::{OnResponse, ShouldExecute};
 
 /// Execution barrier that just takes `shallow_weight` from `weight_credit`.
diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs
index fcbaa93c5998..ebbdf794209f 100644
--- a/xcm/xcm-builder/src/currency_adapter.rs
+++ b/xcm/xcm-builder/src/currency_adapter.rs
@@ -19,7 +19,7 @@
 use frame_support::traits::{ExistenceRequirement::AllowDeath, Get, WithdrawReasons};
 use sp_runtime::traits::{CheckedSub, SaturatedConversion};
 use sp_std::{convert::TryInto, marker::PhantomData, result};
-use xcm::v0::{Error as XcmError, MultiAsset, MultiLocation, Result};
+use xcm::v1::{Error as XcmError, MultiAsset, MultiLocation, Result};
 use xcm_executor::{
 	traits::{Convert, MatchesFungible, TransactAsset},
 	Assets,
@@ -53,7 +53,7 @@ impl From<Error> for XcmError {
 /// # Example
 /// ```
 /// use frame_support::parameter_types;
-/// use xcm::v0::{MultiLocation, Junction};
+/// use xcm::v1::{MultiLocation, Junction};
 /// use xcm_builder::{ParentIsDefault, CurrencyAdapter, IsConcrete};
 ///
 /// /// Our chain's account id.
diff --git a/xcm/xcm-builder/src/filter_asset_location.rs b/xcm/xcm-builder/src/filter_asset_location.rs
index cb2fa80be734..99a0e5e8f7f6 100644
--- a/xcm/xcm-builder/src/filter_asset_location.rs
+++ b/xcm/xcm-builder/src/filter_asset_location.rs
@@ -18,7 +18,7 @@
 
 use frame_support::traits::Get;
 use sp_std::marker::PhantomData;
-use xcm::v0::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation};
+use xcm::v1::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation};
 use xcm_executor::traits::FilterAssetLocation;
 
 /// Accepts an asset iff it is a native asset.
diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs
index d81ddd5a575d..048f3d8d3a52 100644
--- a/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -18,7 +18,7 @@
 
 use frame_support::traits::{tokens::fungibles, Contains, Get};
 use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result};
-use xcm::v0::{
+use xcm::v1::{
 	AssetId::{Abstract, Concrete},
 	Error as XcmError,
 	Fungibility::Fungible,
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 23612629946e..cbaf0b93063e 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -19,7 +19,7 @@ use parity_scale_codec::Encode;
 use sp_io::hashing::blake2_256;
 use sp_runtime::traits::AccountIdConversion;
 use sp_std::{borrow::Borrow, marker::PhantomData};
-use xcm::v0::{Junction, MultiLocation, NetworkId};
+use xcm::v1::{Junction, MultiLocation, NetworkId};
 use xcm_executor::traits::{Convert, InvertLocation};
 
 pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
@@ -155,7 +155,7 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
 /// ```
 /// ```rust
 /// # use frame_support::parameter_types;
-/// # use xcm::v0::{MultiLocation::{self, *}, Junction::*, NetworkId::Any};
+/// # use xcm::v1::{MultiLocation::{self, *}, Junction::*, NetworkId::Any};
 /// # use xcm_builder::LocationInverter;
 /// # use xcm_executor::traits::InvertLocation;
 /// # fn main() {
@@ -200,7 +200,7 @@ mod tests {
 	use super::*;
 
 	use frame_support::parameter_types;
-	use xcm::v0::{Junction::*, MultiLocation::*, NetworkId::Any};
+	use xcm::v1::{Junction::*, MultiLocation::*, NetworkId::Any};
 
 	fn account20() -> Junction {
 		AccountKey20 { network: Any, key: Default::default() }
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 0b635f3c1cb8..8e61bd2f8439 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -19,7 +19,7 @@
 use frame_support::traits::Get;
 use sp_runtime::traits::CheckedConversion;
 use sp_std::{convert::TryFrom, marker::PhantomData};
-use xcm::v0::{
+use xcm::v1::{
 	AssetId::{Abstract, Concrete},
 	Fungibility::Fungible,
 	MultiAsset, MultiLocation,
@@ -32,7 +32,7 @@ use xcm_executor::traits::MatchesFungible;
 /// # Example
 ///
 /// ```
-/// use xcm::v0::prelude::*;
+/// use xcm::v1::prelude::*;
 /// use xcm_builder::IsConcrete;
 /// use xcm_executor::traits::MatchesFungible;
 ///
@@ -62,7 +62,7 @@ impl<T: Get<MultiLocation>, B: TryFrom<u128>> MatchesFungible<B> for IsConcrete<
 /// # Example
 ///
 /// ```
-/// use xcm::v0::prelude::*;
+/// use xcm::v1::prelude::*;
 /// use xcm_builder::IsAbstract;
 /// use xcm_executor::traits::MatchesFungible;
 ///
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 6adc5b478343..c8d6036577e7 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -34,7 +34,7 @@ pub use sp_std::{
 	fmt::Debug,
 	marker::PhantomData,
 };
-pub use xcm::v0::prelude::*;
+pub use xcm::v1::prelude::*;
 pub use xcm_executor::{
 	traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset},
 	Assets, Config,
@@ -203,7 +203,7 @@ impl FilterAssetLocation for TestIsTeleporter {
 	}
 }
 
-use xcm::v0::Response;
+use xcm::v1::Response;
 pub enum ResponseSlot {
 	Expecting(MultiLocation),
 	Received(Response),
@@ -219,7 +219,7 @@ impl OnResponse for TestResponseHandler {
 			_ => false,
 		})
 	}
-	fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::v0::Response) -> Weight {
+	fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::v1::Response) -> Weight {
 		QUERIES.with(|q| {
 			q.borrow_mut().entry(query_id).and_modify(|v| {
 				if matches!(*v, ResponseSlot::Expecting(..)) {
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index 2a1956ca79de..2cc343694fa9 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -20,7 +20,7 @@ use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait};
 use frame_system::RawOrigin as SystemRawOrigin;
 use polkadot_parachain::primitives::IsSystem;
 use sp_std::{convert::TryInto, marker::PhantomData};
-use xcm::v0::{BodyId, BodyPart, Junction, MultiLocation, NetworkId, OriginKind};
+use xcm::v1::{BodyId, BodyPart, Junction, MultiLocation, NetworkId, OriginKind};
 use xcm_executor::traits::{Convert, ConvertOrigin};
 
 /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 5c7465440b29..93c87ce5dad5 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -15,7 +15,7 @@
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
 use super::{mock::*, *};
-use xcm::v0::prelude::*;
+use xcm::v1::prelude::*;
 use xcm_executor::{traits::*, Config, XcmExecutor};
 
 #[test]
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index faee6a08f23c..87b7c2f6b488 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -21,7 +21,7 @@ use frame_support::{
 use parity_scale_codec::Decode;
 use sp_runtime::traits::{SaturatedConversion, Saturating, Zero};
 use sp_std::{convert::TryInto, marker::PhantomData, result::Result};
-use xcm::v0::{AssetId, AssetId::Concrete, Error, MultiAsset, MultiLocation, Order, Xcm};
+use xcm::v1::{AssetId, AssetId::Concrete, Error, MultiAsset, MultiLocation, Order, Xcm};
 use xcm_executor::{
 	traits::{WeightBounds, WeightTrader},
 	Assets,
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index a7e48662e719..5270a30d44d2 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -20,7 +20,7 @@ use sp_std::{
 	mem,
 	prelude::*,
 };
-use xcm::v0::{
+use xcm::v1::{
 	AssetId, AssetInstance,
 	Fungibility::{Fungible, NonFungible},
 	MultiAsset, MultiAssetFilter, MultiAssets, MultiLocation,
@@ -338,7 +338,7 @@ impl Assets {
 	///
 	/// ```
 	/// use xcm_executor::Assets;
-	/// use xcm::v0::prelude::*;
+	/// use xcm::v1::prelude::*;
 	/// let assets_i_have: Assets = vec![ (Null, 100).into(), (vec![0], 100).into() ].into();
 	/// let assets_they_want: MultiAssetFilter = vec![ (Null, 200).into(), (vec![0], 50).into() [.into();
 	///
@@ -387,7 +387,7 @@ impl Assets {
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use xcm::v0::prelude::*;
+	use xcm::v1::prelude::*;
 	use MultiLocation::Null;
 	#[allow(non_snake_case)]
 	fn AF(id: u8, amount: u128) -> MultiAsset {
diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs
index ff39be56ef5e..1a38fb44ea50 100644
--- a/xcm/xcm-executor/src/config.rs
+++ b/xcm/xcm-executor/src/config.rs
@@ -22,7 +22,7 @@ use frame_support::{
 	dispatch::{Dispatchable, Parameter},
 	weights::{GetDispatchInfo, PostDispatchInfo},
 };
-use xcm::v0::SendXcm;
+use xcm::v1::SendXcm;
 
 /// The trait to parameterize the `XcmExecutor`.
 pub trait Config {
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index d6dcbd1f93fd..491558dbdb28 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -22,7 +22,7 @@ use frame_support::{
 	weights::GetDispatchInfo,
 };
 use sp_std::{marker::PhantomData, prelude::*};
-use xcm::v0::{
+use xcm::v1::{
 	Error as XcmError, ExecuteXcm, MultiAssets, MultiLocation, Order, Outcome, Response, SendXcm,
 	Xcm,
 };
diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs
index 49f5db698982..df99a05d0064 100644
--- a/xcm/xcm-executor/src/traits/conversion.rs
+++ b/xcm/xcm-executor/src/traits/conversion.rs
@@ -16,7 +16,7 @@
 
 use parity_scale_codec::{Decode, Encode};
 use sp_std::{borrow::Borrow, convert::TryFrom, prelude::*, result::Result};
-use xcm::v0::{MultiLocation, OriginKind};
+use xcm::v1::{MultiLocation, OriginKind};
 
 /// Generic third-party conversion trait. Use this when you don't want to force the user to use default
 /// implementations of `From` and `Into` for the types you wish to convert between.
@@ -139,7 +139,7 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
 /// which is passed to the next convert item.
 ///
 /// ```rust
-/// # use xcm::v0::{MultiLocation, Junction, OriginKind};
+/// # use xcm::v1::{MultiLocation, Junction, OriginKind};
 /// # use xcm_executor::traits::ConvertOrigin;
 /// // A convertor that will bump the para id and pass it to the next one.
 /// struct BumpParaId;
diff --git a/xcm/xcm-executor/src/traits/filter_asset_location.rs b/xcm/xcm-executor/src/traits/filter_asset_location.rs
index 8b1a7bd1d1dc..a63af84e167c 100644
--- a/xcm/xcm-executor/src/traits/filter_asset_location.rs
+++ b/xcm/xcm-executor/src/traits/filter_asset_location.rs
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use xcm::v0::{MultiAsset, MultiLocation};
+use xcm::v1::{MultiAsset, MultiLocation};
 
 /// Filters assets/location pairs.
 ///
diff --git a/xcm/xcm-executor/src/traits/matches_fungible.rs b/xcm/xcm-executor/src/traits/matches_fungible.rs
index 6634d16d0243..ff466af5b21c 100644
--- a/xcm/xcm-executor/src/traits/matches_fungible.rs
+++ b/xcm/xcm-executor/src/traits/matches_fungible.rs
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use xcm::v0::MultiAsset;
+use xcm::v1::MultiAsset;
 
 pub trait MatchesFungible<Balance> {
 	fn matches_fungible(a: &MultiAsset) -> Option<Balance>;
diff --git a/xcm/xcm-executor/src/traits/matches_fungibles.rs b/xcm/xcm-executor/src/traits/matches_fungibles.rs
index c1722d000f02..2499eae27531 100644
--- a/xcm/xcm-executor/src/traits/matches_fungibles.rs
+++ b/xcm/xcm-executor/src/traits/matches_fungibles.rs
@@ -15,7 +15,7 @@
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
 use sp_std::result;
-use xcm::v0::{Error as XcmError, MultiAsset};
+use xcm::v1::{Error as XcmError, MultiAsset};
 
 /// Errors associated with [`MatchesFungibles`] operation.
 pub enum Error {
diff --git a/xcm/xcm-executor/src/traits/on_response.rs b/xcm/xcm-executor/src/traits/on_response.rs
index 134891b4b704..801aa016d478 100644
--- a/xcm/xcm-executor/src/traits/on_response.rs
+++ b/xcm/xcm-executor/src/traits/on_response.rs
@@ -15,7 +15,7 @@
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
 use frame_support::weights::Weight;
-use xcm::v0::{MultiLocation, Response};
+use xcm::v1::{MultiLocation, Response};
 
 /// Define what needs to be done upon receiving a query response.
 pub trait OnResponse {
diff --git a/xcm/xcm-executor/src/traits/should_execute.rs b/xcm/xcm-executor/src/traits/should_execute.rs
index ed92866146c1..a8d9ad1ca79a 100644
--- a/xcm/xcm-executor/src/traits/should_execute.rs
+++ b/xcm/xcm-executor/src/traits/should_execute.rs
@@ -16,7 +16,7 @@
 
 use frame_support::weights::Weight;
 use sp_std::result::Result;
-use xcm::v0::{MultiLocation, Xcm};
+use xcm::v1::{MultiLocation, Xcm};
 
 /// Trait to determine whether the execution engine should actually execute a given XCM.
 ///
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index d6114efbe09c..60fb0508c676 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -16,7 +16,7 @@
 
 use crate::Assets;
 use sp_std::result::Result;
-use xcm::v0::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult};
+use xcm::v1::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult};
 
 /// Facility for asset transacting.
 ///
diff --git a/xcm/xcm-executor/src/traits/weight.rs b/xcm/xcm-executor/src/traits/weight.rs
index 4e9c805edfbd..c32ec682857c 100644
--- a/xcm/xcm-executor/src/traits/weight.rs
+++ b/xcm/xcm-executor/src/traits/weight.rs
@@ -17,7 +17,7 @@
 use crate::Assets;
 use frame_support::weights::Weight;
 use sp_std::result::Result;
-use xcm::v0::{Error, MultiAsset, MultiLocation, Xcm};
+use xcm::v1::{Error, MultiAsset, MultiLocation, Xcm};
 
 /// Determine the weight of an XCM message.
 pub trait WeightBounds<Call> {
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index f318409bf187..00c1f4109421 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -100,7 +100,7 @@ mod tests {
 
 	use codec::Encode;
 	use frame_support::assert_ok;
-	use xcm::v0::{
+	use xcm::v1::{
 		Junction::{self, Parachain, Parent},
 		MultiAsset::*,
 		MultiLocation::*,
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index c69f20d05eaf..cd84249ad614 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -26,7 +26,7 @@ use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
 
 use polkadot_parachain::primitives::Id as ParaId;
 use polkadot_runtime_parachains::{configuration, origin, shared, ump};
-use xcm::v0::{MultiAsset, MultiLocation, NetworkId};
+use xcm::v1::{MultiAsset, MultiLocation, NetworkId};
 use xcm_builder::{
 	AccountId32Aliases, AllowUnpaidExecutionFrom, ChildParachainAsNative,
 	ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,

From 00ca37b154ed1abefc9aaca907e5e08c0bb0a7e2 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 22:38:08 +0200
Subject: [PATCH 058/166] Spelling

---
 xcm/xcm-simulator/example/src/parachain.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index f4ad471ff697..781b0a8e6a45 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -187,7 +187,7 @@ pub mod mock_msg_queue {
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
 		// XCMP
-		/// Some XCM was executed ok.
+		/// Some XCM was executed OK.
 		Success(Option<T::Hash>),
 		/// Some XCM failed.
 		Fail(Option<T::Hash>, XcmError),

From 768c96ae581e41a588e450a010ecfaeac88db372 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 22:46:24 +0200
Subject: [PATCH 059/166] warnings

---
 xcm/src/lib.rs              | 8 +++++---
 xcm/src/v1/mod.rs           | 4 ++--
 xcm/src/v1/multilocation.rs | 3 +--
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index 705b4d34933b..c3b9a06ba141 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -32,7 +32,9 @@ pub mod v1;
 mod double_encoded;
 pub use double_encoded::DoubleEncoded;
 
+#[derive(Clone, Eq, PartialEq, Debug)]
 pub enum Unsupported {}
+impl Encode for Unsupported {}
 impl Decode for Unsupported {
 	fn decode<I: Input>(_: &mut I) -> Result<Self, CodecError> {
 		Err("Not decodable".into())
@@ -51,7 +53,7 @@ pub enum VersionedXcm<Call> {
 
 impl<Call> From<v1::Xcm<Call>> for VersionedXcm<Call> {
 	fn from(x: v1::Xcm<Call>) -> Self {
-		VersionedXcm::V0(x)
+		VersionedXcm::V1(x)
 	}
 }
 
@@ -68,9 +70,9 @@ impl<Call> TryFrom<VersionedXcm<Call>> for v1::Xcm<Call> {
 pub mod opaque {
 	pub mod v1 {
 		// Everything from v0
-		pub use crate::v0::*;
+		pub use crate::v1::*;
 		// Then override with the opaque types in v0
-		pub use crate::v0::opaque::{Order, Xcm};
+		pub use crate::v1::opaque::{Order, Xcm};
 	}
 
 	/// The basic `VersionedXcm` type which just uses the `Vec<u8>` as an encoded call.
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index eb97acdeebde..38e7cf2c60ce 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -16,9 +16,9 @@
 
 //! Version 0 of the Cross-Consensus Message format data structures.
 
-use crate::{DoubleEncoded, VersionedXcm};
+use crate::DoubleEncoded;
 use alloc::vec::Vec;
-use core::{convert::TryFrom, fmt::Debug, result};
+use core::fmt::Debug;
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index af1b289702b2..b3a7209404cc 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -16,10 +16,9 @@
 
 //! Cross-Consensus Message format data structures.
 
-use core::{convert::TryFrom, mem, result};
+use core::{mem, result};
 
 use super::Junction;
-use crate::VersionedMultiLocation;
 use parity_scale_codec::{self, Decode, Encode};
 
 /// A relative path between state-bearing consensus systems.

From 2936419d834f6159ac3c68a62ed3bc5fb7ea9694 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 22:52:13 +0200
Subject: [PATCH 060/166] Replace some more v0->v1s

---
 runtime/common/src/xcm_sender.rs           | 2 +-
 runtime/parachains/src/hrmp.rs             | 6 +++---
 runtime/parachains/src/ump.rs              | 2 +-
 runtime/westend/src/constants.rs           | 2 +-
 xcm/pallet-xcm/src/mock.rs                 | 6 +++---
 xcm/pallet-xcm/src/tests.rs                | 4 ++--
 xcm/src/v1/multilocation.rs                | 2 +-
 xcm/xcm-simulator/example/src/parachain.rs | 2 +-
 xcm/xcm-simulator/src/lib.rs               | 2 +-
 9 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs
index 151c649a8c4c..819f9b0b0617 100644
--- a/runtime/common/src/xcm_sender.rs
+++ b/runtime/common/src/xcm_sender.rs
@@ -20,7 +20,7 @@ use parity_scale_codec::Encode;
 use runtime_parachains::{configuration, dmp};
 use sp_std::marker::PhantomData;
 use xcm::opaque::{
-	v0::{Error, Junction, MultiLocation, Result, SendXcm, Xcm},
+	v1::{Error, Junction, MultiLocation, Result, SendXcm, Xcm},
 	VersionedXcm,
 };
 
diff --git a/runtime/parachains/src/hrmp.rs b/runtime/parachains/src/hrmp.rs
index 906c9d77d39d..901be0ae4b3b 100644
--- a/runtime/parachains/src/hrmp.rs
+++ b/runtime/parachains/src/hrmp.rs
@@ -1007,7 +1007,7 @@ impl<T: Config> Pallet<T> {
 
 		let notification_bytes = {
 			use parity_scale_codec::Encode as _;
-			use xcm::opaque::{v0::Xcm, VersionedXcm};
+			use xcm::opaque::{v1::Xcm, VersionedXcm};
 
 			VersionedXcm::from(Xcm::HrmpNewChannelOpenRequest {
 				sender: u32::from(origin),
@@ -1066,7 +1066,7 @@ impl<T: Config> Pallet<T> {
 
 		let notification_bytes = {
 			use parity_scale_codec::Encode as _;
-			use xcm::opaque::{v0::Xcm, VersionedXcm};
+			use xcm::opaque::{v1::Xcm, VersionedXcm};
 
 			VersionedXcm::from(Xcm::HrmpChannelAccepted { recipient: u32::from(origin) }).encode()
 		};
@@ -1106,7 +1106,7 @@ impl<T: Config> Pallet<T> {
 		let config = <configuration::Pallet<T>>::config();
 		let notification_bytes = {
 			use parity_scale_codec::Encode as _;
-			use xcm::opaque::{v0::Xcm, VersionedXcm};
+			use xcm::opaque::{v1::Xcm, VersionedXcm};
 
 			VersionedXcm::from(Xcm::HrmpChannelClosing {
 				initiator: u32::from(origin),
diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs
index 32e7edadaf79..b1a39405a468 100644
--- a/runtime/parachains/src/ump.rs
+++ b/runtime/parachains/src/ump.rs
@@ -85,7 +85,7 @@ impl<XcmExecutor: xcm::v1::ExecuteXcm<C::Call>, C: Config> UmpSink for XcmSink<X
 		max_weight: Weight,
 	) -> Result<Weight, (MessageId, Weight)> {
 		use xcm::{
-			v0::{Error as XcmError, Junction, MultiLocation, Xcm},
+			v1::{Error as XcmError, Junction, MultiLocation, Xcm},
 			VersionedXcm,
 		};
 
diff --git a/runtime/westend/src/constants.rs b/runtime/westend/src/constants.rs
index 77bdd954c03b..a6eaba9e2063 100644
--- a/runtime/westend/src/constants.rs
+++ b/runtime/westend/src/constants.rs
@@ -49,7 +49,7 @@ pub mod fee {
 	use frame_support::weights::{
 		WeightToFeeCoefficient, WeightToFeeCoefficients, WeightToFeePolynomial,
 	};
-	use primitives::v0::Balance;
+	use primitives::v1::Balance;
 	use runtime_common::ExtrinsicBaseWeight;
 	use smallvec::smallvec;
 	pub use sp_runtime::Perbill;
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index eb9136b4ed03..e919be21a21d 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -25,8 +25,8 @@ use sp_core::H256;
 use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
 pub use sp_std::{cell::RefCell, fmt::Debug, marker::PhantomData};
 use xcm::{
-	opaque::v0::{Error as XcmError, MultiAsset, Result as XcmResult, SendXcm, Xcm},
-	v0::{MultiLocation, NetworkId, Order},
+	opaque::v1::{Error as XcmError, MultiAsset, Result as XcmResult, SendXcm, Xcm},
+	v1::{MultiLocation, NetworkId, Order},
 };
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative,
@@ -195,7 +195,7 @@ pub(crate) fn last_event() -> Event {
 }
 
 pub(crate) fn buy_execution<C>(debt: Weight) -> Order<C> {
-	use xcm::opaque::v0::prelude::*;
+	use xcm::opaque::v1::prelude::*;
 	Order::BuyExecution { fees: All, weight: 0, debt, halt_on_error: false, xcm: vec![] }
 }
 
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index f0727e619bd2..2fc2de28ef64 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -18,8 +18,8 @@ use crate::mock::*;
 use frame_support::{assert_noop, assert_ok, traits::Currency};
 use polkadot_parachain::primitives::{AccountIdConversion, Id as ParaId};
 use xcm::{
-	opaque::v0::prelude::*,
-	v0::{Junction, Xcm},
+	opaque::v1::prelude::*,
+	v1::{Junction, Xcm},
 };
 
 const ALICE: AccountId = AccountId::new([0u8; 32]);
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index b3a7209404cc..20a9153b570a 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -699,7 +699,7 @@ impl MultiLocation {
 #[cfg(test)]
 mod tests {
 	use super::MultiLocation::*;
-	use crate::opaque::v0::{Junction::*, NetworkId::Any};
+	use crate::opaque::v1::{Junction::*, NetworkId::Any};
 
 	#[test]
 	fn match_and_split_works() {
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 781b0a8e6a45..993aee5de0ca 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -36,7 +36,7 @@ use polkadot_parachain::primitives::{
 	DmpMessageHandler, Id as ParaId, Sibling, XcmpMessageFormat, XcmpMessageHandler,
 };
 use xcm::{
-	v0::{
+	v1::{
 		Error as XcmError, ExecuteXcm,
 		Junction::{Parachain, Parent},
 		MultiAsset,
diff --git a/xcm/xcm-simulator/src/lib.rs b/xcm/xcm-simulator/src/lib.rs
index d68072858e80..f075c7e3d9fb 100644
--- a/xcm/xcm-simulator/src/lib.rs
+++ b/xcm/xcm-simulator/src/lib.rs
@@ -32,7 +32,7 @@ pub use polkadot_runtime_parachains::{
 	dmp,
 	ump::{self, MessageId, UmpSink, XcmSink},
 };
-pub use xcm::{v0::prelude::*, VersionedXcm};
+pub use xcm::{v1::prelude::*, VersionedXcm};
 pub use xcm_executor::XcmExecutor;
 
 pub trait TestExt {

From 015fff2e1ba83d42f2897e2da39ff4985facffbe Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 23:00:39 +0200
Subject: [PATCH 061/166] warnings

---
 xcm/xcm-simulator/example/src/parachain.rs   | 17 ++++-------------
 xcm/xcm-simulator/example/src/relay_chain.rs |  8 ++++----
 2 files changed, 8 insertions(+), 17 deletions(-)

diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 993aee5de0ca..4e870abb0315 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -35,19 +35,10 @@ use polkadot_core_primitives::BlockNumber as RelayBlockNumber;
 use polkadot_parachain::primitives::{
 	DmpMessageHandler, Id as ParaId, Sibling, XcmpMessageFormat, XcmpMessageHandler,
 };
-use xcm::{
-	v1::{
-		Error as XcmError, ExecuteXcm,
-		Junction::{Parachain, Parent},
-		MultiAsset,
-		MultiLocation::{self, X1},
-		NetworkId, Outcome, Xcm,
-	},
-	VersionedXcm,
-};
+use xcm::{v1::prelude::*, VersionedXcm};
 use xcm_builder::{
 	AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter as XcmCurrencyAdapter,
-	EnsureXcmOrigin, FixedRateOfConcreteFungible, FixedWeightBounds, IsConcrete, LocationInverter,
+	EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, IsConcrete, LocationInverter,
 	NativeAsset, ParentIsDefault, SiblingParachainConvertsVia, SignedAccountId32AsNative,
 	SignedToAccountId32, SovereignSignedViaLocation,
 };
@@ -129,7 +120,7 @@ pub type XcmOriginToCallOrigin = (
 
 parameter_types! {
 	pub const UnitWeightCost: Weight = 1;
-	pub KsmPerSecond: (MultiLocation, u128) = (X1(Parent), 1);
+	pub KsmPerSecond: (AssetId, u128) = (Concrete(X1(Parent)), 1);
 }
 
 pub type LocalAssetTransactor =
@@ -149,7 +140,7 @@ impl Config for XcmConfig {
 	type LocationInverter = LocationInverter<Ancestry>;
 	type Barrier = Barrier;
 	type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
-	type Trader = FixedRateOfConcreteFungible<KsmPerSecond, ()>;
+	type Trader = FixedRateOfFungible<KsmPerSecond, ()>;
 	type ResponseHandler = ();
 }
 
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index cd84249ad614..b342ebaf7fff 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -26,11 +26,11 @@ use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
 
 use polkadot_parachain::primitives::Id as ParaId;
 use polkadot_runtime_parachains::{configuration, origin, shared, ump};
-use xcm::v1::{MultiAsset, MultiLocation, NetworkId};
+use xcm::v1::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, AllowUnpaidExecutionFrom, ChildParachainAsNative,
 	ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
-	CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfConcreteFungible, FixedWeightBounds,
+	CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds,
 	IsConcrete, LocationInverter, SignedAccountId32AsNative, SignedToAccountId32,
 	SovereignSignedViaLocation,
 };
@@ -114,7 +114,7 @@ type LocalOriginConverter = (
 
 parameter_types! {
 	pub const BaseXcmWeight: Weight = 1_000;
-	pub KsmPerSecond: (MultiLocation, u128) = (KsmLocation::get(), 1);
+	pub KsmPerSecond: (AssetId, u128) = (Concrete(KsmLocation::get()), 1);
 }
 
 pub type XcmRouter = super::RelayChainXcmRouter;
@@ -131,7 +131,7 @@ impl Config for XcmConfig {
 	type LocationInverter = LocationInverter<Ancestry>;
 	type Barrier = Barrier;
 	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
-	type Trader = FixedRateOfConcreteFungible<KsmPerSecond, ()>;
+	type Trader = FixedRateOfFungible<KsmPerSecond, ()>;
 	type ResponseHandler = ();
 }
 

From b5fe03e83a967793618e737dbb8caec8c1eb1e57 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 23:06:01 +0200
Subject: [PATCH 062/166] format

---
 xcm/src/lib.rs                               | 4 ++--
 xcm/src/v1/mod.rs                            | 6 +++---
 xcm/xcm-simulator/example/src/relay_chain.rs | 5 ++---
 3 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index c3b9a06ba141..f9ce3a3f5266 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -23,9 +23,9 @@
 #![no_std]
 extern crate alloc;
 
-use core::{result::Result, convert::TryFrom};
+use core::{convert::TryFrom, result::Result};
 use derivative::Derivative;
-use parity_scale_codec::{Decode, Encode, Input, Error as CodecError};
+use parity_scale_codec::{Decode, Encode, Error as CodecError, Input};
 
 pub mod v1;
 
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index 38e7cf2c60ce..375a8d8a3cfc 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -23,17 +23,17 @@ use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
 mod junction;
-mod multilocation;
 pub mod multiasset;
+mod multilocation;
 mod order;
 mod traits; // the new multiasset.
 
 pub use junction::{BodyId, BodyPart, Junction, NetworkId};
-pub use multilocation::MultiLocation;
 pub use multiasset::{
 	AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
 	WildFungibility, WildMultiAsset,
 };
+pub use multilocation::MultiLocation;
 pub use order::Order;
 pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 
@@ -45,7 +45,6 @@ pub mod prelude {
 			Junction::*,
 			NetworkId::{self, *},
 		},
-		multilocation::MultiLocation::{self, *},
 		multiasset::{
 			AssetId::{self, *},
 			AssetInstance::{self, *},
@@ -56,6 +55,7 @@ pub mod prelude {
 			WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible},
 			WildMultiAsset::{self, *},
 		},
+		multilocation::MultiLocation::{self, *},
 		opaque,
 		order::Order::{self, *},
 		traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index b342ebaf7fff..7472df198219 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -30,9 +30,8 @@ use xcm::v1::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, AllowUnpaidExecutionFrom, ChildParachainAsNative,
 	ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
-	CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds,
-	IsConcrete, LocationInverter, SignedAccountId32AsNative, SignedToAccountId32,
-	SovereignSignedViaLocation,
+	CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds, IsConcrete,
+	LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
 };
 use xcm_executor::{Config, XcmExecutor};
 

From 608a212fa9ed7ddc1bde53855214a3323bcee5d7 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 23:30:51 +0200
Subject: [PATCH 063/166] Add max_assets param

---
 xcm/src/v1/order.rs            | 12 ++++-----
 xcm/xcm-executor/src/assets.rs | 45 +++++++++++++++++++++++++++++++---
 xcm/xcm-executor/src/lib.rs    |  8 +++---
 3 files changed, 50 insertions(+), 15 deletions(-)

diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index aed5a6ff3634..f5ba0e65bc48 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -39,8 +39,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 1)]
-	// TODO: https://github.com/paritytech/polkadot/issues/3547 introduce `, max_assets: u32`
-	DepositAsset { assets: MultiAssetFilter, dest: MultiLocation },
+	DepositAsset { assets: MultiAssetFilter, max_assets: u32, dest: MultiLocation },
 
 	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
 	/// this consensus system.
@@ -54,8 +53,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 2)]
-	// TODO: https://github.com/paritytech/polkadot/issues/3547 introduce `, max_assets: u32`
-	DepositReserveAsset { assets: MultiAssetFilter, dest: MultiLocation, effects: Vec<Order<()>> },
+	DepositReserveAsset { assets: MultiAssetFilter, max_assets: u32, dest: MultiLocation, effects: Vec<Order<()>> },
 
 	/// Remove the asset(s) (`give`) from holding and replace them with alternative assets.
 	///
@@ -139,9 +137,9 @@ impl<Call> Order<Call> {
 		use Order::*;
 		match order {
 			Noop => Noop,
-			DepositAsset { assets, dest } => DepositAsset { assets, dest },
-			DepositReserveAsset { assets, dest, effects } =>
-				DepositReserveAsset { assets, dest, effects },
+			DepositAsset { assets, max_assets, dest } => DepositAsset { assets, max_assets, dest },
+			DepositReserveAsset { assets, max_assets, dest, effects } =>
+				DepositReserveAsset { assets, max_assets, dest, effects },
 			ExchangeAsset { give, receive } => ExchangeAsset { give, receive },
 			InitiateReserveWithdraw { assets, reserve, effects } =>
 				InitiateReserveWithdraw { assets, reserve, effects },
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 5270a30d44d2..f2354e058165 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -89,6 +89,11 @@ impl Assets {
 		Self::default()
 	}
 
+	/// Total number of distinct assets.
+	pub fn len(&self) -> usize {
+		self.fungible.len() + self.non_fungible.len()
+	}
+
 	/// A borrowing iterator over the fungible assets.
 	pub fn fungible_assets_iter<'a>(&'a self) -> impl Iterator<Item = MultiAsset> + 'a {
 		self.fungible
@@ -231,10 +236,30 @@ impl Assets {
 		&mut self,
 		mask: MultiAssetFilter,
 		saturate: bool,
+		limit: usize,
 	) -> Result<Assets, TakeError> {
 		let mut taken = Assets::new();
 		match mask {
-			MultiAssetFilter::Wild(All) => return Ok(self.swapped(Assets::new())),
+			MultiAssetFilter::Wild(All) => if self.fungible.len() + self.non_fungible.len() <= limit {
+				return Ok(self.swapped(Assets::new()))
+			} else {
+				let fungible = mem::replace(&mut self.fungible, Default::default());
+				fungible.into_iter().for_each(|(c, amount)| {
+					if taken.len() < limit {
+						taken.fungible.insert(c, amount);
+					} else {
+						self.fungible.insert(c, amount);
+					}
+				});
+				let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
+				non_fungible.into_iter().for_each(|(c, instance)| {
+					if taken.len() < limit {
+						taken.non_fungible.insert((c, instance));
+					} else {
+						self.non_fungible.insert((c, instance));
+					}
+				});
+			},
 			MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => {
 				if let Some((id, amount)) = self.fungible.remove_entry(&id) {
 					taken.fungible.insert(id, amount);
@@ -243,7 +268,7 @@ impl Assets {
 			MultiAssetFilter::Wild(AllOf { fun: WildNonFungible, id }) => {
 				let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
 				non_fungible.into_iter().for_each(|(c, instance)| {
-					if c == id {
+					if c == id && taken.len() < limit {
 						taken.non_fungible.insert((c, instance));
 					} else {
 						self.non_fungible.insert((c, instance));
@@ -279,6 +304,9 @@ impl Assets {
 							}
 						},
 					}
+					if taken.len() == limit {
+						break
+					}
 				}
 			},
 		}
@@ -290,7 +318,16 @@ impl Assets {
 	/// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its value minus
 	/// `mask` if `self` contains `asset`, and return `Err` otherwise.
 	pub fn saturating_take(&mut self, asset: MultiAssetFilter) -> Assets {
-		self.general_take(asset, true)
+		self.general_take(asset, true, usize::max_value())
+			.expect("general_take never results in error when saturating")
+	}
+
+	/// Mutates `self` to its original value less `mask` and returns `true` iff it contains at least `mask`.
+	///
+	/// Returns `Ok` with the non-wildcard equivalence of `mask` taken and mutates `self` to its value minus
+	/// `mask` if `self` contains `asset`, and return `Err` otherwise.
+	pub fn limited_saturating_take(&mut self, asset: MultiAssetFilter, limit: usize) -> Assets {
+		self.general_take(asset, true, limit)
 			.expect("general_take never results in error when saturating")
 	}
 
@@ -299,7 +336,7 @@ impl Assets {
 	/// Returns `Ok` with the non-wildcard equivalence of `asset` taken and mutates `self` to its value minus
 	/// `asset` if `self` contains `asset`, and return `Err` otherwise.
 	pub fn try_take(&mut self, mask: MultiAssetFilter) -> Result<Assets, TakeError> {
-		self.general_take(mask, false)
+		self.general_take(mask, false, usize::max_value())
 	}
 
 	/// Consumes `self` and returns its original value excluding `asset` iff it contains at least `asset`.
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index 491558dbdb28..46be5ae644df 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -269,14 +269,14 @@ impl<Config: config::Config> XcmExecutor<Config> {
 		);
 		let mut total_surplus = 0;
 		match effect {
-			Order::DepositAsset { assets, dest } => {
-				let deposited = holding.saturating_take(assets);
+			Order::DepositAsset { assets, max_assets, dest } => {
+				let deposited = holding.limited_saturating_take(assets, max_assets as usize);
 				for asset in deposited.into_assets_iter() {
 					Config::AssetTransactor::deposit_asset(&asset, &dest)?;
 				}
 			},
-			Order::DepositReserveAsset { assets, dest, effects } => {
-				let deposited = holding.saturating_take(assets);
+			Order::DepositReserveAsset { assets, max_assets, dest, effects } => {
+				let deposited = holding.limited_saturating_take(assets, max_assets as usize);
 				for asset in deposited.assets_iter() {
 					Config::AssetTransactor::deposit_asset(&asset, &dest)?;
 				}

From dee3be53d9c03ce2e09a974130d7870c7a07637c Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 23:37:49 +0200
Subject: [PATCH 064/166] building

---
 xcm/pallet-xcm/src/lib.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index ece2590f4d53..38293257c21d 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -165,7 +165,7 @@ pub mod pallet {
 							halt_on_error: false,
 							xcm: vec![],
 						},
-						DepositAsset { assets: Wild(All), dest: beneficiary },
+						DepositAsset { assets: Wild(All), max_assets: 1, dest: beneficiary },
 					],
 				}],
 			};
@@ -222,7 +222,7 @@ pub mod pallet {
 						halt_on_error: false,
 						xcm: vec![],
 					},
-					DepositAsset { assets: Wild(All), dest: beneficiary },
+					DepositAsset { assets: Wild(All), max_assets: 1, dest: beneficiary },
 				],
 			};
 			let weight =

From a6eaaa2a99ee5800a9c7a9f09535656208826f7e Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 23:50:02 +0200
Subject: [PATCH 065/166] test fixes

---
 xcm/pallet-xcm/src/tests.rs | 24 ++++++++++++------------
 xcm/src/v1/multiasset.rs    |  8 +++++++-
 2 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 2fc2de28ef64..da5d4405cc4a 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -38,12 +38,12 @@ fn send_works() {
 	new_test_ext_with_balances(balances).execute_with(|| {
 		let weight = 2 * BaseXcmWeight::get();
 		let sender: MultiLocation =
-			Junction::AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
-		let message = Xcm::ReserveAssetDeposit {
-			assets: vec![ConcreteFungible { id: Parent.into(), amount: SEND_AMOUNT }],
+			AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
+		let message = Xcm::ReserveAssetDeposited {
+			assets: (X1(Parent), SEND_AMOUNT).into(),
 			effects: vec![
 				buy_execution(weight),
-				DepositAsset { assets: vec![All], dest: sender.clone() },
+				DepositAsset { assets: Wild(All), dest: sender.clone() },
 			],
 		};
 		assert_ok!(XcmPallet::send(Origin::signed(ALICE), RelayLocation::get(), message.clone()));
@@ -77,7 +77,7 @@ fn send_fails_when_xcm_router_blocks() {
 			assets: vec![ConcreteFungible { id: Parent.into(), amount: SEND_AMOUNT }],
 			effects: vec![
 				buy_execution(weight),
-				DepositAsset { assets: vec![All], dest: sender.clone() },
+				DepositAsset { assets: Wild(All), dest: sender.clone() },
 			],
 		};
 		assert_noop!(
@@ -114,8 +114,8 @@ fn teleport_assets_works() {
 		assert_ok!(XcmPallet::teleport_assets(
 			Origin::signed(ALICE),
 			RelayLocation::get(),
-			MultiLocation::X1(Junction::AccountId32 { network: NetworkId::Any, id: BOB.into() }),
-			vec![ConcreteFungible { id: MultiLocation::Null, amount: SEND_AMOUNT }],
+			X1(AccountId32 { network: Any, id: BOB.into() }),
+			(Null, SEND_AMOUNT).into(),
 			weight,
 		));
 		assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
@@ -143,7 +143,7 @@ fn reserve_transfer_assets_works() {
 			Origin::signed(ALICE),
 			Parachain(PARA_ID).into(),
 			dest.clone(),
-			vec![ConcreteFungible { id: MultiLocation::Null, amount: SEND_AMOUNT }],
+			(Null, SEND_AMOUNT).into(),
 			weight
 		));
 		// Alice spent amount
@@ -156,8 +156,8 @@ fn reserve_transfer_assets_works() {
 			vec![(
 				Parachain(PARA_ID).into(),
 				Xcm::ReserveAssetDeposit {
-					assets: vec![ConcreteFungible { id: Parent.into(), amount: SEND_AMOUNT }],
-					effects: vec![buy_execution(weight), DepositAsset { assets: vec![All], dest },]
+					assets: (X1(Parent), SEND_AMOUNT).into(),
+					effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), dest },]
 				}
 			)]
 		);
@@ -184,8 +184,8 @@ fn execute_withdraw_to_deposit_works() {
 		assert_ok!(XcmPallet::execute(
 			Origin::signed(ALICE),
 			Box::new(Xcm::WithdrawAsset {
-				assets: vec![ConcreteFungible { id: MultiLocation::Null, amount: SEND_AMOUNT }],
-				effects: vec![buy_execution(weight), DepositAsset { assets: vec![All], dest }],
+				assets: (Null, SEND_AMOUNT).into(),
+				effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), dest }],
 			}),
 			weight
 		));
diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index c11110ed571c..572146ad34ad 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -23,7 +23,7 @@
 //! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
 //!   account.
 
-use super::MultiLocation;
+use super::{Junction, MultiLocation::{self, X1}};
 use alloc::{vec, vec::Vec};
 use core::cmp::Ordering;
 use parity_scale_codec::{self as codec, Decode, Encode};
@@ -70,6 +70,12 @@ impl From<MultiLocation> for AssetId {
 	}
 }
 
+impl From<Junction> for AssetId {
+	fn from(x: Junction) -> Self {
+		Self::Concrete(X1(x))
+	}
+}
+
 impl From<Vec<u8>> for AssetId {
 	fn from(x: Vec<u8>) -> Self {
 		Self::Abstract(x)

From f58a65931f9aa606c01e1aadacd1b8c7d3480996 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Tue, 3 Aug 2021 23:59:12 +0200
Subject: [PATCH 066/166] tests

---
 xcm/pallet-xcm/src/mock.rs  | 10 +++++-----
 xcm/pallet-xcm/src/tests.rs |  6 +++---
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index e919be21a21d..b347b3520882 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -26,12 +26,12 @@ use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
 pub use sp_std::{cell::RefCell, fmt::Debug, marker::PhantomData};
 use xcm::{
 	opaque::v1::{Error as XcmError, MultiAsset, Result as XcmResult, SendXcm, Xcm},
-	v1::{MultiLocation, NetworkId, Order},
+	v1::prelude::*,
 };
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative,
 	ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
-	CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfConcreteFungible, FixedWeightBounds,
+	CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds,
 	IsConcrete, LocationInverter, SignedAccountId32AsNative, SignedToAccountId32,
 	SovereignSignedViaLocation, TakeWeightCredit,
 };
@@ -154,7 +154,7 @@ type LocalOriginConverter = (
 
 parameter_types! {
 	pub const BaseXcmWeight: Weight = 1_000;
-	pub CurrencyPerSecond: (MultiLocation, u128) = (RelayLocation::get(), 1);
+	pub CurrencyPerSecond: (AssetId, u128) = (Concrete(RelayLocation::get()), 1);
 }
 
 pub type Barrier = (TakeWeightCredit, AllowTopLevelPaidExecutionFrom<All<MultiLocation>>);
@@ -170,7 +170,7 @@ impl xcm_executor::Config for XcmConfig {
 	type LocationInverter = LocationInverter<Ancestry>;
 	type Barrier = Barrier;
 	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
-	type Trader = FixedRateOfConcreteFungible<CurrencyPerSecond, ()>;
+	type Trader = FixedRateOfFungible<CurrencyPerSecond, ()>;
 	type ResponseHandler = ();
 }
 
@@ -196,7 +196,7 @@ pub(crate) fn last_event() -> Event {
 
 pub(crate) fn buy_execution<C>(debt: Weight) -> Order<C> {
 	use xcm::opaque::v1::prelude::*;
-	Order::BuyExecution { fees: All, weight: 0, debt, halt_on_error: false, xcm: vec![] }
+	Order::BuyExecution { fees: (RelayLocation::get(), 1).into(), weight: 0, debt, halt_on_error: false, xcm: vec![] }
 }
 
 pub(crate) fn new_test_ext_with_balances(
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index da5d4405cc4a..6c1a7c6203cc 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -73,8 +73,8 @@ fn send_fails_when_xcm_router_blocks() {
 		let weight = 2 * BaseXcmWeight::get();
 		let sender: MultiLocation =
 			Junction::AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
-		let message = Xcm::ReserveAssetDeposit {
-			assets: vec![ConcreteFungible { id: Parent.into(), amount: SEND_AMOUNT }],
+		let message = Xcm::ReserveAssetDeposited {
+			assets: (Parent, SEND_AMOUNT).into(),
 			effects: vec![
 				buy_execution(weight),
 				DepositAsset { assets: Wild(All), dest: sender.clone() },
@@ -155,7 +155,7 @@ fn reserve_transfer_assets_works() {
 			sent_xcm(),
 			vec![(
 				Parachain(PARA_ID).into(),
-				Xcm::ReserveAssetDeposit {
+				Xcm::ReserveAssetDeposited {
 					assets: (X1(Parent), SEND_AMOUNT).into(),
 					effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), dest },]
 				}

From 8a7810001e4583ccf789ca89733aedeeed75459a Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 00:03:38 +0200
Subject: [PATCH 067/166] another test

---
 xcm/xcm-builder/src/weight.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index 87b7c2f6b488..028ce6b061e4 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -162,6 +162,9 @@ impl<T: Get<(AssetId, u128)>, R: TakeRevenue> WeightTrader for FixedRateOfFungib
 		let (id, units_per_second) = T::get();
 		use frame_support::weights::constants::WEIGHT_PER_SECOND;
 		let amount = units_per_second * (weight as u128) / (WEIGHT_PER_SECOND as u128);
+		if amount == 0 {
+			return Ok(payment)
+		}
 		let unused = payment.checked_sub((id, amount).into()).map_err(|_| Error::TooExpensive)?;
 		self.0 = self.0.saturating_add(weight);
 		self.1 = self.1.saturating_add(amount);

From 6eb75ad84691b42fa1898b93279f82296c66a047 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 00:04:55 +0200
Subject: [PATCH 068/166] final test

---
 xcm/pallet-xcm/src/mock.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index b347b3520882..1051a171c06a 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -196,7 +196,7 @@ pub(crate) fn last_event() -> Event {
 
 pub(crate) fn buy_execution<C>(debt: Weight) -> Order<C> {
 	use xcm::opaque::v1::prelude::*;
-	Order::BuyExecution { fees: (RelayLocation::get(), 1).into(), weight: 0, debt, halt_on_error: false, xcm: vec![] }
+	Order::BuyExecution { fees: (RelayLocation::get(), 10).into(), weight: 0, debt, halt_on_error: false, xcm: vec![] }
 }
 
 pub(crate) fn new_test_ext_with_balances(

From c4f61f3390e57ca2f94e74dee11ef4d66fc75625 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Wed, 4 Aug 2021 02:32:00 -0700
Subject: [PATCH 069/166] Update rustdocs and add debug_assert where sensible

---
 xcm/src/v0/multi_location.rs | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 77d30bc7fb5a..e9ae0fe11061 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -38,15 +38,17 @@ use parity_scale_codec::{self, Decode, Encode, Input, Output};
 /// A `MultiLocation` is a *relative identifier*, meaning that it can only be used to define the relative path
 /// between two locations, and cannot generally be used to refer to a location universally. It is comprised of a
 /// number of *junctions*, each morphing the previous location, either diving down into one of its internal locations,
-/// called a *sub-consensus*, or going up into its parent location. Correct `MultiLocation` values must have all
-/// `Parent` junctions as a prefix to all *sub-consensus* junctions.
+/// called a *sub-consensus*, or going up into its parent location.
 ///
-/// This specific `MultiLocation` implementation uses a Rust `enum` in order to make pattern matching easier.
-///
-/// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system.
+/// The `parents` field of this struct indicates the number of parent junctions that exist at the
+/// beginning of this `MultiLocation`. A corollary of such a property is that no parent junctions
+/// can be added in the middle or at the end of a `MultiLocation`, thus ensuring well-formedness
+/// of each and every `MultiLocation` that can be constructed.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug)]
 pub struct MultiLocation {
+	/// The number of parent junctions at the beginning of this `MultiLocation`.
 	parents: u8,
+	/// The interior (i.e. non-parent) junctions that this `MultiLocation` contains.
 	interior: Junctions,
 }
 
@@ -121,6 +123,8 @@ impl MultiLocation {
 	}
 
 	/// Creates a new `MultiLocation` with 0 parents and a `Null` interior.
+	///
+	/// The resulting `MultiLocation` can be interpreted as the "current consensus system".
 	pub const fn empty() -> MultiLocation {
 		MultiLocation { parents: 0, interior: Junctions::Null }
 	}
@@ -144,6 +148,9 @@ impl MultiLocation {
 
 	/// Creates a new `MultiLocation` with no parents and a single `Parachain` interior junction
 	/// specified by `para_id`.
+	///
+	/// The resulting `MultiLocation` can be interpreted as the child-parachain of the current
+	/// consensus system.
 	pub const fn with_parachain_interior(para_id: u32) -> MultiLocation {
 		MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(para_id)) }
 	}
@@ -170,7 +177,9 @@ impl MultiLocation {
 
 	/// Returns the number of parents and junctions in `self`.
 	pub const fn len(&self) -> usize {
-		self.parent_count() as usize + self.interior.len()
+		let len = self.parent_count() as usize + self.interior.len();
+		debug_assert!(len <= MAX_MULTILOCATION_LENGTH);
+		len
 	}
 
 	/// Returns the first interior junction, or `None` if the location is empty or contains only
@@ -530,6 +539,11 @@ impl From<[Junction; 8]> for MultiLocation {
 	}
 }
 
+/// Non-parent junctions that can be constructed, up to the length of 8. This specific `Junctions`
+/// implementation uses a Rust `enum` in order to make pattern matching easier.
+///
+/// Parent junctions cannot be constructed with this type. Refer to `MultiLocation` for
+/// instructions on constructing parent junctions.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
 pub enum Junctions {
 	/// The interpreting consensus system.

From a25f3ea2448e27f016283d1a8fcfd319cc4d5921 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Wed, 4 Aug 2021 02:38:01 -0700
Subject: [PATCH 070/166] Revert debug_assert in const fn len()

---
 xcm/src/v0/multi_location.rs | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index e9ae0fe11061..7ce2989a59cb 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -177,9 +177,7 @@ impl MultiLocation {
 
 	/// Returns the number of parents and junctions in `self`.
 	pub const fn len(&self) -> usize {
-		let len = self.parent_count() as usize + self.interior.len();
-		debug_assert!(len <= MAX_MULTILOCATION_LENGTH);
-		len
+		self.parent_count() as usize + self.interior.len()
 	}
 
 	/// Returns the first interior junction, or `None` if the location is empty or contains only

From 9d0b9f9900070115363ae4fb5198acce109763b9 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 11:56:32 +0200
Subject: [PATCH 071/166] tests

---
 xcm/pallet-xcm/src/mock.rs           | 14 ++++++++++----
 xcm/src/v1/multiasset.rs             |  5 ++++-
 xcm/xcm-simulator/example/src/lib.rs | 10 ++--------
 3 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index 1051a171c06a..0fa4ba225ce2 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -31,9 +31,9 @@ use xcm::{
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative,
 	ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
-	CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds,
-	IsConcrete, LocationInverter, SignedAccountId32AsNative, SignedToAccountId32,
-	SovereignSignedViaLocation, TakeWeightCredit,
+	CurrencyAdapter as XcmCurrencyAdapter, FixedRateOfFungible, FixedWeightBounds, IsConcrete,
+	LocationInverter, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation,
+	TakeWeightCredit,
 };
 use xcm_executor::XcmExecutor;
 
@@ -196,7 +196,13 @@ pub(crate) fn last_event() -> Event {
 
 pub(crate) fn buy_execution<C>(debt: Weight) -> Order<C> {
 	use xcm::opaque::v1::prelude::*;
-	Order::BuyExecution { fees: (RelayLocation::get(), 10).into(), weight: 0, debt, halt_on_error: false, xcm: vec![] }
+	Order::BuyExecution {
+		fees: (RelayLocation::get(), 10).into(),
+		weight: 0,
+		debt,
+		halt_on_error: false,
+		xcm: vec![],
+	}
 }
 
 pub(crate) fn new_test_ext_with_balances(
diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index 572146ad34ad..5716a7b5c980 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -23,7 +23,10 @@
 //! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
 //!   account.
 
-use super::{Junction, MultiLocation::{self, X1}};
+use super::{
+	Junction,
+	MultiLocation::{self, X1},
+};
 use alloc::{vec, vec::Vec};
 use core::cmp::Ordering;
 use parity_scale_codec::{self as codec, Decode, Encode};
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 00c1f4109421..978795a1546e 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -100,13 +100,7 @@ mod tests {
 
 	use codec::Encode;
 	use frame_support::assert_ok;
-	use xcm::v1::{
-		Junction::{self, Parachain, Parent},
-		MultiAsset::*,
-		MultiLocation::*,
-		NetworkId, OriginKind,
-		Xcm::*,
-	};
+	use xcm::v1::prelude::*;
 	use xcm_simulator::TestExt;
 
 	#[test]
@@ -199,7 +193,7 @@ mod tests {
 				relay_chain::Origin::signed(ALICE),
 				X1(Parachain(1)),
 				X1(Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }),
-				vec![ConcreteFungible { id: Null, amount: 123 }],
+				(Null, 123).into(),
 				123,
 			));
 		});

From b5b63c8208dce9c29f3d9af9bffee57dc8739870 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 12:26:48 +0200
Subject: [PATCH 072/166] Rename Null -> Here

---
 runtime/kusama/src/lib.rs                     |  6 +--
 runtime/rococo/src/lib.rs                     |  4 +-
 runtime/westend/src/lib.rs                    |  4 +-
 xcm/pallet-xcm/src/lib.rs                     |  8 ++--
 xcm/pallet-xcm/src/mock.rs                    |  4 +-
 xcm/pallet-xcm/src/tests.rs                   | 16 +++----
 xcm/src/v1/mod.rs                             | 29 ++++++------
 xcm/src/v1/multilocation.rs                   | 40 ++++++++--------
 xcm/src/v1/order.rs                           | 15 ++++--
 xcm/xcm-builder/src/barriers.rs               |  2 +-
 xcm/xcm-builder/src/mock.rs                   |  4 +-
 xcm/xcm-builder/src/origin_conversion.rs      |  2 +-
 xcm/xcm-builder/src/tests.rs                  | 46 +++++++++----------
 xcm/xcm-builder/src/weight.rs                 |  4 +-
 xcm/xcm-executor/src/assets.rs                | 20 ++++----
 xcm/xcm-executor/src/lib.rs                   | 12 ++---
 xcm/xcm-executor/src/traits/transact_asset.rs | 10 ++--
 xcm/xcm-simulator/example/src/lib.rs          |  8 ++--
 xcm/xcm-simulator/example/src/relay_chain.rs  |  4 +-
 19 files changed, 122 insertions(+), 116 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index c2720c8deed1..6fc6b8ac3524 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1199,14 +1199,14 @@ impl auctions::Config for Runtime {
 
 parameter_types! {
 	/// The location of the KSM token, from the context of this chain. Since this token is native to this
-	/// chain, we make it synonymous with it and thus it is the `Null` location, which means "equivalent to
+	/// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to
 	/// the context".
-	pub const KsmLocation: MultiLocation = MultiLocation::Null;
+	pub const KsmLocation: MultiLocation = MultiLocation::Here;
 	/// The Kusama network ID. This is named.
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	/// Our XCM location ancestry - i.e. what, if anything, `Parent` means evaluated in our context. Since
 	/// Kusama is a top-level relay-chain, there is no ancestry.
-	pub const Ancestry: MultiLocation = MultiLocation::Null;
+	pub const Ancestry: MultiLocation = MultiLocation::Here;
 	/// The check account, which holds any native assets that have been teleported out and not back in (yet).
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 88e6072003ff..f05de3d26771 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -583,9 +583,9 @@ impl parachains_paras::Config for Runtime {
 }
 
 parameter_types! {
-	pub const RocLocation: MultiLocation = MultiLocation::Null;
+	pub const RocLocation: MultiLocation = MultiLocation::Here;
 	pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
-	pub const Ancestry: MultiLocation = MultiLocation::Null;
+	pub const Ancestry: MultiLocation = MultiLocation::Here;
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
 
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index a578ff548afc..d0304022c602 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -866,8 +866,8 @@ impl auctions::Config for Runtime {
 }
 
 parameter_types! {
-	pub const WndLocation: MultiLocation = MultiLocation::Null;
-	pub const Ancestry: MultiLocation = MultiLocation::Null;
+	pub const WndLocation: MultiLocation = MultiLocation::Here;
+	pub const Ancestry: MultiLocation = MultiLocation::Here;
 	pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index ece2590f4d53..3486e9777a94 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -165,7 +165,7 @@ pub mod pallet {
 							halt_on_error: false,
 							xcm: vec![],
 						},
-						DepositAsset { assets: Wild(All), dest: beneficiary },
+						DepositAsset { assets: Wild(All), beneficiary },
 					],
 				}],
 			};
@@ -222,7 +222,7 @@ pub mod pallet {
 						halt_on_error: false,
 						xcm: vec![],
 					},
-					DepositAsset { assets: Wild(All), dest: beneficiary },
+					DepositAsset { assets: Wild(All), beneficiary },
 				],
 			};
 			let weight =
@@ -269,7 +269,7 @@ pub mod pallet {
 			message: Xcm<()>,
 		) -> Result<(), XcmError> {
 			let message = match interior {
-				MultiLocation::Null => message,
+				MultiLocation::Here => message,
 				who => Xcm::<()>::RelayedFrom { who, message: Box::new(message) },
 			};
 			log::trace!(target: "xcm::send_xcm", "dest: {:?}, message: {:?}", &dest, &message);
@@ -346,7 +346,7 @@ where
 
 	#[cfg(feature = "runtime-benchmarks")]
 	fn successful_origin() -> O {
-		O::from(Origin::Xcm(MultiLocation::Null))
+		O::from(Origin::Xcm(MultiLocation::Here))
 	}
 }
 
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index 0fa4ba225ce2..b3c12f9531e3 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -133,9 +133,9 @@ impl pallet_balances::Config for Test {
 }
 
 parameter_types! {
-	pub const RelayLocation: MultiLocation = MultiLocation::Null;
+	pub const RelayLocation: MultiLocation = MultiLocation::Here;
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = MultiLocation::Null;
+	pub Ancestry: MultiLocation = MultiLocation::Here;
 	pub UnitWeightCost: Weight = 1_000;
 }
 
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 6c1a7c6203cc..0e8b086e8290 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -43,14 +43,14 @@ fn send_works() {
 			assets: (X1(Parent), SEND_AMOUNT).into(),
 			effects: vec![
 				buy_execution(weight),
-				DepositAsset { assets: Wild(All), dest: sender.clone() },
+				DepositAsset { assets: Wild(All), beneficiary: sender.clone() },
 			],
 		};
 		assert_ok!(XcmPallet::send(Origin::signed(ALICE), RelayLocation::get(), message.clone()));
 		assert_eq!(
 			sent_xcm(),
 			vec![(
-				MultiLocation::Null,
+				MultiLocation::Here,
 				RelayedFrom { who: sender.clone(), message: Box::new(message.clone()) }
 			)]
 		);
@@ -77,7 +77,7 @@ fn send_fails_when_xcm_router_blocks() {
 			assets: (Parent, SEND_AMOUNT).into(),
 			effects: vec![
 				buy_execution(weight),
-				DepositAsset { assets: Wild(All), dest: sender.clone() },
+				DepositAsset { assets: Wild(All), beneficiary: sender.clone() },
 			],
 		};
 		assert_noop!(
@@ -115,7 +115,7 @@ fn teleport_assets_works() {
 			Origin::signed(ALICE),
 			RelayLocation::get(),
 			X1(AccountId32 { network: Any, id: BOB.into() }),
-			(Null, SEND_AMOUNT).into(),
+			(Here, SEND_AMOUNT).into(),
 			weight,
 		));
 		assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
@@ -143,7 +143,7 @@ fn reserve_transfer_assets_works() {
 			Origin::signed(ALICE),
 			Parachain(PARA_ID).into(),
 			dest.clone(),
-			(Null, SEND_AMOUNT).into(),
+			(Here, SEND_AMOUNT).into(),
 			weight
 		));
 		// Alice spent amount
@@ -157,7 +157,7 @@ fn reserve_transfer_assets_works() {
 				Parachain(PARA_ID).into(),
 				Xcm::ReserveAssetDeposited {
 					assets: (X1(Parent), SEND_AMOUNT).into(),
-					effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), dest },]
+					effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), beneficiary: dest },]
 				}
 			)]
 		);
@@ -184,8 +184,8 @@ fn execute_withdraw_to_deposit_works() {
 		assert_ok!(XcmPallet::execute(
 			Origin::signed(ALICE),
 			Box::new(Xcm::WithdrawAsset {
-				assets: (Null, SEND_AMOUNT).into(),
-				effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), dest }],
+				assets: (Here, SEND_AMOUNT).into(),
+				effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), beneficiary: dest }],
 			}),
 			weight
 		));
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index 375a8d8a3cfc..5f7bae368d85 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -143,19 +143,19 @@ pub enum Xcm<Call> {
 	/// created on this system.
 	///
 	/// Some orders are given (`effects`) which should be executed once the corresponding derivative assets have
-	/// been placed into `holding`.
+	/// been placed into the Holding Register.
 	///
-	/// - `assets`: The asset(s) that are minted into holding.
-	/// - `effects`: The order(s) to execute on the holding register.
+	/// - `assets`: The asset(s) that are minted into the Holding Register.
+	/// - `effects`: The order(s) to execute on the Holding Register.
 	///
-	/// Safety: `origin` must be trusted to have irrevocably destroyed the `assets` prior as a consequence of
-	/// sending this message.
+	/// Safety: `origin` must be trusted to have irrevocably destroyed the corresponding`assets` prior as a consequence
+	/// of sending this message.
 	///
 	/// Kind: *Trusted Indication*.
 	///
 	/// Errors:
 	#[codec(index = 2)]
-	TeleportAsset { assets: MultiAssets, effects: Vec<Order<Call>> },
+	ReceiveTeleportedAsset { assets: MultiAssets, effects: Vec<Order<Call>> },
 
 	/// Indication of the contents of the holding register corresponding to the `QueryHolding` order of `query_id`.
 	///
@@ -175,10 +175,10 @@ pub enum Xcm<Call> {
 	},
 
 	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
-	/// ownership of `dest` within this consensus system.
+	/// ownership of `beneficiary`.
 	///
 	/// - `assets`: The asset(s) to be withdrawn.
-	/// - `dest`: The new owner for the assets.
+	/// - `beneficiary`: The new owner for the assets.
 	///
 	/// Safety: No concerns.
 	///
@@ -186,15 +186,16 @@ pub enum Xcm<Call> {
 	///
 	/// Errors:
 	#[codec(index = 4)]
-	TransferAsset { assets: MultiAssets, dest: MultiLocation },
+	TransferAsset { assets: MultiAssets, beneficiary: MultiLocation },
 
 	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
-	/// ownership of `dest` within this consensus system.
+	/// ownership of `dest` within this consensus system (i.e. its sovereign account).
 	///
 	/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`.
 	///
 	/// - `assets`: The asset(s) to be withdrawn.
-	/// - `dest`: The new owner for the assets.
+	/// - `dest`: The location whose sovereign account will own the assets and thus the effective beneficiary for the
+	///   assets and the notification target for the reserve asset deposit message.
 	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposited` which is sent onwards to
 	///   `dest`.
 	///
@@ -303,10 +304,10 @@ impl<Call> Xcm<Call> {
 				assets,
 				effects: effects.into_iter().map(Order::into).collect(),
 			},
-			TeleportAsset { assets, effects } =>
-				TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
+			ReceiveTeleportedAsset { assets, effects } =>
+				ReceiveTeleportedAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
 			QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response },
-			TransferAsset { assets, dest } => TransferAsset { assets, dest },
+			TransferAsset { assets, beneficiary } => TransferAsset { assets, beneficiary },
 			TransferReserveAsset { assets, dest, effects } =>
 				TransferReserveAsset { assets, dest, effects },
 			HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } =>
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 20a9153b570a..e44d5f76a289 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -42,11 +42,11 @@ use parity_scale_codec::{self, Decode, Encode};
 ///
 /// This specific `MultiLocation` implementation uses a Rust `enum` in order to make pattern matching easier.
 ///
-/// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system.
+/// The `MultiLocation` value of `Here` simply refers to the interpreting consensus system.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
 pub enum MultiLocation {
 	/// The interpreting consensus system.
-	Null,
+	Here,
 	/// A relative path comprising 1 junction.
 	X1(Junction),
 	/// A relative path comprising 2 junctions.
@@ -76,7 +76,7 @@ impl From<Junction> for MultiLocation {
 
 impl From<()> for MultiLocation {
 	fn from(_: ()) -> Self {
-		MultiLocation::Null
+		MultiLocation::Here
 	}
 }
 impl From<(Junction,)> for MultiLocation {
@@ -128,7 +128,7 @@ impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction,
 
 impl From<[Junction; 0]> for MultiLocation {
 	fn from(_: [Junction; 0]) -> Self {
-		MultiLocation::Null
+		MultiLocation::Here
 	}
 }
 impl From<[Junction; 1]> for MultiLocation {
@@ -219,7 +219,7 @@ impl MultiLocation {
 	/// Returns first junction, or `None` if the location is empty.
 	pub fn first(&self) -> Option<&Junction> {
 		match &self {
-			MultiLocation::Null => None,
+			MultiLocation::Here => None,
 			MultiLocation::X1(ref a) => Some(a),
 			MultiLocation::X2(ref a, ..) => Some(a),
 			MultiLocation::X3(ref a, ..) => Some(a),
@@ -234,7 +234,7 @@ impl MultiLocation {
 	/// Returns last junction, or `None` if the location is empty.
 	pub fn last(&self) -> Option<&Junction> {
 		match &self {
-			MultiLocation::Null => None,
+			MultiLocation::Here => None,
 			MultiLocation::X1(ref a) => Some(a),
 			MultiLocation::X2(.., ref a) => Some(a),
 			MultiLocation::X3(.., ref a) => Some(a),
@@ -250,8 +250,8 @@ impl MultiLocation {
 	/// (second item in tuple) or `None` if it was empty.
 	pub fn split_first(self) -> (MultiLocation, Option<Junction>) {
 		match self {
-			MultiLocation::Null => (MultiLocation::Null, None),
-			MultiLocation::X1(a) => (MultiLocation::Null, Some(a)),
+			MultiLocation::Here => (MultiLocation::Here, None),
+			MultiLocation::X1(a) => (MultiLocation::Here, Some(a)),
 			MultiLocation::X2(a, b) => (MultiLocation::X1(b), Some(a)),
 			MultiLocation::X3(a, b, c) => (MultiLocation::X2(b, c), Some(a)),
 			MultiLocation::X4(a, b, c, d) => (MultiLocation::X3(b, c, d), Some(a)),
@@ -268,8 +268,8 @@ impl MultiLocation {
 	/// (second item in tuple) or `None` if it was empty.
 	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
 		match self {
-			MultiLocation::Null => (MultiLocation::Null, None),
-			MultiLocation::X1(a) => (MultiLocation::Null, Some(a)),
+			MultiLocation::Here => (MultiLocation::Here, None),
+			MultiLocation::X1(a) => (MultiLocation::Here, Some(a)),
 			MultiLocation::X2(a, b) => (MultiLocation::X1(a), Some(b)),
 			MultiLocation::X3(a, b, c) => (MultiLocation::X2(a, b), Some(c)),
 			MultiLocation::X4(a, b, c, d) => (MultiLocation::X3(a, b, c), Some(d)),
@@ -284,7 +284,7 @@ impl MultiLocation {
 
 	/// Removes the first element from `self`, returning it (or `None` if it was empty).
 	pub fn take_first(&mut self) -> Option<Junction> {
-		let mut d = MultiLocation::Null;
+		let mut d = MultiLocation::Here;
 		mem::swap(&mut *self, &mut d);
 		let (tail, head) = d.split_first();
 		*self = tail;
@@ -293,7 +293,7 @@ impl MultiLocation {
 
 	/// Removes the last element from `self`, returning it (or `None` if it was empty).
 	pub fn take_last(&mut self) -> Option<Junction> {
-		let mut d = MultiLocation::Null;
+		let mut d = MultiLocation::Here;
 		mem::swap(&mut *self, &mut d);
 		let (head, tail) = d.split_last();
 		*self = head;
@@ -304,7 +304,7 @@ impl MultiLocation {
 	/// `self` in case of overflow.
 	pub fn pushed_with(self, new: Junction) -> result::Result<Self, Self> {
 		Ok(match self {
-			MultiLocation::Null => MultiLocation::X1(new),
+			MultiLocation::Here => MultiLocation::X1(new),
 			MultiLocation::X1(a) => MultiLocation::X2(a, new),
 			MultiLocation::X2(a, b) => MultiLocation::X3(a, b, new),
 			MultiLocation::X3(a, b, c) => MultiLocation::X4(a, b, c, new),
@@ -320,7 +320,7 @@ impl MultiLocation {
 	/// `self` in case of overflow.
 	pub fn pushed_front_with(self, new: Junction) -> result::Result<Self, Self> {
 		Ok(match self {
-			MultiLocation::Null => MultiLocation::X1(new),
+			MultiLocation::Here => MultiLocation::X1(new),
 			MultiLocation::X1(a) => MultiLocation::X2(new, a),
 			MultiLocation::X2(a, b) => MultiLocation::X3(new, a, b),
 			MultiLocation::X3(a, b, c) => MultiLocation::X4(new, a, b, c),
@@ -335,7 +335,7 @@ impl MultiLocation {
 	/// Returns the number of junctions in `self`.
 	pub fn len(&self) -> usize {
 		match &self {
-			MultiLocation::Null => 0,
+			MultiLocation::Here => 0,
 			MultiLocation::X1(..) => 1,
 			MultiLocation::X2(..) => 2,
 			MultiLocation::X3(..) => 3,
@@ -480,7 +480,7 @@ impl MultiLocation {
 
 	/// Mutates `self`, suffixing it with `new`. Returns `Err` in case of overflow.
 	pub fn push(&mut self, new: Junction) -> result::Result<(), ()> {
-		let mut n = MultiLocation::Null;
+		let mut n = MultiLocation::Here;
 		mem::swap(&mut *self, &mut n);
 		match n.pushed_with(new) {
 			Ok(result) => {
@@ -496,7 +496,7 @@ impl MultiLocation {
 
 	/// Mutates `self`, prefixing it with `new`. Returns `Err` in case of overflow.
 	pub fn push_front(&mut self, new: Junction) -> result::Result<(), ()> {
-		let mut n = MultiLocation::Null;
+		let mut n = MultiLocation::Here;
 		mem::swap(&mut *self, &mut n);
 		match n.pushed_front_with(new) {
 			Ok(result) => {
@@ -564,7 +564,7 @@ impl MultiLocation {
 	/// This function ensures a multi-junction is in its canonicalized/normalized form, removing
 	/// any internal `[Non-Parent, Parent]` combinations.
 	pub fn canonicalize(&mut self) {
-		let mut normalized = MultiLocation::Null;
+		let mut normalized = MultiLocation::Here;
 		let mut iter = self.iter();
 		// We build up the the new normalized path by taking items from the original multi-location.
 		// When the next item we would add is `Parent`, we instead remove the last item assuming
@@ -787,7 +787,7 @@ mod tests {
 
 		let mut m = X6(Parachain(1), Parent, Parachain(2), Parent, Parachain(3), Parent);
 		m.canonicalize();
-		assert_eq!(m, Null);
+		assert_eq!(m, Here);
 
 		let mut m = X5(Parachain(1), Parent, Parent, Parent, Parachain(3));
 		m.canonicalize();
@@ -795,7 +795,7 @@ mod tests {
 
 		let mut m = X4(Parachain(1), Parachain(2), Parent, Parent);
 		m.canonicalize();
-		assert_eq!(m, Null);
+		assert_eq!(m, Here);
 
 		let mut m = X4(Parent, Parent, Parachain(1), Parachain(2));
 		m.canonicalize();
diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index aed5a6ff3634..61d3530d8c45 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -40,15 +40,16 @@ pub enum Order<Call> {
 	/// Errors:
 	#[codec(index = 1)]
 	// TODO: https://github.com/paritytech/polkadot/issues/3547 introduce `, max_assets: u32`
-	DepositAsset { assets: MultiAssetFilter, dest: MultiLocation },
+	DepositAsset { assets: MultiAssetFilter, beneficiary: MultiLocation },
 
 	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
-	/// this consensus system.
+	/// this consensus system (i.e. its sovereign account).
 	///
 	/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`.
 	///
 	/// - `assets`: The asset(s) to remove from holding.
-	/// - `dest`: The new owner for the assets.
+	/// - `dest`: The location whose sovereign account will own the assets and thus the effective beneficiary for the
+	///   assets and the notification target for the reserve asset deposit message.
 	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposited` which is sent onwards to
 	///   `dest`.
 	///
@@ -84,12 +85,16 @@ pub enum Order<Call> {
 		effects: Vec<Order<()>>,
 	},
 
-	/// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location.
+	/// Remove the asset(s) (`assets`) from holding and send a `ReceiveTeleportedAsset` XCM message to a `destination`
+	/// location.
 	///
 	/// - `assets`: The asset(s) to remove from holding.
 	/// - `destination`: A valid location that has a bi-lateral teleportation arrangement.
 	/// - `effects`: The orders to execute on the assets once arrived *on the destination location*.
 	///
+	/// NOTE: The `destination` location *MUST* respect this origin as a valid teleportation origin for all `assets`.
+	/// If it does not, then the assets may be lost.
+	///
 	/// Errors:
 	#[codec(index = 5)]
 	InitiateTeleport { assets: MultiAssetFilter, dest: MultiLocation, effects: Vec<Order<()>> },
@@ -139,7 +144,7 @@ impl<Call> Order<Call> {
 		use Order::*;
 		match order {
 			Noop => Noop,
-			DepositAsset { assets, dest } => DepositAsset { assets, dest },
+			DepositAsset { assets, beneficiary } => DepositAsset { assets, beneficiary },
 			DepositReserveAsset { assets, dest, effects } =>
 				DepositReserveAsset { assets, dest, effects },
 			ExchangeAsset { give, receive } => ExchangeAsset { give, receive },
diff --git a/xcm/xcm-builder/src/barriers.rs b/xcm/xcm-builder/src/barriers.rs
index f253be18026f..ec1b5d0c7f63 100644
--- a/xcm/xcm-builder/src/barriers.rs
+++ b/xcm/xcm-builder/src/barriers.rs
@@ -51,7 +51,7 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowTopLevelPaidExecutionFro
 		ensure!(T::contains(origin), ());
 		ensure!(top_level, ());
 		match message {
-			Xcm::TeleportAsset { effects, .. } |
+			Xcm::ReceiveTeleportedAsset { effects, .. } |
 			Xcm::WithdrawAsset { effects, .. } |
 			Xcm::ReserveAssetDeposited { effects, .. }
 				if matches!(
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index c8d6036577e7..af568a5fc8de 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -152,7 +152,7 @@ pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
 		// Children at 1000+id
 		X1(Parachain(id)) => 1000 + id as u64,
 		// Self at 3000
-		Null => 3000,
+		Here => 3000,
 		// Parent at 3001
 		X1(Parent) => 3001,
 		l => return Err(l),
@@ -251,7 +251,7 @@ parameter_types! {
 	pub static AllowUnpaidFrom: Vec<MultiLocation> = vec![];
 	pub static AllowPaidFrom: Vec<MultiLocation> = vec![];
 	// 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight.
-	pub static WeightPrice: (AssetId, u128) = (Null.into(), 1_000_000_000_000);
+	pub static WeightPrice: (AssetId, u128) = (Here.into(), 1_000_000_000_000);
 }
 
 pub type TestBarrier = (
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index 2cc343694fa9..1432738263cd 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -170,7 +170,7 @@ where
 		// We institute a root fallback so root can always represent the context. This
 		// guarantees that `successful_origin` will work.
 		if o.caller() == Origin::root().caller() {
-			Ok(MultiLocation::Null)
+			Ok(MultiLocation::Here)
 		} else {
 			Err(o)
 		}
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 93c87ce5dad5..3c66ff705eac 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -32,7 +32,7 @@ fn basic_setup_works() {
 	assert_eq!(to_account(X2(Parent, Parachain(50))), Ok(2050));
 	assert_eq!(to_account(X1(AccountIndex64 { index: 1, network: Any })), Ok(1));
 	assert_eq!(to_account(X1(AccountIndex64 { index: 42, network: Any })), Ok(42));
-	assert_eq!(to_account(Null), Ok(3000));
+	assert_eq!(to_account(Here), Ok(3000));
 }
 
 #[test]
@@ -47,7 +47,7 @@ fn weigher_should_work() {
 				halt_on_error: true,
 				xcm: vec![],
 			},
-			Order::DepositAsset { assets: All.into(), dest: Null },
+			Order::DepositAsset { assets: All.into(), beneficiary: Here },
 		],
 	}
 	.into();
@@ -56,7 +56,7 @@ fn weigher_should_work() {
 
 #[test]
 fn take_weight_credit_barrier_should_work() {
-	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), dest: Null };
+	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
 
 	let mut weight_credit = 10;
 	let r =
@@ -72,7 +72,7 @@ fn take_weight_credit_barrier_should_work() {
 
 #[test]
 fn allow_unpaid_should_work() {
-	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), dest: Null };
+	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
 
 	AllowUnpaidFrom::set(vec![X1(Parent)]);
 
@@ -99,7 +99,7 @@ fn allow_unpaid_should_work() {
 fn allow_paid_should_work() {
 	AllowPaidFrom::set(vec![X1(Parent)]);
 
-	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), dest: Null };
+	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
 		&X1(Parachain(1)),
@@ -115,7 +115,7 @@ fn allow_paid_should_work() {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
 			Order::BuyExecution { fees, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: All.into(), dest: Null },
+			Order::DepositAsset { assets: All.into(), beneficiary: Here },
 		],
 	};
 
@@ -133,7 +133,7 @@ fn allow_paid_should_work() {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
 			Order::BuyExecution { fees, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: All.into(), dest: Null },
+			Order::DepositAsset { assets: All.into(), beneficiary: Here },
 		],
 	};
 
@@ -159,8 +159,8 @@ fn allow_paid_should_work() {
 #[test]
 fn paying_reserve_deposit_should_work() {
 	AllowPaidFrom::set(vec![X1(Parent)]);
-	add_reserve(X1(Parent), (X1(Parent), WildFungible).into());
-	WeightPrice::set((X1(Parent).into(), 1_000_000_000_000));
+	add_reserve(X1(Parent), (Parent, WildFungible).into());
+	WeightPrice::set((Parent.into(), 1_000_000_000_000));
 
 	let origin = X1(Parent);
 	let fees = (X1(Parent), 30).into();
@@ -174,7 +174,7 @@ fn paying_reserve_deposit_should_work() {
 				halt_on_error: true,
 				xcm: vec![],
 			},
-			Order::<TestCall>::DepositAsset { assets: All.into(), dest: Null },
+			Order::<TestCall>::DepositAsset { assets: All.into(), beneficiary: Here },
 		],
 	};
 	let weight_limit = 50;
@@ -188,19 +188,19 @@ fn transfer_should_work() {
 	// we'll let them have message execution for free.
 	AllowUnpaidFrom::set(vec![X1(Parachain(1))]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, (Null, 1000).into());
+	add_asset(1001, (Here, 1000).into());
 	// They want to transfer 100 of them to their sibling parachain #2
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
 		X1(Parachain(1)),
 		Xcm::TransferAsset {
-			assets: (Null, 100).into(),
-			dest: X1(AccountIndex64 { index: 3, network: Any }),
+			assets: (Here, 100).into(),
+			beneficiary: X1(AccountIndex64 { index: 3, network: Any }),
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
-	assert_eq!(assets(3), vec![(Null, 100).into()]);
-	assert_eq!(assets(1001), vec![(Null, 900).into()]);
+	assert_eq!(assets(3), vec![(Here, 100).into()]);
+	assert_eq!(assets(1001), vec![(Here, 900).into()]);
 	assert_eq!(sent_xcm(), vec![]);
 }
 
@@ -208,7 +208,7 @@ fn transfer_should_work() {
 fn reserve_transfer_should_work() {
 	AllowUnpaidFrom::set(vec![X1(Parachain(1))]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, (Null, 1000).into());
+	add_asset(1001, (Here, 1000).into());
 	// The remote account owned by gav.
 	let three = X1(AccountIndex64 { index: 3, network: Any });
 
@@ -217,22 +217,22 @@ fn reserve_transfer_should_work() {
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
 		X1(Parachain(1)),
 		Xcm::TransferReserveAsset {
-			assets: (Null, 100).into(),
+			assets: (Here, 100).into(),
 			dest: X1(Parachain(2)),
-			effects: vec![Order::DepositAsset { assets: All.into(), dest: three.clone() }],
+			effects: vec![Order::DepositAsset { assets: All.into(), beneficiary: three.clone() }],
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
 
-	assert_eq!(assets(1002), vec![(Null, 100).into()]);
+	assert_eq!(assets(1002), vec![(Here, 100).into()]);
 	assert_eq!(
 		sent_xcm(),
 		vec![(
 			X1(Parachain(2)),
 			Xcm::ReserveAssetDeposited {
 				assets: (X1(Parent), 100).into(),
-				effects: vec![Order::DepositAsset { assets: All.into(), dest: three }],
+				effects: vec![Order::DepositAsset { assets: All.into(), beneficiary: three }],
 			}
 		)]
 	);
@@ -287,8 +287,8 @@ fn transacting_should_refund_weight() {
 fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let one = X1(AccountIndex64 { index: 1, network: Any });
 	AllowPaidFrom::set(vec![one.clone()]);
-	add_asset(1, (X1(Parent), 100).into());
-	WeightPrice::set((X1(Parent).into(), 1_000_000_000_000));
+	add_asset(1, (Parent, 100).into());
+	WeightPrice::set((Parent.into(), 1_000_000_000_000));
 
 	let origin = one.clone();
 	let fees = (X1(Parent), 100).into();
@@ -307,7 +307,7 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 					call: TestCall::Any(60, Some(10)).encode().into(),
 				}],
 			},
-			Order::<TestCall>::DepositAsset { assets: All.into(), dest: one.clone() },
+			Order::<TestCall>::DepositAsset { assets: All.into(), beneficiary: one.clone() },
 		],
 	};
 	let weight_limit = 100;
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index 028ce6b061e4..5e197fee89fa 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -37,7 +37,7 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeigh
 				T::get().saturating_add(Self::shallow(message.as_mut())?),
 			Xcm::WithdrawAsset { effects, .. } |
 			Xcm::ReserveAssetDeposited { effects, .. } |
-			Xcm::TeleportAsset { effects, .. } => {
+			Xcm::ReceiveTeleportedAsset { effects, .. } => {
 				let inner: Weight = effects
 					.iter_mut()
 					.map(|effect| match effect {
@@ -62,7 +62,7 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeigh
 			Xcm::RelayedFrom { ref mut message, .. } => Self::deep(message.as_mut())?,
 			Xcm::WithdrawAsset { effects, .. } |
 			Xcm::ReserveAssetDeposited { effects, .. } |
-			Xcm::TeleportAsset { effects, .. } => {
+			Xcm::ReceiveTeleportedAsset { effects, .. } => {
 				let mut extra = 0;
 				for effect in effects.iter_mut() {
 					match effect {
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 5270a30d44d2..8ce2ee4e2de2 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -339,12 +339,12 @@ impl Assets {
 	/// ```
 	/// use xcm_executor::Assets;
 	/// use xcm::v1::prelude::*;
-	/// let assets_i_have: Assets = vec![ (Null, 100).into(), (vec![0], 100).into() ].into();
-	/// let assets_they_want: MultiAssetFilter = vec![ (Null, 200).into(), (vec![0], 50).into() [.into();
+	/// let assets_i_have: Assets = vec![ (Here, 100).into(), (vec![0], 100).into() ].into();
+	/// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), (vec![0], 50).into() [.into();
 	///
 	/// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want);
 	/// assert_eq!(assets_we_can_trade.into_assets_iter().collect::<Vec<_>>(), vec![
-	/// 	(Null, 100).into(), (vec![0], 50).into(),
+	/// 	(Here, 100).into(), (vec![0], 50).into(),
 	/// ]);
 	/// ```
 	pub fn min(&self, mask: &MultiAssetFilter) -> Assets {
@@ -388,7 +388,7 @@ impl Assets {
 mod tests {
 	use super::*;
 	use xcm::v1::prelude::*;
-	use MultiLocation::Null;
+	use MultiLocation::Here;
 	#[allow(non_snake_case)]
 	fn AF(id: u8, amount: u128) -> MultiAsset {
 		(vec![id], amount).into()
@@ -399,11 +399,11 @@ mod tests {
 	}
 	#[allow(non_snake_case)]
 	fn CF(amount: u128) -> MultiAsset {
-		(Null, amount).into()
+		(Here, amount).into()
 	}
 	#[allow(non_snake_case)]
 	fn CNF(instance_id: u128) -> MultiAsset {
-		(Null, AssetInstance::Index { id: instance_id }).into()
+		(Here, AssetInstance::Index { id: instance_id }).into()
 	}
 
 	fn test_assets() -> Assets {
@@ -517,8 +517,8 @@ mod tests {
 	#[test]
 	fn min_all_concrete_works() {
 		let assets = test_assets();
-		let fungible = Wild((Null, WildFungible).into());
-		let non_fungible = Wild((Null, WildNonFungible).into());
+		let fungible = Wild((Here, WildFungible).into());
+		let non_fungible = Wild((Here, WildNonFungible).into());
 
 		let fungible = assets.min(&fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
@@ -581,8 +581,8 @@ mod tests {
 	#[test]
 	fn saturating_take_all_concrete_works() {
 		let mut assets = test_assets();
-		let fungible = Wild((Null, WildFungible).into());
-		let non_fungible = Wild((Null, WildNonFungible).into());
+		let fungible = Wild((Here, WildFungible).into());
+		let non_fungible = Wild((Here, WildNonFungible).into());
 
 		let fungible = assets.saturating_take(fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index 491558dbdb28..ed7f0b8e5053 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -162,10 +162,10 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				}
 				Some((assets.into(), effects))
 			},
-			(origin, Xcm::TransferAsset { assets, dest }) => {
+			(origin, Xcm::TransferAsset { assets, beneficiary }) => {
 				// Take `assets` from the origin account (on-chain) and place into dest account.
 				for asset in assets.inner() {
-					Config::AssetTransactor::beam_asset(&asset, &origin, &dest)?;
+					Config::AssetTransactor::beam_asset(&asset, &origin, &beneficiary)?;
 				}
 				None
 			},
@@ -179,7 +179,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				Config::XcmSender::send_xcm(dest, Xcm::ReserveAssetDeposited { assets, effects })?;
 				None
 			},
-			(origin, Xcm::TeleportAsset { assets, effects }) => {
+			(origin, Xcm::ReceiveTeleportedAsset { assets, effects }) => {
 				// check whether we trust origin to teleport this asset to us via config trait.
 				for asset in assets.inner() {
 					// We only trust the origin to send us assets that they identify as their
@@ -269,10 +269,10 @@ impl<Config: config::Config> XcmExecutor<Config> {
 		);
 		let mut total_surplus = 0;
 		match effect {
-			Order::DepositAsset { assets, dest } => {
+			Order::DepositAsset { assets, beneficiary } => {
 				let deposited = holding.saturating_take(assets);
 				for asset in deposited.into_assets_iter() {
-					Config::AssetTransactor::deposit_asset(&asset, &dest)?;
+					Config::AssetTransactor::deposit_asset(&asset, &beneficiary)?;
 				}
 			},
 			Order::DepositReserveAsset { assets, dest, effects } => {
@@ -294,7 +294,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 					Config::AssetTransactor::check_out(&origin, &asset);
 				}
 				let assets = Self::reanchored(assets, &dest);
-				Config::XcmSender::send_xcm(dest, Xcm::TeleportAsset { assets, effects })?;
+				Config::XcmSender::send_xcm(dest, Xcm::ReceiveTeleportedAsset { assets, effects })?;
 			},
 			Order::QueryHolding { query_id, dest, assets } => {
 				let assets = Self::reanchored(holding.min(&assets), &dest);
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index 60fb0508c676..a810ce173ca3 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -193,7 +193,7 @@ impl TransactAsset for Tuple {
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use MultiLocation::Null;
+	use MultiLocation::Here;
 
 	pub struct UnimplementedTransactor;
 	impl TransactAsset for UnimplementedTransactor {}
@@ -273,7 +273,7 @@ mod tests {
 			(UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
 
 		assert_eq!(
-			MultiTransactor::deposit_asset(&(Null, 1).into(), &Null),
+			MultiTransactor::deposit_asset(&(Here, 1).into(), &Here),
 			Err(XcmError::AssetNotFound)
 		);
 	}
@@ -282,7 +282,7 @@ mod tests {
 	fn unimplemented_and_not_found_continue_iteration() {
 		type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, SuccessfulTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&(Null, 1).into(), &Null), Ok(()));
+		assert_eq!(MultiTransactor::deposit_asset(&(Here, 1).into(), &Here), Ok(()));
 	}
 
 	#[test]
@@ -290,7 +290,7 @@ mod tests {
 		type MultiTransactor = (OverflowTransactor, SuccessfulTransactor);
 
 		assert_eq!(
-			MultiTransactor::deposit_asset(&(Null, 1).into(), &Null),
+			MultiTransactor::deposit_asset(&(Here, 1).into(), &Here),
 			Err(XcmError::Overflow)
 		);
 	}
@@ -299,6 +299,6 @@ mod tests {
 	fn success_stops_iteration() {
 		type MultiTransactor = (SuccessfulTransactor, OverflowTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&(Null, 1).into(), &Null), Ok(()));
+		assert_eq!(MultiTransactor::deposit_asset(&(Here, 1).into(), &Here), Ok(()));
 	}
 }
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 978795a1546e..305865508bf5 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -112,7 +112,7 @@ mod tests {
 		);
 		Relay::execute_with(|| {
 			assert_ok!(RelayChainPalletXcm::send_xcm(
-				Null,
+				Here,
 				X1(Parachain(1)),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
@@ -139,7 +139,7 @@ mod tests {
 		);
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
-				Null,
+				Here,
 				X1(Parent),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
@@ -166,7 +166,7 @@ mod tests {
 		);
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
-				Null,
+				Here,
 				X2(Parent, Parachain(2)),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
@@ -193,7 +193,7 @@ mod tests {
 				relay_chain::Origin::signed(ALICE),
 				X1(Parachain(1)),
 				X1(Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }),
-				(Null, 123).into(),
+				(Here, 123).into(),
 				123,
 			));
 		});
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index 7472df198219..e691e3e7ad35 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -91,10 +91,10 @@ impl shared::Config for Runtime {}
 impl configuration::Config for Runtime {}
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = MultiLocation::Null;
+	pub const KsmLocation: MultiLocation = MultiLocation::Here;
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = MultiLocation::Null;
+	pub Ancestry: MultiLocation = MultiLocation::Here;
 	pub UnitWeightCost: Weight = 1_000;
 }
 

From e9dbc72d84f15711d3b03d7daedb77559a2f8d31 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 12:32:43 +0200
Subject: [PATCH 073/166] Introduce

---
 xcm/src/lib.rs | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index f9ce3a3f5266..e7d31a2a7d74 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -29,6 +29,10 @@ use parity_scale_codec::{Decode, Encode, Error as CodecError, Input};
 
 pub mod v1;
 
+pub mod latest {
+	pub use super::v1::*;
+}
+
 mod double_encoded;
 pub use double_encoded::DoubleEncoded;
 
@@ -75,6 +79,10 @@ pub mod opaque {
 		pub use crate::v1::opaque::{Order, Xcm};
 	}
 
+	pub mod latest {
+		pub use super::v1::*;
+	}
+
 	/// The basic `VersionedXcm` type which just uses the `Vec<u8>` as an encoded call.
 	pub type VersionedXcm = super::VersionedXcm<()>;
 }

From 36ccb47bdc1cb1e20e45c2c6dcee4b9dac325624 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 13:00:12 +0200
Subject: [PATCH 074/166] More ergonomics

---
 xcm/src/v1/multiasset.rs       | 53 +++++++++++++++++++++----
 xcm/xcm-executor/src/assets.rs | 70 +++++++++++++++++-----------------
 2 files changed, 81 insertions(+), 42 deletions(-)

diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index 5716a7b5c980..cc0672b2d2d8 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -39,10 +39,7 @@ pub enum AssetInstance {
 
 	/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
 	/// values up to `2**128 - 1`.
-	Index {
-		#[codec(compact)]
-		id: u128,
-	},
+	Index(#[codec(compact)] u128),
 
 	/// A 4-byte fixed-length datum.
 	Array4([u8; 4]),
@@ -60,6 +57,48 @@ pub enum AssetInstance {
 	Blob(Vec<u8>),
 }
 
+impl From<()> for AssetInstance {
+	fn from(_: ()) -> Self {
+		Self::Undefined
+	}
+}
+
+/*impl From<u128> for AssetInstance {
+	fn from(x: u128) -> Self {
+		Self::Index(x)
+	}
+}*/
+
+impl From<[u8; 4]> for AssetInstance {
+	fn from(x: [u8; 4]) -> Self {
+		Self::Array4(x)
+	}
+}
+
+impl From<[u8; 8]> for AssetInstance {
+	fn from(x: [u8; 8]) -> Self {
+		Self::Array8(x)
+	}
+}
+
+impl From<[u8; 16]> for AssetInstance {
+	fn from(x: [u8; 16]) -> Self {
+		Self::Array16(x)
+	}
+}
+
+impl From<[u8; 32]> for AssetInstance {
+	fn from(x: [u8; 32]) -> Self {
+		Self::Array32(x)
+	}
+}
+
+impl From<Vec<u8>> for AssetInstance {
+	fn from(x: Vec<u8>) -> Self {
+		Self::Blob(x)
+	}
+}
+
 /// Classification of an asset being concrete or abstract.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum AssetId {
@@ -128,9 +167,9 @@ impl From<u128> for Fungibility {
 	}
 }
 
-impl From<AssetInstance> for Fungibility {
-	fn from(instance: AssetInstance) -> Fungibility {
-		Fungibility::NonFungible(instance)
+impl<T: Into<AssetInstance>> From<T> for Fungibility {
+	fn from(instance: T) -> Fungibility {
+		Fungibility::NonFungible(instance.into())
 	}
 }
 
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 8ce2ee4e2de2..fb9394d22d1d 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -394,24 +394,24 @@ mod tests {
 		(vec![id], amount).into()
 	}
 	#[allow(non_snake_case)]
-	fn ANF(class: u8, instance_id: u128) -> MultiAsset {
-		(vec![class], AssetInstance::Index { id: instance_id }).into()
+	fn ANF(class: u8, instance_id: u8) -> MultiAsset {
+		(vec![class], vec![instance_id]).into()
 	}
 	#[allow(non_snake_case)]
 	fn CF(amount: u128) -> MultiAsset {
 		(Here, amount).into()
 	}
 	#[allow(non_snake_case)]
-	fn CNF(instance_id: u128) -> MultiAsset {
-		(Here, AssetInstance::Index { id: instance_id }).into()
+	fn CNF(instance_id: u8) -> MultiAsset {
+		(Here, [instance_id; 4]).into()
 	}
 
 	fn test_assets() -> Assets {
 		let mut assets = Assets::new();
 		assets.subsume(AF(1, 100));
-		assets.subsume(ANF(2, 200));
+		assets.subsume(ANF(2, 20));
 		assets.subsume(CF(300));
-		assets.subsume(CNF(400));
+		assets.subsume(CNF(40));
 		assets
 	}
 
@@ -420,9 +420,9 @@ mod tests {
 		let t1 = test_assets();
 		let mut t2 = Assets::new();
 		t2.subsume(AF(1, 50));
-		t2.subsume(ANF(2, 100));
+		t2.subsume(ANF(2, 10));
 		t2.subsume(CF(300));
-		t2.subsume(CNF(500));
+		t2.subsume(CNF(50));
 		let mut r1 = t1.clone();
 		r1.subsume_assets(t2.clone());
 		let mut r2 = t1.clone();
@@ -443,12 +443,12 @@ mod tests {
 		let t = t.checked_sub(CF(151)).unwrap_err();
 		let t = t.checked_sub(CF(150)).unwrap();
 		let t = t.checked_sub(CF(1)).unwrap_err();
-		let t = t.checked_sub(ANF(2, 201)).unwrap_err();
-		let t = t.checked_sub(ANF(2, 200)).unwrap();
-		let t = t.checked_sub(ANF(2, 200)).unwrap_err();
-		let t = t.checked_sub(CNF(401)).unwrap_err();
-		let t = t.checked_sub(CNF(400)).unwrap();
-		let t = t.checked_sub(CNF(400)).unwrap_err();
+		let t = t.checked_sub(ANF(2, 21)).unwrap_err();
+		let t = t.checked_sub(ANF(2, 20)).unwrap();
+		let t = t.checked_sub(ANF(2, 20)).unwrap_err();
+		let t = t.checked_sub(CNF(41)).unwrap_err();
+		let t = t.checked_sub(CNF(40)).unwrap();
+		let t = t.checked_sub(CNF(40)).unwrap_err();
 		assert_eq!(t, Assets::new());
 	}
 
@@ -459,8 +459,8 @@ mod tests {
 		// Order defined by implementation: CF, AF, CNF, ANF
 		assert_eq!(Some(CF(300)), iter.next());
 		assert_eq!(Some(AF(1, 100)), iter.next());
-		assert_eq!(Some(CNF(400)), iter.next());
-		assert_eq!(Some(ANF(2, 200)), iter.next());
+		assert_eq!(Some(CNF(40)), iter.next());
+		assert_eq!(Some(ANF(2, 20)), iter.next());
 		assert_eq!(None, iter.next());
 	}
 
@@ -468,14 +468,14 @@ mod tests {
 	fn assets_into_works() {
 		let mut assets_vec: Vec<MultiAsset> = Vec::new();
 		assets_vec.push(AF(1, 100));
-		assets_vec.push(ANF(2, 200));
+		assets_vec.push(ANF(2, 20));
 		assets_vec.push(CF(300));
-		assets_vec.push(CNF(400));
+		assets_vec.push(CNF(40));
 		// Push same group of tokens again
 		assets_vec.push(AF(1, 100));
-		assets_vec.push(ANF(2, 200));
+		assets_vec.push(ANF(2, 20));
 		assets_vec.push(CF(300));
-		assets_vec.push(CNF(400));
+		assets_vec.push(CNF(40));
 
 		let assets: Assets = assets_vec.into();
 		let mut iter = assets.into_assets_iter();
@@ -483,8 +483,8 @@ mod tests {
 		assert_eq!(Some(CF(600)), iter.next());
 		assert_eq!(Some(AF(1, 200)), iter.next());
 		// Non-fungibles collapse
-		assert_eq!(Some(CNF(400)), iter.next());
-		assert_eq!(Some(ANF(2, 200)), iter.next());
+		assert_eq!(Some(CNF(40)), iter.next());
+		assert_eq!(Some(ANF(2, 20)), iter.next());
 		assert_eq!(None, iter.next());
 	}
 
@@ -511,7 +511,7 @@ mod tests {
 		assert_eq!(fungible, vec![AF(1, 100)]);
 		let non_fungible = assets.min(&non_fungible);
 		let non_fungible = non_fungible.assets_iter().collect::<Vec<_>>();
-		assert_eq!(non_fungible, vec![ANF(2, 200)]);
+		assert_eq!(non_fungible, vec![ANF(2, 20)]);
 	}
 
 	#[test]
@@ -525,7 +525,7 @@ mod tests {
 		assert_eq!(fungible, vec![CF(300)]);
 		let non_fungible = assets.min(&non_fungible);
 		let non_fungible = non_fungible.assets_iter().collect::<Vec<_>>();
-		assert_eq!(non_fungible, vec![CNF(400)]);
+		assert_eq!(non_fungible, vec![CNF(40)]);
 	}
 
 	#[test]
@@ -536,16 +536,16 @@ mod tests {
 		// This is less than 100, so it will decrease to 50
 		assets2.subsume(AF(1, 50));
 		// This asset does not exist, so not included
-		assets2.subsume(ANF(2, 400));
+		assets2.subsume(ANF(2, 40));
 		// This is more then 300, so it should stay at 300
 		assets2.subsume(CF(600));
 		// This asset should be included
-		assets2.subsume(CNF(400));
+		assets2.subsume(CNF(40));
 		let assets2: MultiAssets = assets2.into();
 
 		let assets_min = assets1.min(&assets2.into());
 		let assets_min = assets_min.into_assets_iter().collect::<Vec<_>>();
-		assert_eq!(assets_min, vec![CF(300), AF(1, 50), CNF(400)]);
+		assert_eq!(assets_min, vec![CF(300), AF(1, 50), CNF(40)]);
 	}
 
 	#[test]
@@ -572,10 +572,10 @@ mod tests {
 		assert_eq!(fungible, vec![AF(1, 100)]);
 		let non_fungible = assets.saturating_take(non_fungible);
 		let non_fungible = non_fungible.assets_iter().collect::<Vec<_>>();
-		assert_eq!(non_fungible, vec![ANF(2, 200)]);
+		assert_eq!(non_fungible, vec![ANF(2, 20)]);
 		// Assets drained of abstract
 		let final_assets = assets.assets_iter().collect::<Vec<_>>();
-		assert_eq!(final_assets, vec![CF(300), CNF(400)]);
+		assert_eq!(final_assets, vec![CF(300), CNF(40)]);
 	}
 
 	#[test]
@@ -589,10 +589,10 @@ mod tests {
 		assert_eq!(fungible, vec![CF(300)]);
 		let non_fungible = assets.saturating_take(non_fungible);
 		let non_fungible = non_fungible.assets_iter().collect::<Vec<_>>();
-		assert_eq!(non_fungible, vec![CNF(400)]);
+		assert_eq!(non_fungible, vec![CNF(40)]);
 		// Assets drained of concrete
 		let assets = assets.assets_iter().collect::<Vec<_>>();
-		assert_eq!(assets, vec![AF(1, 100), ANF(2, 200)]);
+		assert_eq!(assets, vec![AF(1, 100), ANF(2, 20)]);
 	}
 
 	#[test]
@@ -603,18 +603,18 @@ mod tests {
 		// We should take 50
 		assets2.subsume(AF(1, 50));
 		// This asset should not be taken
-		assets2.subsume(ANF(2, 400));
+		assets2.subsume(ANF(2, 40));
 		// This is more then 300, so it takes everything
 		assets2.subsume(CF(600));
 		// This asset should be taken
-		assets2.subsume(CNF(400));
+		assets2.subsume(CNF(40));
 		let assets2: MultiAssets = assets2.into();
 
 		let taken = assets1.saturating_take(assets2.into());
 		let taken = taken.into_assets_iter().collect::<Vec<_>>();
-		assert_eq!(taken, vec![CF(300), AF(1, 50), CNF(400)]);
+		assert_eq!(taken, vec![CF(300), AF(1, 50), CNF(40)]);
 
 		let assets = assets1.into_assets_iter().collect::<Vec<_>>();
-		assert_eq!(assets, vec![AF(1, 50), ANF(2, 200)]);
+		assert_eq!(assets, vec![AF(1, 50), ANF(2, 20)]);
 	}
 }

From de33d7d1cc392a16f47989a727520de3fbd32478 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 13:00:20 +0200
Subject: [PATCH 075/166] More ergonomics

---
 xcm/pallet-xcm/src/tests.rs  | 10 ++++++++--
 xcm/src/v1/mod.rs            |  6 ++++--
 xcm/xcm-builder/src/tests.rs |  9 ++++++---
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 0e8b086e8290..9285817c5270 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -157,7 +157,10 @@ fn reserve_transfer_assets_works() {
 				Parachain(PARA_ID).into(),
 				Xcm::ReserveAssetDeposited {
 					assets: (X1(Parent), SEND_AMOUNT).into(),
-					effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), beneficiary: dest },]
+					effects: vec![
+						buy_execution(weight),
+						DepositAsset { assets: Wild(All), beneficiary: dest },
+					]
 				}
 			)]
 		);
@@ -185,7 +188,10 @@ fn execute_withdraw_to_deposit_works() {
 			Origin::signed(ALICE),
 			Box::new(Xcm::WithdrawAsset {
 				assets: (Here, SEND_AMOUNT).into(),
-				effects: vec![buy_execution(weight), DepositAsset { assets: Wild(All), beneficiary: dest }],
+				effects: vec![
+					buy_execution(weight),
+					DepositAsset { assets: Wild(All), beneficiary: dest }
+				],
 			}),
 			weight
 		));
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index 5f7bae368d85..c27bb1788069 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -304,8 +304,10 @@ impl<Call> Xcm<Call> {
 				assets,
 				effects: effects.into_iter().map(Order::into).collect(),
 			},
-			ReceiveTeleportedAsset { assets, effects } =>
-				ReceiveTeleportedAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
+			ReceiveTeleportedAsset { assets, effects } => ReceiveTeleportedAsset {
+				assets,
+				effects: effects.into_iter().map(Order::into).collect(),
+			},
 			QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response },
 			TransferAsset { assets, beneficiary } => TransferAsset { assets, beneficiary },
 			TransferReserveAsset { assets, dest, effects } =>
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 3c66ff705eac..f918fb67124e 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -56,7 +56,8 @@ fn weigher_should_work() {
 
 #[test]
 fn take_weight_credit_barrier_should_work() {
-	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
+	let mut message =
+		opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
 
 	let mut weight_credit = 10;
 	let r =
@@ -72,7 +73,8 @@ fn take_weight_credit_barrier_should_work() {
 
 #[test]
 fn allow_unpaid_should_work() {
-	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
+	let mut message =
+		opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
 
 	AllowUnpaidFrom::set(vec![X1(Parent)]);
 
@@ -99,7 +101,8 @@ fn allow_unpaid_should_work() {
 fn allow_paid_should_work() {
 	AllowPaidFrom::set(vec![X1(Parent)]);
 
-	let mut message = opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
+	let mut message =
+		opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
 		&X1(Parachain(1)),

From 7ff049359905c9bd54e018e97d01bebcd5459f11 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 14:42:05 +0200
Subject: [PATCH 076/166] test fix

---
 xcm/xcm-simulator/example/src/lib.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 305865508bf5..12e39a51e30f 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -192,7 +192,7 @@ mod tests {
 			assert_ok!(RelayChainPalletXcm::reserve_transfer_assets(
 				relay_chain::Origin::signed(ALICE),
 				X1(Parachain(1)),
-				X1(Junction::AccountId32 { network: NetworkId::Any, id: ALICE.into() }),
+				X1(AccountId32 { network: Any, id: ALICE.into() }),
 				(Here, 123).into(),
 				123,
 			));

From 84c44f8244732e3fbf499a5ce54806aa42191ad2 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 14:48:47 +0200
Subject: [PATCH 077/166] test fixes

---
 xcm/pallet-xcm/src/tests.rs  |  8 ++++----
 xcm/xcm-builder/src/tests.rs | 14 +++++++-------
 xcm/xcm-executor/src/lib.rs  |  2 +-
 3 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 9285817c5270..dd86ca3a05e0 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -43,7 +43,7 @@ fn send_works() {
 			assets: (X1(Parent), SEND_AMOUNT).into(),
 			effects: vec![
 				buy_execution(weight),
-				DepositAsset { assets: Wild(All), beneficiary: sender.clone() },
+				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
 		assert_ok!(XcmPallet::send(Origin::signed(ALICE), RelayLocation::get(), message.clone()));
@@ -77,7 +77,7 @@ fn send_fails_when_xcm_router_blocks() {
 			assets: (Parent, SEND_AMOUNT).into(),
 			effects: vec![
 				buy_execution(weight),
-				DepositAsset { assets: Wild(All), beneficiary: sender.clone() },
+				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
 		assert_noop!(
@@ -159,7 +159,7 @@ fn reserve_transfer_assets_works() {
 					assets: (X1(Parent), SEND_AMOUNT).into(),
 					effects: vec![
 						buy_execution(weight),
-						DepositAsset { assets: Wild(All), beneficiary: dest },
+						DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
 					]
 				}
 			)]
@@ -190,7 +190,7 @@ fn execute_withdraw_to_deposit_works() {
 				assets: (Here, SEND_AMOUNT).into(),
 				effects: vec![
 					buy_execution(weight),
-					DepositAsset { assets: Wild(All), beneficiary: dest }
+					DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }
 				],
 			}),
 			weight
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index f918fb67124e..86ad5ccc7720 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -47,7 +47,7 @@ fn weigher_should_work() {
 				halt_on_error: true,
 				xcm: vec![],
 			},
-			Order::DepositAsset { assets: All.into(), beneficiary: Here },
+			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	}
 	.into();
@@ -118,7 +118,7 @@ fn allow_paid_should_work() {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
 			Order::BuyExecution { fees, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: All.into(), beneficiary: Here },
+			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	};
 
@@ -136,7 +136,7 @@ fn allow_paid_should_work() {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
 			Order::BuyExecution { fees, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
-			Order::DepositAsset { assets: All.into(), beneficiary: Here },
+			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	};
 
@@ -177,7 +177,7 @@ fn paying_reserve_deposit_should_work() {
 				halt_on_error: true,
 				xcm: vec![],
 			},
-			Order::<TestCall>::DepositAsset { assets: All.into(), beneficiary: Here },
+			Order::<TestCall>::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	};
 	let weight_limit = 50;
@@ -222,7 +222,7 @@ fn reserve_transfer_should_work() {
 		Xcm::TransferReserveAsset {
 			assets: (Here, 100).into(),
 			dest: X1(Parachain(2)),
-			effects: vec![Order::DepositAsset { assets: All.into(), beneficiary: three.clone() }],
+			effects: vec![Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: three.clone() }],
 		},
 		50,
 	);
@@ -235,7 +235,7 @@ fn reserve_transfer_should_work() {
 			X1(Parachain(2)),
 			Xcm::ReserveAssetDeposited {
 				assets: (X1(Parent), 100).into(),
-				effects: vec![Order::DepositAsset { assets: All.into(), beneficiary: three }],
+				effects: vec![Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: three }],
 			}
 		)]
 	);
@@ -310,7 +310,7 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 					call: TestCall::Any(60, Some(10)).encode().into(),
 				}],
 			},
-			Order::<TestCall>::DepositAsset { assets: All.into(), beneficiary: one.clone() },
+			Order::<TestCall>::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: one.clone() },
 		],
 	};
 	let weight_limit = 100;
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index e01f8ebbd0a7..e59aa54a1fd8 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -270,7 +270,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 		let mut total_surplus = 0;
 		match effect {
 			Order::DepositAsset { assets, max_assets, beneficiary } => {
-				let deposited = holding.limited_saturating_take(assets, max_assets);
+				let deposited = holding.limited_saturating_take(assets, max_assets as usize);
 				for asset in deposited.into_assets_iter() {
 					Config::AssetTransactor::deposit_asset(&asset, &beneficiary)?;
 				}

From 7d52b93684791097df80d0a44f16801397a00659 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 14:59:56 +0200
Subject: [PATCH 078/166] docs

---
 xcm/src/v1/order.rs | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index f17b12357a7d..b9f1c6afd2b2 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -31,11 +31,14 @@ pub enum Order<Call> {
 	#[codec(index = 0)]
 	Noop,
 
-	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
-	/// this consensus system.
+	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `beneficiary`
+	/// within this consensus system.
 	///
 	/// - `assets`: The asset(s) to remove from holding.
-	/// - `dest`: The new owner for the assets.
+	/// - `max_assets`: The maximum number of unique assets/asset instances to remove from holding. Only the first
+	///   `max_assets` assets/instances of those matched by `assets` will be removed, prioritised under standard asset
+	///   ordering. Any others will remain in holding.
+	/// - `beneficiary`: The new owner for the assets.
 	///
 	/// Errors:
 	#[codec(index = 1)]
@@ -47,6 +50,9 @@ pub enum Order<Call> {
 	/// Send an onward XCM message to `dest` of `ReserveAssetDeposited` with the given `effects`.
 	///
 	/// - `assets`: The asset(s) to remove from holding.
+	/// - `max_assets`: The maximum number of unique assets/asset instances to remove from holding. Only the first
+	///   `max_assets` assets/instances of those matched by `assets` will be removed, prioritised under standard asset
+	///   ordering. Any others will remain in holding.
 	/// - `dest`: The location whose sovereign account will own the assets and thus the effective beneficiary for the
 	///   assets and the notification target for the reserve asset deposit message.
 	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposited` which is sent onwards to

From 51c7d0554c4822df1b9bc7122c92da5ba9f19fe9 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 15:43:04 +0200
Subject: [PATCH 079/166] BuyExecution includes

---
 xcm/pallet-xcm/src/lib.rs      |  6 ++-
 xcm/pallet-xcm/src/mock.rs     |  3 +-
 xcm/src/v1/order.rs            | 35 +++++++++++++-----
 xcm/xcm-builder/src/tests.rs   | 37 ++++++++++++++-----
 xcm/xcm-builder/src/weight.rs  | 67 +++++++++++++++++++++-------------
 xcm/xcm-executor/src/assets.rs | 41 +++++++++++----------
 xcm/xcm-executor/src/lib.rs    | 30 ++++++++++-----
 7 files changed, 144 insertions(+), 75 deletions(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 676c3205bd65..bbbcfe1163b3 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -163,7 +163,8 @@ pub mod pallet {
 							weight: 0,
 							debt: dest_weight,
 							halt_on_error: false,
-							xcm: vec![],
+							orders: vec![],
+							instructions: vec![],
 						},
 						DepositAsset { assets: Wild(All), max_assets: 1, beneficiary },
 					],
@@ -220,7 +221,8 @@ pub mod pallet {
 						weight: 0,
 						debt: dest_weight,
 						halt_on_error: false,
-						xcm: vec![],
+						orders: vec![],
+						instructions: vec![],
 					},
 					DepositAsset { assets: Wild(All), max_assets: 1, beneficiary },
 				],
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index b3c12f9531e3..50a2471d74d7 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -201,7 +201,8 @@ pub(crate) fn buy_execution<C>(debt: Weight) -> Order<C> {
 		weight: 0,
 		debt,
 		halt_on_error: false,
-		xcm: vec![],
+		orders: vec![],
+		instructions: vec![],
 	}
 }
 
diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index b9f1c6afd2b2..6a2b04e9acf3 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -60,7 +60,12 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 2)]
-	DepositReserveAsset { assets: MultiAssetFilter, max_assets: u32, dest: MultiLocation, effects: Vec<Order<()>> },
+	DepositReserveAsset {
+		assets: MultiAssetFilter,
+		max_assets: u32,
+		dest: MultiLocation,
+		effects: Vec<Order<()>>,
+	},
 
 	/// Remove the asset(s) (`give`) from holding and replace them with alternative assets.
 	///
@@ -120,11 +125,20 @@ pub enum Order<Call> {
 		assets: MultiAssetFilter,
 	},
 
-	/// Pay for the execution of some XCM with up to `weight` picoseconds of execution time, paying for this with
-	/// up to `fees` from the holding register.
+	/// Pay for the execution of some XCM `instructions` and `orders` with up to `weight` picoseconds of execution time,
+	/// paying for this with up to `fees` from the Holding Register.
 	///
 	/// - `fees`: The asset(s) to remove from holding to pay for fees.
-	///
+	/// - `weight`: The amount of weight to purchase; this should be at least the shallow weight of `effects` and `xcm`.
+	/// - `debt`: The amount of weight-debt already incurred to be pay off; this should be equal to the unpaid weight of
+	///   any surrounding operations/orders.
+	/// - `halt_on_error`: If `true`, the execution of the `orders` and `operations` will halt on the first failure. If
+	///   `false`, then execution will continue regardless.
+	/// - `orders`: Orders to be executed with the existing Holding Register; execution of these orders happens PRIOR to
+	///   execution of the `operations`. The (shallow) weight for these must be paid for with the `weight` purchased.
+	/// - `instructions`: XCM instructions to be executed outside of the context of the current Holding Register;
+	///   execution of these instructions happens AFTER the execution of the `orders`. The (shallow) weight for these
+	///   must be paid for with the `weight` purchased.
 	/// Errors:
 	#[codec(index = 7)]
 	BuyExecution {
@@ -132,7 +146,8 @@ pub enum Order<Call> {
 		weight: u64,
 		debt: u64,
 		halt_on_error: bool,
-		xcm: Vec<Xcm<Call>>,
+		orders: Vec<Order<Call>>,
+		instructions: Vec<Xcm<Call>>,
 	},
 }
 
@@ -148,7 +163,8 @@ impl<Call> Order<Call> {
 		use Order::*;
 		match order {
 			Noop => Noop,
-			DepositAsset { assets, max_assets, beneficiary } => DepositAsset { assets, max_assets, beneficiary },
+			DepositAsset { assets, max_assets, beneficiary } =>
+				DepositAsset { assets, max_assets, beneficiary },
 			DepositReserveAsset { assets, max_assets, dest, effects } =>
 				DepositReserveAsset { assets, max_assets, dest, effects },
 			ExchangeAsset { give, receive } => ExchangeAsset { give, receive },
@@ -157,9 +173,10 @@ impl<Call> Order<Call> {
 			InitiateTeleport { assets, dest, effects } =>
 				InitiateTeleport { assets, dest, effects },
 			QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest, assets },
-			BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
-				let xcm = xcm.into_iter().map(Xcm::from).collect();
-				BuyExecution { fees, weight, debt, halt_on_error, xcm }
+			BuyExecution { fees, weight, debt, halt_on_error, orders, instructions } => {
+				let orders = orders.into_iter().map(Order::from).collect();
+				let instructions = instructions.into_iter().map(Xcm::from).collect();
+				BuyExecution { fees, weight, debt, halt_on_error, orders, instructions }
 			},
 		}
 	}
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 86ad5ccc7720..0f250ddbb954 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -45,7 +45,8 @@ fn weigher_should_work() {
 				weight: 0,
 				debt: 30,
 				halt_on_error: true,
-				xcm: vec![],
+				orders: vec![],
+				instructions: vec![],
 			},
 			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
@@ -117,7 +118,7 @@ fn allow_paid_should_work() {
 	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::BuyExecution { fees, weight: 0, debt: 20, halt_on_error: true, xcm: vec![] },
+			Order::BuyExecution { fees, weight: 0, debt: 20, halt_on_error: true, orders: vec![], instructions: vec![] },
 			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	};
@@ -135,7 +136,7 @@ fn allow_paid_should_work() {
 	let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::BuyExecution { fees, weight: 0, debt: 30, halt_on_error: true, xcm: vec![] },
+			Order::BuyExecution { fees, weight: 0, debt: 30, halt_on_error: true, orders: vec![], instructions: vec![] },
 			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	};
@@ -175,9 +176,14 @@ fn paying_reserve_deposit_should_work() {
 				weight: 0,
 				debt: 30,
 				halt_on_error: true,
-				xcm: vec![],
+				orders: vec![],
+				instructions: vec![],
+			},
+			Order::<TestCall>::DepositAsset {
+				assets: All.into(),
+				max_assets: 1,
+				beneficiary: Here,
 			},
-			Order::<TestCall>::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	};
 	let weight_limit = 50;
@@ -222,7 +228,11 @@ fn reserve_transfer_should_work() {
 		Xcm::TransferReserveAsset {
 			assets: (Here, 100).into(),
 			dest: X1(Parachain(2)),
-			effects: vec![Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: three.clone() }],
+			effects: vec![Order::DepositAsset {
+				assets: All.into(),
+				max_assets: 1,
+				beneficiary: three.clone(),
+			}],
 		},
 		50,
 	);
@@ -235,7 +245,11 @@ fn reserve_transfer_should_work() {
 			X1(Parachain(2)),
 			Xcm::ReserveAssetDeposited {
 				assets: (X1(Parent), 100).into(),
-				effects: vec![Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: three }],
+				effects: vec![Order::DepositAsset {
+					assets: All.into(),
+					max_assets: 1,
+					beneficiary: three
+				}],
 			}
 		)]
 	);
@@ -303,14 +317,19 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 				weight: 70,
 				debt: 30,
 				halt_on_error: true,
-				xcm: vec![Xcm::<TestCall>::Transact {
+				orders: vec![],
+				instructions: vec![Xcm::<TestCall>::Transact {
 					origin_type: OriginKind::Native,
 					require_weight_at_most: 60,
 					// call estimated at 70 but only takes 10.
 					call: TestCall::Any(60, Some(10)).encode().into(),
 				}],
 			},
-			Order::<TestCall>::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: one.clone() },
+			Order::<TestCall>::DepositAsset {
+				assets: All.into(),
+				max_assets: 1,
+				beneficiary: one.clone(),
+			},
 		],
 	};
 	let weight_limit = 100;
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index 5e197fee89fa..679aa0928216 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -38,21 +38,11 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeigh
 			Xcm::WithdrawAsset { effects, .. } |
 			Xcm::ReserveAssetDeposited { effects, .. } |
 			Xcm::ReceiveTeleportedAsset { effects, .. } => {
-				let inner: Weight = effects
-					.iter_mut()
-					.map(|effect| match effect {
-						Order::BuyExecution { .. } => {
-							// On success, execution of this will result in more weight being consumed but
-							// we don't count it here since this is only the *shallow*, non-negotiable weight
-							// spend and doesn't count weight placed behind a `BuyExecution` since it will not
-							// be definitely consumed from any existing weight credit if execution of the message
-							// is attempted.
-							T::get()
-						},
-						_ => T::get(),
-					})
-					.sum();
-				T::get().saturating_add(inner)
+				let mut extra = T::get();
+				for order in effects.iter_mut() {
+					extra.saturating_accrue(Self::shallow_order(order)?);
+				}
+				extra
 			},
 			_ => T::get(),
 		})
@@ -64,16 +54,43 @@ impl<T: Get<Weight>, C: Decode + GetDispatchInfo> WeightBounds<C> for FixedWeigh
 			Xcm::ReserveAssetDeposited { effects, .. } |
 			Xcm::ReceiveTeleportedAsset { effects, .. } => {
 				let mut extra = 0;
-				for effect in effects.iter_mut() {
-					match effect {
-						Order::BuyExecution { xcm, .. } =>
-							for message in xcm.iter_mut() {
-								extra.saturating_accrue(
-									Self::shallow(message)?.saturating_add(Self::deep(message)?),
-								);
-							},
-						_ => {},
-					}
+				for order in effects.iter_mut() {
+					extra.saturating_accrue(Self::deep_order(order)?);
+				}
+				extra
+			},
+			_ => 0,
+		})
+	}
+}
+
+impl<T: Get<Weight>, C: Decode + GetDispatchInfo> FixedWeightBounds<T, C> {
+	fn shallow_order(order: &mut Order<C>) -> Result<Weight, ()> {
+		Ok(match order {
+			Order::BuyExecution { .. } => {
+				// On success, execution of this will result in more weight being consumed but
+				// we don't count it here since this is only the *shallow*, non-negotiable weight
+				// spend and doesn't count weight placed behind a `BuyExecution` since it will not
+				// be definitely consumed from any existing weight credit if execution of the message
+				// is attempted.
+				T::get()
+			},
+			_ => T::get(),
+		})
+	}
+	fn deep_order(order: &mut Order<C>) -> Result<Weight, ()> {
+		Ok(match order {
+			Order::BuyExecution { orders, instructions, .. } => {
+				let mut extra = 0;
+				for instruction in instructions.iter_mut() {
+					extra.saturating_accrue(
+						Self::shallow(instruction)?.saturating_add(Self::deep(instruction)?),
+					);
+				}
+				for order in orders.iter_mut() {
+					extra.saturating_accrue(
+						Self::shallow_order(order)?.saturating_add(Self::deep_order(order)?),
+					);
 				}
 				extra
 			},
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 6a939935b46d..f90e4b0a0e03 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -240,26 +240,27 @@ impl Assets {
 	) -> Result<Assets, TakeError> {
 		let mut taken = Assets::new();
 		match mask {
-			MultiAssetFilter::Wild(All) => if self.fungible.len() + self.non_fungible.len() <= limit {
-				return Ok(self.swapped(Assets::new()))
-			} else {
-				let fungible = mem::replace(&mut self.fungible, Default::default());
-				fungible.into_iter().for_each(|(c, amount)| {
-					if taken.len() < limit {
-						taken.fungible.insert(c, amount);
-					} else {
-						self.fungible.insert(c, amount);
-					}
-				});
-				let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
-				non_fungible.into_iter().for_each(|(c, instance)| {
-					if taken.len() < limit {
-						taken.non_fungible.insert((c, instance));
-					} else {
-						self.non_fungible.insert((c, instance));
-					}
-				});
-			},
+			MultiAssetFilter::Wild(All) =>
+				if self.fungible.len() + self.non_fungible.len() <= limit {
+					return Ok(self.swapped(Assets::new()))
+				} else {
+					let fungible = mem::replace(&mut self.fungible, Default::default());
+					fungible.into_iter().for_each(|(c, amount)| {
+						if taken.len() < limit {
+							taken.fungible.insert(c, amount);
+						} else {
+							self.fungible.insert(c, amount);
+						}
+					});
+					let non_fungible = mem::replace(&mut self.non_fungible, Default::default());
+					non_fungible.into_iter().for_each(|(c, instance)| {
+						if taken.len() < limit {
+							taken.non_fungible.insert((c, instance));
+						} else {
+							self.non_fungible.insert((c, instance));
+						}
+					});
+				},
 			MultiAssetFilter::Wild(AllOf { fun: WildFungible, id }) => {
 				if let Some((id, amount)) = self.fungible.remove_entry(&id) {
 					taken.fungible.insert(id, amount);
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index e59aa54a1fd8..88fe03ad27d7 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -247,28 +247,28 @@ impl<Config: config::Config> XcmExecutor<Config> {
 
 		if let Some((mut holding, effects)) = maybe_holding_effects {
 			for effect in effects.into_iter() {
-				total_surplus += Self::execute_effects(&origin, &mut holding, effect, trader)?;
+				total_surplus += Self::execute_orders(&origin, &mut holding, effect, trader)?;
 			}
 		}
 
 		Ok(total_surplus)
 	}
 
-	fn execute_effects(
+	fn execute_orders(
 		origin: &MultiLocation,
 		holding: &mut Assets,
-		effect: Order<Config::Call>,
+		order: Order<Config::Call>,
 		trader: &mut Config::Trader,
 	) -> Result<Weight, XcmError> {
 		log::trace!(
-			target: "xcm::execute_effects",
+			target: "xcm::execute_orders",
 			"origin: {:?}, holding: {:?}, effect: {:?}",
 			origin,
 			holding,
-			effect,
+			order,
 		);
 		let mut total_surplus = 0;
-		match effect {
+		match order {
 			Order::DepositAsset { assets, max_assets, beneficiary } => {
 				let deposited = holding.limited_saturating_take(assets, max_assets as usize);
 				for asset in deposited.into_assets_iter() {
@@ -303,7 +303,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 					Xcm::QueryResponse { query_id, response: Response::Assets(assets) },
 				)?;
 			},
-			Order::BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
+			Order::BuyExecution { fees, weight, debt, halt_on_error, orders, instructions } => {
 				// pay for `weight` using up to `fees` of the holding register.
 				let purchasing_weight =
 					Weight::from(weight.checked_add(debt).ok_or(XcmError::Overflow)?);
@@ -313,11 +313,23 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				holding.subsume_assets(unspent);
 
 				let mut remaining_weight = weight;
-				for message in xcm.into_iter() {
+				for order in orders.into_iter() {
+					match Self::execute_orders(
+						origin,
+						holding,
+						order,
+						trader,
+					) {
+						Err(e) if halt_on_error => return Err(e),
+						Err(_) => {},
+						Ok(surplus) => total_surplus += surplus,
+					}
+				}
+				for instruction in instructions.into_iter() {
 					match Self::do_execute_xcm(
 						origin.clone(),
 						false,
-						message,
+						instruction,
 						&mut remaining_weight,
 						None,
 						trader,

From 851b00e8139c8b2762ff82843a722d207caac3a4 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 17:00:05 +0200
Subject: [PATCH 080/166] Fix XCM extrinsics

---
 runtime/kusama/src/lib.rs                    |  1 +
 runtime/rococo/src/lib.rs                    |  1 +
 runtime/westend/src/lib.rs                   |  1 +
 xcm/pallet-xcm/src/lib.rs                    | 36 +++++++++++++++-----
 xcm/pallet-xcm/src/mock.rs                   |  5 +--
 xcm/pallet-xcm/src/tests.rs                  | 10 +++---
 xcm/src/v1/multiasset.rs                     | 16 +++++++++
 xcm/xcm-builder/src/tests.rs                 | 18 ++++++++--
 xcm/xcm-executor/src/lib.rs                  |  7 +---
 xcm/xcm-simulator/example/src/lib.rs         |  6 ++--
 xcm/xcm-simulator/example/src/parachain.rs   |  1 +
 xcm/xcm-simulator/example/src/relay_chain.rs |  1 +
 12 files changed, 78 insertions(+), 25 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index 6fc6b8ac3524..32a5455b8d13 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1323,6 +1323,7 @@ impl pallet_xcm::Config for Runtime {
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
+	type LocationInverter = LocationInverter<Ancestry>;
 }
 
 parameter_types! {
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index f05de3d26771..c82e777f7f02 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -695,6 +695,7 @@ impl pallet_xcm::Config for Runtime {
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
+	type LocationInverter = LocationInverter<Ancestry>;
 }
 
 impl parachains_session_info::Config for Runtime {}
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index d0304022c602..9944efa1f5f4 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -956,6 +956,7 @@ impl pallet_xcm::Config for Runtime {
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
+	type LocationInverter = LocationInverter<Ancestry>;
 }
 
 construct_runtime! {
diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index bbbcfe1163b3..779898a604bb 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -39,7 +39,7 @@ pub mod pallet {
 	use frame_support::pallet_prelude::*;
 	use frame_system::pallet_prelude::*;
 	use sp_runtime::traits::AccountIdConversion;
-	use xcm_executor::traits::WeightBounds;
+	use xcm_executor::traits::{WeightBounds, InvertLocation};
 
 	#[pallet::pallet]
 	#[pallet::generate_store(pub(super) trait Store)]
@@ -77,6 +77,9 @@ pub mod pallet {
 
 		/// Means of measuring the weight consumed by an XCM message locally.
 		type Weigher: WeightBounds<Self::Call>;
+
+		/// Means of inverting a location.
+		type LocationInverter: InvertLocation;
 	}
 
 	#[pallet::event]
@@ -96,6 +99,8 @@ pub mod pallet {
 		UnweighableMessage,
 		/// The assets to be sent are empty.
 		Empty,
+		/// Could not reanchor the assets to declare the fees for the destination chain.
+		CannotReanchor,
 	}
 
 	#[pallet::hooks]
@@ -143,13 +148,20 @@ pub mod pallet {
 			dest: MultiLocation,
 			beneficiary: MultiLocation,
 			assets: MultiAssets,
+			fee_asset_item: u32,
 			dest_weight: Weight,
 		) -> DispatchResult {
 			let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
 			let value = (origin_location, assets.drain());
 			ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
 			let (origin_location, assets) = value;
-			let fees = assets.first().ok_or(Error::<T>::Empty)?.clone();
+			let inv_dest = T::LocationInverter::invert_location(&dest);
+			let fees = assets.get(fee_asset_item as usize)
+				.ok_or(Error::<T>::Empty)?
+				.clone()
+				.reanchored(&inv_dest)
+				.map_err(|_| Error::<T>::CannotReanchor)?;
+			let max_assets = assets.len() as u32;
 			let assets = assets.into();
 			let mut message = Xcm::WithdrawAsset {
 				assets,
@@ -166,7 +178,7 @@ pub mod pallet {
 							orders: vec![],
 							instructions: vec![],
 						},
-						DepositAsset { assets: Wild(All), max_assets: 1, beneficiary },
+						DepositAsset { assets: Wild(All), max_assets, beneficiary },
 					],
 				}],
 			};
@@ -203,13 +215,21 @@ pub mod pallet {
 			dest: MultiLocation,
 			beneficiary: MultiLocation,
 			assets: MultiAssets,
+			fee_asset_item: u32,
 			dest_weight: Weight,
 		) -> DispatchResult {
 			let origin_location = T::ExecuteXcmOrigin::ensure_origin(origin)?;
 			let value = (origin_location, assets.drain());
 			ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
-			let (origin_location, assets) = value;
-			let fees = assets.first().ok_or(Error::<T>::Empty)?.clone();
+			let (origin_location, mut assets) = value;
+			let inv_dest = T::LocationInverter::invert_location(&dest);
+			let fees = assets.get(fee_asset_item as usize)
+				.ok_or(Error::<T>::Empty)?
+				.clone()
+				.reanchored(&inv_dest)
+				.map_err(|_| Error::<T>::CannotReanchor)?;
+			let max_assets = assets.len() as u32;
+			assets.sort();
 			let assets = assets.into();
 			let mut message = Xcm::TransferReserveAsset {
 				assets,
@@ -217,14 +237,14 @@ pub mod pallet {
 				effects: vec![
 					BuyExecution {
 						fees,
-						// Zero weight for additional XCM (since there are none to execute)
+						// Zero weight for additional instructions/orders (since there are none to execute)
 						weight: 0,
-						debt: dest_weight,
+						debt: dest_weight,	// covers this, `TransferReserveAsset` xcm, and `DepositAsset` order.
 						halt_on_error: false,
 						orders: vec![],
 						instructions: vec![],
 					},
-					DepositAsset { assets: Wild(All), max_assets: 1, beneficiary },
+					DepositAsset { assets: Wild(All), max_assets, beneficiary },
 				],
 			};
 			let weight =
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index 50a2471d74d7..ca143ce11db0 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -186,6 +186,7 @@ impl pallet_xcm::Config for Test {
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
+	type LocationInverter = LocationInverter<Ancestry>;
 }
 
 impl origin::Config for Test {}
@@ -194,10 +195,10 @@ pub(crate) fn last_event() -> Event {
 	System::events().pop().expect("Event expected").event
 }
 
-pub(crate) fn buy_execution<C>(debt: Weight) -> Order<C> {
+pub(crate) fn buy_execution<C>(fees: impl Into<MultiAsset>, debt: Weight) -> Order<C> {
 	use xcm::opaque::v1::prelude::*;
 	Order::BuyExecution {
-		fees: (RelayLocation::get(), 10).into(),
+		fees: fees.into(),
 		weight: 0,
 		debt,
 		halt_on_error: false,
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index dd86ca3a05e0..f10e0490484d 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -42,7 +42,7 @@ fn send_works() {
 		let message = Xcm::ReserveAssetDeposited {
 			assets: (X1(Parent), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution(weight),
+				buy_execution((Parent, SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -76,7 +76,7 @@ fn send_fails_when_xcm_router_blocks() {
 		let message = Xcm::ReserveAssetDeposited {
 			assets: (Parent, SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution(weight),
+				buy_execution((Parent, SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -116,6 +116,7 @@ fn teleport_assets_works() {
 			RelayLocation::get(),
 			X1(AccountId32 { network: Any, id: BOB.into() }),
 			(Here, SEND_AMOUNT).into(),
+			0,
 			weight,
 		));
 		assert_eq!(Balances::total_balance(&ALICE), INITIAL_BALANCE - SEND_AMOUNT);
@@ -144,6 +145,7 @@ fn reserve_transfer_assets_works() {
 			Parachain(PARA_ID).into(),
 			dest.clone(),
 			(Here, SEND_AMOUNT).into(),
+			0,
 			weight
 		));
 		// Alice spent amount
@@ -158,7 +160,7 @@ fn reserve_transfer_assets_works() {
 				Xcm::ReserveAssetDeposited {
 					assets: (X1(Parent), SEND_AMOUNT).into(),
 					effects: vec![
-						buy_execution(weight),
+						buy_execution((Parent, SEND_AMOUNT), weight),
 						DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
 					]
 				}
@@ -189,7 +191,7 @@ fn execute_withdraw_to_deposit_works() {
 			Box::new(Xcm::WithdrawAsset {
 				assets: (Here, SEND_AMOUNT).into(),
 				effects: vec![
-					buy_execution(weight),
+					buy_execution((Here, SEND_AMOUNT), weight),
 					DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }
 				],
 			}),
diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index cc0672b2d2d8..dc3c4641e232 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -217,6 +217,12 @@ impl MultiAsset {
 		self.id.reanchor(prepend)
 	}
 
+	/// Prepend a `MultiLocation` to a concrete asset, giving it a new root location.
+	pub fn reanchored(mut self, prepend: &MultiLocation) -> Result<Self, ()> {
+		self.reanchor(prepend)?;
+		Ok(self)
+	}
+
 	/// Returns true if `self` is a super-set of the given `inner`.
 	pub fn contains(&self, inner: &MultiAsset) -> bool {
 		use Fungibility::*;
@@ -307,10 +313,20 @@ impl MultiAssets {
 		&self.0
 	}
 
+	/// Return the number of distinct asset instances contained.
+	pub fn len(&self) -> usize {
+		self.0.len()
+	}
+
 	/// Prepend a `MultiLocation` to any concrete asset items, giving it a new root location.
 	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
 		self.0.iter_mut().try_for_each(|i| i.reanchor(prepend))
 	}
+
+	/// Return a reference to an item at a specific index or `None` if it doesn't exist.
+	pub fn get(&self, index: usize) -> Option<&MultiAsset> {
+		self.0.get(index)
+	}
 }
 /// Classification of whether an asset is fungible or not, along with an optional amount or instance.
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 0f250ddbb954..8f95687f29cf 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -118,7 +118,14 @@ fn allow_paid_should_work() {
 	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::BuyExecution { fees, weight: 0, debt: 20, halt_on_error: true, orders: vec![], instructions: vec![] },
+			Order::BuyExecution {
+				fees,
+				weight: 0,
+				debt: 20,
+				halt_on_error: true,
+				orders: vec![],
+				instructions: vec![],
+			},
 			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	};
@@ -136,7 +143,14 @@ fn allow_paid_should_work() {
 	let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
 		assets: (X1(Parent), 100).into(),
 		effects: vec![
-			Order::BuyExecution { fees, weight: 0, debt: 30, halt_on_error: true, orders: vec![], instructions: vec![] },
+			Order::BuyExecution {
+				fees,
+				weight: 0,
+				debt: 30,
+				halt_on_error: true,
+				orders: vec![],
+				instructions: vec![],
+			},
 			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
 		],
 	};
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index 88fe03ad27d7..c30c5d3f9a77 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -314,12 +314,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 
 				let mut remaining_weight = weight;
 				for order in orders.into_iter() {
-					match Self::execute_orders(
-						origin,
-						holding,
-						order,
-						trader,
-					) {
+					match Self::execute_orders(origin, holding, order, trader) {
 						Err(e) if halt_on_error => return Err(e),
 						Err(_) => {},
 						Ok(surplus) => total_surplus += surplus,
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 12e39a51e30f..a02aeaaff456 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -17,10 +17,9 @@
 mod parachain;
 mod relay_chain;
 
-use sp_runtime::AccountId32;
 use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain};
 
-pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]);
+pub const ALICE: sp_runtime::AccountId32 = sp_runtime::AccountId32::new([0u8; 32]);
 
 decl_test_parachain! {
 	pub struct ParaA {
@@ -194,7 +193,8 @@ mod tests {
 				X1(Parachain(1)),
 				X1(AccountId32 { network: Any, id: ALICE.into() }),
 				(Here, 123).into(),
-				123,
+				0,
+				3,
 			));
 		});
 
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 4e870abb0315..3e7212c48fa4 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -293,6 +293,7 @@ impl pallet_xcm::Config for Runtime {
 	type XcmTeleportFilter = ();
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type Weigher = FixedWeightBounds<UnitWeightCost, Call>;
+	type LocationInverter = LocationInverter<Ancestry>;
 }
 
 type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index e691e3e7ad35..adbf0b965f41 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -147,6 +147,7 @@ impl pallet_xcm::Config for Runtime {
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type Weigher = FixedWeightBounds<BaseXcmWeight, Call>;
+	type LocationInverter = LocationInverter<Ancestry>;
 }
 
 parameter_types! {

From 20bb7140a0eec64d2416d3dd0fc9e0fdc2283db2 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 17:04:34 +0200
Subject: [PATCH 081/166] fmt

---
 xcm/pallet-xcm/src/lib.rs | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 779898a604bb..b6742e9b58d0 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -39,7 +39,7 @@ pub mod pallet {
 	use frame_support::pallet_prelude::*;
 	use frame_system::pallet_prelude::*;
 	use sp_runtime::traits::AccountIdConversion;
-	use xcm_executor::traits::{WeightBounds, InvertLocation};
+	use xcm_executor::traits::{InvertLocation, WeightBounds};
 
 	#[pallet::pallet]
 	#[pallet::generate_store(pub(super) trait Store)]
@@ -156,7 +156,8 @@ pub mod pallet {
 			ensure!(T::XcmTeleportFilter::contains(&value), Error::<T>::Filtered);
 			let (origin_location, assets) = value;
 			let inv_dest = T::LocationInverter::invert_location(&dest);
-			let fees = assets.get(fee_asset_item as usize)
+			let fees = assets
+				.get(fee_asset_item as usize)
 				.ok_or(Error::<T>::Empty)?
 				.clone()
 				.reanchored(&inv_dest)
@@ -223,7 +224,8 @@ pub mod pallet {
 			ensure!(T::XcmReserveTransferFilter::contains(&value), Error::<T>::Filtered);
 			let (origin_location, mut assets) = value;
 			let inv_dest = T::LocationInverter::invert_location(&dest);
-			let fees = assets.get(fee_asset_item as usize)
+			let fees = assets
+				.get(fee_asset_item as usize)
 				.ok_or(Error::<T>::Empty)?
 				.clone()
 				.reanchored(&inv_dest)
@@ -239,7 +241,7 @@ pub mod pallet {
 						fees,
 						// Zero weight for additional instructions/orders (since there are none to execute)
 						weight: 0,
-						debt: dest_weight,	// covers this, `TransferReserveAsset` xcm, and `DepositAsset` order.
+						debt: dest_weight, // covers this, `TransferReserveAsset` xcm, and `DepositAsset` order.
 						halt_on_error: false,
 						orders: vec![],
 						instructions: vec![],

From 3f85ebd8de67c8bc27a2cefceb1e72bac5fad608 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 17:58:34 +0200
Subject: [PATCH 082/166] Make Vec<MultiAsset>/MultiAssets conversions safe

---
 xcm/src/v1/multiasset.rs | 66 +++++++++++++++++++++++++++++-----------
 1 file changed, 49 insertions(+), 17 deletions(-)

diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index dc3c4641e232..ea7d17212749 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -243,27 +243,40 @@ pub struct MultiAssets(Vec<MultiAsset>);
 
 impl Decode for MultiAssets {
 	fn decode<I: codec::Input>(input: &mut I) -> Result<Self, parity_scale_codec::Error> {
-		let r = Vec::<MultiAsset>::decode(input)?;
-		if r.is_empty() {
-			return Ok(Self(Vec::new()))
-		}
-		r.iter().skip(1).try_fold(
-			&r[0],
-			|a, b| -> Result<&MultiAsset, parity_scale_codec::Error> {
-				if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) {
-					Ok(b)
-				} else {
-					Err("Out of order".into())
-				}
-			},
-		)?;
-		Ok(Self(r))
+		Self::from_sorted_and_deduplicated(Vec::<MultiAsset>::decode(input)?)
+			.map_err(|()| "Out of order".into())
 	}
 }
 
 impl From<Vec<MultiAsset>> for MultiAssets {
-	fn from(x: Vec<MultiAsset>) -> Self {
-		Self(x)
+	fn from(mut assets: Vec<MultiAsset>) -> Self {
+		let mut res = Vec::with_capacity(assets.len());
+		if !assets.is_empty() {
+			assets.sort();
+			let mut iter = assets.into_iter();
+			if let Some(first) = iter.next() {
+				let last = iter.fold(first, |a, b| -> MultiAsset {
+					match (a, b) {
+						(
+							MultiAsset { fun: Fungibility::Fungible(a_amount), id: a_id },
+							MultiAsset { fun: Fungibility::Fungible(b_amount), id: b_id },
+						) if a_id == b_id =>
+							MultiAsset { id: a_id, fun: Fungibility::Fungible(a_amount + b_amount) },
+						(
+							MultiAsset { fun: Fungibility::NonFungible(a_instance), id: a_id },
+							MultiAsset { fun: Fungibility::NonFungible(b_instance), id: b_id },
+						) if a_id == b_id && a_instance == b_instance =>
+							MultiAsset { fun: Fungibility::NonFungible(a_instance), id: a_id },
+						(to_push, to_remember) => {
+							res.push(to_push);
+							to_remember
+						},
+					}
+				});
+				res.push(last);
+			}
+		}
+		Self(res)
 	}
 }
 
@@ -279,6 +292,25 @@ impl MultiAssets {
 		Self(Vec::new())
 	}
 
+	/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
+	/// which contain no duplicates.
+	///
+	/// Returns `Ok` if the operation succeeds and `Err` if `r` is out of order or had duplicates. If you can't
+	/// guarantee that `r` is sorted and deduplicated, then use `From::<Vec<MultiAsset>>::from` which is infallible.
+	pub fn from_sorted_and_deduplicated(r: Vec<MultiAsset>) -> Result<Self, ()> {
+		if r.is_empty() {
+			return Ok(Self(Vec::new()))
+		}
+		r.iter().skip(1).try_fold(&r[0], |a, b| -> Result<&MultiAsset, ()> {
+			if a.id < b.id || a < b && (a.is_non_fungible(None) || b.is_non_fungible(None)) {
+				Ok(b)
+			} else {
+				Err(())
+			}
+		})?;
+		Ok(Self(r))
+	}
+
 	/// Add some asset onto the list. This is quite a laborious operation since it maintains the ordering.
 	pub fn push(&mut self, a: MultiAsset) {
 		if let Fungibility::Fungible(ref amount) = a.fun {

From 61a2231c2fba6bc9579e27b24076dd8a4f543f7a Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 18:07:41 +0200
Subject: [PATCH 083/166] More MultiAssets conversion safety

---
 xcm/src/v1/multiasset.rs | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index ea7d17212749..7b90b8581984 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -311,6 +311,27 @@ impl MultiAssets {
 		Ok(Self(r))
 	}
 
+	/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
+	/// which contain no duplicates.
+	///
+	/// In release mode, this skips any checks to ensure that `r` is correct, making it a negligible-cost operation.
+	/// Generally though you should avoid using it unless you have a strict proof that `r` is valid.
+	#[cfg(test)]
+	pub fn from_sorted_and_deduplicated_skip_checks(r: Vec<MultiAsset>) -> Self {
+		Self::from_sorted_and_deduplicated(r).expect("Invalid input r is not sorted/deduped")
+	}
+	/// Create a new instance of `MultiAssets` from a `Vec<MultiAsset>` whose contents are sorted and
+	/// which contain no duplicates.
+	///
+	/// In release mode, this skips any checks to ensure that `r` is correct, making it a negligible-cost operation.
+	/// Generally though you should avoid using it unless you have a strict proof that `r` is valid.
+	///
+	/// In test mode, this checks anyway and panics on fail.
+	#[cfg(not(test))]
+	pub fn from_sorted_and_deduplicated_skip_checks(r: Vec<MultiAsset>) -> Self {
+		Self(r)
+	}
+
 	/// Add some asset onto the list. This is quite a laborious operation since it maintains the ordering.
 	pub fn push(&mut self, a: MultiAsset) {
 		if let Fungibility::Fungible(ref amount) = a.fun {

From 86442655ad27960910cee7e6ed5ec64977eb4849 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 19:12:37 +0200
Subject: [PATCH 084/166] spelling

---
 xcm/src/v1/order.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index 6a2b04e9acf3..f311b5f9bf05 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -36,7 +36,7 @@ pub enum Order<Call> {
 	///
 	/// - `assets`: The asset(s) to remove from holding.
 	/// - `max_assets`: The maximum number of unique assets/asset instances to remove from holding. Only the first
-	///   `max_assets` assets/instances of those matched by `assets` will be removed, prioritised under standard asset
+	///   `max_assets` assets/instances of those matched by `assets` will be removed, prioritized under standard asset
 	///   ordering. Any others will remain in holding.
 	/// - `beneficiary`: The new owner for the assets.
 	///
@@ -51,7 +51,7 @@ pub enum Order<Call> {
 	///
 	/// - `assets`: The asset(s) to remove from holding.
 	/// - `max_assets`: The maximum number of unique assets/asset instances to remove from holding. Only the first
-	///   `max_assets` assets/instances of those matched by `assets` will be removed, prioritised under standard asset
+	///   `max_assets` assets/instances of those matched by `assets` will be removed, prioritized under standard asset
 	///   ordering. Any others will remain in holding.
 	/// - `dest`: The location whose sovereign account will own the assets and thus the effective beneficiary for the
 	///   assets and the notification target for the reserve asset deposit message.

From 1e75953246dab079422496ad8de9659d2a483f6f Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Wed, 4 Aug 2021 19:14:40 +0200
Subject: [PATCH 085/166] fix doc test

---
 xcm/xcm-executor/src/assets.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index f90e4b0a0e03..212f60cdc9b6 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -378,7 +378,7 @@ impl Assets {
 	/// use xcm_executor::Assets;
 	/// use xcm::v1::prelude::*;
 	/// let assets_i_have: Assets = vec![ (Here, 100).into(), (vec![0], 100).into() ].into();
-	/// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), (vec![0], 50).into() [.into();
+	/// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), (vec![0], 50).into() ].into();
 	///
 	/// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want);
 	/// assert_eq!(assets_we_can_trade.into_assets_iter().collect::<Vec<_>>(), vec![

From 669dcb0ff9f441267c3fd2cbb3066c7f1c863ca6 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 11:14:39 +0200
Subject: [PATCH 086/166] Apply suggestions from code review

Co-authored-by: Amar Singh <asinghchrony@protonmail.com>
---
 xcm/src/lib.rs                 |  2 +-
 xcm/src/v1/multiasset.rs       | 10 ++--------
 xcm/src/v1/order.rs            |  2 +-
 xcm/xcm-executor/src/assets.rs |  4 ++++
 4 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index e7d31a2a7d74..d7d318225200 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -73,7 +73,7 @@ impl<Call> TryFrom<VersionedXcm<Call>> for v1::Xcm<Call> {
 
 pub mod opaque {
 	pub mod v1 {
-		// Everything from v0
+		// Everything from v1
 		pub use crate::v1::*;
 		// Then override with the opaque types in v0
 		pub use crate::v1::opaque::{Order, Xcm};
diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index 7b90b8581984..61a82b7c32e1 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -34,7 +34,7 @@ use parity_scale_codec::{self as codec, Decode, Encode};
 /// A general identifier for an instance of a non-fungible asset class.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
 pub enum AssetInstance {
-	/// Undefined - used if the NFA class has only one instance.
+	/// Undefined - used if the non-fungible asset class has only one instance.
 	Undefined,
 
 	/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
@@ -63,12 +63,6 @@ impl From<()> for AssetInstance {
 	}
 }
 
-/*impl From<u128> for AssetInstance {
-	fn from(x: u128) -> Self {
-		Self::Index(x)
-	}
-}*/
-
 impl From<[u8; 4]> for AssetInstance {
 	fn from(x: [u8; 4]) -> Self {
 		Self::Array4(x)
@@ -381,7 +375,7 @@ impl MultiAssets {
 		self.0.get(index)
 	}
 }
-/// Classification of whether an asset is fungible or not, along with an optional amount or instance.
+/// Classification of whether an asset is fungible or not.
 #[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum WildFungibility {
 	Fungible,
diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index f311b5f9bf05..0c92e5c4ce8c 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -130,7 +130,7 @@ pub enum Order<Call> {
 	///
 	/// - `fees`: The asset(s) to remove from holding to pay for fees.
 	/// - `weight`: The amount of weight to purchase; this should be at least the shallow weight of `effects` and `xcm`.
-	/// - `debt`: The amount of weight-debt already incurred to be pay off; this should be equal to the unpaid weight of
+	/// - `debt`: The amount of weight-debt already incurred to be paid off; this should be equal to the unpaid weight of
 	///   any surrounding operations/orders.
 	/// - `halt_on_error`: If `true`, the execution of the `orders` and `operations` will halt on the first failure. If
 	///   `false`, then execution will continue regardless.
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 212f60cdc9b6..adc48b899d23 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -428,18 +428,22 @@ mod tests {
 	use xcm::v1::prelude::*;
 	use MultiLocation::Here;
 	#[allow(non_snake_case)]
+  /// Abstract fungible constructor
 	fn AF(id: u8, amount: u128) -> MultiAsset {
 		(vec![id], amount).into()
 	}
 	#[allow(non_snake_case)]
+  /// Abstract non-fungible constructor
 	fn ANF(class: u8, instance_id: u8) -> MultiAsset {
 		(vec![class], vec![instance_id]).into()
 	}
 	#[allow(non_snake_case)]
+  /// Concrete fungible constructor
 	fn CF(amount: u128) -> MultiAsset {
 		(Here, amount).into()
 	}
 	#[allow(non_snake_case)]
+  /// Concrete non-fungible constructor
 	fn CNF(instance_id: u8) -> MultiAsset {
 		(Here, [instance_id; 4]).into()
 	}

From 767bdb597970201712757e5149f81e4e44ea4490 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 11:17:20 +0200
Subject: [PATCH 087/166] Apply suggestions from code review

Co-authored-by: Amar Singh <asinghchrony@protonmail.com>
---
 xcm/src/lib.rs           | 2 +-
 xcm/src/v1/mod.rs        | 2 +-
 xcm/src/v1/multiasset.rs | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index d7d318225200..3addd73421e5 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -75,7 +75,7 @@ pub mod opaque {
 	pub mod v1 {
 		// Everything from v1
 		pub use crate::v1::*;
-		// Then override with the opaque types in v0
+		// Then override with the opaque types in v1
 		pub use crate::v1::opaque::{Order, Xcm};
 	}
 
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index c27bb1788069..c78506c5c042 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -148,7 +148,7 @@ pub enum Xcm<Call> {
 	/// - `assets`: The asset(s) that are minted into the Holding Register.
 	/// - `effects`: The order(s) to execute on the Holding Register.
 	///
-	/// Safety: `origin` must be trusted to have irrevocably destroyed the corresponding`assets` prior as a consequence
+	/// Safety: `origin` must be trusted to have irrevocably destroyed the corresponding `assets` prior as a consequence
 	/// of sending this message.
 	///
 	/// Kind: *Trusted Indication*.
diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index 61a82b7c32e1..a52725a58c1a 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -386,7 +386,7 @@ pub enum WildFungibility {
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode, Decode)]
 pub enum WildMultiAsset {
 	/// All assets in the holding register, up to `usize` individual assets (different instances of non-fungibles could
-	/// as separate assets).
+	/// be separate assets).
 	All,
 	/// All assets in the holding register of a given fungibility and ID. If operating on non-fungibles, then a limit
 	/// is provided for the maximum amount of matching instances.

From ec2c1e98345233243e7ca3198457acbcb96b24e2 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 11:26:10 +0200
Subject: [PATCH 088/166] fmt

---
 xcm/xcm-executor/src/assets.rs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index adc48b899d23..f04483f1a6fa 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -428,22 +428,22 @@ mod tests {
 	use xcm::v1::prelude::*;
 	use MultiLocation::Here;
 	#[allow(non_snake_case)]
-  /// Abstract fungible constructor
+	/// Abstract fungible constructor
 	fn AF(id: u8, amount: u128) -> MultiAsset {
 		(vec![id], amount).into()
 	}
 	#[allow(non_snake_case)]
-  /// Abstract non-fungible constructor
+	/// Abstract non-fungible constructor
 	fn ANF(class: u8, instance_id: u8) -> MultiAsset {
 		(vec![class], vec![instance_id]).into()
 	}
 	#[allow(non_snake_case)]
-  /// Concrete fungible constructor
+	/// Concrete fungible constructor
 	fn CF(amount: u128) -> MultiAsset {
 		(Here, amount).into()
 	}
 	#[allow(non_snake_case)]
-  /// Concrete non-fungible constructor
+	/// Concrete non-fungible constructor
 	fn CNF(instance_id: u8) -> MultiAsset {
 		(Here, [instance_id; 4]).into()
 	}

From 740f6f305a9d201e7a90a0ec20002caffa6da0e3 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 11:29:11 +0200
Subject: [PATCH 089/166] Add v0, remove VersionedMultiAsset

---
 xcm/src/lib.rs               |  33 +-
 xcm/src/v0/junction.rs       | 194 +++++++++
 xcm/src/v0/mod.rs            | 331 ++++++++++++++
 xcm/src/v0/multi_asset.rs    | 380 ++++++++++++++++
 xcm/src/v0/multi_location.rs | 820 +++++++++++++++++++++++++++++++++++
 xcm/src/v0/order.rs          | 154 +++++++
 xcm/src/v0/traits.rs         | 261 +++++++++++
 7 files changed, 2148 insertions(+), 25 deletions(-)
 create mode 100644 xcm/src/v0/junction.rs
 create mode 100644 xcm/src/v0/mod.rs
 create mode 100644 xcm/src/v0/multi_asset.rs
 create mode 100644 xcm/src/v0/multi_location.rs
 create mode 100644 xcm/src/v0/order.rs
 create mode 100644 xcm/src/v0/traits.rs

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index 3addd73421e5..0300e8f23c6d 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -51,7 +51,7 @@ impl Decode for Unsupported {
 #[codec(encode_bound())]
 #[codec(decode_bound())]
 pub enum VersionedXcm<Call> {
-	V0(Unsupported),
+	V0(v0::Xcm<Call>),
 	V1(v1::Xcm<Call>),
 }
 
@@ -72,6 +72,12 @@ impl<Call> TryFrom<VersionedXcm<Call>> for v1::Xcm<Call> {
 }
 
 pub mod opaque {
+	pub mod v0 {
+		// Everything from v0
+		pub use crate::v0::*;
+		// Then override with the opaque types in v0
+		pub use crate::v0::opaque::{Order, Xcm};
+	}
 	pub mod v1 {
 		// Everything from v1
 		pub use crate::v1::*;
@@ -90,7 +96,7 @@ pub mod opaque {
 /// A versioned multi-location, a relative location of a cross-consensus system identifier.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum VersionedMultiLocation {
-	V0(v1::MultiLocation),
+	V0(v0::MultiLocation),
 	V1(v1::MultiLocation),
 }
 
@@ -109,26 +115,3 @@ impl TryFrom<VersionedMultiLocation> for v1::MultiLocation {
 		}
 	}
 }
-
-/// A versioned multi-asset, an identifier for an asset within a consensus system.
-#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
-pub enum VersionedMultiAsset {
-	V0(Unsupported),
-	V1(v1::MultiAsset),
-}
-
-impl From<v1::MultiAsset> for VersionedMultiAsset {
-	fn from(x: v1::MultiAsset) -> Self {
-		VersionedMultiAsset::V1(x)
-	}
-}
-
-impl core::convert::TryFrom<VersionedMultiAsset> for v1::MultiAsset {
-	type Error = ();
-	fn try_from(x: VersionedMultiAsset) -> core::result::Result<Self, ()> {
-		match x {
-			VersionedMultiAsset::V1(x) => Ok(x),
-			_ => Err(()),
-		}
-	}
-}
diff --git a/xcm/src/v0/junction.rs b/xcm/src/v0/junction.rs
new file mode 100644
index 000000000000..cf474f62851a
--- /dev/null
+++ b/xcm/src/v0/junction.rs
@@ -0,0 +1,194 @@
+// Copyright 2020 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Support data structures for `MultiLocation`, primarily the `Junction` datatype.
+
+use alloc::vec::Vec;
+use parity_scale_codec::{self, Decode, Encode};
+
+/// A global identifier of an account-bearing consensus system.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum NetworkId {
+	/// Unidentified/any.
+	Any,
+	/// Some named network.
+	Named(Vec<u8>),
+	/// The Polkadot Relay chain
+	Polkadot,
+	/// Kusama.
+	Kusama,
+}
+
+/// An identifier of a pluralistic body.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum BodyId {
+	/// The only body in its context.
+	Unit,
+	/// A named body.
+	Named(Vec<u8>),
+	/// An indexed body.
+	// TODO: parity-scale-codec#262: Change to be a tuple.
+	Index {
+		#[codec(compact)]
+		id: u32,
+	},
+	/// The unambiguous executive body (for Polkadot, this would be the Polkadot council).
+	Executive,
+	/// The unambiguous technical body (for Polkadot, this would be the Technical Committee).
+	Technical,
+	/// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a majority of
+	/// lock-voters).
+	Legislative,
+	/// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a "grand oracle", it
+	/// may be considered as that).
+	Judicial,
+}
+
+/// A part of a pluralistic body.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum BodyPart {
+	/// The body's declaration, under whatever means it decides.
+	Voice,
+	/// A given number of members of the body.
+	Members {
+		#[codec(compact)]
+		count: u32,
+	},
+	/// A given number of members of the body, out of some larger caucus.
+	Fraction {
+		#[codec(compact)]
+		nom: u32,
+		#[codec(compact)]
+		denom: u32,
+	},
+	/// No less than the given proportion of members of the body.
+	AtLeastProportion {
+		#[codec(compact)]
+		nom: u32,
+		#[codec(compact)]
+		denom: u32,
+	},
+	/// More than than the given proportion of members of the body.
+	MoreThanProportion {
+		#[codec(compact)]
+		nom: u32,
+		#[codec(compact)]
+		denom: u32,
+	},
+}
+
+impl BodyPart {
+	/// Returns `true` if the part represents a strict majority (> 50%) of the body in question.
+	pub fn is_majority(&self) -> bool {
+		match self {
+			BodyPart::Fraction { nom, denom } if *nom * 2 > *denom => true,
+			BodyPart::AtLeastProportion { nom, denom } if *nom * 2 > *denom => true,
+			BodyPart::MoreThanProportion { nom, denom } if *nom * 2 >= *denom => true,
+			_ => false,
+		}
+	}
+}
+
+/// A single item in a path to describe the relative location of a consensus system.
+///
+/// Each item assumes a pre-existing location as its context and is defined in terms of it.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum Junction {
+	/// The consensus system of which the context is a member and state-wise super-set.
+	///
+	/// NOTE: This item is *not* a sub-consensus item: a consensus system may not identify itself trustlessly as
+	/// a location that includes this junction.
+	Parent,
+	/// An indexed parachain belonging to and operated by the context.
+	///
+	/// Generally used when the context is a Polkadot Relay-chain.
+	Parachain(#[codec(compact)] u32),
+	/// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
+	/// the context.
+	///
+	/// Generally used when the context is a Substrate-based chain.
+	AccountId32 { network: NetworkId, id: [u8; 32] },
+	/// An 8-byte index for an account of a specific network that is respected as a sovereign endpoint within
+	/// the context.
+	///
+	/// May be used when the context is a Frame-based chain and includes e.g. an indices pallet.
+	AccountIndex64 {
+		network: NetworkId,
+		#[codec(compact)]
+		index: u64,
+	},
+	/// A 20-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
+	/// the context.
+	///
+	/// May be used when the context is an Ethereum or Bitcoin chain or smart-contract.
+	AccountKey20 { network: NetworkId, key: [u8; 20] },
+	/// An instanced, indexed pallet that forms a constituent part of the context.
+	///
+	/// Generally used when the context is a Frame-based chain.
+	PalletInstance(u8),
+	/// A non-descript index within the context location.
+	///
+	/// Usage will vary widely owing to its generality.
+	///
+	/// NOTE: Try to avoid using this and instead use a more specific item.
+	GeneralIndex {
+		#[codec(compact)]
+		id: u128,
+	},
+	/// A nondescript datum acting as a key within the context location.
+	///
+	/// Usage will vary widely owing to its generality.
+	///
+	/// NOTE: Try to avoid using this and instead use a more specific item.
+	GeneralKey(Vec<u8>),
+	/// The unambiguous child.
+	///
+	/// Not currently used except as a fallback when deriving ancestry.
+	OnlyChild,
+	/// A pluralistic body existing within consensus.
+	///
+	/// Typical to be used to represent a governance origin of a chain, but could in principle be used to represent
+	/// things such as multisigs also.
+	Plurality { id: BodyId, part: BodyPart },
+}
+
+impl Junction {
+	/// Returns true if this junction is a `Parent` item.
+	pub fn is_parent(&self) -> bool {
+		match self {
+			Junction::Parent => true,
+			_ => false,
+		}
+	}
+
+	/// Returns true if this junction can be considered an interior part of its context. This is generally `true`,
+	/// except for the `Parent` item.
+	pub fn is_interior(&self) -> bool {
+		match self {
+			Junction::Parent => false,
+
+			Junction::Parachain(..) |
+			Junction::AccountId32 { .. } |
+			Junction::AccountIndex64 { .. } |
+			Junction::AccountKey20 { .. } |
+			Junction::PalletInstance { .. } |
+			Junction::GeneralIndex { .. } |
+			Junction::GeneralKey(..) |
+			Junction::OnlyChild |
+			Junction::Plurality { .. } => true,
+		}
+	}
+}
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
new file mode 100644
index 000000000000..6ebfe3a960a1
--- /dev/null
+++ b/xcm/src/v0/mod.rs
@@ -0,0 +1,331 @@
+// Copyright 2020 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Version 0 of the Cross-Consensus Message format data structures.
+
+use crate::{DoubleEncoded, VersionedXcm};
+use alloc::vec::Vec;
+use core::{convert::TryFrom, fmt::Debug, result};
+use derivative::Derivative;
+use parity_scale_codec::{self, Decode, Encode};
+
+mod junction;
+mod multi_asset;
+mod multi_location;
+mod order;
+mod traits;
+pub use junction::{BodyId, BodyPart, Junction, NetworkId};
+pub use multi_asset::{AssetInstance, MultiAsset};
+pub use multi_location::MultiLocation;
+pub use order::Order;
+pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
+
+/// A prelude for importing all types typically used when interacting with XCM messages.
+pub mod prelude {
+	pub use super::{
+		junction::{BodyId, BodyPart, Junction::*, NetworkId},
+		multi_asset::{
+			AssetInstance::{self, *},
+			MultiAsset::{self, *},
+		},
+		multi_location::MultiLocation::{self, *},
+		order::Order::{self, *},
+		traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
+		OriginKind,
+		Xcm::{self, *},
+	};
+}
+
+// TODO: #2841 #XCMENCODE Efficient encodings for Vec<MultiAsset>, Vec<Order>, using initial byte values 128+ to encode
+//   the number of items in the vector.
+
+/// Basically just the XCM (more general) version of `ParachainDispatchOrigin`.
+#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug)]
+pub enum OriginKind {
+	/// Origin should just be the native dispatch origin representation for the sender in the
+	/// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin
+	/// if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a
+	/// primary/native dispatch origin form.
+	Native,
+
+	/// Origin should just be the standard account-based origin with the sovereign account of
+	/// the sender. For Cumulus/Frame chains, this is the `Signed` origin.
+	SovereignAccount,
+
+	/// Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin.
+	/// This will not usually be an available option.
+	Superuser,
+
+	/// Origin should be interpreted as an XCM native origin and the `MultiLocation` should be
+	/// encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be
+	/// the `pallet_xcm::Origin::Xcm` type.
+	Xcm,
+}
+
+/// Response data to a query.
+#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
+pub enum Response {
+	/// Some assets.
+	Assets(Vec<MultiAsset>),
+}
+
+/// Cross-Consensus Message: A message from one consensus system to another.
+///
+/// Consensus systems that may send and receive messages include blockchains and smart contracts.
+///
+/// All messages are delivered from a known *origin*, expressed as a `MultiLocation`.
+///
+/// This is the inner XCM format and is version-sensitive. Messages are typically passed using the outer
+/// XCM format, known as `VersionedXcm`.
+#[derive(Derivative, Encode, Decode)]
+#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
+#[codec(encode_bound())]
+#[codec(decode_bound())]
+pub enum Xcm<Call> {
+	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place them into `holding`. Execute the
+	/// orders (`effects`).
+	///
+	/// - `assets`: The asset(s) to be withdrawn into holding.
+	/// - `effects`: The order(s) to execute on the holding account.
+	///
+	/// Kind: *Instruction*.
+	///
+	/// Errors:
+	#[codec(index = 0)]
+	WithdrawAsset { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+
+	/// Asset(s) (`assets`) have been received into the ownership of this system on the `origin` system.
+	///
+	/// Some orders are given (`effects`) which should be executed once the corresponding derivative assets have
+	/// been placed into `holding`.
+	///
+	/// - `assets`: The asset(s) that are minted into holding.
+	/// - `effects`: The order(s) to execute on the holding account.
+	///
+	/// Safety: `origin` must be trusted to have received and be storing `assets` such that they may later be
+	/// withdrawn should this system send a corresponding message.
+	///
+	/// Kind: *Trusted Indication*.
+	///
+	/// Errors:
+	#[codec(index = 1)]
+	ReserveAssetDeposit { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+
+	/// Asset(s) (`assets`) have been destroyed on the `origin` system and equivalent assets should be
+	/// created on this system.
+	///
+	/// Some orders are given (`effects`) which should be executed once the corresponding derivative assets have
+	/// been placed into `holding`.
+	///
+	/// - `assets`: The asset(s) that are minted into holding.
+	/// - `effects`: The order(s) to execute on the holding account.
+	///
+	/// Safety: `origin` must be trusted to have irrevocably destroyed the `assets` prior as a consequence of
+	/// sending this message.
+	///
+	/// Kind: *Trusted Indication*.
+	///
+	/// Errors:
+	#[codec(index = 2)]
+	TeleportAsset { assets: Vec<MultiAsset>, effects: Vec<Order<Call>> },
+
+	/// Indication of the contents of the holding account corresponding to the `QueryHolding` order of `query_id`.
+	///
+	/// - `query_id`: The identifier of the query that resulted in this message being sent.
+	/// - `assets`: The message content.
+	///
+	/// Safety: No concerns.
+	///
+	/// Kind: *Information*.
+	///
+	/// Errors:
+	#[codec(index = 3)]
+	QueryResponse {
+		#[codec(compact)]
+		query_id: u64,
+		response: Response,
+	},
+
+	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
+	/// ownership of `dest` within this consensus system.
+	///
+	/// - `assets`: The asset(s) to be withdrawn.
+	/// - `dest`: The new owner for the assets.
+	///
+	/// Safety: No concerns.
+	///
+	/// Kind: *Instruction*.
+	///
+	/// Errors:
+	#[codec(index = 4)]
+	TransferAsset { assets: Vec<MultiAsset>, dest: MultiLocation },
+
+	/// Withdraw asset(s) (`assets`) from the ownership of `origin` and place equivalent assets under the
+	/// ownership of `dest` within this consensus system.
+	///
+	/// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`.
+	///
+	/// - `assets`: The asset(s) to be withdrawn.
+	/// - `dest`: The new owner for the assets.
+	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to
+	///   `dest`.
+	///
+	/// Safety: No concerns.
+	///
+	/// Kind: *Instruction*.
+	///
+	/// Errors:
+	#[codec(index = 5)]
+	TransferReserveAsset { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+
+	/// Apply the encoded transaction `call`, whose dispatch-origin should be `origin` as expressed by the kind
+	/// of origin `origin_type`.
+	///
+	/// - `origin_type`: The means of expressing the message origin as a dispatch origin.
+	/// - `max_weight`: The weight of `call`; this should be at least the chain's calculated weight and will
+	///   be used in the weight determination arithmetic.
+	/// - `call`: The encoded transaction to be applied.
+	///
+	/// Safety: No concerns.
+	///
+	/// Kind: *Instruction*.
+	///
+	/// Errors:
+	#[codec(index = 6)]
+	Transact { origin_type: OriginKind, require_weight_at_most: u64, call: DoubleEncoded<Call> },
+
+	/// A message to notify about a new incoming HRMP channel. This message is meant to be sent by the
+	/// relay-chain to a para.
+	///
+	/// - `sender`: The sender in the to-be opened channel. Also, the initiator of the channel opening.
+	/// - `max_message_size`: The maximum size of a message proposed by the sender.
+	/// - `max_capacity`: The maximum number of messages that can be queued in the channel.
+	///
+	/// Safety: The message should originate directly from the relay-chain.
+	///
+	/// Kind: *System Notification*
+	#[codec(index = 7)]
+	HrmpNewChannelOpenRequest {
+		#[codec(compact)]
+		sender: u32,
+		#[codec(compact)]
+		max_message_size: u32,
+		#[codec(compact)]
+		max_capacity: u32,
+	},
+
+	/// A message to notify about that a previously sent open channel request has been accepted by
+	/// the recipient. That means that the channel will be opened during the next relay-chain session
+	/// change. This message is meant to be sent by the relay-chain to a para.
+	///
+	/// Safety: The message should originate directly from the relay-chain.
+	///
+	/// Kind: *System Notification*
+	///
+	/// Errors:
+	#[codec(index = 8)]
+	HrmpChannelAccepted {
+		#[codec(compact)]
+		recipient: u32,
+	},
+
+	/// A message to notify that the other party in an open channel decided to close it. In particular,
+	/// `initiator` is going to close the channel opened from `sender` to the `recipient`. The close
+	/// will be enacted at the next relay-chain session change. This message is meant to be sent by
+	/// the relay-chain to a para.
+	///
+	/// Safety: The message should originate directly from the relay-chain.
+	///
+	/// Kind: *System Notification*
+	///
+	/// Errors:
+	#[codec(index = 9)]
+	HrmpChannelClosing {
+		#[codec(compact)]
+		initiator: u32,
+		#[codec(compact)]
+		sender: u32,
+		#[codec(compact)]
+		recipient: u32,
+	},
+
+	/// A message to indicate that the embedded XCM is actually arriving on behalf of some consensus
+	/// location within the origin.
+	///
+	/// Safety: `who` must be an interior location of the context. This basically means that no `Parent`
+	/// junctions are allowed in it. This should be verified at the time of XCM execution.
+	///
+	/// Kind: *Instruction*
+	///
+	/// Errors:
+	#[codec(index = 10)]
+	RelayedFrom { who: MultiLocation, message: alloc::boxed::Box<Xcm<Call>> },
+}
+
+impl<Call> From<Xcm<Call>> for VersionedXcm<Call> {
+	fn from(x: Xcm<Call>) -> Self {
+		VersionedXcm::V0(x)
+	}
+}
+
+impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
+	type Error = ();
+	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
+		match x {
+			VersionedXcm::V0(x) => Ok(x),
+		}
+	}
+}
+
+impl<Call> Xcm<Call> {
+	pub fn into<C>(self) -> Xcm<C> {
+		Xcm::from(self)
+	}
+	pub fn from<C>(xcm: Xcm<C>) -> Self {
+		use Xcm::*;
+		match xcm {
+			WithdrawAsset { assets, effects } =>
+				WithdrawAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
+			ReserveAssetDeposit { assets, effects } => ReserveAssetDeposit {
+				assets,
+				effects: effects.into_iter().map(Order::into).collect(),
+			},
+			TeleportAsset { assets, effects } =>
+				TeleportAsset { assets, effects: effects.into_iter().map(Order::into).collect() },
+			QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response },
+			TransferAsset { assets, dest } => TransferAsset { assets, dest },
+			TransferReserveAsset { assets, dest, effects } =>
+				TransferReserveAsset { assets, dest, effects },
+			HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } =>
+				HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity },
+			HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient },
+			HrmpChannelClosing { initiator, sender, recipient } =>
+				HrmpChannelClosing { initiator, sender, recipient },
+			Transact { origin_type, require_weight_at_most, call } =>
+				Transact { origin_type, require_weight_at_most, call: call.into() },
+			RelayedFrom { who, message } =>
+				RelayedFrom { who, message: alloc::boxed::Box::new((*message).into()) },
+		}
+	}
+}
+
+pub mod opaque {
+	/// The basic concrete type of `generic::Xcm`, which doesn't make any assumptions about the format of a
+	/// call other than it is pre-encoded.
+	pub type Xcm = super::Xcm<()>;
+
+	pub use super::order::opaque::*;
+}
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
new file mode 100644
index 000000000000..9a4b251ab312
--- /dev/null
+++ b/xcm/src/v0/multi_asset.rs
@@ -0,0 +1,380 @@
+// Copyright 2020 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Cross-Consensus Message format data structures.
+
+use alloc::vec::Vec;
+use core::{convert::TryFrom, result};
+
+use super::MultiLocation;
+use parity_scale_codec::{self, Decode, Encode};
+
+/// A general identifier for an instance of a non-fungible asset class.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum AssetInstance {
+	/// Undefined - used if the NFA class has only one instance.
+	Undefined,
+
+	/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
+	/// values up to `2**128 - 1`.
+	Index {
+		#[codec(compact)]
+		id: u128,
+	},
+
+	/// A 4-byte fixed-length datum.
+	Array4([u8; 4]),
+
+	/// An 8-byte fixed-length datum.
+	Array8([u8; 8]),
+
+	/// A 16-byte fixed-length datum.
+	Array16([u8; 16]),
+
+	/// A 32-byte fixed-length datum.
+	Array32([u8; 32]),
+
+	/// An arbitrary piece of data. Use only when necessary.
+	Blob(Vec<u8>),
+}
+
+/// A single general identifier for an asset.
+///
+/// Represents both fungible and non-fungible assets. May only be used to represent a single asset class.
+///
+/// Wildcards may or may not be allowed by the interpreting context.
+///
+/// Assets classes may be identified in one of two ways: either an abstract identifier or a concrete identifier.
+/// Implementations may support only one of these. A single asset may be referenced from multiple asset identifiers,
+/// though will tend to have only a single *preferred* identifier.
+///
+/// ### Abstract identifiers
+///
+/// Abstract identifiers are absolute identifiers that represent a notional asset which can exist within multiple
+/// consensus systems. These tend to be simpler to deal with since their broad meaning is unchanged regardless stay of
+/// the consensus system in which it is interpreted.
+///
+/// However, in the attempt to provide uniformity across consensus systems, they may conflate different instantiations
+/// of some notional asset (e.g. the reserve asset and a local reserve-backed derivative of it) under the same name,
+/// leading to confusion. It also implies that one notional asset is accounted for locally in only one way. This may not
+/// be the case, e.g. where there are multiple bridge instances each providing a bridged "BTC" token yet none being
+/// fungible between the others.
+///
+/// Since they are meant to be absolute and universal, a global registry is needed to ensure that name collisions do not
+/// occur.
+///
+/// An abstract identifier is represented as a simple variable-size byte string. As of writing, no global registry
+/// exists and no proposals have been put forth for asset labeling.
+///
+/// ### Concrete identifiers
+///
+/// Concrete identifiers are *relative identifiers* that specifically identify a single asset through its location in a
+/// consensus system relative to the context interpreting. Use of a `MultiLocation` ensures that similar but non
+/// fungible variants of the same underlying asset can be properly distinguished, and obviates the need for any kind of
+/// central registry.
+///
+/// The limitation is that the asset identifier cannot be trivially copied between consensus systems and must instead be
+/// "re-anchored" whenever being moved to a new consensus system, using the two systems' relative paths.
+///
+/// Throughout XCM, messages are authored such that *when interpreted from the receiver's point of view* they will have
+/// the desired meaning/effect. This means that relative paths should always by constructed to be read from the point of
+/// view of the receiving system, *which may be have a completely different meaning in the authoring system*.
+///
+/// Concrete identifiers are the preferred way of identifying an asset since they are entirely unambiguous.
+///
+/// A concrete identifier is represented by a `MultiLocation`. If a system has an unambiguous primary asset (such as
+/// Bitcoin with BTC or Ethereum with ETH), then it will conventionally be identified as the chain itself. Alternative
+/// and more specific ways of referring to an asset within a system include:
+///
+/// - `<chain>/PalletInstance(<id>)` for a Frame chain with a single-asset pallet instance (such as an instance of the
+///   Balances pallet).
+/// - `<chain>/PalletInstance(<id>)/GeneralIndex(<index>)` for a Frame chain with an indexed multi-asset pallet instance
+///   (such as an instance of the Assets pallet).
+/// - `<chain>/AccountId32` for an ERC-20-style single-asset smart-contract on a Frame-based contracts chain.
+/// - `<chain>/AccountKey20` for an ERC-20-style single-asset smart-contract on an Ethereum-like chain.
+///
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum MultiAsset {
+	/// No assets. Rarely used.
+	None,
+
+	/// All assets. Typically used for the subset of assets to be used for an `Order`, and in that context means
+	/// "all assets currently in holding".
+	All,
+
+	/// All fungible assets. Typically used for the subset of assets to be used for an `Order`, and in that context
+	/// means "all fungible assets currently in holding".
+	AllFungible,
+
+	/// All non-fungible assets. Typically used for the subset of assets to be used for an `Order`, and in that
+	/// context means "all non-fungible assets currently in holding".
+	AllNonFungible,
+
+	/// All fungible assets of a given abstract asset `id`entifier.
+	AllAbstractFungible { id: Vec<u8> },
+
+	/// All non-fungible assets of a given abstract asset `class`.
+	AllAbstractNonFungible { class: Vec<u8> },
+
+	/// All fungible assets of a given concrete asset `id`entifier.
+	AllConcreteFungible { id: MultiLocation },
+
+	/// All non-fungible assets of a given concrete asset `class`.
+	AllConcreteNonFungible { class: MultiLocation },
+
+	/// Some specific `amount` of the fungible asset identified by an abstract `id`.
+	AbstractFungible {
+		id: Vec<u8>,
+		#[codec(compact)]
+		amount: u128,
+	},
+
+	/// Some specific `instance` of the non-fungible asset whose `class` is identified abstractly.
+	AbstractNonFungible { class: Vec<u8>, instance: AssetInstance },
+
+	/// Some specific `amount` of the fungible asset identified by an concrete `id`.
+	ConcreteFungible {
+		id: MultiLocation,
+		#[codec(compact)]
+		amount: u128,
+	},
+
+	/// Some specific `instance` of the non-fungible asset whose `class` is identified concretely.
+	ConcreteNonFungible { class: MultiLocation, instance: AssetInstance },
+}
+
+impl MultiAsset {
+	/// Returns `true` if the `MultiAsset` is a wildcard and can refer to classes of assets, instead of just one.
+	///
+	/// Typically can also be inferred by the name starting with `All`.
+	pub fn is_wildcard(&self) -> bool {
+		match self {
+			MultiAsset::None |
+			MultiAsset::AbstractFungible { .. } |
+			MultiAsset::AbstractNonFungible { .. } |
+			MultiAsset::ConcreteFungible { .. } |
+			MultiAsset::ConcreteNonFungible { .. } => false,
+
+			MultiAsset::All |
+			MultiAsset::AllFungible |
+			MultiAsset::AllNonFungible |
+			MultiAsset::AllAbstractFungible { .. } |
+			MultiAsset::AllConcreteFungible { .. } |
+			MultiAsset::AllAbstractNonFungible { .. } |
+			MultiAsset::AllConcreteNonFungible { .. } => true,
+		}
+	}
+
+	fn is_none(&self) -> bool {
+		match self {
+			MultiAsset::None |
+			MultiAsset::AbstractFungible { amount: 0, .. } |
+			MultiAsset::ConcreteFungible { amount: 0, .. } => true,
+
+			_ => false,
+		}
+	}
+
+	fn is_fungible(&self) -> bool {
+		match self {
+			MultiAsset::All |
+			MultiAsset::AllFungible |
+			MultiAsset::AllAbstractFungible { .. } |
+			MultiAsset::AllConcreteFungible { .. } |
+			MultiAsset::AbstractFungible { .. } |
+			MultiAsset::ConcreteFungible { .. } => true,
+
+			_ => false,
+		}
+	}
+
+	fn is_non_fungible(&self) -> bool {
+		match self {
+			MultiAsset::All |
+			MultiAsset::AllNonFungible |
+			MultiAsset::AllAbstractNonFungible { .. } |
+			MultiAsset::AllConcreteNonFungible { .. } |
+			MultiAsset::AbstractNonFungible { .. } |
+			MultiAsset::ConcreteNonFungible { .. } => true,
+
+			_ => false,
+		}
+	}
+
+	fn is_concrete_fungible(&self, id: &MultiLocation) -> bool {
+		match self {
+			MultiAsset::AllFungible => true,
+			MultiAsset::AllConcreteFungible { id: i } |
+			MultiAsset::ConcreteFungible { id: i, .. } => i == id,
+
+			_ => false,
+		}
+	}
+
+	fn is_abstract_fungible(&self, id: &[u8]) -> bool {
+		match self {
+			MultiAsset::AllFungible => true,
+			MultiAsset::AllAbstractFungible { id: i } |
+			MultiAsset::AbstractFungible { id: i, .. } => i == id,
+			_ => false,
+		}
+	}
+
+	fn is_concrete_non_fungible(&self, class: &MultiLocation) -> bool {
+		match self {
+			MultiAsset::AllNonFungible => true,
+			MultiAsset::AllConcreteNonFungible { class: i } |
+			MultiAsset::ConcreteNonFungible { class: i, .. } => i == class,
+			_ => false,
+		}
+	}
+
+	fn is_abstract_non_fungible(&self, class: &[u8]) -> bool {
+		match self {
+			MultiAsset::AllNonFungible => true,
+			MultiAsset::AllAbstractNonFungible { class: i } |
+			MultiAsset::AbstractNonFungible { class: i, .. } => i == class,
+			_ => false,
+		}
+	}
+
+	fn is_all(&self) -> bool {
+		matches!(self, MultiAsset::All)
+	}
+
+	/// Returns true if `self` is a super-set of the given `inner`.
+	///
+	/// Typically, any wildcard is never contained in anything else, and a wildcard can contain any other non-wildcard.
+	/// For more details, see the implementation and tests.
+	pub fn contains(&self, inner: &MultiAsset) -> bool {
+		use MultiAsset::*;
+
+		// Inner cannot be wild
+		if inner.is_wildcard() {
+			return false
+		}
+		// Everything contains nothing.
+		if inner.is_none() {
+			return true
+		}
+
+		// Everything contains anything.
+		if self.is_all() {
+			return true
+		}
+		// Nothing contains nothing.
+		if self.is_none() {
+			return false
+		}
+
+		match self {
+			// Anything fungible contains "all fungibles"
+			AllFungible => inner.is_fungible(),
+			// Anything non-fungible contains "all non-fungibles"
+			AllNonFungible => inner.is_non_fungible(),
+
+			AllConcreteFungible { id } => inner.is_concrete_fungible(id),
+			AllAbstractFungible { id } => inner.is_abstract_fungible(id),
+			AllConcreteNonFungible { class } => inner.is_concrete_non_fungible(class),
+			AllAbstractNonFungible { class } => inner.is_abstract_non_fungible(class),
+
+			ConcreteFungible { id, amount } => matches!(
+				inner,
+				ConcreteFungible { id: inner_id , amount: inner_amount } if inner_id == id && amount >= inner_amount
+			),
+			AbstractFungible { id, amount } => matches!(
+				inner,
+				AbstractFungible { id: inner_id , amount: inner_amount } if inner_id == id && amount >= inner_amount
+			),
+			ConcreteNonFungible { .. } => self == inner,
+			AbstractNonFungible { .. } => self == inner,
+			_ => false,
+		}
+	}
+
+	pub fn reanchor(&mut self, prepend: &MultiLocation) -> Result<(), ()> {
+		use MultiAsset::*;
+		match self {
+			AllConcreteFungible { ref mut id } |
+			AllConcreteNonFungible { class: ref mut id } |
+			ConcreteFungible { ref mut id, .. } |
+			ConcreteNonFungible { class: ref mut id, .. } =>
+				id.prepend_with(prepend.clone()).map_err(|_| ()),
+			_ => Ok(()),
+		}
+	}
+}
+
+#[cfg(test)]
+mod tests {
+	use super::*;
+
+	#[test]
+	fn contains_works() {
+		use alloc::vec;
+		use MultiAsset::*;
+		// trivial case: all contains any non-wildcard.
+		assert!(All.contains(&None));
+		assert!(All.contains(&AbstractFungible { id: alloc::vec![99u8], amount: 1 }));
+
+		// trivial case: none contains nothing, except itself.
+		assert!(None.contains(&None));
+		assert!(!None.contains(&AllFungible));
+		assert!(!None.contains(&All));
+
+		// A bit more sneaky: Nothing can contain wildcard, even All ir the thing itself.
+		assert!(!All.contains(&All));
+		assert!(!All.contains(&AllFungible));
+		assert!(!AllFungible.contains(&AllFungible));
+		assert!(!AllNonFungible.contains(&AllNonFungible));
+
+		// For fungibles, containing is basically equality, or equal id with higher amount.
+		assert!(!AbstractFungible { id: vec![99u8], amount: 99 }
+			.contains(&AbstractFungible { id: vec![1u8], amount: 99 }));
+		assert!(AbstractFungible { id: vec![99u8], amount: 99 }
+			.contains(&AbstractFungible { id: vec![99u8], amount: 99 }));
+		assert!(AbstractFungible { id: vec![99u8], amount: 99 }
+			.contains(&AbstractFungible { id: vec![99u8], amount: 9 }));
+		assert!(!AbstractFungible { id: vec![99u8], amount: 99 }
+			.contains(&AbstractFungible { id: vec![99u8], amount: 100 }));
+
+		// For non-fungibles, containing is equality.
+		assert!(!AbstractNonFungible {
+			class: vec![99u8],
+			instance: AssetInstance::Index { id: 9 }
+		}
+		.contains(&AbstractNonFungible {
+			class: vec![98u8],
+			instance: AssetInstance::Index { id: 9 }
+		}));
+		assert!(!AbstractNonFungible {
+			class: vec![99u8],
+			instance: AssetInstance::Index { id: 8 }
+		}
+		.contains(&AbstractNonFungible {
+			class: vec![99u8],
+			instance: AssetInstance::Index { id: 9 }
+		}));
+		assert!(AbstractNonFungible {
+			class: vec![99u8],
+			instance: AssetInstance::Index { id: 9 }
+		}
+		.contains(&AbstractNonFungible {
+			class: vec![99u8],
+			instance: AssetInstance::Index { id: 9 }
+		}));
+	}
+}
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
new file mode 100644
index 000000000000..e45df25a0ff6
--- /dev/null
+++ b/xcm/src/v0/multi_location.rs
@@ -0,0 +1,820 @@
+// Copyright 2020-2021 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Cross-Consensus Message format data structures.
+
+use core::{convert::TryFrom, mem, result};
+
+use super::Junction;
+use crate::VersionedMultiLocation;
+use parity_scale_codec::{self, Decode, Encode};
+
+/// A relative path between state-bearing consensus systems.
+///
+/// A location in a consensus system is defined as an *isolatable state machine* held within global consensus. The
+/// location in question need not have a sophisticated consensus algorithm of its own; a single account within
+/// Ethereum, for example, could be considered a location.
+///
+/// A very-much non-exhaustive list of types of location include:
+/// - A (normal, layer-1) block chain, e.g. the Bitcoin mainnet or a parachain.
+/// - A layer-0 super-chain, e.g. the Polkadot Relay chain.
+/// - A layer-2 smart contract, e.g. an ERC-20 on Ethereum.
+/// - A logical functional component of a chain, e.g. a single instance of a pallet on a Frame-based Substrate chain.
+/// - An account.
+///
+/// A `MultiLocation` is a *relative identifier*, meaning that it can only be used to define the relative path
+/// between two locations, and cannot generally be used to refer to a location universally. It is comprised of a
+/// number of *junctions*, each morphing the previous location, either diving down into one of its internal locations,
+/// called a *sub-consensus*, or going up into its parent location. Correct `MultiLocation` values must have all
+/// `Parent` junctions as a prefix to all *sub-consensus* junctions.
+///
+/// This specific `MultiLocation` implementation uses a Rust `enum` in order to make pattern matching easier.
+///
+/// The `MultiLocation` value of `Null` simply refers to the interpreting consensus system.
+#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
+pub enum MultiLocation {
+	/// The interpreting consensus system.
+	Null,
+	/// A relative path comprising 1 junction.
+	X1(Junction),
+	/// A relative path comprising 2 junctions.
+	X2(Junction, Junction),
+	/// A relative path comprising 3 junctions.
+	X3(Junction, Junction, Junction),
+	/// A relative path comprising 4 junctions.
+	X4(Junction, Junction, Junction, Junction),
+	/// A relative path comprising 5 junctions.
+	X5(Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 6 junctions.
+	X6(Junction, Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 7 junctions.
+	X7(Junction, Junction, Junction, Junction, Junction, Junction, Junction),
+	/// A relative path comprising 8 junctions.
+	X8(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction),
+}
+
+/// Maximum number of junctions a `MultiLocation` can contain.
+pub const MAX_MULTILOCATION_LENGTH: usize = 8;
+
+impl From<Junction> for MultiLocation {
+	fn from(x: Junction) -> Self {
+		MultiLocation::X1(x)
+	}
+}
+
+impl From<()> for MultiLocation {
+	fn from(_: ()) -> Self {
+		MultiLocation::Null
+	}
+}
+impl From<(Junction,)> for MultiLocation {
+	fn from(x: (Junction,)) -> Self {
+		MultiLocation::X1(x.0)
+	}
+}
+impl From<(Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction)) -> Self {
+		MultiLocation::X2(x.0, x.1)
+	}
+}
+impl From<(Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction)) -> Self {
+		MultiLocation::X3(x.0, x.1, x.2)
+	}
+}
+impl From<(Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation::X4(x.0, x.1, x.2, x.3)
+	}
+}
+impl From<(Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation::X5(x.0, x.1, x.2, x.3, x.4)
+	}
+}
+impl From<(Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation::X6(x.0, x.1, x.2, x.3, x.4, x.5)
+	}
+}
+impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction)>
+	for MultiLocation
+{
+	fn from(x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation::X7(x.0, x.1, x.2, x.3, x.4, x.5, x.6)
+	}
+}
+impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)>
+	for MultiLocation
+{
+	fn from(
+		x: (Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction),
+	) -> Self {
+		MultiLocation::X8(x.0, x.1, x.2, x.3, x.4, x.5, x.6, x.7)
+	}
+}
+
+impl From<[Junction; 0]> for MultiLocation {
+	fn from(_: [Junction; 0]) -> Self {
+		MultiLocation::Null
+	}
+}
+impl From<[Junction; 1]> for MultiLocation {
+	fn from(x: [Junction; 1]) -> Self {
+		let [x0] = x;
+		MultiLocation::X1(x0)
+	}
+}
+impl From<[Junction; 2]> for MultiLocation {
+	fn from(x: [Junction; 2]) -> Self {
+		let [x0, x1] = x;
+		MultiLocation::X2(x0, x1)
+	}
+}
+impl From<[Junction; 3]> for MultiLocation {
+	fn from(x: [Junction; 3]) -> Self {
+		let [x0, x1, x2] = x;
+		MultiLocation::X3(x0, x1, x2)
+	}
+}
+impl From<[Junction; 4]> for MultiLocation {
+	fn from(x: [Junction; 4]) -> Self {
+		let [x0, x1, x2, x3] = x;
+		MultiLocation::X4(x0, x1, x2, x3)
+	}
+}
+impl From<[Junction; 5]> for MultiLocation {
+	fn from(x: [Junction; 5]) -> Self {
+		let [x0, x1, x2, x3, x4] = x;
+		MultiLocation::X5(x0, x1, x2, x3, x4)
+	}
+}
+impl From<[Junction; 6]> for MultiLocation {
+	fn from(x: [Junction; 6]) -> Self {
+		let [x0, x1, x2, x3, x4, x5] = x;
+		MultiLocation::X6(x0, x1, x2, x3, x4, x5)
+	}
+}
+impl From<[Junction; 7]> for MultiLocation {
+	fn from(x: [Junction; 7]) -> Self {
+		let [x0, x1, x2, x3, x4, x5, x6] = x;
+		MultiLocation::X7(x0, x1, x2, x3, x4, x5, x6)
+	}
+}
+impl From<[Junction; 8]> for MultiLocation {
+	fn from(x: [Junction; 8]) -> Self {
+		let [x0, x1, x2, x3, x4, x5, x6, x7] = x;
+		MultiLocation::X8(x0, x1, x2, x3, x4, x5, x6, x7)
+	}
+}
+
+pub struct MultiLocationIterator(MultiLocation);
+impl Iterator for MultiLocationIterator {
+	type Item = Junction;
+	fn next(&mut self) -> Option<Junction> {
+		self.0.take_first()
+	}
+}
+
+pub struct MultiLocationReverseIterator(MultiLocation);
+impl Iterator for MultiLocationReverseIterator {
+	type Item = Junction;
+	fn next(&mut self) -> Option<Junction> {
+		self.0.take_last()
+	}
+}
+
+pub struct MultiLocationRefIterator<'a>(&'a MultiLocation, usize);
+impl<'a> Iterator for MultiLocationRefIterator<'a> {
+	type Item = &'a Junction;
+	fn next(&mut self) -> Option<&'a Junction> {
+		let result = self.0.at(self.1);
+		self.1 += 1;
+		result
+	}
+}
+
+pub struct MultiLocationReverseRefIterator<'a>(&'a MultiLocation, usize);
+impl<'a> Iterator for MultiLocationReverseRefIterator<'a> {
+	type Item = &'a Junction;
+	fn next(&mut self) -> Option<&'a Junction> {
+		self.1 += 1;
+		self.0.at(self.0.len().checked_sub(self.1)?)
+	}
+}
+
+impl MultiLocation {
+	/// Returns first junction, or `None` if the location is empty.
+	pub fn first(&self) -> Option<&Junction> {
+		match &self {
+			MultiLocation::Null => None,
+			MultiLocation::X1(ref a) => Some(a),
+			MultiLocation::X2(ref a, ..) => Some(a),
+			MultiLocation::X3(ref a, ..) => Some(a),
+			MultiLocation::X4(ref a, ..) => Some(a),
+			MultiLocation::X5(ref a, ..) => Some(a),
+			MultiLocation::X6(ref a, ..) => Some(a),
+			MultiLocation::X7(ref a, ..) => Some(a),
+			MultiLocation::X8(ref a, ..) => Some(a),
+		}
+	}
+
+	/// Returns last junction, or `None` if the location is empty.
+	pub fn last(&self) -> Option<&Junction> {
+		match &self {
+			MultiLocation::Null => None,
+			MultiLocation::X1(ref a) => Some(a),
+			MultiLocation::X2(.., ref a) => Some(a),
+			MultiLocation::X3(.., ref a) => Some(a),
+			MultiLocation::X4(.., ref a) => Some(a),
+			MultiLocation::X5(.., ref a) => Some(a),
+			MultiLocation::X6(.., ref a) => Some(a),
+			MultiLocation::X7(.., ref a) => Some(a),
+			MultiLocation::X8(.., ref a) => Some(a),
+		}
+	}
+
+	/// Splits off the first junction, returning the remaining suffix (first item in tuple) and the first element
+	/// (second item in tuple) or `None` if it was empty.
+	pub fn split_first(self) -> (MultiLocation, Option<Junction>) {
+		match self {
+			MultiLocation::Null => (MultiLocation::Null, None),
+			MultiLocation::X1(a) => (MultiLocation::Null, Some(a)),
+			MultiLocation::X2(a, b) => (MultiLocation::X1(b), Some(a)),
+			MultiLocation::X3(a, b, c) => (MultiLocation::X2(b, c), Some(a)),
+			MultiLocation::X4(a, b, c, d) => (MultiLocation::X3(b, c, d), Some(a)),
+			MultiLocation::X5(a, b, c, d, e) => (MultiLocation::X4(b, c, d, e), Some(a)),
+			MultiLocation::X6(a, b, c, d, e, f) => (MultiLocation::X5(b, c, d, e, f), Some(a)),
+			MultiLocation::X7(a, b, c, d, e, f, g) =>
+				(MultiLocation::X6(b, c, d, e, f, g), Some(a)),
+			MultiLocation::X8(a, b, c, d, e, f, g, h) =>
+				(MultiLocation::X7(b, c, d, e, f, g, h), Some(a)),
+		}
+	}
+
+	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
+	/// (second item in tuple) or `None` if it was empty.
+	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
+		match self {
+			MultiLocation::Null => (MultiLocation::Null, None),
+			MultiLocation::X1(a) => (MultiLocation::Null, Some(a)),
+			MultiLocation::X2(a, b) => (MultiLocation::X1(a), Some(b)),
+			MultiLocation::X3(a, b, c) => (MultiLocation::X2(a, b), Some(c)),
+			MultiLocation::X4(a, b, c, d) => (MultiLocation::X3(a, b, c), Some(d)),
+			MultiLocation::X5(a, b, c, d, e) => (MultiLocation::X4(a, b, c, d), Some(e)),
+			MultiLocation::X6(a, b, c, d, e, f) => (MultiLocation::X5(a, b, c, d, e), Some(f)),
+			MultiLocation::X7(a, b, c, d, e, f, g) =>
+				(MultiLocation::X6(a, b, c, d, e, f), Some(g)),
+			MultiLocation::X8(a, b, c, d, e, f, g, h) =>
+				(MultiLocation::X7(a, b, c, d, e, f, g), Some(h)),
+		}
+	}
+
+	/// Removes the first element from `self`, returning it (or `None` if it was empty).
+	pub fn take_first(&mut self) -> Option<Junction> {
+		let mut d = MultiLocation::Null;
+		mem::swap(&mut *self, &mut d);
+		let (tail, head) = d.split_first();
+		*self = tail;
+		head
+	}
+
+	/// Removes the last element from `self`, returning it (or `None` if it was empty).
+	pub fn take_last(&mut self) -> Option<Junction> {
+		let mut d = MultiLocation::Null;
+		mem::swap(&mut *self, &mut d);
+		let (head, tail) = d.split_last();
+		*self = head;
+		tail
+	}
+
+	/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with the original value of
+	/// `self` in case of overflow.
+	pub fn pushed_with(self, new: Junction) -> result::Result<Self, Self> {
+		Ok(match self {
+			MultiLocation::Null => MultiLocation::X1(new),
+			MultiLocation::X1(a) => MultiLocation::X2(a, new),
+			MultiLocation::X2(a, b) => MultiLocation::X3(a, b, new),
+			MultiLocation::X3(a, b, c) => MultiLocation::X4(a, b, c, new),
+			MultiLocation::X4(a, b, c, d) => MultiLocation::X5(a, b, c, d, new),
+			MultiLocation::X5(a, b, c, d, e) => MultiLocation::X6(a, b, c, d, e, new),
+			MultiLocation::X6(a, b, c, d, e, f) => MultiLocation::X7(a, b, c, d, e, f, new),
+			MultiLocation::X7(a, b, c, d, e, f, g) => MultiLocation::X8(a, b, c, d, e, f, g, new),
+			s => Err(s)?,
+		})
+	}
+
+	/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
+	/// `self` in case of overflow.
+	pub fn pushed_front_with(self, new: Junction) -> result::Result<Self, Self> {
+		Ok(match self {
+			MultiLocation::Null => MultiLocation::X1(new),
+			MultiLocation::X1(a) => MultiLocation::X2(new, a),
+			MultiLocation::X2(a, b) => MultiLocation::X3(new, a, b),
+			MultiLocation::X3(a, b, c) => MultiLocation::X4(new, a, b, c),
+			MultiLocation::X4(a, b, c, d) => MultiLocation::X5(new, a, b, c, d),
+			MultiLocation::X5(a, b, c, d, e) => MultiLocation::X6(new, a, b, c, d, e),
+			MultiLocation::X6(a, b, c, d, e, f) => MultiLocation::X7(new, a, b, c, d, e, f),
+			MultiLocation::X7(a, b, c, d, e, f, g) => MultiLocation::X8(new, a, b, c, d, e, f, g),
+			s => Err(s)?,
+		})
+	}
+
+	/// Returns the number of junctions in `self`.
+	pub fn len(&self) -> usize {
+		match &self {
+			MultiLocation::Null => 0,
+			MultiLocation::X1(..) => 1,
+			MultiLocation::X2(..) => 2,
+			MultiLocation::X3(..) => 3,
+			MultiLocation::X4(..) => 4,
+			MultiLocation::X5(..) => 5,
+			MultiLocation::X6(..) => 6,
+			MultiLocation::X7(..) => 7,
+			MultiLocation::X8(..) => 8,
+		}
+	}
+
+	/// Returns the junction at index `i`, or `None` if the location doesn't contain that many elements.
+	pub fn at(&self, i: usize) -> Option<&Junction> {
+		Some(match (i, &self) {
+			(0, MultiLocation::X1(ref a)) => a,
+			(0, MultiLocation::X2(ref a, ..)) => a,
+			(0, MultiLocation::X3(ref a, ..)) => a,
+			(0, MultiLocation::X4(ref a, ..)) => a,
+			(0, MultiLocation::X5(ref a, ..)) => a,
+			(0, MultiLocation::X6(ref a, ..)) => a,
+			(0, MultiLocation::X7(ref a, ..)) => a,
+			(0, MultiLocation::X8(ref a, ..)) => a,
+			(1, MultiLocation::X2(_, ref a)) => a,
+			(1, MultiLocation::X3(_, ref a, ..)) => a,
+			(1, MultiLocation::X4(_, ref a, ..)) => a,
+			(1, MultiLocation::X5(_, ref a, ..)) => a,
+			(1, MultiLocation::X6(_, ref a, ..)) => a,
+			(1, MultiLocation::X7(_, ref a, ..)) => a,
+			(1, MultiLocation::X8(_, ref a, ..)) => a,
+			(2, MultiLocation::X3(_, _, ref a)) => a,
+			(2, MultiLocation::X4(_, _, ref a, ..)) => a,
+			(2, MultiLocation::X5(_, _, ref a, ..)) => a,
+			(2, MultiLocation::X6(_, _, ref a, ..)) => a,
+			(2, MultiLocation::X7(_, _, ref a, ..)) => a,
+			(2, MultiLocation::X8(_, _, ref a, ..)) => a,
+			(3, MultiLocation::X4(_, _, _, ref a)) => a,
+			(3, MultiLocation::X5(_, _, _, ref a, ..)) => a,
+			(3, MultiLocation::X6(_, _, _, ref a, ..)) => a,
+			(3, MultiLocation::X7(_, _, _, ref a, ..)) => a,
+			(3, MultiLocation::X8(_, _, _, ref a, ..)) => a,
+			(4, MultiLocation::X5(_, _, _, _, ref a)) => a,
+			(4, MultiLocation::X6(_, _, _, _, ref a, ..)) => a,
+			(4, MultiLocation::X7(_, _, _, _, ref a, ..)) => a,
+			(4, MultiLocation::X8(_, _, _, _, ref a, ..)) => a,
+			(5, MultiLocation::X6(_, _, _, _, _, ref a)) => a,
+			(5, MultiLocation::X7(_, _, _, _, _, ref a, ..)) => a,
+			(5, MultiLocation::X8(_, _, _, _, _, ref a, ..)) => a,
+			(6, MultiLocation::X7(_, _, _, _, _, _, ref a)) => a,
+			(6, MultiLocation::X8(_, _, _, _, _, _, ref a, ..)) => a,
+			(7, MultiLocation::X8(_, _, _, _, _, _, _, ref a)) => a,
+			_ => return None,
+		})
+	}
+
+	/// Returns a mutable reference to the junction at index `i`, or `None` if the location doesn't contain that many
+	/// elements.
+	pub fn at_mut(&mut self, i: usize) -> Option<&mut Junction> {
+		Some(match (i, self) {
+			(0, MultiLocation::X1(ref mut a)) => a,
+			(0, MultiLocation::X2(ref mut a, ..)) => a,
+			(0, MultiLocation::X3(ref mut a, ..)) => a,
+			(0, MultiLocation::X4(ref mut a, ..)) => a,
+			(0, MultiLocation::X5(ref mut a, ..)) => a,
+			(0, MultiLocation::X6(ref mut a, ..)) => a,
+			(0, MultiLocation::X7(ref mut a, ..)) => a,
+			(0, MultiLocation::X8(ref mut a, ..)) => a,
+			(1, MultiLocation::X2(_, ref mut a)) => a,
+			(1, MultiLocation::X3(_, ref mut a, ..)) => a,
+			(1, MultiLocation::X4(_, ref mut a, ..)) => a,
+			(1, MultiLocation::X5(_, ref mut a, ..)) => a,
+			(1, MultiLocation::X6(_, ref mut a, ..)) => a,
+			(1, MultiLocation::X7(_, ref mut a, ..)) => a,
+			(1, MultiLocation::X8(_, ref mut a, ..)) => a,
+			(2, MultiLocation::X3(_, _, ref mut a)) => a,
+			(2, MultiLocation::X4(_, _, ref mut a, ..)) => a,
+			(2, MultiLocation::X5(_, _, ref mut a, ..)) => a,
+			(2, MultiLocation::X6(_, _, ref mut a, ..)) => a,
+			(2, MultiLocation::X7(_, _, ref mut a, ..)) => a,
+			(2, MultiLocation::X8(_, _, ref mut a, ..)) => a,
+			(3, MultiLocation::X4(_, _, _, ref mut a)) => a,
+			(3, MultiLocation::X5(_, _, _, ref mut a, ..)) => a,
+			(3, MultiLocation::X6(_, _, _, ref mut a, ..)) => a,
+			(3, MultiLocation::X7(_, _, _, ref mut a, ..)) => a,
+			(3, MultiLocation::X8(_, _, _, ref mut a, ..)) => a,
+			(4, MultiLocation::X5(_, _, _, _, ref mut a)) => a,
+			(4, MultiLocation::X6(_, _, _, _, ref mut a, ..)) => a,
+			(4, MultiLocation::X7(_, _, _, _, ref mut a, ..)) => a,
+			(4, MultiLocation::X8(_, _, _, _, ref mut a, ..)) => a,
+			(5, MultiLocation::X6(_, _, _, _, _, ref mut a)) => a,
+			(5, MultiLocation::X7(_, _, _, _, _, ref mut a, ..)) => a,
+			(5, MultiLocation::X8(_, _, _, _, _, ref mut a, ..)) => a,
+			(6, MultiLocation::X7(_, _, _, _, _, _, ref mut a)) => a,
+			(6, MultiLocation::X8(_, _, _, _, _, _, ref mut a, ..)) => a,
+			(7, MultiLocation::X8(_, _, _, _, _, _, _, ref mut a)) => a,
+			_ => return None,
+		})
+	}
+
+	/// Returns a reference iterator over the junctions.
+	pub fn iter(&self) -> MultiLocationRefIterator {
+		MultiLocationRefIterator(&self, 0)
+	}
+
+	/// Returns a reference iterator over the junctions in reverse.
+	pub fn iter_rev(&self) -> MultiLocationReverseRefIterator {
+		MultiLocationReverseRefIterator(&self, 0)
+	}
+
+	/// Consumes `self` and returns an iterator over the junctions.
+	pub fn into_iter(self) -> MultiLocationIterator {
+		MultiLocationIterator(self)
+	}
+
+	/// Consumes `self` and returns an iterator over the junctions in reverse.
+	pub fn into_iter_rev(self) -> MultiLocationReverseIterator {
+		MultiLocationReverseIterator(self)
+	}
+
+	/// Ensures that self begins with `prefix` and that it has a single `Junction` item following.
+	/// If so, returns a reference to this `Junction` item.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v0::{MultiLocation::*, Junction::*};
+	/// # fn main() {
+	/// let mut m = X3(Parent, PalletInstance(3), OnlyChild);
+	/// assert_eq!(m.match_and_split(&X2(Parent, PalletInstance(3))), Some(&OnlyChild));
+	/// assert_eq!(m.match_and_split(&X1(Parent)), None);
+	/// # }
+	/// ```
+	pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> {
+		if prefix.len() + 1 != self.len() {
+			return None
+		}
+		for i in 0..prefix.len() {
+			if prefix.at(i) != self.at(i) {
+				return None
+			}
+		}
+		return self.at(prefix.len())
+	}
+
+	/// Mutates `self`, suffixing it with `new`. Returns `Err` in case of overflow.
+	pub fn push(&mut self, new: Junction) -> result::Result<(), ()> {
+		let mut n = MultiLocation::Null;
+		mem::swap(&mut *self, &mut n);
+		match n.pushed_with(new) {
+			Ok(result) => {
+				*self = result;
+				Ok(())
+			},
+			Err(old) => {
+				*self = old;
+				Err(())
+			},
+		}
+	}
+
+	/// Mutates `self`, prefixing it with `new`. Returns `Err` in case of overflow.
+	pub fn push_front(&mut self, new: Junction) -> result::Result<(), ()> {
+		let mut n = MultiLocation::Null;
+		mem::swap(&mut *self, &mut n);
+		match n.pushed_front_with(new) {
+			Ok(result) => {
+				*self = result;
+				Ok(())
+			},
+			Err(old) => {
+				*self = old;
+				Err(())
+			},
+		}
+	}
+
+	/// Returns the number of `Parent` junctions at the beginning of `self`.
+	pub fn leading_parent_count(&self) -> usize {
+		use Junction::Parent;
+		match self {
+			MultiLocation::X8(Parent, Parent, Parent, Parent, Parent, Parent, Parent, Parent) => 8,
+
+			MultiLocation::X8(Parent, Parent, Parent, Parent, Parent, Parent, Parent, ..) => 7,
+			MultiLocation::X7(Parent, Parent, Parent, Parent, Parent, Parent, Parent) => 7,
+
+			MultiLocation::X8(Parent, Parent, Parent, Parent, Parent, Parent, ..) => 6,
+			MultiLocation::X7(Parent, Parent, Parent, Parent, Parent, Parent, ..) => 6,
+			MultiLocation::X6(Parent, Parent, Parent, Parent, Parent, Parent) => 6,
+
+			MultiLocation::X8(Parent, Parent, Parent, Parent, Parent, ..) => 5,
+			MultiLocation::X7(Parent, Parent, Parent, Parent, Parent, ..) => 5,
+			MultiLocation::X6(Parent, Parent, Parent, Parent, Parent, ..) => 5,
+			MultiLocation::X5(Parent, Parent, Parent, Parent, Parent) => 5,
+
+			MultiLocation::X8(Parent, Parent, Parent, Parent, ..) => 4,
+			MultiLocation::X7(Parent, Parent, Parent, Parent, ..) => 4,
+			MultiLocation::X6(Parent, Parent, Parent, Parent, ..) => 4,
+			MultiLocation::X5(Parent, Parent, Parent, Parent, ..) => 4,
+			MultiLocation::X4(Parent, Parent, Parent, Parent) => 4,
+
+			MultiLocation::X8(Parent, Parent, Parent, ..) => 3,
+			MultiLocation::X7(Parent, Parent, Parent, ..) => 3,
+			MultiLocation::X6(Parent, Parent, Parent, ..) => 3,
+			MultiLocation::X5(Parent, Parent, Parent, ..) => 3,
+			MultiLocation::X4(Parent, Parent, Parent, ..) => 3,
+			MultiLocation::X3(Parent, Parent, Parent) => 3,
+
+			MultiLocation::X8(Parent, Parent, ..) => 2,
+			MultiLocation::X7(Parent, Parent, ..) => 2,
+			MultiLocation::X6(Parent, Parent, ..) => 2,
+			MultiLocation::X5(Parent, Parent, ..) => 2,
+			MultiLocation::X4(Parent, Parent, ..) => 2,
+			MultiLocation::X3(Parent, Parent, ..) => 2,
+			MultiLocation::X2(Parent, Parent) => 2,
+
+			MultiLocation::X8(Parent, ..) => 1,
+			MultiLocation::X7(Parent, ..) => 1,
+			MultiLocation::X6(Parent, ..) => 1,
+			MultiLocation::X5(Parent, ..) => 1,
+			MultiLocation::X4(Parent, ..) => 1,
+			MultiLocation::X3(Parent, ..) => 1,
+			MultiLocation::X2(Parent, ..) => 1,
+			MultiLocation::X1(Parent) => 1,
+			_ => 0,
+		}
+	}
+
+	/// This function ensures a multi-junction is in its canonicalized/normalized form, removing
+	/// any internal `[Non-Parent, Parent]` combinations.
+	pub fn canonicalize(&mut self) {
+		let mut normalized = MultiLocation::Null;
+		let mut iter = self.iter();
+		// We build up the the new normalized path by taking items from the original multi-location.
+		// When the next item we would add is `Parent`, we instead remove the last item assuming
+		// it is non-parent.
+		const EXPECT_MESSAGE: &'static str =
+			"`self` is a well formed multi-location with N junctions; \
+			this loop iterates over the junctions of `self`; \
+			the loop can push to the new multi-location at most one time; \
+			thus the size of the new multi-location is at most N junctions; \
+			qed";
+		while let Some(j) = iter.next() {
+			if j == &Junction::Parent {
+				match normalized.last() {
+					None | Some(Junction::Parent) => {},
+					Some(_) => {
+						normalized.take_last();
+						continue
+					},
+				}
+			}
+
+			normalized.push(j.clone()).expect(EXPECT_MESSAGE);
+		}
+
+		core::mem::swap(self, &mut normalized);
+	}
+
+	/// Mutate `self` so that it is suffixed with `suffix`. The correct normalized form is returned,
+	/// removing any internal `[Non-Parent, Parent]`  combinations.
+	///
+	/// In the case of overflow, `self` is unmodified and  we return `Err` with `suffix`.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v0::{MultiLocation::*, Junction::*};
+	/// # fn main() {
+	/// let mut m = X3(Parent, Parachain(21), OnlyChild);
+	/// assert_eq!(m.append_with(X2(Parent, PalletInstance(3))), Ok(()));
+	/// assert_eq!(m, X3(Parent, Parachain(21), PalletInstance(3)));
+	/// # }
+	/// ```
+	pub fn append_with(&mut self, suffix: MultiLocation) -> Result<(), MultiLocation> {
+		let mut prefix = suffix;
+		core::mem::swap(self, &mut prefix);
+		match self.prepend_with(prefix) {
+			Ok(()) => Ok(()),
+			Err(prefix) => {
+				let mut suffix = prefix;
+				core::mem::swap(self, &mut suffix);
+				Err(suffix)
+			},
+		}
+	}
+
+	/// Mutate `self` so that it is prefixed with `prefix`. The correct normalized form is returned,
+	/// removing any internal [Non-Parent, `Parent`] combinations.
+	///
+	/// In the case of overflow, `self` is unmodified and  we return `Err` with `prefix`.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
+	/// # fn main() {
+	/// let mut m = X3(Parent, Parent, PalletInstance(3));
+	/// assert_eq!(m.prepend_with(X3(Parent, Parachain(21), OnlyChild)), Ok(()));
+	/// assert_eq!(m, X2(Parent, PalletInstance(3)));
+	/// # }
+	/// ```
+	pub fn prepend_with(&mut self, prefix: MultiLocation) -> Result<(), MultiLocation> {
+		let mut prefix = prefix;
+
+		// This will guarantee that all `Parent` junctions in the prefix are leading, which is
+		// important for calculating the `skipped` items below.
+		prefix.canonicalize();
+
+		let self_leading_parents = self.leading_parent_count();
+		// These are the number of `non-parent` items in the prefix that we can
+		// potentially remove if the original location leads with parents.
+		let prefix_rest = prefix.len() - prefix.leading_parent_count();
+		// 2 * skipped items will be removed when performing the normalization below.
+		let skipped = self_leading_parents.min(prefix_rest);
+
+		// Pre-pending this prefix would create a multi-location with too many junctions.
+		if self.len() + prefix.len() - 2 * skipped > MAX_MULTILOCATION_LENGTH {
+			return Err(prefix)
+		}
+
+		// Here we cancel out `[Non-Parent, Parent]` items (normalization), where
+		// the non-parent item comes from the end of the prefix, and the parent item
+		// comes from the front of the original location.
+		//
+		// We calculated already how many of these there should be above.
+		for _ in 0..skipped {
+			let _non_parent = prefix.take_last();
+			let _parent = self.take_first();
+			debug_assert!(
+				_non_parent.is_some() && _non_parent != Some(Junction::Parent),
+				"prepend_with should always remove a non-parent from the end of the prefix",
+			);
+			debug_assert!(
+				_parent == Some(Junction::Parent),
+				"prepend_with should always remove a parent from the front of the location",
+			);
+		}
+
+		for j in prefix.into_iter_rev() {
+			self.push_front(j)
+				.expect("len + prefix minus 2*skipped is less than max length; qed");
+		}
+		Ok(())
+	}
+
+	/// Returns true iff `self` is an interior location. For this it may not contain any `Junction`s
+	/// for which `Junction::is_interior` returns `false`. This is generally true, except for the
+	/// `Parent` item.
+	///
+	/// # Example
+	/// ```rust
+	/// # use xcm::v0::{MultiLocation::*, Junction::*, NetworkId::Any};
+	/// # fn main() {
+	/// let parent = X1(Parent);
+	/// assert_eq!(parent.is_interior(), false);
+	/// let m = X2(PalletInstance(12), AccountIndex64 { network: Any, index: 23 });
+	/// assert_eq!(m.is_interior(), true);
+	/// # }
+	/// ```
+	pub fn is_interior(&self) -> bool {
+		self.iter().all(Junction::is_interior)
+	}
+}
+
+impl From<MultiLocation> for VersionedMultiLocation {
+	fn from(x: MultiLocation) -> Self {
+		VersionedMultiLocation::V0(x)
+	}
+}
+
+impl TryFrom<VersionedMultiLocation> for MultiLocation {
+	type Error = ();
+	fn try_from(x: VersionedMultiLocation) -> result::Result<Self, ()> {
+		match x {
+			VersionedMultiLocation::V0(x) => Ok(x),
+		}
+	}
+}
+
+#[cfg(test)]
+mod tests {
+	use super::MultiLocation::*;
+	use crate::opaque::v0::{Junction::*, NetworkId::Any};
+
+	#[test]
+	fn match_and_split_works() {
+		let m = X3(Parent, Parachain(42), AccountIndex64 { network: Any, index: 23 });
+		assert_eq!(m.match_and_split(&X1(Parent)), None);
+		assert_eq!(
+			m.match_and_split(&X2(Parent, Parachain(42))),
+			Some(&AccountIndex64 { network: Any, index: 23 })
+		);
+		assert_eq!(m.match_and_split(&m), None);
+	}
+
+	#[test]
+	fn append_with_works() {
+		let acc = AccountIndex64 { network: Any, index: 23 };
+		let mut m = X2(Parent, Parachain(42));
+		assert_eq!(m.append_with(X2(PalletInstance(3), acc.clone())), Ok(()));
+		assert_eq!(m, X4(Parent, Parachain(42), PalletInstance(3), acc.clone()));
+
+		// cannot append to create overly long multilocation
+		let acc = AccountIndex64 { network: Any, index: 23 };
+		let mut m = X7(Parent, Parent, Parent, Parent, Parent, Parent, Parachain(42));
+		let suffix = X2(PalletInstance(3), acc.clone());
+		assert_eq!(m.append_with(suffix.clone()), Err(suffix));
+	}
+
+	#[test]
+	fn prepend_with_works() {
+		let mut m = X3(Parent, Parachain(42), AccountIndex64 { network: Any, index: 23 });
+		assert_eq!(m.prepend_with(X2(Parent, OnlyChild)), Ok(()));
+		assert_eq!(m, X3(Parent, Parachain(42), AccountIndex64 { network: Any, index: 23 }));
+
+		// cannot prepend to create overly long multilocation
+		let mut m = X7(Parent, Parent, Parent, Parent, Parent, Parent, Parachain(42));
+		let prefix = X2(Parent, Parent);
+		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
+
+		// Can handle shared prefix and resizing correctly.
+		let mut m = X1(Parent);
+		let prefix = X8(
+			Parachain(100),
+			OnlyChild,
+			OnlyChild,
+			OnlyChild,
+			OnlyChild,
+			OnlyChild,
+			OnlyChild,
+			Parent,
+		);
+		assert_eq!(m.prepend_with(prefix.clone()), Ok(()));
+		assert_eq!(m, X5(Parachain(100), OnlyChild, OnlyChild, OnlyChild, OnlyChild));
+
+		let mut m = X1(Parent);
+		let prefix = X8(Parent, Parent, Parent, Parent, Parent, Parent, Parent, Parent);
+		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
+
+		let mut m = X1(Parent);
+		let prefix = X7(Parent, Parent, Parent, Parent, Parent, Parent, Parent);
+		assert_eq!(m.prepend_with(prefix.clone()), Ok(()));
+		assert_eq!(m, X8(Parent, Parent, Parent, Parent, Parent, Parent, Parent, Parent));
+
+		let mut m = X1(Parent);
+		let prefix = X8(Parent, Parent, Parent, Parent, OnlyChild, Parent, Parent, Parent);
+		assert_eq!(m.prepend_with(prefix.clone()), Ok(()));
+		assert_eq!(m, X7(Parent, Parent, Parent, Parent, Parent, Parent, Parent));
+	}
+
+	#[test]
+	fn canonicalize_works() {
+		let mut m = X1(Parent);
+		m.canonicalize();
+		assert_eq!(m, X1(Parent));
+
+		let mut m = X1(Parachain(1));
+		m.canonicalize();
+		assert_eq!(m, X1(Parachain(1)));
+
+		let mut m = X6(Parent, Parachain(1), Parent, Parachain(2), Parent, Parachain(3));
+		m.canonicalize();
+		assert_eq!(m, X2(Parent, Parachain(3)));
+
+		let mut m = X5(Parachain(1), Parent, Parachain(2), Parent, Parachain(3));
+		m.canonicalize();
+		assert_eq!(m, X1(Parachain(3)));
+
+		let mut m = X6(Parachain(1), Parent, Parachain(2), Parent, Parachain(3), Parent);
+		m.canonicalize();
+		assert_eq!(m, Null);
+
+		let mut m = X5(Parachain(1), Parent, Parent, Parent, Parachain(3));
+		m.canonicalize();
+		assert_eq!(m, X3(Parent, Parent, Parachain(3)));
+
+		let mut m = X4(Parachain(1), Parachain(2), Parent, Parent);
+		m.canonicalize();
+		assert_eq!(m, Null);
+
+		let mut m = X4(Parent, Parent, Parachain(1), Parachain(2));
+		m.canonicalize();
+		assert_eq!(m, X4(Parent, Parent, Parachain(1), Parachain(2)));
+	}
+}
diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
new file mode 100644
index 000000000000..c63df711758f
--- /dev/null
+++ b/xcm/src/v0/order.rs
@@ -0,0 +1,154 @@
+// Copyright 2020 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Version 0 of the Cross-Consensus Message format data structures.
+
+use super::{MultiAsset, MultiLocation, Xcm};
+use alloc::vec::Vec;
+use derivative::Derivative;
+use parity_scale_codec::{self, Decode, Encode};
+
+/// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
+#[derive(Derivative, Encode, Decode)]
+#[derivative(Clone(bound = ""), Eq(bound = ""), PartialEq(bound = ""), Debug(bound = ""))]
+#[codec(encode_bound())]
+#[codec(decode_bound())]
+pub enum Order<Call> {
+	/// Do nothing. Not generally used.
+	#[codec(index = 0)]
+	Null,
+
+	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
+	/// this consensus system.
+	///
+	/// - `assets`: The asset(s) to remove from holding.
+	/// - `dest`: The new owner for the assets.
+	///
+	/// Errors:
+	#[codec(index = 1)]
+	DepositAsset { assets: Vec<MultiAsset>, dest: MultiLocation },
+
+	/// Remove the asset(s) (`assets`) from holding and place equivalent assets under the ownership of `dest` within
+	/// this consensus system.
+	///
+	/// Send an onward XCM message to `dest` of `ReserveAssetDeposit` with the given `effects`.
+	///
+	/// - `assets`: The asset(s) to remove from holding.
+	/// - `dest`: The new owner for the assets.
+	/// - `effects`: The orders that should be contained in the `ReserveAssetDeposit` which is sent onwards to
+	///   `dest`.
+	///
+	/// Errors:
+	#[codec(index = 2)]
+	DepositReserveAsset { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+
+	/// Remove the asset(s) (`give`) from holding and replace them with alternative assets.
+	///
+	/// The minimum amount of assets to be received into holding for the order not to fail may be stated.
+	///
+	/// - `give`: The asset(s) to remove from holding.
+	/// - `receive`: The minimum amount of assets(s) which `give` should be exchanged for. The meaning of wildcards
+	///   is undefined and they should be not be used.
+	///
+	/// Errors:
+	#[codec(index = 3)]
+	ExchangeAsset { give: Vec<MultiAsset>, receive: Vec<MultiAsset> },
+
+	/// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a reserve location.
+	///
+	/// - `assets`: The asset(s) to remove from holding.
+	/// - `reserve`: A valid location that acts as a reserve for all asset(s) in `assets`. The sovereign account
+	///   of this consensus system *on the reserve location* will have appropriate assets withdrawn and `effects` will
+	///   be executed on them. There will typically be only one valid location on any given asset/chain combination.
+	/// - `effects`: The orders to execute on the assets once withdrawn *on the reserve location*.
+	///
+	/// Errors:
+	#[codec(index = 4)]
+	InitiateReserveWithdraw {
+		assets: Vec<MultiAsset>,
+		reserve: MultiLocation,
+		effects: Vec<Order<()>>,
+	},
+
+	/// Remove the asset(s) (`assets`) from holding and send a `TeleportAsset` XCM message to a destination location.
+	///
+	/// - `assets`: The asset(s) to remove from holding.
+	/// - `destination`: A valid location that has a bi-lateral teleportation arrangement.
+	/// - `effects`: The orders to execute on the assets once arrived *on the destination location*.
+	///
+	/// Errors:
+	#[codec(index = 5)]
+	InitiateTeleport { assets: Vec<MultiAsset>, dest: MultiLocation, effects: Vec<Order<()>> },
+
+	/// Send a `Balances` XCM message with the `assets` value equal to the holding contents, or a portion thereof.
+	///
+	/// - `query_id`: An identifier that will be replicated into the returned XCM message.
+	/// - `dest`: A valid destination for the returned XCM message. This may be limited to the current origin.
+	/// - `assets`: A filter for the assets that should be reported back. The assets reported back will be, asset-
+	///   wise, *the lesser of this value and the holding account*. No wildcards will be used when reporting assets
+	///   back.
+	///
+	/// Errors:
+	#[codec(index = 6)]
+	QueryHolding {
+		#[codec(compact)]
+		query_id: u64,
+		dest: MultiLocation,
+		assets: Vec<MultiAsset>,
+	},
+
+	/// Pay for the execution of some XCM with up to `weight` picoseconds of execution time, paying for this with
+	/// up to `fees` from the holding account.
+	///
+	/// Errors:
+	#[codec(index = 7)]
+	BuyExecution {
+		fees: MultiAsset,
+		weight: u64,
+		debt: u64,
+		halt_on_error: bool,
+		xcm: Vec<Xcm<Call>>,
+	},
+}
+
+pub mod opaque {
+	pub type Order = super::Order<()>;
+}
+
+impl<Call> Order<Call> {
+	pub fn into<C>(self) -> Order<C> {
+		Order::from(self)
+	}
+	pub fn from<C>(order: Order<C>) -> Self {
+		use Order::*;
+		match order {
+			Null => Null,
+			DepositAsset { assets, dest } => DepositAsset { assets, dest },
+			DepositReserveAsset { assets, dest, effects } =>
+				DepositReserveAsset { assets, dest, effects },
+			ExchangeAsset { give, receive } => ExchangeAsset { give, receive },
+			InitiateReserveWithdraw { assets, reserve, effects } =>
+				InitiateReserveWithdraw { assets, reserve, effects },
+			InitiateTeleport { assets, dest, effects } =>
+				InitiateTeleport { assets, dest, effects },
+			QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest, assets },
+			BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
+				let xcm = xcm.into_iter().map(Xcm::from).collect();
+				BuyExecution { fees, weight, debt, halt_on_error, xcm }
+			},
+		}
+	}
+}
diff --git a/xcm/src/v0/traits.rs b/xcm/src/v0/traits.rs
new file mode 100644
index 000000000000..e1673fd5d990
--- /dev/null
+++ b/xcm/src/v0/traits.rs
@@ -0,0 +1,261 @@
+// Copyright 2020 Parity Technologies (UK) Ltd.
+// This file is part of Cumulus.
+
+// Substrate is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Substrate is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Cross-Consensus Message format data structures.
+
+use core::result;
+use parity_scale_codec::{Decode, Encode};
+
+use super::{MultiLocation, Xcm};
+
+#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
+pub enum Error {
+	Undefined,
+	/// An arithmetic overflow happened.
+	Overflow,
+	/// The operation is intentionally unsupported.
+	Unimplemented,
+	UnhandledXcmVersion,
+	/// The implementation does not handle a given XCM.
+	UnhandledXcmMessage,
+	/// The implementation does not handle an effect present in an XCM.
+	UnhandledEffect,
+	EscalationOfPrivilege,
+	UntrustedReserveLocation,
+	UntrustedTeleportLocation,
+	DestinationBufferOverflow,
+	/// The message and destination was recognized as being reachable but the operation could not be completed.
+	/// A human-readable explanation of the specific issue is provided.
+	SendFailed(#[codec(skip)] &'static str),
+	/// The message and destination combination was not recognized as being reachable.
+	CannotReachDestination(MultiLocation, Xcm<()>),
+	MultiLocationFull,
+	FailedToDecode,
+	BadOrigin,
+	ExceedsMaxMessageSize,
+	/// An asset transaction (like withdraw or deposit) failed.
+	/// See implementers of the `TransactAsset` trait for sources.
+	/// Causes can include type conversion failures between id or balance types.
+	FailedToTransactAsset(#[codec(skip)] &'static str),
+	/// Execution of the XCM would potentially result in a greater weight used than the pre-specified
+	/// weight limit. The amount that is potentially required is the parameter.
+	WeightLimitReached(Weight),
+	/// An asset wildcard was passed where it was not expected (e.g. as the asset to withdraw in a
+	/// `WithdrawAsset` XCM).
+	Wildcard,
+	/// The case where an XCM message has specified a optional weight limit and the weight required for
+	/// processing is too great.
+	///
+	/// Used by:
+	/// - `Transact`
+	TooMuchWeightRequired,
+	/// The fees specified by the XCM message were not found in the holding account.
+	///
+	/// Used by:
+	/// - `BuyExecution`
+	NotHoldingFees,
+	/// The weight of an XCM message is not computable ahead of execution. This generally means at least part
+	/// of the message is invalid, which could be due to it containing overly nested structures or an invalid
+	/// nested data segment (e.g. for the call in `Transact`).
+	WeightNotComputable,
+	/// The XCM did not pass the barrier condition for execution. The barrier condition differs on different
+	/// chains and in different circumstances, but generally it means that the conditions surrounding the message
+	/// were not such that the chain considers the message worth spending time executing. Since most chains
+	/// lift the barrier to execution on appropriate payment, presentation of an NFT voucher, or based on the
+	/// message origin, it means that none of those were the case.
+	Barrier,
+	/// Indicates that it is not possible for a location to have an asset be withdrawn or transferred from its
+	/// ownership. This probably means it doesn't own (enough of) it, but may also indicate that it is under a
+	/// lock, hold, freeze or is otherwise unavailable.
+	NotWithdrawable,
+	/// Indicates that the consensus system cannot deposit an asset under the ownership of a particular location.
+	LocationCannotHold,
+	/// The assets given to purchase weight is are insufficient for the weight desired.
+	TooExpensive,
+	/// The given asset is not handled.
+	AssetNotFound,
+}
+
+impl From<()> for Error {
+	fn from(_: ()) -> Self {
+		Self::Undefined
+	}
+}
+
+pub type Result = result::Result<(), Error>;
+
+/// Local weight type; execution time in picoseconds.
+pub type Weight = u64;
+
+/// Outcome of an XCM execution.
+#[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
+pub enum Outcome {
+	/// Execution completed successfully; given weight was used.
+	Complete(Weight),
+	/// Execution started, but did not complete successfully due to the given error; given weight was used.
+	Incomplete(Weight, Error),
+	/// Execution did not start due to the given error.
+	Error(Error),
+}
+
+impl Outcome {
+	pub fn ensure_complete(self) -> Result {
+		match self {
+			Outcome::Complete(_) => Ok(()),
+			Outcome::Incomplete(_, e) => Err(e),
+			Outcome::Error(e) => Err(e),
+		}
+	}
+	pub fn ensure_execution(self) -> result::Result<Weight, Error> {
+		match self {
+			Outcome::Complete(w) => Ok(w),
+			Outcome::Incomplete(w, _) => Ok(w),
+			Outcome::Error(e) => Err(e),
+		}
+	}
+	/// How much weight was used by the XCM execution attempt.
+	pub fn weight_used(&self) -> Weight {
+		match self {
+			Outcome::Complete(w) => *w,
+			Outcome::Incomplete(w, _) => *w,
+			Outcome::Error(_) => 0,
+		}
+	}
+}
+
+/// Type of XCM message executor.
+pub trait ExecuteXcm<Call> {
+	/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight. The weight limit is
+	/// a basic hard-limit and the implementation may place further restrictions or requirements on weight and
+	/// other aspects.
+	fn execute_xcm(origin: MultiLocation, message: Xcm<Call>, weight_limit: Weight) -> Outcome {
+		log::debug!(
+			target: "xcm::execute_xcm",
+			"origin: {:?}, message: {:?}, weight_limit: {:?}",
+			origin,
+			message,
+			weight_limit,
+		);
+		Self::execute_xcm_in_credit(origin, message, weight_limit, 0)
+	}
+
+	/// Execute some XCM `message` from `origin` using no more than `weight_limit` weight.
+	///
+	/// Some amount of `weight_credit` may be provided which, depending on the implementation, may allow
+	/// execution without associated payment.
+	fn execute_xcm_in_credit(
+		origin: MultiLocation,
+		message: Xcm<Call>,
+		weight_limit: Weight,
+		weight_credit: Weight,
+	) -> Outcome;
+}
+
+impl<C> ExecuteXcm<C> for () {
+	fn execute_xcm_in_credit(
+		_origin: MultiLocation,
+		_message: Xcm<C>,
+		_weight_limit: Weight,
+		_weight_credit: Weight,
+	) -> Outcome {
+		Outcome::Error(Error::Unimplemented)
+	}
+}
+
+/// Utility for sending an XCM message.
+///
+/// These can be amalgamated in tuples to form sophisticated routing systems. In tuple format, each router might return
+/// `CannotReachDestination` to pass the execution to the next sender item. Note that each `CannotReachDestination`
+/// might alter the destination and the XCM message for to the next router.
+///
+///
+/// # Example
+/// ```rust
+/// # use xcm::v0::{MultiLocation, Xcm, Junction, Error, OriginKind, SendXcm, Result};
+/// # use parity_scale_codec::Encode;
+///
+/// /// A sender that only passes the message through and does nothing.
+/// struct Sender1;
+/// impl SendXcm for Sender1 {
+///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
+///         return Err(Error::CannotReachDestination(destination, message))
+///     }
+/// }
+///
+/// /// A sender that accepts a message that has an X2 junction, otherwise stops the routing.
+/// struct Sender2;
+/// impl SendXcm for Sender2 {
+///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
+///         if let MultiLocation::X2(j1, j2) = destination {
+///             Ok(())
+///         } else {
+///             Err(Error::Undefined)
+///         }
+///     }
+/// }
+///
+/// /// A sender that accepts a message from an X1 parent junction, passing through otherwise.
+/// struct Sender3;
+/// impl SendXcm for Sender3 {
+///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
+///         match destination {
+///             MultiLocation::X1(j) if j == Junction::Parent => Ok(()),
+///             _ => Err(Error::CannotReachDestination(destination, message)),
+///         }
+///     }
+/// }
+///
+/// // A call to send via XCM. We don't really care about this.
+/// # fn main() {
+/// let call: Vec<u8> = ().encode();
+/// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
+/// let destination = MultiLocation::X1(Junction::Parent);
+///
+/// assert!(
+///     // Sender2 will block this.
+///     <(Sender1, Sender2, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
+///         .is_err()
+/// );
+///
+/// assert!(
+///     // Sender3 will catch this.
+///     <(Sender1, Sender3) as SendXcm>::send_xcm(destination.clone(), message.clone())
+///         .is_ok()
+/// );
+/// # }
+/// ```
+pub trait SendXcm {
+	/// Send an XCM `message` to a given `destination`.
+	///
+	/// If it is not a destination which can be reached with this type but possibly could by others, then it *MUST*
+	/// return `CannotReachDestination`. Any other error will cause the tuple implementation to exit early without
+	/// trying other type fields.
+	fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result;
+}
+
+#[impl_trait_for_tuples::impl_for_tuples(30)]
+impl SendXcm for Tuple {
+	fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
+		for_tuples!( #(
+			// we shadow `destination` and `message` in each expansion for the next one.
+			let (destination, message) = match Tuple::send_xcm(destination, message) {
+				Err(Error::CannotReachDestination(d, m)) => (d, m),
+				o @ _ => return o,
+			};
+		)* );
+		Err(Error::CannotReachDestination(destination, message))
+	}
+}

From 9f8606d7e6e2870f884989167bb061a7be705c07 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 11:30:39 +0200
Subject: [PATCH 090/166] Remove VersionedMultiLocation

---
 xcm/src/lib.rs               | 24 +-----------------------
 xcm/src/v0/multi_location.rs | 16 ----------------
 2 files changed, 1 insertion(+), 39 deletions(-)

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index 0300e8f23c6d..d12d9e864a69 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -27,6 +27,7 @@ use core::{convert::TryFrom, result::Result};
 use derivative::Derivative;
 use parity_scale_codec::{Decode, Encode, Error as CodecError, Input};
 
+pub mod v0;
 pub mod v1;
 
 pub mod latest {
@@ -92,26 +93,3 @@ pub mod opaque {
 	/// The basic `VersionedXcm` type which just uses the `Vec<u8>` as an encoded call.
 	pub type VersionedXcm = super::VersionedXcm<()>;
 }
-
-/// A versioned multi-location, a relative location of a cross-consensus system identifier.
-#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
-pub enum VersionedMultiLocation {
-	V0(v0::MultiLocation),
-	V1(v1::MultiLocation),
-}
-
-impl From<v1::MultiLocation> for VersionedMultiLocation {
-	fn from(x: v1::MultiLocation) -> Self {
-		VersionedMultiLocation::V1(x)
-	}
-}
-
-impl TryFrom<VersionedMultiLocation> for v1::MultiLocation {
-	type Error = ();
-	fn try_from(x: VersionedMultiLocation) -> Result<Self, ()> {
-		match x {
-			VersionedMultiLocation::V0(x) => Ok(x),
-			VersionedMultiLocation::V1(x) => Ok(x),
-		}
-	}
-}
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index e45df25a0ff6..a54610ea6509 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -19,7 +19,6 @@
 use core::{convert::TryFrom, mem, result};
 
 use super::Junction;
-use crate::VersionedMultiLocation;
 use parity_scale_codec::{self, Decode, Encode};
 
 /// A relative path between state-bearing consensus systems.
@@ -697,21 +696,6 @@ impl MultiLocation {
 	}
 }
 
-impl From<MultiLocation> for VersionedMultiLocation {
-	fn from(x: MultiLocation) -> Self {
-		VersionedMultiLocation::V0(x)
-	}
-}
-
-impl TryFrom<VersionedMultiLocation> for MultiLocation {
-	type Error = ();
-	fn try_from(x: VersionedMultiLocation) -> result::Result<Self, ()> {
-		match x {
-			VersionedMultiLocation::V0(x) => Ok(x),
-		}
-	}
-}
-
 #[cfg(test)]
 mod tests {
 	use super::MultiLocation::*;

From 1c4a89a6504b384fcf0ef1130c7840286ce9eac5 Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 12:35:44 +0200
Subject: [PATCH 091/166] Update xcm/src/v1/order.rs

Co-authored-by: Amar Singh <asinghchrony@protonmail.com>
---
 xcm/src/v1/order.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index 0c92e5c4ce8c..e588bdf40e25 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
 
-//! Version 0 of the Cross-Consensus Message format data structures.
+//! Version 1 of the Cross-Consensus Message format data structures.
 
 use super::{MultiAsset, MultiAssetFilter, MultiLocation, Xcm};
 use alloc::vec::Vec;

From d3fb09069eb505eb1903fc32b377b326e796237e Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 12:35:49 +0200
Subject: [PATCH 092/166] Update xcm/src/v1/mod.rs

Co-authored-by: Amar Singh <asinghchrony@protonmail.com>
---
 xcm/src/v1/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index c78506c5c042..535e8ad11333 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
 
-//! Version 0 of the Cross-Consensus Message format data structures.
+//! Version 1 of the Cross-Consensus Message format data structures.
 
 use crate::DoubleEncoded;
 use alloc::vec::Vec;

From a5c2bde937926c2c8acfaa317c97b7e65d1d7be8 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 13:33:55 +0200
Subject: [PATCH 093/166] XCM v0 backwards compatibility

---
 xcm/src/lib.rs               |   5 +-
 xcm/src/v0/junction.rs       | 194 -----------------------------------
 xcm/src/v0/mod.rs            |  40 +-------
 xcm/src/v0/multi_asset.rs    |  43 ++------
 xcm/src/v0/multi_location.rs |   2 +-
 xcm/src/v1/junction.rs       |   5 +-
 xcm/src/v1/mod.rs            |  45 +++++++-
 xcm/src/v1/multiasset.rs     |  93 ++++++++++++++++-
 xcm/src/v1/multilocation.rs  |  18 ++++
 xcm/src/v1/order.rs          |  32 +++++-
 10 files changed, 198 insertions(+), 279 deletions(-)
 delete mode 100644 xcm/src/v0/junction.rs

diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index d12d9e864a69..5e39800da19c 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -23,7 +23,7 @@
 #![no_std]
 extern crate alloc;
 
-use core::{convert::TryFrom, result::Result};
+use core::{convert::{TryFrom, TryInto}, result::Result};
 use derivative::Derivative;
 use parity_scale_codec::{Decode, Encode, Error as CodecError, Input};
 
@@ -66,8 +66,9 @@ impl<Call> TryFrom<VersionedXcm<Call>> for v1::Xcm<Call> {
 	type Error = ();
 	fn try_from(x: VersionedXcm<Call>) -> Result<Self, ()> {
 		match x {
+			// v1-based chains can interpret v0 messages.
+			VersionedXcm::V0(x) => x.try_into(),
 			VersionedXcm::V1(x) => Ok(x),
-			_ => Err(()),
 		}
 	}
 }
diff --git a/xcm/src/v0/junction.rs b/xcm/src/v0/junction.rs
deleted file mode 100644
index cf474f62851a..000000000000
--- a/xcm/src/v0/junction.rs
+++ /dev/null
@@ -1,194 +0,0 @@
-// Copyright 2020 Parity Technologies (UK) Ltd.
-// This file is part of Cumulus.
-
-// Substrate is free software: you can redistribute it and/or modify
-// it under the terms of the GNU General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-
-// Substrate is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-// You should have received a copy of the GNU General Public License
-// along with Cumulus.  If not, see <http://www.gnu.org/licenses/>.
-
-//! Support data structures for `MultiLocation`, primarily the `Junction` datatype.
-
-use alloc::vec::Vec;
-use parity_scale_codec::{self, Decode, Encode};
-
-/// A global identifier of an account-bearing consensus system.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum NetworkId {
-	/// Unidentified/any.
-	Any,
-	/// Some named network.
-	Named(Vec<u8>),
-	/// The Polkadot Relay chain
-	Polkadot,
-	/// Kusama.
-	Kusama,
-}
-
-/// An identifier of a pluralistic body.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum BodyId {
-	/// The only body in its context.
-	Unit,
-	/// A named body.
-	Named(Vec<u8>),
-	/// An indexed body.
-	// TODO: parity-scale-codec#262: Change to be a tuple.
-	Index {
-		#[codec(compact)]
-		id: u32,
-	},
-	/// The unambiguous executive body (for Polkadot, this would be the Polkadot council).
-	Executive,
-	/// The unambiguous technical body (for Polkadot, this would be the Technical Committee).
-	Technical,
-	/// The unambiguous legislative body (for Polkadot, this could be considered the opinion of a majority of
-	/// lock-voters).
-	Legislative,
-	/// The unambiguous judicial body (this doesn't exist on Polkadot, but if it were to get a "grand oracle", it
-	/// may be considered as that).
-	Judicial,
-}
-
-/// A part of a pluralistic body.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum BodyPart {
-	/// The body's declaration, under whatever means it decides.
-	Voice,
-	/// A given number of members of the body.
-	Members {
-		#[codec(compact)]
-		count: u32,
-	},
-	/// A given number of members of the body, out of some larger caucus.
-	Fraction {
-		#[codec(compact)]
-		nom: u32,
-		#[codec(compact)]
-		denom: u32,
-	},
-	/// No less than the given proportion of members of the body.
-	AtLeastProportion {
-		#[codec(compact)]
-		nom: u32,
-		#[codec(compact)]
-		denom: u32,
-	},
-	/// More than than the given proportion of members of the body.
-	MoreThanProportion {
-		#[codec(compact)]
-		nom: u32,
-		#[codec(compact)]
-		denom: u32,
-	},
-}
-
-impl BodyPart {
-	/// Returns `true` if the part represents a strict majority (> 50%) of the body in question.
-	pub fn is_majority(&self) -> bool {
-		match self {
-			BodyPart::Fraction { nom, denom } if *nom * 2 > *denom => true,
-			BodyPart::AtLeastProportion { nom, denom } if *nom * 2 > *denom => true,
-			BodyPart::MoreThanProportion { nom, denom } if *nom * 2 >= *denom => true,
-			_ => false,
-		}
-	}
-}
-
-/// A single item in a path to describe the relative location of a consensus system.
-///
-/// Each item assumes a pre-existing location as its context and is defined in terms of it.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum Junction {
-	/// The consensus system of which the context is a member and state-wise super-set.
-	///
-	/// NOTE: This item is *not* a sub-consensus item: a consensus system may not identify itself trustlessly as
-	/// a location that includes this junction.
-	Parent,
-	/// An indexed parachain belonging to and operated by the context.
-	///
-	/// Generally used when the context is a Polkadot Relay-chain.
-	Parachain(#[codec(compact)] u32),
-	/// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
-	/// the context.
-	///
-	/// Generally used when the context is a Substrate-based chain.
-	AccountId32 { network: NetworkId, id: [u8; 32] },
-	/// An 8-byte index for an account of a specific network that is respected as a sovereign endpoint within
-	/// the context.
-	///
-	/// May be used when the context is a Frame-based chain and includes e.g. an indices pallet.
-	AccountIndex64 {
-		network: NetworkId,
-		#[codec(compact)]
-		index: u64,
-	},
-	/// A 20-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
-	/// the context.
-	///
-	/// May be used when the context is an Ethereum or Bitcoin chain or smart-contract.
-	AccountKey20 { network: NetworkId, key: [u8; 20] },
-	/// An instanced, indexed pallet that forms a constituent part of the context.
-	///
-	/// Generally used when the context is a Frame-based chain.
-	PalletInstance(u8),
-	/// A non-descript index within the context location.
-	///
-	/// Usage will vary widely owing to its generality.
-	///
-	/// NOTE: Try to avoid using this and instead use a more specific item.
-	GeneralIndex {
-		#[codec(compact)]
-		id: u128,
-	},
-	/// A nondescript datum acting as a key within the context location.
-	///
-	/// Usage will vary widely owing to its generality.
-	///
-	/// NOTE: Try to avoid using this and instead use a more specific item.
-	GeneralKey(Vec<u8>),
-	/// The unambiguous child.
-	///
-	/// Not currently used except as a fallback when deriving ancestry.
-	OnlyChild,
-	/// A pluralistic body existing within consensus.
-	///
-	/// Typical to be used to represent a governance origin of a chain, but could in principle be used to represent
-	/// things such as multisigs also.
-	Plurality { id: BodyId, part: BodyPart },
-}
-
-impl Junction {
-	/// Returns true if this junction is a `Parent` item.
-	pub fn is_parent(&self) -> bool {
-		match self {
-			Junction::Parent => true,
-			_ => false,
-		}
-	}
-
-	/// Returns true if this junction can be considered an interior part of its context. This is generally `true`,
-	/// except for the `Parent` item.
-	pub fn is_interior(&self) -> bool {
-		match self {
-			Junction::Parent => false,
-
-			Junction::Parachain(..) |
-			Junction::AccountId32 { .. } |
-			Junction::AccountIndex64 { .. } |
-			Junction::AccountKey20 { .. } |
-			Junction::PalletInstance { .. } |
-			Junction::GeneralIndex { .. } |
-			Junction::GeneralKey(..) |
-			Junction::OnlyChild |
-			Junction::Plurality { .. } => true,
-		}
-	}
-}
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 6ebfe3a960a1..ffef612499c6 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -18,16 +18,14 @@
 
 use crate::{DoubleEncoded, VersionedXcm};
 use alloc::vec::Vec;
-use core::{convert::TryFrom, fmt::Debug, result};
+use core::{convert::TryFrom, result};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
-mod junction;
 mod multi_asset;
 mod multi_location;
 mod order;
 mod traits;
-pub use junction::{BodyId, BodyPart, Junction, NetworkId};
 pub use multi_asset::{AssetInstance, MultiAsset};
 pub use multi_location::MultiLocation;
 pub use order::Order;
@@ -36,7 +34,7 @@ pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
 	pub use super::{
-		junction::{BodyId, BodyPart, Junction::*, NetworkId},
+		BodyId, BodyPart, Junction::*, NetworkId,
 		multi_asset::{
 			AssetInstance::{self, *},
 			MultiAsset::{self, *},
@@ -49,38 +47,7 @@ pub mod prelude {
 	};
 }
 
-// TODO: #2841 #XCMENCODE Efficient encodings for Vec<MultiAsset>, Vec<Order>, using initial byte values 128+ to encode
-//   the number of items in the vector.
-
-/// Basically just the XCM (more general) version of `ParachainDispatchOrigin`.
-#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug)]
-pub enum OriginKind {
-	/// Origin should just be the native dispatch origin representation for the sender in the
-	/// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin
-	/// if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a
-	/// primary/native dispatch origin form.
-	Native,
-
-	/// Origin should just be the standard account-based origin with the sovereign account of
-	/// the sender. For Cumulus/Frame chains, this is the `Signed` origin.
-	SovereignAccount,
-
-	/// Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin.
-	/// This will not usually be an available option.
-	Superuser,
-
-	/// Origin should be interpreted as an XCM native origin and the `MultiLocation` should be
-	/// encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be
-	/// the `pallet_xcm::Origin::Xcm` type.
-	Xcm,
-}
-
-/// Response data to a query.
-#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
-pub enum Response {
-	/// Some assets.
-	Assets(Vec<MultiAsset>),
-}
+pub use super::v1::{Response, OriginKind, BodyId, BodyPart, Junction, NetworkId};
 
 /// Cross-Consensus Message: A message from one consensus system to another.
 ///
@@ -286,6 +253,7 @@ impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
 	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
 		match x {
 			VersionedXcm::V0(x) => Ok(x),
+			VersionedXcm::V1(_) => Err(()),	// v0-based chains cannot interpret v1 messages.
 		}
 	}
 }
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
index 9a4b251ab312..d89d13dd4e0c 100644
--- a/xcm/src/v0/multi_asset.rs
+++ b/xcm/src/v0/multi_asset.rs
@@ -17,39 +17,10 @@
 //! Cross-Consensus Message format data structures.
 
 use alloc::vec::Vec;
-use core::{convert::TryFrom, result};
-
 use super::MultiLocation;
 use parity_scale_codec::{self, Decode, Encode};
 
-/// A general identifier for an instance of a non-fungible asset class.
-#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
-pub enum AssetInstance {
-	/// Undefined - used if the NFA class has only one instance.
-	Undefined,
-
-	/// A compact index. Technically this could be greater than `u128`, but this implementation supports only
-	/// values up to `2**128 - 1`.
-	Index {
-		#[codec(compact)]
-		id: u128,
-	},
-
-	/// A 4-byte fixed-length datum.
-	Array4([u8; 4]),
-
-	/// An 8-byte fixed-length datum.
-	Array8([u8; 8]),
-
-	/// A 16-byte fixed-length datum.
-	Array16([u8; 16]),
-
-	/// A 32-byte fixed-length datum.
-	Array32([u8; 32]),
-
-	/// An arbitrary piece of data. Use only when necessary.
-	Blob(Vec<u8>),
-}
+pub use super::super::v1::AssetInstance;
 
 /// A single general identifier for an asset.
 ///
@@ -354,27 +325,27 @@ mod tests {
 		// For non-fungibles, containing is equality.
 		assert!(!AbstractNonFungible {
 			class: vec![99u8],
-			instance: AssetInstance::Index { id: 9 }
+			instance: AssetInstance::Index(9)
 		}
 		.contains(&AbstractNonFungible {
 			class: vec![98u8],
-			instance: AssetInstance::Index { id: 9 }
+			instance: AssetInstance::Index(9)
 		}));
 		assert!(!AbstractNonFungible {
 			class: vec![99u8],
-			instance: AssetInstance::Index { id: 8 }
+			instance: AssetInstance::Index(8)
 		}
 		.contains(&AbstractNonFungible {
 			class: vec![99u8],
-			instance: AssetInstance::Index { id: 9 }
+			instance: AssetInstance::Index(9)
 		}));
 		assert!(AbstractNonFungible {
 			class: vec![99u8],
-			instance: AssetInstance::Index { id: 9 }
+			instance: AssetInstance::Index(9)
 		}
 		.contains(&AbstractNonFungible {
 			class: vec![99u8],
-			instance: AssetInstance::Index { id: 9 }
+			instance: AssetInstance::Index(9)
 		}));
 	}
 }
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index a54610ea6509..41ef20dfffd9 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -16,7 +16,7 @@
 
 //! Cross-Consensus Message format data structures.
 
-use core::{convert::TryFrom, mem, result};
+use core::{mem, result};
 
 use super::Junction;
 use parity_scale_codec::{self, Decode, Encode};
diff --git a/xcm/src/v1/junction.rs b/xcm/src/v1/junction.rs
index cf474f62851a..981756f5536b 100644
--- a/xcm/src/v1/junction.rs
+++ b/xcm/src/v1/junction.rs
@@ -41,10 +41,7 @@ pub enum BodyId {
 	Named(Vec<u8>),
 	/// An indexed body.
 	// TODO: parity-scale-codec#262: Change to be a tuple.
-	Index {
-		#[codec(compact)]
-		id: u32,
-	},
+	Index(#[codec(compact)] u32),
 	/// The unambiguous executive body (for Polkadot, this would be the Polkadot council).
 	Executive,
 	/// The unambiguous technical body (for Polkadot, this would be the Technical Committee).
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index c78506c5c042..41d909074651 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -18,7 +18,8 @@
 
 use crate::DoubleEncoded;
 use alloc::vec::Vec;
-use core::fmt::Debug;
+use core::{fmt::Debug, convert::{TryFrom, TryInto}, result};
+use super::v0::{Xcm as Xcm0, MultiLocation as MultiLocation0};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
@@ -37,6 +38,7 @@ pub use multilocation::MultiLocation;
 pub use order::Order;
 pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 
+
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
 	pub use super::{
@@ -332,3 +334,44 @@ pub mod opaque {
 
 	pub use super::order::opaque::*;
 }
+
+impl<Call> TryFrom<Xcm0<Call>> for Xcm<Call> {
+	type Error = ();
+	fn try_from(old: Xcm0<Call>) -> result::Result<Xcm<Call>, ()> {
+		use Xcm::*;
+		Ok(match old {
+			Xcm0::WithdrawAsset { assets, effects } =>
+				WithdrawAsset {
+					assets: assets.try_into()?,
+					effects: effects.into_iter()
+						.map(Order::try_from)
+						.collect::<result::Result<_, _>>()?,
+				},
+			Xcm0::ReserveAssetDeposit { assets, effects } => ReserveAssetDeposited {
+				assets: assets.try_into()?,
+				effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+			},
+			Xcm0::TeleportAsset { assets, effects } => ReceiveTeleportedAsset {
+				assets: assets.try_into()?,
+				effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+			},
+			Xcm0::QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response },
+			Xcm0::TransferAsset { assets, dest } => TransferAsset { assets: assets.try_into()?, beneficiary: dest.into() },
+			Xcm0::TransferReserveAsset { assets, dest, effects } =>
+				TransferReserveAsset {
+					assets: assets.try_into()?,
+					dest: dest.into(),
+					effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+				},
+			Xcm0::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } =>
+				HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity },
+			Xcm0::HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient },
+			Xcm0::HrmpChannelClosing { initiator, sender, recipient } =>
+				HrmpChannelClosing { initiator, sender, recipient },
+			Xcm0::Transact { origin_type, require_weight_at_most, call } =>
+				Transact { origin_type, require_weight_at_most, call: call.into() },
+			Xcm0::RelayedFrom { who, message } =>
+				RelayedFrom { who: who.into(), message: alloc::boxed::Box::new((*message).try_into()?) },
+		})
+	}
+}
diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index a52725a58c1a..1b9f693ce054 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -28,7 +28,7 @@ use super::{
 	MultiLocation::{self, X1},
 };
 use alloc::{vec, vec::Vec};
-use core::cmp::Ordering;
+use core::{cmp::Ordering, convert::{TryFrom, TryInto}, result};
 use parity_scale_codec::{self as codec, Decode, Encode};
 
 /// A general identifier for an instance of a non-fungible asset class.
@@ -231,6 +231,44 @@ impl MultiAsset {
 	}
 }
 
+impl TryFrom<super::super::v0::MultiAsset> for MultiAsset {
+	type Error = ();
+	fn try_from(old: super::super::v0::MultiAsset) -> result::Result<MultiAsset, ()> {
+		use super::super::v0::MultiAsset as V0;
+		use Fungibility::*;
+		use AssetId::*;
+		let (id, fun) = match old {
+			V0::ConcreteFungible { id, amount } => (Concrete(id.into()), Fungible(amount)),
+			V0::ConcreteNonFungible { class, instance } => (Concrete(class.into()), NonFungible(instance)),
+			V0::AbstractFungible { id, amount } => (Abstract(id), Fungible(amount)),
+			V0::AbstractNonFungible { class, instance } => (Abstract(class), NonFungible(instance)),
+			_ => return Err(()),
+		};
+		Ok(MultiAsset { id, fun })
+	}
+}
+
+impl TryFrom<super::super::v0::MultiAsset> for Option<MultiAsset> {
+	type Error = ();
+	fn try_from(old: super::super::v0::MultiAsset) -> result::Result<Option<MultiAsset>, ()> {
+		match old {
+			super::super::v0::MultiAsset::None => return Ok(None),
+			x => return Ok(Some(x.try_into()?)),
+		}
+	}
+}
+
+impl TryFrom<Vec<super::super::v0::MultiAsset>> for MultiAsset {
+	type Error = ();
+	fn try_from(mut old: Vec<super::super::v0::MultiAsset>) -> result::Result<MultiAsset, ()> {
+		if old.len() == 1 {
+			old.remove(0).try_into()
+		} else {
+			Err(())
+		}
+	}
+}
+
 /// A `Vec` of `MultiAsset`s. There may be no duplicate fungible items in here and when decoding, they must be sorted.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Encode)]
 pub struct MultiAssets(Vec<MultiAsset>);
@@ -242,6 +280,17 @@ impl Decode for MultiAssets {
 	}
 }
 
+impl TryFrom<Vec<super::super::v0::MultiAsset>> for MultiAssets {
+	type Error = ();
+	fn try_from(old: Vec<super::super::v0::MultiAsset>) -> result::Result<MultiAssets, ()> {
+		let v = old.into_iter()
+			.map(Option::<MultiAsset>::try_from)
+			.filter_map(|x| x.transpose())
+			.collect::<result::Result<Vec<MultiAsset>, ()>>()?;
+		Ok(v.into())
+	}
+}
+
 impl From<Vec<MultiAsset>> for MultiAssets {
 	fn from(mut assets: Vec<MultiAsset>) -> Self {
 		let mut res = Vec::with_capacity(assets.len());
@@ -390,7 +439,36 @@ pub enum WildMultiAsset {
 	All,
 	/// All assets in the holding register of a given fungibility and ID. If operating on non-fungibles, then a limit
 	/// is provided for the maximum amount of matching instances.
-	AllOf { fun: WildFungibility, id: AssetId },
+	AllOf { id: AssetId, fun: WildFungibility },
+}
+
+impl TryFrom<super::super::v0::MultiAsset> for WildMultiAsset {
+	type Error = ();
+	fn try_from(old: super::super::v0::MultiAsset) -> result::Result<WildMultiAsset, ()> {
+		use super::super::v0::MultiAsset as V0;
+		use WildFungibility::*;
+		use AssetId::*;
+		let (id, fun) = match old {
+			V0::All => return Ok(WildMultiAsset::All),
+			V0::AllConcreteFungible { id } => (Concrete(id.into()), Fungible),
+			V0::AllConcreteNonFungible { class } => (Concrete(class.into()), NonFungible),
+			V0::AllAbstractFungible { id } => (Abstract(id), Fungible),
+			V0::AllAbstractNonFungible { class } => (Abstract(class), NonFungible),
+			_ => return Err(()),
+		};
+		Ok(WildMultiAsset::AllOf { id, fun })
+	}
+}
+
+impl TryFrom<Vec<super::super::v0::MultiAsset>> for WildMultiAsset {
+	type Error = ();
+	fn try_from(mut old: Vec<super::super::v0::MultiAsset>) -> result::Result<WildMultiAsset, ()> {
+		if old.len() == 1 {
+			old.remove(0).try_into()
+		} else {
+			Err(())
+		}
+	}
 }
 
 impl WildMultiAsset {
@@ -476,3 +554,14 @@ impl MultiAssetFilter {
 		}
 	}
 }
+
+impl TryFrom<Vec<super::super::v0::MultiAsset>> for MultiAssetFilter {
+	type Error = ();
+	fn try_from(mut old: Vec<super::super::v0::MultiAsset>) -> result::Result<MultiAssetFilter, ()> {
+		if old.len() == 1 && old[0].is_wildcard() {
+			Ok(MultiAssetFilter::Wild(old.remove(0).try_into()?))
+		} else {
+			Ok(MultiAssetFilter::Definite(old.try_into()?))
+		}
+	}
+}
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index e44d5f76a289..1181cdea9ef5 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -696,6 +696,24 @@ impl MultiLocation {
 	}
 }
 
+impl From<super::MultiLocation0> for MultiLocation {
+	fn from(old: super::MultiLocation0) -> Self {
+		use MultiLocation::*;
+		use super::MultiLocation0;
+		match old {
+			MultiLocation0::Null => Here,
+			MultiLocation0::X1(j0) => X1(j0),
+			MultiLocation0::X2(j0, j1) => X2(j0, j1),
+			MultiLocation0::X3(j0, j1, j2) => X3(j0, j1, j2),
+			MultiLocation0::X4(j0, j1, j2, j3) => X4(j0, j1, j2, j3),
+			MultiLocation0::X5(j0, j1, j2, j3, j4) => X5(j0, j1, j2, j3, j4),
+			MultiLocation0::X6(j0, j1, j2, j3, j4, j5) => X6(j0, j1, j2, j3, j4, j5),
+			MultiLocation0::X7(j0, j1, j2, j3, j4, j5, j6) => X7(j0, j1, j2, j3, j4, j5, j6),
+			MultiLocation0::X8(j0, j1, j2, j3, j4, j5, j6, j7) => X8(j0, j1, j2, j3, j4, j5, j6, j7),
+		}
+	}
+}
+
 #[cfg(test)]
 mod tests {
 	use super::MultiLocation::*;
diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index 0c92e5c4ce8c..e6abaa81e696 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -16,8 +16,9 @@
 
 //! Version 0 of the Cross-Consensus Message format data structures.
 
-use super::{MultiAsset, MultiAssetFilter, MultiLocation, Xcm};
-use alloc::vec::Vec;
+use core::{convert::{TryFrom, TryInto}, result};
+use alloc::{vec, vec::Vec};
+use super::{MultiAsset, MultiAssets, MultiAssetFilter, MultiLocation, Xcm};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
@@ -76,7 +77,7 @@ pub enum Order<Call> {
 	///
 	/// Errors:
 	#[codec(index = 3)]
-	ExchangeAsset { give: MultiAssetFilter, receive: Vec<MultiAsset> },
+	ExchangeAsset { give: MultiAssetFilter, receive: MultiAssets },
 
 	/// Remove the asset(s) (`assets`) from holding and send a `WithdrawAsset` XCM message to a reserve location.
 	///
@@ -181,3 +182,28 @@ impl<Call> Order<Call> {
 		}
 	}
 }
+
+impl<Call> TryFrom<super::super::v0::Order<Call>> for Order<Call> {
+	type Error = ();
+	fn try_from(old: super::super::v0::Order<Call>) -> result::Result<Order<Call>, ()> {
+		use Order::*;
+		use super::super::v0::Order as Order0;
+		Ok(match old {
+			Order0::Null => Noop,
+			Order0::DepositAsset { assets, dest } =>
+				DepositAsset { assets: assets.try_into()?, max_assets: 1, beneficiary: dest.into() },
+			Order0::DepositReserveAsset { assets, dest, effects } =>
+				DepositReserveAsset { assets: assets.try_into()?, max_assets: 1, dest: dest.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
+			Order0::ExchangeAsset { give, receive } => ExchangeAsset { give: give.try_into()?, receive: receive.try_into()? },
+			Order0::InitiateReserveWithdraw { assets, reserve, effects } =>
+				InitiateReserveWithdraw { assets: assets.try_into()?, reserve: reserve.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
+			Order0::InitiateTeleport { assets, dest, effects } =>
+				InitiateTeleport { assets: assets.try_into()?, dest: dest.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
+			Order0::QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest: dest.into(), assets: assets.try_into()? },
+			Order0::BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
+				let instructions = xcm.into_iter().map(Xcm::<Call>::try_from).collect::<result::Result<_, _>>()?;
+				BuyExecution { fees: fees.try_into()?, weight, debt, halt_on_error, orders: vec![], instructions }
+			},
+		})
+	}
+}

From 7130ed71671649ee0e44ca8817944398e29410d4 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 15:01:58 +0200
Subject: [PATCH 094/166] Full compatibility

---
 runtime/common/src/xcm_sender.rs | 17 +++++-----
 runtime/kusama/src/lib.rs        |  2 +-
 runtime/rococo/src/lib.rs        |  2 +-
 runtime/westend/src/lib.rs       |  2 +-
 xcm/src/v0/mod.rs                | 44 +++++++++++++++++++++++++-
 xcm/src/v0/multi_asset.rs        | 53 ++++++++++++++++++++++++++++++--
 xcm/src/v0/multi_location.rs     | 19 +++++++++++-
 xcm/src/v0/order.rs              | 29 +++++++++++++++++
 xcm/src/v1/mod.rs                |  6 ++--
 xcm/src/v1/multilocation.rs      |  8 ++---
 xcm/src/v1/order.rs              |  6 ++--
 xcm/src/v1/traits.rs             | 25 +++++++++++++--
 12 files changed, 185 insertions(+), 28 deletions(-)

diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs
index 819f9b0b0617..247c345873ac 100644
--- a/runtime/common/src/xcm_sender.rs
+++ b/runtime/common/src/xcm_sender.rs
@@ -20,28 +20,29 @@ use parity_scale_codec::Encode;
 use runtime_parachains::{configuration, dmp};
 use sp_std::marker::PhantomData;
 use xcm::opaque::{
-	v1::{Error, Junction, MultiLocation, Result, SendXcm, Xcm},
-	VersionedXcm,
+	v1::{Error, Junction, MultiLocation, Result, SendXcm, Xcm, WrapVersion},
 };
+use xcm::v1::prelude::XcmError;
 
 /// XCM sender for relay chain. It only sends downward message.
-pub struct ChildParachainRouter<T>(PhantomData<T>);
+pub struct ChildParachainRouter<T, W>(PhantomData<(T, W)>);
 
-impl<T: configuration::Config + dmp::Config> SendXcm for ChildParachainRouter<T> {
+impl<T: configuration::Config + dmp::Config, W: WrapVersion> SendXcm for ChildParachainRouter<T, W> {
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {
-		match dest {
+		match &dest {
 			MultiLocation::X1(Junction::Parachain(id)) => {
 				// Downward message passing.
+				let versioned_xcm = W::wrap_version(&dest, msg).map_err(|()| Error::DestinationUnsupported)?;
 				let config = <configuration::Pallet<T>>::config();
 				<dmp::Pallet<T>>::queue_downward_message(
 					&config,
-					id.into(),
-					VersionedXcm::from(msg).encode(),
+					(*id).into(),
+					versioned_xcm.encode(),
 				)
 				.map_err(Into::<Error>::into)?;
 				Ok(())
 			},
-			d => Err(Error::CannotReachDestination(d, msg)),
+			d => Err(Error::CannotReachDestination(dest, msg)),
 		}
 	}
 }
diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index 32a5455b8d13..dc00d4d7a7ea 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1258,7 +1258,7 @@ parameter_types! {
 /// individual routers.
 pub type XcmRouter = (
 	// Only one router so far - use DMP to communicate with child parachains.
-	xcm_sender::ChildParachainRouter<Runtime>,
+	xcm_sender::ChildParachainRouter<Runtime, ForceV0>,
 );
 
 parameter_types! {
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index c82e777f7f02..a195289f15ba 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -620,7 +620,7 @@ parameter_types! {
 /// individual routers.
 pub type XcmRouter = (
 	// Only one router so far - use DMP to communicate with child parachains.
-	xcm_sender::ChildParachainRouter<Runtime>,
+	xcm_sender::ChildParachainRouter<Runtime, ForceV0>,
 );
 
 parameter_types! {
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index 9944efa1f5f4..d7b00dd550db 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -903,7 +903,7 @@ parameter_types! {
 /// individual routers.
 pub type XcmRouter = (
 	// Only one router so far - use DMP to communicate with child parachains.
-	xcm_sender::ChildParachainRouter<Runtime>,
+	xcm_sender::ChildParachainRouter<Runtime, ForceV0>,
 );
 
 parameter_types! {
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index ffef612499c6..f54732c56ffa 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -18,7 +18,7 @@
 
 use crate::{DoubleEncoded, VersionedXcm};
 use alloc::vec::Vec;
-use core::{convert::TryFrom, result};
+use core::{convert::{TryFrom, TryInto}, result};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
@@ -30,6 +30,7 @@ pub use multi_asset::{AssetInstance, MultiAsset};
 pub use multi_location::MultiLocation;
 pub use order::Order;
 pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
+use super::v1::Xcm as Xcm1;
 
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
@@ -297,3 +298,44 @@ pub mod opaque {
 
 	pub use super::order::opaque::*;
 }
+
+impl<Call> TryFrom<Xcm1<Call>> for Xcm<Call> {
+	type Error = ();
+	fn try_from(x: Xcm1<Call>) -> result::Result<Xcm<Call>, ()> {
+		use Xcm::*;
+		Ok(match x {
+			Xcm1::WithdrawAsset { assets, effects } =>
+				WithdrawAsset {
+					assets: assets.into(),
+					effects: effects.into_iter()
+						.map(Order::try_from)
+						.collect::<result::Result<_, _>>()?,
+				},
+			Xcm1::ReserveAssetDeposited { assets, effects } => ReserveAssetDeposit {
+				assets: assets.into(),
+				effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+			},
+			Xcm1::ReceiveTeleportedAsset { assets, effects } => TeleportAsset {
+				assets: assets.into(),
+				effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+			},
+			Xcm1::QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response },
+			Xcm1::TransferAsset { assets, beneficiary } => TransferAsset { assets: assets.into(), dest: beneficiary.into() },
+			Xcm1::TransferReserveAsset { assets, dest, effects } =>
+				TransferReserveAsset {
+					assets: assets.into(),
+					dest: dest.into(),
+					effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+				},
+			Xcm1::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } =>
+				HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity },
+			Xcm1::HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient },
+			Xcm1::HrmpChannelClosing { initiator, sender, recipient } =>
+				HrmpChannelClosing { initiator, sender, recipient },
+			Xcm1::Transact { origin_type, require_weight_at_most, call } =>
+				Transact { origin_type, require_weight_at_most, call: call.into() },
+			Xcm1::RelayedFrom { who, message } =>
+				RelayedFrom { who: who.into(), message: alloc::boxed::Box::new((*message).try_into()?) },
+		})
+	}
+}
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
index d89d13dd4e0c..696576453b65 100644
--- a/xcm/src/v0/multi_asset.rs
+++ b/xcm/src/v0/multi_asset.rs
@@ -16,11 +16,12 @@
 
 //! Cross-Consensus Message format data structures.
 
-use alloc::vec::Vec;
+use alloc::{vec, vec::Vec};
 use super::MultiLocation;
 use parity_scale_codec::{self, Decode, Encode};
+use crate::v1::{MultiAsset as MultiAsset1, WildMultiAsset, MultiAssetFilter, MultiAssets};
 
-pub use super::super::v1::AssetInstance;
+pub use crate::v1::AssetInstance;
 
 /// A single general identifier for an asset.
 ///
@@ -289,6 +290,54 @@ impl MultiAsset {
 	}
 }
 
+impl From<MultiAsset1> for MultiAsset {
+	fn from(a: MultiAsset1) -> MultiAsset {
+		use MultiAsset::*;
+		use crate::v1::{Fungibility::*, AssetId::*};
+		match (a.id, a.fun) {
+			(Concrete(id), Fungible(amount)) => ConcreteFungible { id: id.into(), amount },
+			(Concrete(class), NonFungible(instance)) => ConcreteNonFungible { class: class.into(), instance },
+			(Abstract(id), Fungible(amount)) => AbstractFungible { id, amount },
+			(Abstract(class), NonFungible(instance)) => AbstractNonFungible { class, instance },
+		}
+	}
+}
+
+impl From<MultiAssets> for Vec<MultiAsset> {
+	fn from(a: MultiAssets) -> Vec<MultiAsset> {
+		a.drain().into_iter().map(MultiAsset::from).collect()
+	}
+}
+
+impl From<WildMultiAsset> for MultiAsset {
+	fn from(a: WildMultiAsset) -> MultiAsset {
+		use MultiAsset::*;
+		use crate::v1::{WildFungibility::*, AssetId::*};
+		match a {
+			WildMultiAsset::All => All,
+			WildMultiAsset::AllOf { id, fun } => match (id, fun) {
+				(Concrete(id), Fungible) => AllConcreteFungible { id: id.into()},
+				(Concrete(class), NonFungible) => AllConcreteNonFungible { class: class.into()},
+				(Abstract(id), Fungible) => AllAbstractFungible { id},
+				(Abstract(class), NonFungible) => AllAbstractNonFungible { class},
+			}
+		}
+	}
+}
+
+impl From<WildMultiAsset> for Vec<MultiAsset> {
+	fn from(a: WildMultiAsset) -> Vec<MultiAsset> { vec![a.into()] }
+}
+
+impl From<MultiAssetFilter> for Vec<MultiAsset> {
+	fn from(a: MultiAssetFilter) -> Vec<MultiAsset> {
+		match a {
+			MultiAssetFilter::Definite(assets) => assets.into(),
+			MultiAssetFilter::Wild(wildcard) => wildcard.into(),
+		}
+	}
+}
+
 #[cfg(test)]
 mod tests {
 	use super::*;
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 41ef20dfffd9..311ec67c190c 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -18,7 +18,7 @@
 
 use core::{mem, result};
 
-use super::Junction;
+use super::{Junction, super::v1::MultiLocation as MultiLocation1};
 use parity_scale_codec::{self, Decode, Encode};
 
 /// A relative path between state-bearing consensus systems.
@@ -696,6 +696,23 @@ impl MultiLocation {
 	}
 }
 
+impl From<MultiLocation1> for MultiLocation {
+	fn from(old: MultiLocation1) -> Self {
+		use MultiLocation::*;
+		match old {
+			MultiLocation1::Here => Null,
+			MultiLocation1::X1(j0) => X1(j0),
+			MultiLocation1::X2(j0, j1) => X2(j0, j1),
+			MultiLocation1::X3(j0, j1, j2) => X3(j0, j1, j2),
+			MultiLocation1::X4(j0, j1, j2, j3) => X4(j0, j1, j2, j3),
+			MultiLocation1::X5(j0, j1, j2, j3, j4) => X5(j0, j1, j2, j3, j4),
+			MultiLocation1::X6(j0, j1, j2, j3, j4, j5) => X6(j0, j1, j2, j3, j4, j5),
+			MultiLocation1::X7(j0, j1, j2, j3, j4, j5, j6) => X7(j0, j1, j2, j3, j4, j5, j6),
+			MultiLocation1::X8(j0, j1, j2, j3, j4, j5, j6, j7) => X8(j0, j1, j2, j3, j4, j5, j6, j7),
+		}
+	}
+}
+
 #[cfg(test)]
 mod tests {
 	use super::MultiLocation::*;
diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index c63df711758f..de4059558cc9 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -18,8 +18,10 @@
 
 use super::{MultiAsset, MultiLocation, Xcm};
 use alloc::vec::Vec;
+use core::{result, convert::TryFrom};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
+use super::super::v1::Order as Order1;
 
 /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
 #[derive(Derivative, Encode, Decode)]
@@ -152,3 +154,30 @@ impl<Call> Order<Call> {
 		}
 	}
 }
+
+impl<Call> TryFrom<Order1<Call>> for Order<Call> {
+	type Error = ();
+	fn try_from(old: Order1<Call>) -> result::Result<Order<Call>, ()> {
+		use Order::*;
+		Ok(match old {
+			Order1::Noop => Null,
+			Order1::DepositAsset { assets, beneficiary, .. } =>
+				DepositAsset { assets: assets.into(), dest: beneficiary.into() },
+			Order1::DepositReserveAsset { assets, dest, effects, .. } =>
+				DepositReserveAsset { assets: assets.into(), dest: dest.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
+			Order1::ExchangeAsset { give, receive } => ExchangeAsset { give: give.into(), receive: receive.into() },
+			Order1::InitiateReserveWithdraw { assets, reserve, effects } =>
+				InitiateReserveWithdraw { assets: assets.into(), reserve: reserve.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
+			Order1::InitiateTeleport { assets, dest, effects } =>
+				InitiateTeleport { assets: assets.into(), dest: dest.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
+			Order1::QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest: dest.into(), assets: assets.into() },
+			Order1::BuyExecution { fees, weight, debt, halt_on_error, instructions, orders } => {
+				if !orders.is_empty() {
+					return Err(())
+				}
+				let xcm = instructions.into_iter().map(Xcm::<Call>::try_from).collect::<result::Result<_, _>>()?;
+				BuyExecution { fees: fees.into(), weight, debt, halt_on_error, xcm }
+			},
+		})
+	}
+}
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index c3e5f1d63b09..1a24e48c9bcc 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -19,7 +19,7 @@
 use crate::DoubleEncoded;
 use alloc::vec::Vec;
 use core::{fmt::Debug, convert::{TryFrom, TryInto}, result};
-use super::v0::{Xcm as Xcm0, MultiLocation as MultiLocation0};
+use super::v0::Xcm as Xcm0;
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
@@ -36,7 +36,7 @@ pub use multiasset::{
 };
 pub use multilocation::MultiLocation;
 pub use order::Order;
-pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
+pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm, WrapVersion};
 
 
 /// A prelude for importing all types typically used when interacting with XCM messages.
@@ -60,7 +60,7 @@ pub mod prelude {
 		multilocation::MultiLocation::{self, *},
 		opaque,
 		order::Order::{self, *},
-		traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
+		traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm, ForceV0},
 		OriginKind, Response,
 		Xcm::{self, *},
 	};
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 1181cdea9ef5..4a9866c90eb1 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -17,8 +17,7 @@
 //! Cross-Consensus Message format data structures.
 
 use core::{mem, result};
-
-use super::Junction;
+use super::{Junction, super::v0::MultiLocation as MultiLocation0};
 use parity_scale_codec::{self, Decode, Encode};
 
 /// A relative path between state-bearing consensus systems.
@@ -696,10 +695,9 @@ impl MultiLocation {
 	}
 }
 
-impl From<super::MultiLocation0> for MultiLocation {
-	fn from(old: super::MultiLocation0) -> Self {
+impl From<MultiLocation0> for MultiLocation {
+	fn from(old: MultiLocation0) -> Self {
 		use MultiLocation::*;
-		use super::MultiLocation0;
 		match old {
 			MultiLocation0::Null => Here,
 			MultiLocation0::X1(j0) => X1(j0),
diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index 93dc82b13a39..7010b1f580e3 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -21,6 +21,7 @@ use alloc::{vec, vec::Vec};
 use super::{MultiAsset, MultiAssets, MultiAssetFilter, MultiLocation, Xcm};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
+use super::super::v0::Order as Order0;
 
 /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
 #[derive(Derivative, Encode, Decode)]
@@ -183,11 +184,10 @@ impl<Call> Order<Call> {
 	}
 }
 
-impl<Call> TryFrom<super::super::v0::Order<Call>> for Order<Call> {
+impl<Call> TryFrom<Order0<Call>> for Order<Call> {
 	type Error = ();
-	fn try_from(old: super::super::v0::Order<Call>) -> result::Result<Order<Call>, ()> {
+	fn try_from(old: Order0<Call>) -> result::Result<Order<Call>, ()> {
 		use Order::*;
-		use super::super::v0::Order as Order0;
 		Ok(match old {
 			Order0::Null => Noop,
 			Order0::DepositAsset { assets, dest } =>
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
index fc1c3ce88b57..e05759b59e16 100644
--- a/xcm/src/v1/traits.rs
+++ b/xcm/src/v1/traits.rs
@@ -16,10 +16,10 @@
 
 //! Cross-Consensus Message format data structures.
 
-use core::result;
+use core::{result, convert::TryInto};
 use parity_scale_codec::{Decode, Encode};
 
-use super::{MultiLocation, Xcm};
+use super::{MultiLocation, Xcm, super::VersionedXcm};
 
 #[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
 pub enum Error {
@@ -87,6 +87,8 @@ pub enum Error {
 	TooExpensive,
 	/// The given asset is not handled.
 	AssetNotFound,
+	/// The given message cannot be translated into a format that the destination can be expected to interpret.
+	DestinationUnsupported,
 }
 
 impl From<()> for Error {
@@ -259,3 +261,22 @@ impl SendXcm for Tuple {
 		Err(Error::CannotReachDestination(destination, message))
 	}
 }
+
+/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will interpret it.
+pub trait WrapVersion {
+	fn wrap_version<Call>(dest: &MultiLocation, xcm: Xcm<Call>) -> result::Result<VersionedXcm<Call>, ()>;
+}
+
+impl WrapVersion for () {
+	fn wrap_version<Call>(_: &MultiLocation, xcm: Xcm<Call>) -> result::Result<VersionedXcm<Call>, ()> {
+		Ok(VersionedXcm::<Call>::from(xcm))
+	}
+}
+
+/// `WrapVersion` implementation which attempts to always convert the XCM to version 0 before wrapping it.
+pub struct ForceV0;
+impl WrapVersion for ForceV0 {
+	fn wrap_version<Call>(_: &MultiLocation, xcm: Xcm<Call>) -> result::Result<VersionedXcm<Call>, ()> {
+		Ok(VersionedXcm::<Call>::V0(xcm.try_into()?))
+	}
+}

From efa012dbc31eebf5089309c8bdc944b27fa1ee02 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 15:51:00 +0200
Subject: [PATCH 095/166] fmt

---
 runtime/common/src/xcm_sender.rs | 14 +++----
 xcm/src/lib.rs                   |  5 ++-
 xcm/src/v0/mod.rs                | 66 ++++++++++++++++++++------------
 xcm/src/v0/multi_asset.rs        | 64 ++++++++++++++-----------------
 xcm/src/v0/multi_location.rs     |  5 ++-
 xcm/src/v0/order.rs              | 45 ++++++++++++++++------
 xcm/src/v1/mod.rs                | 61 ++++++++++++++++++-----------
 xcm/src/v1/multiasset.rs         | 20 +++++++---
 xcm/src/v1/multilocation.rs      |  5 ++-
 xcm/src/v1/order.rs              | 58 ++++++++++++++++++++++------
 xcm/src/v1/traits.rs             | 19 ++++++---
 11 files changed, 233 insertions(+), 129 deletions(-)

diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs
index 247c345873ac..4c2575a3face 100644
--- a/runtime/common/src/xcm_sender.rs
+++ b/runtime/common/src/xcm_sender.rs
@@ -19,20 +19,20 @@
 use parity_scale_codec::Encode;
 use runtime_parachains::{configuration, dmp};
 use sp_std::marker::PhantomData;
-use xcm::opaque::{
-	v1::{Error, Junction, MultiLocation, Result, SendXcm, Xcm, WrapVersion},
-};
-use xcm::v1::prelude::XcmError;
+use xcm::opaque::v1::{Error, Junction, MultiLocation, Result, SendXcm, WrapVersion, Xcm};
 
 /// XCM sender for relay chain. It only sends downward message.
 pub struct ChildParachainRouter<T, W>(PhantomData<(T, W)>);
 
-impl<T: configuration::Config + dmp::Config, W: WrapVersion> SendXcm for ChildParachainRouter<T, W> {
+impl<T: configuration::Config + dmp::Config, W: WrapVersion> SendXcm
+	for ChildParachainRouter<T, W>
+{
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {
 		match &dest {
 			MultiLocation::X1(Junction::Parachain(id)) => {
 				// Downward message passing.
-				let versioned_xcm = W::wrap_version(&dest, msg).map_err(|()| Error::DestinationUnsupported)?;
+				let versioned_xcm =
+					W::wrap_version(&dest, msg).map_err(|()| Error::DestinationUnsupported)?;
 				let config = <configuration::Pallet<T>>::config();
 				<dmp::Pallet<T>>::queue_downward_message(
 					&config,
@@ -42,7 +42,7 @@ impl<T: configuration::Config + dmp::Config, W: WrapVersion> SendXcm for ChildPa
 				.map_err(Into::<Error>::into)?;
 				Ok(())
 			},
-			d => Err(Error::CannotReachDestination(dest, msg)),
+			_ => Err(Error::CannotReachDestination(dest, msg)),
 		}
 	}
 }
diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index 5e39800da19c..4bce0086eca8 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -23,7 +23,10 @@
 #![no_std]
 extern crate alloc;
 
-use core::{convert::{TryFrom, TryInto}, result::Result};
+use core::{
+	convert::{TryFrom, TryInto},
+	result::Result,
+};
 use derivative::Derivative;
 use parity_scale_codec::{Decode, Encode, Error as CodecError, Input};
 
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index f54732c56ffa..54b1a0e25267 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -18,7 +18,10 @@
 
 use crate::{DoubleEncoded, VersionedXcm};
 use alloc::vec::Vec;
-use core::{convert::{TryFrom, TryInto}, result};
+use core::{
+	convert::{TryFrom, TryInto},
+	result,
+};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
@@ -26,16 +29,15 @@ mod multi_asset;
 mod multi_location;
 mod order;
 mod traits;
+use super::v1::Xcm as Xcm1;
 pub use multi_asset::{AssetInstance, MultiAsset};
 pub use multi_location::MultiLocation;
 pub use order::Order;
 pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
-use super::v1::Xcm as Xcm1;
 
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
 	pub use super::{
-		BodyId, BodyPart, Junction::*, NetworkId,
 		multi_asset::{
 			AssetInstance::{self, *},
 			MultiAsset::{self, *},
@@ -43,12 +45,14 @@ pub mod prelude {
 		multi_location::MultiLocation::{self, *},
 		order::Order::{self, *},
 		traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
-		OriginKind,
+		BodyId, BodyPart,
+		Junction::*,
+		NetworkId, OriginKind,
 		Xcm::{self, *},
 	};
 }
 
-pub use super::v1::{Response, OriginKind, BodyId, BodyPart, Junction, NetworkId};
+pub use super::v1::{BodyId, BodyPart, Junction, NetworkId, OriginKind, Response};
 
 /// Cross-Consensus Message: A message from one consensus system to another.
 ///
@@ -254,7 +258,7 @@ impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
 	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
 		match x {
 			VersionedXcm::V0(x) => Ok(x),
-			VersionedXcm::V1(_) => Err(()),	// v0-based chains cannot interpret v1 messages.
+			VersionedXcm::V1(_) => Err(()), // v0-based chains cannot interpret v1 messages.
 		}
 	}
 }
@@ -304,29 +308,39 @@ impl<Call> TryFrom<Xcm1<Call>> for Xcm<Call> {
 	fn try_from(x: Xcm1<Call>) -> result::Result<Xcm<Call>, ()> {
 		use Xcm::*;
 		Ok(match x {
-			Xcm1::WithdrawAsset { assets, effects } =>
-				WithdrawAsset {
-					assets: assets.into(),
-					effects: effects.into_iter()
-						.map(Order::try_from)
-						.collect::<result::Result<_, _>>()?,
-				},
+			Xcm1::WithdrawAsset { assets, effects } => WithdrawAsset {
+				assets: assets.into(),
+				effects: effects
+					.into_iter()
+					.map(Order::try_from)
+					.collect::<result::Result<_, _>>()?,
+			},
 			Xcm1::ReserveAssetDeposited { assets, effects } => ReserveAssetDeposit {
 				assets: assets.into(),
-				effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+				effects: effects
+					.into_iter()
+					.map(Order::try_from)
+					.collect::<result::Result<_, _>>()?,
 			},
 			Xcm1::ReceiveTeleportedAsset { assets, effects } => TeleportAsset {
 				assets: assets.into(),
-				effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+				effects: effects
+					.into_iter()
+					.map(Order::try_from)
+					.collect::<result::Result<_, _>>()?,
+			},
+			Xcm1::QueryResponse { query_id: u64, response } =>
+				QueryResponse { query_id: u64, response },
+			Xcm1::TransferAsset { assets, beneficiary } =>
+				TransferAsset { assets: assets.into(), dest: beneficiary.into() },
+			Xcm1::TransferReserveAsset { assets, dest, effects } => TransferReserveAsset {
+				assets: assets.into(),
+				dest: dest.into(),
+				effects: effects
+					.into_iter()
+					.map(Order::try_from)
+					.collect::<result::Result<_, _>>()?,
 			},
-			Xcm1::QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response },
-			Xcm1::TransferAsset { assets, beneficiary } => TransferAsset { assets: assets.into(), dest: beneficiary.into() },
-			Xcm1::TransferReserveAsset { assets, dest, effects } =>
-				TransferReserveAsset {
-					assets: assets.into(),
-					dest: dest.into(),
-					effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
-				},
 			Xcm1::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } =>
 				HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity },
 			Xcm1::HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient },
@@ -334,8 +348,10 @@ impl<Call> TryFrom<Xcm1<Call>> for Xcm<Call> {
 				HrmpChannelClosing { initiator, sender, recipient },
 			Xcm1::Transact { origin_type, require_weight_at_most, call } =>
 				Transact { origin_type, require_weight_at_most, call: call.into() },
-			Xcm1::RelayedFrom { who, message } =>
-				RelayedFrom { who: who.into(), message: alloc::boxed::Box::new((*message).try_into()?) },
+			Xcm1::RelayedFrom { who, message } => RelayedFrom {
+				who: who.into(),
+				message: alloc::boxed::Box::new((*message).try_into()?),
+			},
 		})
 	}
 }
diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
index 696576453b65..3225e38a213a 100644
--- a/xcm/src/v0/multi_asset.rs
+++ b/xcm/src/v0/multi_asset.rs
@@ -16,10 +16,10 @@
 
 //! Cross-Consensus Message format data structures.
 
-use alloc::{vec, vec::Vec};
 use super::MultiLocation;
+use crate::v1::{MultiAsset as MultiAsset1, MultiAssetFilter, MultiAssets, WildMultiAsset};
+use alloc::{vec, vec::Vec};
 use parity_scale_codec::{self, Decode, Encode};
-use crate::v1::{MultiAsset as MultiAsset1, WildMultiAsset, MultiAssetFilter, MultiAssets};
 
 pub use crate::v1::AssetInstance;
 
@@ -292,11 +292,12 @@ impl MultiAsset {
 
 impl From<MultiAsset1> for MultiAsset {
 	fn from(a: MultiAsset1) -> MultiAsset {
+		use crate::v1::{AssetId::*, Fungibility::*};
 		use MultiAsset::*;
-		use crate::v1::{Fungibility::*, AssetId::*};
 		match (a.id, a.fun) {
 			(Concrete(id), Fungible(amount)) => ConcreteFungible { id: id.into(), amount },
-			(Concrete(class), NonFungible(instance)) => ConcreteNonFungible { class: class.into(), instance },
+			(Concrete(class), NonFungible(instance)) =>
+				ConcreteNonFungible { class: class.into(), instance },
 			(Abstract(id), Fungible(amount)) => AbstractFungible { id, amount },
 			(Abstract(class), NonFungible(instance)) => AbstractNonFungible { class, instance },
 		}
@@ -311,22 +312,24 @@ impl From<MultiAssets> for Vec<MultiAsset> {
 
 impl From<WildMultiAsset> for MultiAsset {
 	fn from(a: WildMultiAsset) -> MultiAsset {
+		use crate::v1::{AssetId::*, WildFungibility::*};
 		use MultiAsset::*;
-		use crate::v1::{WildFungibility::*, AssetId::*};
 		match a {
 			WildMultiAsset::All => All,
 			WildMultiAsset::AllOf { id, fun } => match (id, fun) {
-				(Concrete(id), Fungible) => AllConcreteFungible { id: id.into()},
-				(Concrete(class), NonFungible) => AllConcreteNonFungible { class: class.into()},
-				(Abstract(id), Fungible) => AllAbstractFungible { id},
-				(Abstract(class), NonFungible) => AllAbstractNonFungible { class},
-			}
+				(Concrete(id), Fungible) => AllConcreteFungible { id: id.into() },
+				(Concrete(class), NonFungible) => AllConcreteNonFungible { class: class.into() },
+				(Abstract(id), Fungible) => AllAbstractFungible { id },
+				(Abstract(class), NonFungible) => AllAbstractNonFungible { class },
+			},
 		}
 	}
 }
 
 impl From<WildMultiAsset> for Vec<MultiAsset> {
-	fn from(a: WildMultiAsset) -> Vec<MultiAsset> { vec![a.into()] }
+	fn from(a: WildMultiAsset) -> Vec<MultiAsset> {
+		vec![a.into()]
+	}
 }
 
 impl From<MultiAssetFilter> for Vec<MultiAsset> {
@@ -372,29 +375,20 @@ mod tests {
 			.contains(&AbstractFungible { id: vec![99u8], amount: 100 }));
 
 		// For non-fungibles, containing is equality.
-		assert!(!AbstractNonFungible {
-			class: vec![99u8],
-			instance: AssetInstance::Index(9)
-		}
-		.contains(&AbstractNonFungible {
-			class: vec![98u8],
-			instance: AssetInstance::Index(9)
-		}));
-		assert!(!AbstractNonFungible {
-			class: vec![99u8],
-			instance: AssetInstance::Index(8)
-		}
-		.contains(&AbstractNonFungible {
-			class: vec![99u8],
-			instance: AssetInstance::Index(9)
-		}));
-		assert!(AbstractNonFungible {
-			class: vec![99u8],
-			instance: AssetInstance::Index(9)
-		}
-		.contains(&AbstractNonFungible {
-			class: vec![99u8],
-			instance: AssetInstance::Index(9)
-		}));
+		assert!(!AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index(9) }
+			.contains(&AbstractNonFungible {
+				class: vec![98u8],
+				instance: AssetInstance::Index(9)
+			}));
+		assert!(!AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index(8) }
+			.contains(&AbstractNonFungible {
+				class: vec![99u8],
+				instance: AssetInstance::Index(9)
+			}));
+		assert!(AbstractNonFungible { class: vec![99u8], instance: AssetInstance::Index(9) }
+			.contains(&AbstractNonFungible {
+				class: vec![99u8],
+				instance: AssetInstance::Index(9)
+			}));
 	}
 }
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 311ec67c190c..1426529f2fdb 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -18,7 +18,7 @@
 
 use core::{mem, result};
 
-use super::{Junction, super::v1::MultiLocation as MultiLocation1};
+use super::{super::v1::MultiLocation as MultiLocation1, Junction};
 use parity_scale_codec::{self, Decode, Encode};
 
 /// A relative path between state-bearing consensus systems.
@@ -708,7 +708,8 @@ impl From<MultiLocation1> for MultiLocation {
 			MultiLocation1::X5(j0, j1, j2, j3, j4) => X5(j0, j1, j2, j3, j4),
 			MultiLocation1::X6(j0, j1, j2, j3, j4, j5) => X6(j0, j1, j2, j3, j4, j5),
 			MultiLocation1::X7(j0, j1, j2, j3, j4, j5, j6) => X7(j0, j1, j2, j3, j4, j5, j6),
-			MultiLocation1::X8(j0, j1, j2, j3, j4, j5, j6, j7) => X8(j0, j1, j2, j3, j4, j5, j6, j7),
+			MultiLocation1::X8(j0, j1, j2, j3, j4, j5, j6, j7) =>
+				X8(j0, j1, j2, j3, j4, j5, j6, j7),
 		}
 	}
 }
diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index de4059558cc9..3ce20d22bdd8 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -16,12 +16,11 @@
 
 //! Version 0 of the Cross-Consensus Message format data structures.
 
-use super::{MultiAsset, MultiLocation, Xcm};
+use super::{super::v1::Order as Order1, MultiAsset, MultiLocation, Xcm};
 use alloc::vec::Vec;
-use core::{result, convert::TryFrom};
+use core::{convert::TryFrom, result};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
-use super::super::v1::Order as Order1;
 
 /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
 #[derive(Derivative, Encode, Decode)]
@@ -163,19 +162,43 @@ impl<Call> TryFrom<Order1<Call>> for Order<Call> {
 			Order1::Noop => Null,
 			Order1::DepositAsset { assets, beneficiary, .. } =>
 				DepositAsset { assets: assets.into(), dest: beneficiary.into() },
-			Order1::DepositReserveAsset { assets, dest, effects, .. } =>
-				DepositReserveAsset { assets: assets.into(), dest: dest.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
-			Order1::ExchangeAsset { give, receive } => ExchangeAsset { give: give.into(), receive: receive.into() },
+			Order1::DepositReserveAsset { assets, dest, effects, .. } => DepositReserveAsset {
+				assets: assets.into(),
+				dest: dest.into(),
+				effects: effects
+					.into_iter()
+					.map(Order::<()>::try_from)
+					.collect::<result::Result<_, _>>()?,
+			},
+			Order1::ExchangeAsset { give, receive } =>
+				ExchangeAsset { give: give.into(), receive: receive.into() },
 			Order1::InitiateReserveWithdraw { assets, reserve, effects } =>
-				InitiateReserveWithdraw { assets: assets.into(), reserve: reserve.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
-			Order1::InitiateTeleport { assets, dest, effects } =>
-				InitiateTeleport { assets: assets.into(), dest: dest.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
-			Order1::QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest: dest.into(), assets: assets.into() },
+				InitiateReserveWithdraw {
+					assets: assets.into(),
+					reserve: reserve.into(),
+					effects: effects
+						.into_iter()
+						.map(Order::<()>::try_from)
+						.collect::<result::Result<_, _>>()?,
+				},
+			Order1::InitiateTeleport { assets, dest, effects } => InitiateTeleport {
+				assets: assets.into(),
+				dest: dest.into(),
+				effects: effects
+					.into_iter()
+					.map(Order::<()>::try_from)
+					.collect::<result::Result<_, _>>()?,
+			},
+			Order1::QueryHolding { query_id, dest, assets } =>
+				QueryHolding { query_id, dest: dest.into(), assets: assets.into() },
 			Order1::BuyExecution { fees, weight, debt, halt_on_error, instructions, orders } => {
 				if !orders.is_empty() {
 					return Err(())
 				}
-				let xcm = instructions.into_iter().map(Xcm::<Call>::try_from).collect::<result::Result<_, _>>()?;
+				let xcm = instructions
+					.into_iter()
+					.map(Xcm::<Call>::try_from)
+					.collect::<result::Result<_, _>>()?;
 				BuyExecution { fees: fees.into(), weight, debt, halt_on_error, xcm }
 			},
 		})
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index 1a24e48c9bcc..99ba9be3b0bb 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -16,10 +16,14 @@
 
 //! Version 1 of the Cross-Consensus Message format data structures.
 
+use super::v0::Xcm as Xcm0;
 use crate::DoubleEncoded;
 use alloc::vec::Vec;
-use core::{fmt::Debug, convert::{TryFrom, TryInto}, result};
-use super::v0::Xcm as Xcm0;
+use core::{
+	convert::{TryFrom, TryInto},
+	fmt::Debug,
+	result,
+};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
@@ -38,7 +42,6 @@ pub use multilocation::MultiLocation;
 pub use order::Order;
 pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm, WrapVersion};
 
-
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
 	pub use super::{
@@ -60,7 +63,7 @@ pub mod prelude {
 		multilocation::MultiLocation::{self, *},
 		opaque,
 		order::Order::{self, *},
-		traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm, ForceV0},
+		traits::{Error as XcmError, ExecuteXcm, ForceV0, Outcome, Result as XcmResult, SendXcm},
 		OriginKind, Response,
 		Xcm::{self, *},
 	};
@@ -340,29 +343,39 @@ impl<Call> TryFrom<Xcm0<Call>> for Xcm<Call> {
 	fn try_from(old: Xcm0<Call>) -> result::Result<Xcm<Call>, ()> {
 		use Xcm::*;
 		Ok(match old {
-			Xcm0::WithdrawAsset { assets, effects } =>
-				WithdrawAsset {
-					assets: assets.try_into()?,
-					effects: effects.into_iter()
-						.map(Order::try_from)
-						.collect::<result::Result<_, _>>()?,
-				},
+			Xcm0::WithdrawAsset { assets, effects } => WithdrawAsset {
+				assets: assets.try_into()?,
+				effects: effects
+					.into_iter()
+					.map(Order::try_from)
+					.collect::<result::Result<_, _>>()?,
+			},
 			Xcm0::ReserveAssetDeposit { assets, effects } => ReserveAssetDeposited {
 				assets: assets.try_into()?,
-				effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+				effects: effects
+					.into_iter()
+					.map(Order::try_from)
+					.collect::<result::Result<_, _>>()?,
 			},
 			Xcm0::TeleportAsset { assets, effects } => ReceiveTeleportedAsset {
 				assets: assets.try_into()?,
-				effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
+				effects: effects
+					.into_iter()
+					.map(Order::try_from)
+					.collect::<result::Result<_, _>>()?,
+			},
+			Xcm0::QueryResponse { query_id: u64, response } =>
+				QueryResponse { query_id: u64, response },
+			Xcm0::TransferAsset { assets, dest } =>
+				TransferAsset { assets: assets.try_into()?, beneficiary: dest.into() },
+			Xcm0::TransferReserveAsset { assets, dest, effects } => TransferReserveAsset {
+				assets: assets.try_into()?,
+				dest: dest.into(),
+				effects: effects
+					.into_iter()
+					.map(Order::try_from)
+					.collect::<result::Result<_, _>>()?,
 			},
-			Xcm0::QueryResponse { query_id: u64, response } => QueryResponse { query_id: u64, response },
-			Xcm0::TransferAsset { assets, dest } => TransferAsset { assets: assets.try_into()?, beneficiary: dest.into() },
-			Xcm0::TransferReserveAsset { assets, dest, effects } =>
-				TransferReserveAsset {
-					assets: assets.try_into()?,
-					dest: dest.into(),
-					effects: effects.into_iter().map(Order::try_from).collect::<result::Result<_, _>>()?,
-				},
 			Xcm0::HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity } =>
 				HrmpNewChannelOpenRequest { sender, max_message_size, max_capacity },
 			Xcm0::HrmpChannelAccepted { recipient } => HrmpChannelAccepted { recipient },
@@ -370,8 +383,10 @@ impl<Call> TryFrom<Xcm0<Call>> for Xcm<Call> {
 				HrmpChannelClosing { initiator, sender, recipient },
 			Xcm0::Transact { origin_type, require_weight_at_most, call } =>
 				Transact { origin_type, require_weight_at_most, call: call.into() },
-			Xcm0::RelayedFrom { who, message } =>
-				RelayedFrom { who: who.into(), message: alloc::boxed::Box::new((*message).try_into()?) },
+			Xcm0::RelayedFrom { who, message } => RelayedFrom {
+				who: who.into(),
+				message: alloc::boxed::Box::new((*message).try_into()?),
+			},
 		})
 	}
 }
diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index 1b9f693ce054..5f14d8f2f01a 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -28,7 +28,11 @@ use super::{
 	MultiLocation::{self, X1},
 };
 use alloc::{vec, vec::Vec};
-use core::{cmp::Ordering, convert::{TryFrom, TryInto}, result};
+use core::{
+	cmp::Ordering,
+	convert::{TryFrom, TryInto},
+	result,
+};
 use parity_scale_codec::{self as codec, Decode, Encode};
 
 /// A general identifier for an instance of a non-fungible asset class.
@@ -235,11 +239,12 @@ impl TryFrom<super::super::v0::MultiAsset> for MultiAsset {
 	type Error = ();
 	fn try_from(old: super::super::v0::MultiAsset) -> result::Result<MultiAsset, ()> {
 		use super::super::v0::MultiAsset as V0;
-		use Fungibility::*;
 		use AssetId::*;
+		use Fungibility::*;
 		let (id, fun) = match old {
 			V0::ConcreteFungible { id, amount } => (Concrete(id.into()), Fungible(amount)),
-			V0::ConcreteNonFungible { class, instance } => (Concrete(class.into()), NonFungible(instance)),
+			V0::ConcreteNonFungible { class, instance } =>
+				(Concrete(class.into()), NonFungible(instance)),
 			V0::AbstractFungible { id, amount } => (Abstract(id), Fungible(amount)),
 			V0::AbstractNonFungible { class, instance } => (Abstract(class), NonFungible(instance)),
 			_ => return Err(()),
@@ -283,7 +288,8 @@ impl Decode for MultiAssets {
 impl TryFrom<Vec<super::super::v0::MultiAsset>> for MultiAssets {
 	type Error = ();
 	fn try_from(old: Vec<super::super::v0::MultiAsset>) -> result::Result<MultiAssets, ()> {
-		let v = old.into_iter()
+		let v = old
+			.into_iter()
 			.map(Option::<MultiAsset>::try_from)
 			.filter_map(|x| x.transpose())
 			.collect::<result::Result<Vec<MultiAsset>, ()>>()?;
@@ -446,8 +452,8 @@ impl TryFrom<super::super::v0::MultiAsset> for WildMultiAsset {
 	type Error = ();
 	fn try_from(old: super::super::v0::MultiAsset) -> result::Result<WildMultiAsset, ()> {
 		use super::super::v0::MultiAsset as V0;
-		use WildFungibility::*;
 		use AssetId::*;
+		use WildFungibility::*;
 		let (id, fun) = match old {
 			V0::All => return Ok(WildMultiAsset::All),
 			V0::AllConcreteFungible { id } => (Concrete(id.into()), Fungible),
@@ -557,7 +563,9 @@ impl MultiAssetFilter {
 
 impl TryFrom<Vec<super::super::v0::MultiAsset>> for MultiAssetFilter {
 	type Error = ();
-	fn try_from(mut old: Vec<super::super::v0::MultiAsset>) -> result::Result<MultiAssetFilter, ()> {
+	fn try_from(
+		mut old: Vec<super::super::v0::MultiAsset>,
+	) -> result::Result<MultiAssetFilter, ()> {
 		if old.len() == 1 && old[0].is_wildcard() {
 			Ok(MultiAssetFilter::Wild(old.remove(0).try_into()?))
 		} else {
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 4a9866c90eb1..bd1548fd6f59 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -16,8 +16,8 @@
 
 //! Cross-Consensus Message format data structures.
 
+use super::{super::v0::MultiLocation as MultiLocation0, Junction};
 use core::{mem, result};
-use super::{Junction, super::v0::MultiLocation as MultiLocation0};
 use parity_scale_codec::{self, Decode, Encode};
 
 /// A relative path between state-bearing consensus systems.
@@ -707,7 +707,8 @@ impl From<MultiLocation0> for MultiLocation {
 			MultiLocation0::X5(j0, j1, j2, j3, j4) => X5(j0, j1, j2, j3, j4),
 			MultiLocation0::X6(j0, j1, j2, j3, j4, j5) => X6(j0, j1, j2, j3, j4, j5),
 			MultiLocation0::X7(j0, j1, j2, j3, j4, j5, j6) => X7(j0, j1, j2, j3, j4, j5, j6),
-			MultiLocation0::X8(j0, j1, j2, j3, j4, j5, j6, j7) => X8(j0, j1, j2, j3, j4, j5, j6, j7),
+			MultiLocation0::X8(j0, j1, j2, j3, j4, j5, j6, j7) =>
+				X8(j0, j1, j2, j3, j4, j5, j6, j7),
 		}
 	}
 }
diff --git a/xcm/src/v1/order.rs b/xcm/src/v1/order.rs
index 7010b1f580e3..06363c39ce83 100644
--- a/xcm/src/v1/order.rs
+++ b/xcm/src/v1/order.rs
@@ -16,12 +16,16 @@
 
 //! Version 1 of the Cross-Consensus Message format data structures.
 
-use core::{convert::{TryFrom, TryInto}, result};
+use super::{
+	super::v0::Order as Order0, MultiAsset, MultiAssetFilter, MultiAssets, MultiLocation, Xcm,
+};
 use alloc::{vec, vec::Vec};
-use super::{MultiAsset, MultiAssets, MultiAssetFilter, MultiLocation, Xcm};
+use core::{
+	convert::{TryFrom, TryInto},
+	result,
+};
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
-use super::super::v0::Order as Order0;
 
 /// An instruction to be executed on some or all of the assets in holding, used by asset-related XCM messages.
 #[derive(Derivative, Encode, Decode)]
@@ -192,17 +196,47 @@ impl<Call> TryFrom<Order0<Call>> for Order<Call> {
 			Order0::Null => Noop,
 			Order0::DepositAsset { assets, dest } =>
 				DepositAsset { assets: assets.try_into()?, max_assets: 1, beneficiary: dest.into() },
-			Order0::DepositReserveAsset { assets, dest, effects } =>
-				DepositReserveAsset { assets: assets.try_into()?, max_assets: 1, dest: dest.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
-			Order0::ExchangeAsset { give, receive } => ExchangeAsset { give: give.try_into()?, receive: receive.try_into()? },
+			Order0::DepositReserveAsset { assets, dest, effects } => DepositReserveAsset {
+				assets: assets.try_into()?,
+				max_assets: 1,
+				dest: dest.into(),
+				effects: effects
+					.into_iter()
+					.map(Order::<()>::try_from)
+					.collect::<result::Result<_, _>>()?,
+			},
+			Order0::ExchangeAsset { give, receive } =>
+				ExchangeAsset { give: give.try_into()?, receive: receive.try_into()? },
 			Order0::InitiateReserveWithdraw { assets, reserve, effects } =>
-				InitiateReserveWithdraw { assets: assets.try_into()?, reserve: reserve.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
-			Order0::InitiateTeleport { assets, dest, effects } =>
-				InitiateTeleport { assets: assets.try_into()?, dest: dest.into(), effects: effects.into_iter().map(Order::<()>::try_from).collect::<result::Result<_, _>>()? },
-			Order0::QueryHolding { query_id, dest, assets } => QueryHolding { query_id, dest: dest.into(), assets: assets.try_into()? },
+				InitiateReserveWithdraw {
+					assets: assets.try_into()?,
+					reserve: reserve.into(),
+					effects: effects
+						.into_iter()
+						.map(Order::<()>::try_from)
+						.collect::<result::Result<_, _>>()?,
+				},
+			Order0::InitiateTeleport { assets, dest, effects } => InitiateTeleport {
+				assets: assets.try_into()?,
+				dest: dest.into(),
+				effects: effects
+					.into_iter()
+					.map(Order::<()>::try_from)
+					.collect::<result::Result<_, _>>()?,
+			},
+			Order0::QueryHolding { query_id, dest, assets } =>
+				QueryHolding { query_id, dest: dest.into(), assets: assets.try_into()? },
 			Order0::BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
-				let instructions = xcm.into_iter().map(Xcm::<Call>::try_from).collect::<result::Result<_, _>>()?;
-				BuyExecution { fees: fees.try_into()?, weight, debt, halt_on_error, orders: vec![], instructions }
+				let instructions =
+					xcm.into_iter().map(Xcm::<Call>::try_from).collect::<result::Result<_, _>>()?;
+				BuyExecution {
+					fees: fees.try_into()?,
+					weight,
+					debt,
+					halt_on_error,
+					orders: vec![],
+					instructions,
+				}
 			},
 		})
 	}
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
index e05759b59e16..54a40796de66 100644
--- a/xcm/src/v1/traits.rs
+++ b/xcm/src/v1/traits.rs
@@ -16,10 +16,10 @@
 
 //! Cross-Consensus Message format data structures.
 
-use core::{result, convert::TryInto};
+use core::{convert::TryInto, result};
 use parity_scale_codec::{Decode, Encode};
 
-use super::{MultiLocation, Xcm, super::VersionedXcm};
+use super::{super::VersionedXcm, MultiLocation, Xcm};
 
 #[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
 pub enum Error {
@@ -264,11 +264,17 @@ impl SendXcm for Tuple {
 
 /// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will interpret it.
 pub trait WrapVersion {
-	fn wrap_version<Call>(dest: &MultiLocation, xcm: Xcm<Call>) -> result::Result<VersionedXcm<Call>, ()>;
+	fn wrap_version<Call>(
+		dest: &MultiLocation,
+		xcm: Xcm<Call>,
+	) -> result::Result<VersionedXcm<Call>, ()>;
 }
 
 impl WrapVersion for () {
-	fn wrap_version<Call>(_: &MultiLocation, xcm: Xcm<Call>) -> result::Result<VersionedXcm<Call>, ()> {
+	fn wrap_version<Call>(
+		_: &MultiLocation,
+		xcm: Xcm<Call>,
+	) -> result::Result<VersionedXcm<Call>, ()> {
 		Ok(VersionedXcm::<Call>::from(xcm))
 	}
 }
@@ -276,7 +282,10 @@ impl WrapVersion for () {
 /// `WrapVersion` implementation which attempts to always convert the XCM to version 0 before wrapping it.
 pub struct ForceV0;
 impl WrapVersion for ForceV0 {
-	fn wrap_version<Call>(_: &MultiLocation, xcm: Xcm<Call>) -> result::Result<VersionedXcm<Call>, ()> {
+	fn wrap_version<Call>(
+		_: &MultiLocation,
+		xcm: Xcm<Call>,
+	) -> result::Result<VersionedXcm<Call>, ()> {
 		Ok(VersionedXcm::<Call>::V0(xcm.try_into()?))
 	}
 }

From e33710b6f515e6067d300046ee586da558ef18fe Mon Sep 17 00:00:00 2001
From: Shawn Tabrizi <shawntabrizi@gmail.com>
Date: Thu, 5 Aug 2021 19:06:14 +0200
Subject: [PATCH 096/166] Update xcm/pallet-xcm/src/lib.rs

---
 xcm/pallet-xcm/src/lib.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 4e22576ca50f..e95cb31188eb 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -235,7 +235,6 @@ pub mod pallet {
 				.reanchored(&inv_dest)
 				.map_err(|_| Error::<T>::CannotReanchor)?;
 			let max_assets = assets.len() as u32;
-			assets.sort();
 			let assets = assets.into();
 			let mut message = Xcm::TransferReserveAsset {
 				assets,

From fe598863d5eb79d9692c134d13e873fff731f9eb Mon Sep 17 00:00:00 2001
From: Gavin Wood <gavin@parity.io>
Date: Thu, 5 Aug 2021 23:55:08 +0200
Subject: [PATCH 097/166] Update xcm/src/v0/order.rs

Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
---
 xcm/src/v0/order.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/src/v0/order.rs b/xcm/src/v0/order.rs
index 3ce20d22bdd8..4674046e2628 100644
--- a/xcm/src/v0/order.rs
+++ b/xcm/src/v0/order.rs
@@ -191,7 +191,7 @@ impl<Call> TryFrom<Order1<Call>> for Order<Call> {
 			},
 			Order1::QueryHolding { query_id, dest, assets } =>
 				QueryHolding { query_id, dest: dest.into(), assets: assets.into() },
-			Order1::BuyExecution { fees, weight, debt, halt_on_error, instructions, orders } => {
+			Order1::BuyExecution { fees, weight, debt, halt_on_error, orders, instructions } => {
 				if !orders.is_empty() {
 					return Err(())
 				}

From d2bd1e004e89065ee71681c633499e831f23f7c5 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Fri, 6 Aug 2021 13:59:21 +0200
Subject: [PATCH 098/166] Tweaks to versioning system

---
 runtime/kusama/src/lib.rs                     |  4 +-
 runtime/parachains/src/dmp.rs                 |  2 +-
 runtime/parachains/src/ump.rs                 |  6 +-
 runtime/rococo/src/lib.rs                     |  4 +-
 runtime/westend/src/lib.rs                    |  4 +-
 xcm/pallet-xcm/src/lib.rs                     |  4 +-
 xcm/pallet-xcm/src/mock.rs                    |  8 +--
 xcm/src/lib.rs                                | 63 ++++++++++++++++++-
 xcm/src/v0/mod.rs                             | 18 +-----
 xcm/src/v1/mod.rs                             |  4 +-
 xcm/src/v1/multilocation.rs                   |  8 +--
 xcm/src/v1/traits.rs                          | 32 +---------
 xcm/xcm-builder/src/barriers.rs               |  2 +-
 xcm/xcm-builder/src/currency_adapter.rs       |  4 +-
 xcm/xcm-builder/src/filter_asset_location.rs  |  2 +-
 xcm/xcm-builder/src/fungibles_adapter.rs      |  2 +-
 xcm/xcm-builder/src/location_conversion.rs    |  6 +-
 xcm/xcm-builder/src/matches_fungible.rs       |  6 +-
 xcm/xcm-builder/src/mock.rs                   |  6 +-
 xcm/xcm-builder/src/origin_conversion.rs      |  2 +-
 xcm/xcm-builder/src/tests.rs                  |  2 +-
 xcm/xcm-builder/src/weight.rs                 |  2 +-
 xcm/xcm-executor/src/assets.rs                |  6 +-
 xcm/xcm-executor/src/config.rs                |  2 +-
 xcm/xcm-executor/src/lib.rs                   |  2 +-
 xcm/xcm-executor/src/traits/conversion.rs     |  4 +-
 .../src/traits/filter_asset_location.rs       |  2 +-
 .../src/traits/matches_fungible.rs            |  2 +-
 .../src/traits/matches_fungibles.rs           |  2 +-
 xcm/xcm-executor/src/traits/on_response.rs    |  2 +-
 xcm/xcm-executor/src/traits/should_execute.rs |  2 +-
 xcm/xcm-executor/src/traits/transact_asset.rs |  2 +-
 xcm/xcm-executor/src/traits/weight.rs         |  2 +-
 xcm/xcm-simulator/example/src/lib.rs          |  2 +-
 xcm/xcm-simulator/example/src/parachain.rs    |  2 +-
 xcm/xcm-simulator/example/src/relay_chain.rs  |  2 +-
 xcm/xcm-simulator/src/lib.rs                  |  2 +-
 37 files changed, 122 insertions(+), 105 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index dc00d4d7a7ea..2a83120b41ed 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -75,7 +75,7 @@ use sp_staking::SessionIndex;
 use sp_version::NativeVersion;
 use sp_version::RuntimeVersion;
 use static_assertions::const_assert;
-use xcm::v1::prelude::*;
+use xcm::latest::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
 	BackingToPlurality, ChildParachainAsNative, ChildParachainConvertsVia,
@@ -1258,7 +1258,7 @@ parameter_types! {
 /// individual routers.
 pub type XcmRouter = (
 	// Only one router so far - use DMP to communicate with child parachains.
-	xcm_sender::ChildParachainRouter<Runtime, ForceV0>,
+	xcm_sender::ChildParachainRouter<Runtime, xcm::AlwaysRelease>,
 );
 
 parameter_types! {
diff --git a/runtime/parachains/src/dmp.rs b/runtime/parachains/src/dmp.rs
index 1ff8fed4528d..6ca7f09fc773 100644
--- a/runtime/parachains/src/dmp.rs
+++ b/runtime/parachains/src/dmp.rs
@@ -22,7 +22,7 @@ use frame_support::pallet_prelude::*;
 use primitives::v1::{DownwardMessage, Hash, Id as ParaId, InboundDownwardMessage};
 use sp_runtime::traits::{BlakeTwo256, Hash as HashT, SaturatedConversion};
 use sp_std::{fmt, prelude::*};
-use xcm::v1::Error as XcmError;
+use xcm::latest::Error as XcmError;
 
 pub use pallet::*;
 
diff --git a/runtime/parachains/src/ump.rs b/runtime/parachains/src/ump.rs
index b1a39405a468..31a72875407a 100644
--- a/runtime/parachains/src/ump.rs
+++ b/runtime/parachains/src/ump.rs
@@ -27,7 +27,7 @@ use sp_std::{
 	marker::PhantomData,
 	prelude::*,
 };
-use xcm::v1::Outcome;
+use xcm::latest::Outcome;
 
 pub use pallet::*;
 
@@ -78,14 +78,14 @@ pub type MessageId = [u8; 32];
 /// and will be forwarded to the XCM Executor.
 pub struct XcmSink<XcmExecutor, Config>(PhantomData<(XcmExecutor, Config)>);
 
-impl<XcmExecutor: xcm::v1::ExecuteXcm<C::Call>, C: Config> UmpSink for XcmSink<XcmExecutor, C> {
+impl<XcmExecutor: xcm::latest::ExecuteXcm<C::Call>, C: Config> UmpSink for XcmSink<XcmExecutor, C> {
 	fn process_upward_message(
 		origin: ParaId,
 		data: &[u8],
 		max_weight: Weight,
 	) -> Result<Weight, (MessageId, Weight)> {
 		use xcm::{
-			v1::{Error as XcmError, Junction, MultiLocation, Xcm},
+			latest::{Error as XcmError, Junction, MultiLocation, Xcm},
 			VersionedXcm,
 		};
 
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index a195289f15ba..e4b5f737cd22 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -80,7 +80,7 @@ use polkadot_parachain::primitives::Id as ParaId;
 
 use constants::{currency::*, fee::*, time::*};
 use frame_support::traits::InstanceFilter;
-use xcm::v1::prelude::*;
+use xcm::latest::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, BackingToPlurality, ChildParachainAsNative, ChildParachainConvertsVia,
 	ChildSystemParachainAsSuperuser, CurrencyAdapter as XcmCurrencyAdapter, FixedWeightBounds,
@@ -620,7 +620,7 @@ parameter_types! {
 /// individual routers.
 pub type XcmRouter = (
 	// Only one router so far - use DMP to communicate with child parachains.
-	xcm_sender::ChildParachainRouter<Runtime, ForceV0>,
+	xcm_sender::ChildParachainRouter<Runtime, xcm::AlwaysRelease>,
 );
 
 parameter_types! {
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index d7b00dd550db..4d4efab21f2c 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -44,7 +44,7 @@ use runtime_parachains::{
 	session_info as parachains_session_info, shared as parachains_shared, ump as parachains_ump,
 };
 
-use xcm::v1::prelude::*;
+use xcm::latest::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,
 	ChildParachainAsNative, ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
@@ -903,7 +903,7 @@ parameter_types! {
 /// individual routers.
 pub type XcmRouter = (
 	// Only one router so far - use DMP to communicate with child parachains.
-	xcm_sender::ChildParachainRouter<Runtime, ForceV0>,
+	xcm_sender::ChildParachainRouter<Runtime, xcm::AlwaysRelease>,
 );
 
 parameter_types! {
diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 4e22576ca50f..4c0854625d81 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -27,7 +27,7 @@ use codec::{Decode, Encode};
 use frame_support::traits::{Contains, EnsureOrigin, Filter, Get, OriginTrait};
 use sp_runtime::{traits::BadOrigin, RuntimeDebug};
 use sp_std::{boxed::Box, convert::TryInto, marker::PhantomData, prelude::*, vec};
-use xcm::v1::prelude::*;
+use xcm::latest::prelude::*;
 use xcm_executor::traits::ConvertOrigin;
 
 use frame_support::PalletId;
@@ -85,7 +85,7 @@ pub mod pallet {
 	#[pallet::event]
 	#[pallet::generate_deposit(pub(super) fn deposit_event)]
 	pub enum Event<T: Config> {
-		Attempted(xcm::v1::Outcome),
+		Attempted(xcm::latest::Outcome),
 		Sent(MultiLocation, MultiLocation, Xcm<()>),
 	}
 
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index ca143ce11db0..f7468cb3455d 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -25,8 +25,8 @@ use sp_core::H256;
 use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
 pub use sp_std::{cell::RefCell, fmt::Debug, marker::PhantomData};
 use xcm::{
-	opaque::v1::{Error as XcmError, MultiAsset, Result as XcmResult, SendXcm, Xcm},
-	v1::prelude::*,
+	opaque::latest::{Error as XcmError, MultiAsset, Result as XcmResult, SendXcm, Xcm},
+	latest::prelude::*,
 };
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative,
@@ -181,7 +181,7 @@ impl pallet_xcm::Config for Test {
 	type SendXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
 	type XcmRouter = (TestSendXcmErrX8, TestSendXcm);
 	type ExecuteXcmOrigin = xcm_builder::EnsureXcmOrigin<Origin, LocalOriginToLocation>;
-	type XcmExecuteFilter = All<(MultiLocation, xcm::v1::Xcm<Call>)>;
+	type XcmExecuteFilter = All<(MultiLocation, xcm::latest::Xcm<Call>)>;
 	type XcmExecutor = XcmExecutor<XcmConfig>;
 	type XcmTeleportFilter = All<(MultiLocation, Vec<MultiAsset>)>;
 	type XcmReserveTransferFilter = All<(MultiLocation, Vec<MultiAsset>)>;
@@ -196,7 +196,7 @@ pub(crate) fn last_event() -> Event {
 }
 
 pub(crate) fn buy_execution<C>(fees: impl Into<MultiAsset>, debt: Weight) -> Order<C> {
-	use xcm::opaque::v1::prelude::*;
+	use xcm::opaque::latest::prelude::*;
 	Order::BuyExecution {
 		fees: fees.into(),
 		weight: 0,
diff --git a/xcm/src/lib.rs b/xcm/src/lib.rs
index 4bce0086eca8..05443fc76b1c 100644
--- a/xcm/src/lib.rs
+++ b/xcm/src/lib.rs
@@ -59,23 +59,84 @@ pub enum VersionedXcm<Call> {
 	V1(v1::Xcm<Call>),
 }
 
+impl<Call> From<v0::Xcm<Call>> for VersionedXcm<Call> {
+	fn from(x: v0::Xcm<Call>) -> Self {
+		VersionedXcm::V0(x)
+	}
+}
+
 impl<Call> From<v1::Xcm<Call>> for VersionedXcm<Call> {
 	fn from(x: v1::Xcm<Call>) -> Self {
 		VersionedXcm::V1(x)
 	}
 }
 
+impl<Call> TryFrom<VersionedXcm<Call>> for v0::Xcm<Call> {
+	type Error = ();
+	fn try_from(x: VersionedXcm<Call>) -> Result<Self, ()> {
+		match x {
+			VersionedXcm::V0(x) => Ok(x),
+			VersionedXcm::V1(x) => x.try_into(),
+		}
+	}
+}
+
 impl<Call> TryFrom<VersionedXcm<Call>> for v1::Xcm<Call> {
 	type Error = ();
 	fn try_from(x: VersionedXcm<Call>) -> Result<Self, ()> {
 		match x {
-			// v1-based chains can interpret v0 messages.
 			VersionedXcm::V0(x) => x.try_into(),
 			VersionedXcm::V1(x) => Ok(x),
 		}
 	}
 }
 
+/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will interpret it.
+pub trait WrapVersion {
+	fn wrap_version<Call>(
+		dest: &latest::MultiLocation,
+		xcm: impl Into<VersionedXcm<Call>>,
+	) -> Result<VersionedXcm<Call>, ()>;
+}
+
+/// `()` implementation does nothing with the XCM, just sending with whatever version it was authored as.
+impl WrapVersion for () {
+	fn wrap_version<Call>(
+		_: &latest::MultiLocation,
+		xcm: impl Into<VersionedXcm<Call>>,
+	) -> Result<VersionedXcm<Call>, ()> {
+		Ok(xcm.into())
+	}
+}
+
+/// `WrapVersion` implementation which attempts to always convert the XCM to version 0 before wrapping it.
+pub struct AlwaysV0;
+impl WrapVersion for AlwaysV0 {
+	fn wrap_version<Call>(
+		_: &latest::MultiLocation,
+		xcm: impl Into<VersionedXcm<Call>>,
+	) -> Result<VersionedXcm<Call>, ()> {
+		Ok(VersionedXcm::<Call>::V0(xcm.into().try_into()?))
+	}
+}
+
+/// `WrapVersion` implementation which attempts to always convert the XCM to version 1 before wrapping it.
+pub struct AlwaysV1;
+impl WrapVersion for AlwaysV1 {
+	fn wrap_version<Call>(
+		_: &latest::MultiLocation,
+		xcm: impl Into<VersionedXcm<Call>>,
+	) -> Result<VersionedXcm<Call>, ()> {
+		Ok(VersionedXcm::<Call>::V1(xcm.into().try_into()?))
+	}
+}
+
+/// `WrapVersion` implementation which attempts to always convert the XCM to the latest version before wrapping it.
+pub type AlwaysLatest = AlwaysV1;
+
+/// `WrapVersion` implementation which attempts to always convert the XCM to the release version before wrapping it.
+pub type AlwaysRelease = AlwaysV0;
+
 pub mod opaque {
 	pub mod v0 {
 		// Everything from v0
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index 54b1a0e25267..ad2f70e31cf5 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -16,7 +16,7 @@
 
 //! Version 0 of the Cross-Consensus Message format data structures.
 
-use crate::{DoubleEncoded, VersionedXcm};
+use crate::DoubleEncoded;
 use alloc::vec::Vec;
 use core::{
 	convert::{TryFrom, TryInto},
@@ -247,22 +247,6 @@ pub enum Xcm<Call> {
 	RelayedFrom { who: MultiLocation, message: alloc::boxed::Box<Xcm<Call>> },
 }
 
-impl<Call> From<Xcm<Call>> for VersionedXcm<Call> {
-	fn from(x: Xcm<Call>) -> Self {
-		VersionedXcm::V0(x)
-	}
-}
-
-impl<Call> TryFrom<VersionedXcm<Call>> for Xcm<Call> {
-	type Error = ();
-	fn try_from(x: VersionedXcm<Call>) -> result::Result<Self, ()> {
-		match x {
-			VersionedXcm::V0(x) => Ok(x),
-			VersionedXcm::V1(_) => Err(()), // v0-based chains cannot interpret v1 messages.
-		}
-	}
-}
-
 impl<Call> Xcm<Call> {
 	pub fn into<C>(self) -> Xcm<C> {
 		Xcm::from(self)
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index 99ba9be3b0bb..6b7b4d4f2aea 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -40,7 +40,7 @@ pub use multiasset::{
 };
 pub use multilocation::MultiLocation;
 pub use order::Order;
-pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm, WrapVersion};
+pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
@@ -63,7 +63,7 @@ pub mod prelude {
 		multilocation::MultiLocation::{self, *},
 		opaque,
 		order::Order::{self, *},
-		traits::{Error as XcmError, ExecuteXcm, ForceV0, Outcome, Result as XcmResult, SendXcm},
+		traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
 		OriginKind, Response,
 		Xcm::{self, *},
 	};
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index bd1548fd6f59..57cdda4209d4 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -458,7 +458,7 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v1::{MultiLocation::*, Junction::*};
+	/// # use xcm::latest::{MultiLocation::*, Junction::*};
 	/// # fn main() {
 	/// let mut m = X3(Parent, PalletInstance(3), OnlyChild);
 	/// assert_eq!(m.match_and_split(&X2(Parent, PalletInstance(3))), Some(&OnlyChild));
@@ -598,7 +598,7 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v1::{MultiLocation::*, Junction::*};
+	/// # use xcm::latest::{MultiLocation::*, Junction::*};
 	/// # fn main() {
 	/// let mut m = X3(Parent, Parachain(21), OnlyChild);
 	/// assert_eq!(m.append_with(X2(Parent, PalletInstance(3))), Ok(()));
@@ -625,7 +625,7 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v1::{MultiLocation::*, Junction::*, NetworkId::Any};
+	/// # use xcm::latest::{MultiLocation::*, Junction::*, NetworkId::Any};
 	/// # fn main() {
 	/// let mut m = X3(Parent, Parent, PalletInstance(3));
 	/// assert_eq!(m.prepend_with(X3(Parent, Parachain(21), OnlyChild)), Ok(()));
@@ -682,7 +682,7 @@ impl MultiLocation {
 	///
 	/// # Example
 	/// ```rust
-	/// # use xcm::v1::{MultiLocation::*, Junction::*, NetworkId::Any};
+	/// # use xcm::latest::{MultiLocation::*, Junction::*, NetworkId::Any};
 	/// # fn main() {
 	/// let parent = X1(Parent);
 	/// assert_eq!(parent.is_interior(), false);
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
index 54a40796de66..94fd4449f21d 100644
--- a/xcm/src/v1/traits.rs
+++ b/xcm/src/v1/traits.rs
@@ -16,10 +16,10 @@
 
 //! Cross-Consensus Message format data structures.
 
-use core::{convert::TryInto, result};
+use core::result;
 use parity_scale_codec::{Decode, Encode};
 
-use super::{super::VersionedXcm, MultiLocation, Xcm};
+use super::{MultiLocation, Xcm};
 
 #[derive(Clone, Encode, Decode, Eq, PartialEq, Debug)]
 pub enum Error {
@@ -261,31 +261,3 @@ impl SendXcm for Tuple {
 		Err(Error::CannotReachDestination(destination, message))
 	}
 }
-
-/// Convert an `Xcm` datum into a `VersionedXcm`, based on a destination `MultiLocation` which will interpret it.
-pub trait WrapVersion {
-	fn wrap_version<Call>(
-		dest: &MultiLocation,
-		xcm: Xcm<Call>,
-	) -> result::Result<VersionedXcm<Call>, ()>;
-}
-
-impl WrapVersion for () {
-	fn wrap_version<Call>(
-		_: &MultiLocation,
-		xcm: Xcm<Call>,
-	) -> result::Result<VersionedXcm<Call>, ()> {
-		Ok(VersionedXcm::<Call>::from(xcm))
-	}
-}
-
-/// `WrapVersion` implementation which attempts to always convert the XCM to version 0 before wrapping it.
-pub struct ForceV0;
-impl WrapVersion for ForceV0 {
-	fn wrap_version<Call>(
-		_: &MultiLocation,
-		xcm: Xcm<Call>,
-	) -> result::Result<VersionedXcm<Call>, ()> {
-		Ok(VersionedXcm::<Call>::V0(xcm.try_into()?))
-	}
-}
diff --git a/xcm/xcm-builder/src/barriers.rs b/xcm/xcm-builder/src/barriers.rs
index ec1b5d0c7f63..3e412af629da 100644
--- a/xcm/xcm-builder/src/barriers.rs
+++ b/xcm/xcm-builder/src/barriers.rs
@@ -19,7 +19,7 @@
 use frame_support::{ensure, traits::Contains, weights::Weight};
 use polkadot_parachain::primitives::IsSystem;
 use sp_std::{marker::PhantomData, result::Result};
-use xcm::v1::{Junction, MultiLocation, Order, Xcm};
+use xcm::latest::{Junction, MultiLocation, Order, Xcm};
 use xcm_executor::traits::{OnResponse, ShouldExecute};
 
 /// Execution barrier that just takes `shallow_weight` from `weight_credit`.
diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs
index ebbdf794209f..9742d035c78a 100644
--- a/xcm/xcm-builder/src/currency_adapter.rs
+++ b/xcm/xcm-builder/src/currency_adapter.rs
@@ -19,7 +19,7 @@
 use frame_support::traits::{ExistenceRequirement::AllowDeath, Get, WithdrawReasons};
 use sp_runtime::traits::{CheckedSub, SaturatedConversion};
 use sp_std::{convert::TryInto, marker::PhantomData, result};
-use xcm::v1::{Error as XcmError, MultiAsset, MultiLocation, Result};
+use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result};
 use xcm_executor::{
 	traits::{Convert, MatchesFungible, TransactAsset},
 	Assets,
@@ -53,7 +53,7 @@ impl From<Error> for XcmError {
 /// # Example
 /// ```
 /// use frame_support::parameter_types;
-/// use xcm::v1::{MultiLocation, Junction};
+/// use xcm::latest::{MultiLocation, Junction};
 /// use xcm_builder::{ParentIsDefault, CurrencyAdapter, IsConcrete};
 ///
 /// /// Our chain's account id.
diff --git a/xcm/xcm-builder/src/filter_asset_location.rs b/xcm/xcm-builder/src/filter_asset_location.rs
index 99a0e5e8f7f6..9794c2f44f5b 100644
--- a/xcm/xcm-builder/src/filter_asset_location.rs
+++ b/xcm/xcm-builder/src/filter_asset_location.rs
@@ -18,7 +18,7 @@
 
 use frame_support::traits::Get;
 use sp_std::marker::PhantomData;
-use xcm::v1::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation};
+use xcm::latest::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation};
 use xcm_executor::traits::FilterAssetLocation;
 
 /// Accepts an asset iff it is a native asset.
diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs
index 048f3d8d3a52..d9f1e026ee0b 100644
--- a/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -18,7 +18,7 @@
 
 use frame_support::traits::{tokens::fungibles, Contains, Get};
 use sp_std::{borrow::Borrow, marker::PhantomData, prelude::*, result};
-use xcm::v1::{
+use xcm::latest::{
 	AssetId::{Abstract, Concrete},
 	Error as XcmError,
 	Fungibility::Fungible,
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index cbaf0b93063e..5daaf11d4b81 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -19,7 +19,7 @@ use parity_scale_codec::Encode;
 use sp_io::hashing::blake2_256;
 use sp_runtime::traits::AccountIdConversion;
 use sp_std::{borrow::Borrow, marker::PhantomData};
-use xcm::v1::{Junction, MultiLocation, NetworkId};
+use xcm::latest::{Junction, MultiLocation, NetworkId};
 use xcm_executor::traits::{Convert, InvertLocation};
 
 pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
@@ -155,7 +155,7 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
 /// ```
 /// ```rust
 /// # use frame_support::parameter_types;
-/// # use xcm::v1::{MultiLocation::{self, *}, Junction::*, NetworkId::Any};
+/// # use xcm::latest::{MultiLocation::{self, *}, Junction::*, NetworkId::Any};
 /// # use xcm_builder::LocationInverter;
 /// # use xcm_executor::traits::InvertLocation;
 /// # fn main() {
@@ -200,7 +200,7 @@ mod tests {
 	use super::*;
 
 	use frame_support::parameter_types;
-	use xcm::v1::{Junction::*, MultiLocation::*, NetworkId::Any};
+	use xcm::latest::{Junction::*, MultiLocation::*, NetworkId::Any};
 
 	fn account20() -> Junction {
 		AccountKey20 { network: Any, key: Default::default() }
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 8e61bd2f8439..f1e619c97068 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -19,7 +19,7 @@
 use frame_support::traits::Get;
 use sp_runtime::traits::CheckedConversion;
 use sp_std::{convert::TryFrom, marker::PhantomData};
-use xcm::v1::{
+use xcm::latest::{
 	AssetId::{Abstract, Concrete},
 	Fungibility::Fungible,
 	MultiAsset, MultiLocation,
@@ -32,7 +32,7 @@ use xcm_executor::traits::MatchesFungible;
 /// # Example
 ///
 /// ```
-/// use xcm::v1::prelude::*;
+/// use xcm::latest::prelude::*;
 /// use xcm_builder::IsConcrete;
 /// use xcm_executor::traits::MatchesFungible;
 ///
@@ -62,7 +62,7 @@ impl<T: Get<MultiLocation>, B: TryFrom<u128>> MatchesFungible<B> for IsConcrete<
 /// # Example
 ///
 /// ```
-/// use xcm::v1::prelude::*;
+/// use xcm::latest::prelude::*;
 /// use xcm_builder::IsAbstract;
 /// use xcm_executor::traits::MatchesFungible;
 ///
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index af568a5fc8de..adedd965a4ba 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -34,7 +34,7 @@ pub use sp_std::{
 	fmt::Debug,
 	marker::PhantomData,
 };
-pub use xcm::v1::prelude::*;
+pub use xcm::latest::prelude::*;
 pub use xcm_executor::{
 	traits::{ConvertOrigin, FilterAssetLocation, InvertLocation, OnResponse, TransactAsset},
 	Assets, Config,
@@ -203,7 +203,7 @@ impl FilterAssetLocation for TestIsTeleporter {
 	}
 }
 
-use xcm::v1::Response;
+use xcm::latest::Response;
 pub enum ResponseSlot {
 	Expecting(MultiLocation),
 	Received(Response),
@@ -219,7 +219,7 @@ impl OnResponse for TestResponseHandler {
 			_ => false,
 		})
 	}
-	fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::v1::Response) -> Weight {
+	fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::latest::Response) -> Weight {
 		QUERIES.with(|q| {
 			q.borrow_mut().entry(query_id).and_modify(|v| {
 				if matches!(*v, ResponseSlot::Expecting(..)) {
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index 1432738263cd..08a6de91c648 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -20,7 +20,7 @@ use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait};
 use frame_system::RawOrigin as SystemRawOrigin;
 use polkadot_parachain::primitives::IsSystem;
 use sp_std::{convert::TryInto, marker::PhantomData};
-use xcm::v1::{BodyId, BodyPart, Junction, MultiLocation, NetworkId, OriginKind};
+use xcm::latest::{BodyId, BodyPart, Junction, MultiLocation, NetworkId, OriginKind};
 use xcm_executor::traits::{Convert, ConvertOrigin};
 
 /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 8f95687f29cf..31f141ab68be 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -15,7 +15,7 @@
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
 use super::{mock::*, *};
-use xcm::v1::prelude::*;
+use xcm::latest::prelude::*;
 use xcm_executor::{traits::*, Config, XcmExecutor};
 
 #[test]
diff --git a/xcm/xcm-builder/src/weight.rs b/xcm/xcm-builder/src/weight.rs
index 679aa0928216..12ec9ff173d8 100644
--- a/xcm/xcm-builder/src/weight.rs
+++ b/xcm/xcm-builder/src/weight.rs
@@ -21,7 +21,7 @@ use frame_support::{
 use parity_scale_codec::Decode;
 use sp_runtime::traits::{SaturatedConversion, Saturating, Zero};
 use sp_std::{convert::TryInto, marker::PhantomData, result::Result};
-use xcm::v1::{AssetId, AssetId::Concrete, Error, MultiAsset, MultiLocation, Order, Xcm};
+use xcm::latest::{AssetId, AssetId::Concrete, Error, MultiAsset, MultiLocation, Order, Xcm};
 use xcm_executor::{
 	traits::{WeightBounds, WeightTrader},
 	Assets,
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index f04483f1a6fa..006bea157015 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -20,7 +20,7 @@ use sp_std::{
 	mem,
 	prelude::*,
 };
-use xcm::v1::{
+use xcm::latest::{
 	AssetId, AssetInstance,
 	Fungibility::{Fungible, NonFungible},
 	MultiAsset, MultiAssetFilter, MultiAssets, MultiLocation,
@@ -376,7 +376,7 @@ impl Assets {
 	///
 	/// ```
 	/// use xcm_executor::Assets;
-	/// use xcm::v1::prelude::*;
+	/// use xcm::latest::prelude::*;
 	/// let assets_i_have: Assets = vec![ (Here, 100).into(), (vec![0], 100).into() ].into();
 	/// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), (vec![0], 50).into() ].into();
 	///
@@ -425,7 +425,7 @@ impl Assets {
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use xcm::v1::prelude::*;
+	use xcm::latest::prelude::*;
 	use MultiLocation::Here;
 	#[allow(non_snake_case)]
 	/// Abstract fungible constructor
diff --git a/xcm/xcm-executor/src/config.rs b/xcm/xcm-executor/src/config.rs
index 1a38fb44ea50..7f4bf08f5fa0 100644
--- a/xcm/xcm-executor/src/config.rs
+++ b/xcm/xcm-executor/src/config.rs
@@ -22,7 +22,7 @@ use frame_support::{
 	dispatch::{Dispatchable, Parameter},
 	weights::{GetDispatchInfo, PostDispatchInfo},
 };
-use xcm::v1::SendXcm;
+use xcm::latest::SendXcm;
 
 /// The trait to parameterize the `XcmExecutor`.
 pub trait Config {
diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index c30c5d3f9a77..102f241fbc4e 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -22,7 +22,7 @@ use frame_support::{
 	weights::GetDispatchInfo,
 };
 use sp_std::{marker::PhantomData, prelude::*};
-use xcm::v1::{
+use xcm::latest::{
 	Error as XcmError, ExecuteXcm, MultiAssets, MultiLocation, Order, Outcome, Response, SendXcm,
 	Xcm,
 };
diff --git a/xcm/xcm-executor/src/traits/conversion.rs b/xcm/xcm-executor/src/traits/conversion.rs
index df99a05d0064..4342fc5002e5 100644
--- a/xcm/xcm-executor/src/traits/conversion.rs
+++ b/xcm/xcm-executor/src/traits/conversion.rs
@@ -16,7 +16,7 @@
 
 use parity_scale_codec::{Decode, Encode};
 use sp_std::{borrow::Borrow, convert::TryFrom, prelude::*, result::Result};
-use xcm::v1::{MultiLocation, OriginKind};
+use xcm::latest::{MultiLocation, OriginKind};
 
 /// Generic third-party conversion trait. Use this when you don't want to force the user to use default
 /// implementations of `From` and `Into` for the types you wish to convert between.
@@ -139,7 +139,7 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
 /// which is passed to the next convert item.
 ///
 /// ```rust
-/// # use xcm::v1::{MultiLocation, Junction, OriginKind};
+/// # use xcm::latest::{MultiLocation, Junction, OriginKind};
 /// # use xcm_executor::traits::ConvertOrigin;
 /// // A convertor that will bump the para id and pass it to the next one.
 /// struct BumpParaId;
diff --git a/xcm/xcm-executor/src/traits/filter_asset_location.rs b/xcm/xcm-executor/src/traits/filter_asset_location.rs
index a63af84e167c..31b9c47a828c 100644
--- a/xcm/xcm-executor/src/traits/filter_asset_location.rs
+++ b/xcm/xcm-executor/src/traits/filter_asset_location.rs
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use xcm::v1::{MultiAsset, MultiLocation};
+use xcm::latest::{MultiAsset, MultiLocation};
 
 /// Filters assets/location pairs.
 ///
diff --git a/xcm/xcm-executor/src/traits/matches_fungible.rs b/xcm/xcm-executor/src/traits/matches_fungible.rs
index ff466af5b21c..4989f263a63d 100644
--- a/xcm/xcm-executor/src/traits/matches_fungible.rs
+++ b/xcm/xcm-executor/src/traits/matches_fungible.rs
@@ -14,7 +14,7 @@
 // You should have received a copy of the GNU General Public License
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
-use xcm::v1::MultiAsset;
+use xcm::latest::MultiAsset;
 
 pub trait MatchesFungible<Balance> {
 	fn matches_fungible(a: &MultiAsset) -> Option<Balance>;
diff --git a/xcm/xcm-executor/src/traits/matches_fungibles.rs b/xcm/xcm-executor/src/traits/matches_fungibles.rs
index 2499eae27531..f5baafdcd97a 100644
--- a/xcm/xcm-executor/src/traits/matches_fungibles.rs
+++ b/xcm/xcm-executor/src/traits/matches_fungibles.rs
@@ -15,7 +15,7 @@
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
 use sp_std::result;
-use xcm::v1::{Error as XcmError, MultiAsset};
+use xcm::latest::{Error as XcmError, MultiAsset};
 
 /// Errors associated with [`MatchesFungibles`] operation.
 pub enum Error {
diff --git a/xcm/xcm-executor/src/traits/on_response.rs b/xcm/xcm-executor/src/traits/on_response.rs
index 801aa016d478..8af238e7cef2 100644
--- a/xcm/xcm-executor/src/traits/on_response.rs
+++ b/xcm/xcm-executor/src/traits/on_response.rs
@@ -15,7 +15,7 @@
 // along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
 
 use frame_support::weights::Weight;
-use xcm::v1::{MultiLocation, Response};
+use xcm::latest::{MultiLocation, Response};
 
 /// Define what needs to be done upon receiving a query response.
 pub trait OnResponse {
diff --git a/xcm/xcm-executor/src/traits/should_execute.rs b/xcm/xcm-executor/src/traits/should_execute.rs
index a8d9ad1ca79a..a6f7c0207b1a 100644
--- a/xcm/xcm-executor/src/traits/should_execute.rs
+++ b/xcm/xcm-executor/src/traits/should_execute.rs
@@ -16,7 +16,7 @@
 
 use frame_support::weights::Weight;
 use sp_std::result::Result;
-use xcm::v1::{MultiLocation, Xcm};
+use xcm::latest::{MultiLocation, Xcm};
 
 /// Trait to determine whether the execution engine should actually execute a given XCM.
 ///
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index a810ce173ca3..e261d9c9c963 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -16,7 +16,7 @@
 
 use crate::Assets;
 use sp_std::result::Result;
-use xcm::v1::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult};
+use xcm::latest::{Error as XcmError, MultiAsset, MultiLocation, Result as XcmResult};
 
 /// Facility for asset transacting.
 ///
diff --git a/xcm/xcm-executor/src/traits/weight.rs b/xcm/xcm-executor/src/traits/weight.rs
index c32ec682857c..8c9e6ec6366d 100644
--- a/xcm/xcm-executor/src/traits/weight.rs
+++ b/xcm/xcm-executor/src/traits/weight.rs
@@ -17,7 +17,7 @@
 use crate::Assets;
 use frame_support::weights::Weight;
 use sp_std::result::Result;
-use xcm::v1::{Error, MultiAsset, MultiLocation, Xcm};
+use xcm::latest::{Error, MultiAsset, MultiLocation, Xcm};
 
 /// Determine the weight of an XCM message.
 pub trait WeightBounds<Call> {
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index a02aeaaff456..2426b83819bb 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -99,7 +99,7 @@ mod tests {
 
 	use codec::Encode;
 	use frame_support::assert_ok;
-	use xcm::v1::prelude::*;
+	use xcm::latest::prelude::*;
 	use xcm_simulator::TestExt;
 
 	#[test]
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 3e7212c48fa4..bf2eff15c27c 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -35,7 +35,7 @@ use polkadot_core_primitives::BlockNumber as RelayBlockNumber;
 use polkadot_parachain::primitives::{
 	DmpMessageHandler, Id as ParaId, Sibling, XcmpMessageFormat, XcmpMessageHandler,
 };
-use xcm::{v1::prelude::*, VersionedXcm};
+use xcm::{latest::prelude::*, VersionedXcm};
 use xcm_builder::{
 	AccountId32Aliases, AllowUnpaidExecutionFrom, CurrencyAdapter as XcmCurrencyAdapter,
 	EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds, IsConcrete, LocationInverter,
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index adbf0b965f41..b89bc2abca01 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -26,7 +26,7 @@ use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
 
 use polkadot_parachain::primitives::Id as ParaId;
 use polkadot_runtime_parachains::{configuration, origin, shared, ump};
-use xcm::v1::prelude::*;
+use xcm::latest::prelude::*;
 use xcm_builder::{
 	AccountId32Aliases, AllowUnpaidExecutionFrom, ChildParachainAsNative,
 	ChildParachainConvertsVia, ChildSystemParachainAsSuperuser,
diff --git a/xcm/xcm-simulator/src/lib.rs b/xcm/xcm-simulator/src/lib.rs
index f075c7e3d9fb..7a3ad25d1555 100644
--- a/xcm/xcm-simulator/src/lib.rs
+++ b/xcm/xcm-simulator/src/lib.rs
@@ -32,7 +32,7 @@ pub use polkadot_runtime_parachains::{
 	dmp,
 	ump::{self, MessageId, UmpSink, XcmSink},
 };
-pub use xcm::{v1::prelude::*, VersionedXcm};
+pub use xcm::{latest::prelude::*, VersionedXcm};
 pub use xcm_executor::XcmExecutor;
 
 pub trait TestExt {

From d9ff88c24983e694e6c6778474c8e8e6dfe754b9 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Fri, 6 Aug 2021 14:04:21 +0200
Subject: [PATCH 099/166] Fixes

---
 runtime/common/src/xcm_sender.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs
index 4c2575a3face..c386fc5252d4 100644
--- a/runtime/common/src/xcm_sender.rs
+++ b/runtime/common/src/xcm_sender.rs
@@ -19,12 +19,12 @@
 use parity_scale_codec::Encode;
 use runtime_parachains::{configuration, dmp};
 use sp_std::marker::PhantomData;
-use xcm::opaque::v1::{Error, Junction, MultiLocation, Result, SendXcm, WrapVersion, Xcm};
+use xcm::opaque::v1::{Error, Junction, MultiLocation, Result, SendXcm, Xcm};
 
 /// XCM sender for relay chain. It only sends downward message.
 pub struct ChildParachainRouter<T, W>(PhantomData<(T, W)>);
 
-impl<T: configuration::Config + dmp::Config, W: WrapVersion> SendXcm
+impl<T: configuration::Config + dmp::Config, W: xcm::WrapVersion> SendXcm
 	for ChildParachainRouter<T, W>
 {
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {

From b40668efb3522ca8c670ddac6842a3781bbc8f73 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Fri, 6 Aug 2021 14:57:10 +0200
Subject: [PATCH 100/166] fmt

---
 xcm/pallet-xcm/src/mock.rs  | 2 +-
 xcm/xcm-builder/src/mock.rs | 6 +++++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index f7468cb3455d..7929534126b2 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -25,8 +25,8 @@ use sp_core::H256;
 use sp_runtime::{testing::Header, traits::IdentityLookup, AccountId32};
 pub use sp_std::{cell::RefCell, fmt::Debug, marker::PhantomData};
 use xcm::{
-	opaque::latest::{Error as XcmError, MultiAsset, Result as XcmResult, SendXcm, Xcm},
 	latest::prelude::*,
+	opaque::latest::{Error as XcmError, MultiAsset, Result as XcmResult, SendXcm, Xcm},
 };
 use xcm_builder::{
 	AccountId32Aliases, AllowTopLevelPaidExecutionFrom, ChildParachainAsNative,
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index adedd965a4ba..21835dd39b1e 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -219,7 +219,11 @@ impl OnResponse for TestResponseHandler {
 			_ => false,
 		})
 	}
-	fn on_response(_origin: MultiLocation, query_id: u64, response: xcm::latest::Response) -> Weight {
+	fn on_response(
+		_origin: MultiLocation,
+		query_id: u64,
+		response: xcm::latest::Response,
+	) -> Weight {
 		QUERIES.with(|q| {
 			q.borrow_mut().entry(query_id).and_modify(|v| {
 				if matches!(*v, ResponseSlot::Expecting(..)) {

From a123f94d64399c63f608d0079906c03c1bca5506 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 08:05:14 -0700
Subject: [PATCH 101/166] Fix pallet-xcm tests

---
 xcm/pallet-xcm/src/mock.rs  |  6 +++---
 xcm/pallet-xcm/src/tests.rs | 38 ++++++++++++++++---------------------
 2 files changed, 19 insertions(+), 25 deletions(-)

diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index 7929534126b2..845ced90b58e 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -75,7 +75,7 @@ impl SendXcm for TestSendXcm {
 pub struct TestSendXcmErrX8;
 impl SendXcm for TestSendXcmErrX8 {
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> XcmResult {
-		if let MultiLocation::X8(..) = dest {
+		if dest.len() >= 8 {
 			Err(XcmError::Undefined)
 		} else {
 			SENT_XCM.with(|q| q.borrow_mut().push((dest, msg)));
@@ -133,9 +133,9 @@ impl pallet_balances::Config for Test {
 }
 
 parameter_types! {
-	pub const RelayLocation: MultiLocation = MultiLocation::Here;
+	pub const RelayLocation: MultiLocation = MultiLocation::here();
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = MultiLocation::Here;
+	pub Ancestry: MultiLocation = MultiLocation::here();
 	pub UnitWeightCost: Weight = 1_000;
 }
 
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index f10e0490484d..764eeaff98c4 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -40,9 +40,9 @@ fn send_works() {
 		let sender: MultiLocation =
 			AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (X1(Parent), SEND_AMOUNT).into(),
+			assets: (MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((Parent, SEND_AMOUNT), weight),
+				buy_execution((MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -50,7 +50,7 @@ fn send_works() {
 		assert_eq!(
 			sent_xcm(),
 			vec![(
-				MultiLocation::Here,
+				MultiLocation::here(),
 				RelayedFrom { who: sender.clone(), message: Box::new(message.clone()) }
 			)]
 		);
@@ -74,25 +74,16 @@ fn send_fails_when_xcm_router_blocks() {
 		let sender: MultiLocation =
 			Junction::AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (Parent, SEND_AMOUNT).into(),
+			assets: (MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((Parent, SEND_AMOUNT), weight),
+				buy_execution((MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
 		assert_noop!(
 			XcmPallet::send(
 				Origin::signed(ALICE),
-				X8(
-					Junction::Parent,
-					Junction::Parent,
-					Junction::Parent,
-					Junction::Parent,
-					Junction::Parent,
-					Junction::Parent,
-					Junction::Parent,
-					Junction::Parent
-				),
+				MultiLocation::with_parents(8).unwrap(),
 				message.clone()
 			),
 			crate::Error::<Test>::SendFailure
@@ -114,8 +105,8 @@ fn teleport_assets_works() {
 		assert_ok!(XcmPallet::teleport_assets(
 			Origin::signed(ALICE),
 			RelayLocation::get(),
-			X1(AccountId32 { network: Any, id: BOB.into() }),
-			(Here, SEND_AMOUNT).into(),
+			X1(AccountId32 { network: Any, id: BOB.into() }).into(),
+			(MultiLocation::here(), SEND_AMOUNT).into(),
 			0,
 			weight,
 		));
@@ -144,7 +135,7 @@ fn reserve_transfer_assets_works() {
 			Origin::signed(ALICE),
 			Parachain(PARA_ID).into(),
 			dest.clone(),
-			(Here, SEND_AMOUNT).into(),
+			(MultiLocation::here(), SEND_AMOUNT).into(),
 			0,
 			weight
 		));
@@ -158,9 +149,12 @@ fn reserve_transfer_assets_works() {
 			vec![(
 				Parachain(PARA_ID).into(),
 				Xcm::ReserveAssetDeposited {
-					assets: (X1(Parent), SEND_AMOUNT).into(),
+					assets: (MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT).into(),
 					effects: vec![
-						buy_execution((Parent, SEND_AMOUNT), weight),
+						buy_execution(
+							(MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT),
+							weight
+						),
 						DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
 					]
 				}
@@ -189,9 +183,9 @@ fn execute_withdraw_to_deposit_works() {
 		assert_ok!(XcmPallet::execute(
 			Origin::signed(ALICE),
 			Box::new(Xcm::WithdrawAsset {
-				assets: (Here, SEND_AMOUNT).into(),
+				assets: (MultiLocation::here(), SEND_AMOUNT).into(),
 				effects: vec![
-					buy_execution((Here, SEND_AMOUNT), weight),
+					buy_execution((MultiLocation::here(), SEND_AMOUNT), weight),
 					DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }
 				],
 			}),

From 5c330ad07ee39e9d71bb65fea8d0e58498e86ffe Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 10:47:14 -0700
Subject: [PATCH 102/166] fix

---
 xcm/xcm-executor/src/traits/transact_asset.rs | 1 -
 1 file changed, 1 deletion(-)

diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index dd155a60bf98..608498fd2dd9 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -193,7 +193,6 @@ impl TransactAsset for Tuple {
 #[cfg(test)]
 mod tests {
 	use super::*;
-	use MultiLocation::Here;
 
 	pub struct UnimplementedTransactor;
 	impl TransactAsset for UnimplementedTransactor {}

From 0edc39fcacc08a12ea0e411a384a3a527fef6daa Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 12:38:34 -0700
Subject: [PATCH 103/166] Substitute with_parent with with_parents_const

---
 Cargo.lock                                 |  1 +
 xcm/Cargo.toml                             |  1 +
 xcm/pallet-xcm/src/tests.rs                | 14 ++--
 xcm/src/v1/multilocation.rs                | 32 ++++-----
 xcm/src/v1/traits.rs                       |  2 +-
 xcm/xcm-builder/src/currency_adapter.rs    |  2 +-
 xcm/xcm-builder/src/matches_fungible.rs    |  4 +-
 xcm/xcm-builder/src/tests.rs               | 84 +++++++++++-----------
 xcm/xcm-simulator/example/src/lib.rs       |  2 +-
 xcm/xcm-simulator/example/src/parachain.rs |  6 +-
 10 files changed, 71 insertions(+), 77 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index cd449c18b316..5514cf38ac8c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12282,6 +12282,7 @@ dependencies = [
  "impl-trait-for-tuples",
  "log",
  "parity-scale-codec",
+ "static_assertions",
 ]
 
 [[package]]
diff --git a/xcm/Cargo.toml b/xcm/Cargo.toml
index a1bfa76130a7..67865f32f929 100644
--- a/xcm/Cargo.toml
+++ b/xcm/Cargo.toml
@@ -10,6 +10,7 @@ impl-trait-for-tuples = "0.2.0"
 parity-scale-codec = { version = "2.0.0", default-features = false, features = [ "derive" ] }
 derivative = {version = "2.2.0", default-features = false, features = [ "use_core" ] }
 log = { version = "0.4.14", default-features = false }
+static_assertions = "1.1.0"
 
 [features]
 default = ["std"]
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 764eeaff98c4..b0785493f059 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -40,9 +40,9 @@ fn send_works() {
 		let sender: MultiLocation =
 			AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT).into(),
+			assets: (MultiLocation::with_parents::<1>(), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT), weight),
+				buy_execution((MultiLocation::with_parents::<1>(), SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -74,16 +74,16 @@ fn send_fails_when_xcm_router_blocks() {
 		let sender: MultiLocation =
 			Junction::AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT).into(),
+			assets: (MultiLocation::with_parents::<1>(), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT), weight),
+				buy_execution((MultiLocation::with_parents::<1>(), SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
 		assert_noop!(
 			XcmPallet::send(
 				Origin::signed(ALICE),
-				MultiLocation::with_parents(8).unwrap(),
+				MultiLocation::with_parents::<8>(),
 				message.clone()
 			),
 			crate::Error::<Test>::SendFailure
@@ -149,10 +149,10 @@ fn reserve_transfer_assets_works() {
 			vec![(
 				Parachain(PARA_ID).into(),
 				Xcm::ReserveAssetDeposited {
-					assets: (MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT).into(),
+					assets: (MultiLocation::with_parents::<1>(), SEND_AMOUNT).into(),
 					effects: vec![
 						buy_execution(
-							(MultiLocation::with_parents(1).unwrap(), SEND_AMOUNT),
+							(MultiLocation::with_parents::<1>(), SEND_AMOUNT),
 							weight
 						),
 						DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index b4ef955a4732..2cd8d6b81a81 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -22,6 +22,7 @@ use core::{
 	mem, result,
 };
 use parity_scale_codec::{self, Decode, Encode};
+use static_assertions::const_assert;
 
 /// A relative path between state-bearing consensus systems.
 ///
@@ -81,21 +82,12 @@ impl MultiLocation {
 
 	/// Creates a new `MultiLocation` with the specified number of parents in the `P` const generic
 	/// parameter and a `Null` interior.
-	// #FIXME: Use a where clause to evaluate P for well-formedness once const eval of const
-	//         generics is possible.
-	pub const fn with_parents_const<const P: u8>() -> MultiLocation {
+	pub const fn with_parents<const P: u8>() -> MultiLocation {
+		// If this condition does not hold, then P may overflow MAX_MULTILOCATION_LENGTH.
+		const_assert!(MAX_MULTILOCATION_LENGTH >= 255);
 		MultiLocation { parents: P, interior: Junctions::Null }
 	}
 
-	/// Creates a new `MultiLocation` with the specified number of parents and a `Null` interior.
-	/// Returns an error if `parents` is greater than `MAX_MULTILOCATION_LENGTH`.
-	pub const fn with_parents(parents: u8) -> result::Result<MultiLocation, ()> {
-		if parents as usize > MAX_MULTILOCATION_LENGTH {
-			return Err(())
-		}
-		Ok(MultiLocation { parents, interior: Junctions::Null })
-	}
-
 	/// Creates a new `MultiLocation` with no parents and a single `Parachain` interior junction
 	/// specified by `para_id`.
 	///
@@ -837,16 +829,16 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 		use Junctions::*;
 		match old {
 			MultiLocation0::Null => Ok(MultiLocation::here()),
-			MultiLocation0::X1(j0) if j0.is_parent() => MultiLocation::with_parents(1),
+			MultiLocation0::X1(j0) if j0.is_parent() => Ok(MultiLocation::with_parents::<1>()),
 			MultiLocation0::X1(j0) => Ok(X1(j0.try_into()?).into()),
 			MultiLocation0::X2(j0, j1) if j0.is_parent() && j1.is_parent() =>
-				MultiLocation::with_parents(2),
+				Ok(MultiLocation::with_parents::<2>()),
 			MultiLocation0::X2(j0, j1) if j0.is_parent() =>
 				Ok(MultiLocation { parents: 1, interior: X1(j1.try_into()?) }),
 			MultiLocation0::X2(j0, j1) => Ok(X2(j0.try_into()?, j1.try_into()?).into()),
 			MultiLocation0::X3(j0, j1, j2)
 				if j0.is_parent() && j1.is_parent() && j2.is_parent() =>
-				MultiLocation::with_parents(3),
+				Ok(MultiLocation::with_parents::<3>()),
 			MultiLocation0::X3(j0, j1, j2) if j0.is_parent() && j1.is_parent() =>
 				Ok(MultiLocation { parents: 2, interior: X1(j2.try_into()?) }),
 			MultiLocation0::X3(j0, j1, j2) if j0.is_parent() =>
@@ -855,7 +847,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 				Ok(X3(j0.try_into()?, j1.try_into()?, j2.try_into()?).into()),
 			MultiLocation0::X4(j0, j1, j2, j3)
 				if j0.is_parent() && j1.is_parent() && j2.is_parent() && j3.is_parent() =>
-				MultiLocation::with_parents(4),
+				Ok(MultiLocation::with_parents::<4>()),
 			MultiLocation0::X4(j0, j1, j2, j3)
 				if j0.is_parent() && j1.is_parent() && j2.is_parent() =>
 				Ok(MultiLocation { parents: 3, interior: X1(j3.try_into()?) }),
@@ -871,7 +863,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 				if j0.is_parent() &&
 					j1.is_parent() && j2.is_parent() &&
 					j3.is_parent() && j4.is_parent() =>
-				MultiLocation::with_parents(5),
+				Ok(MultiLocation::with_parents::<5>()),
 			MultiLocation0::X5(j0, j1, j2, j3, j4)
 				if j0.is_parent() && j1.is_parent() && j2.is_parent() && j3.is_parent() =>
 				Ok(MultiLocation { parents: 4, interior: X1(j4.try_into()?) }),
@@ -900,7 +892,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 					j1.is_parent() && j2.is_parent() &&
 					j3.is_parent() && j4.is_parent() &&
 					j5.is_parent() =>
-				MultiLocation::with_parents(6),
+				Ok(MultiLocation::with_parents::<6>()),
 			MultiLocation0::X6(j0, j1, j2, j3, j4, j5)
 				if j0.is_parent() &&
 					j1.is_parent() && j2.is_parent() &&
@@ -944,7 +936,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 					j1.is_parent() && j2.is_parent() &&
 					j3.is_parent() && j4.is_parent() &&
 					j5.is_parent() && j6.is_parent() =>
-				MultiLocation::with_parents(7),
+				Ok(MultiLocation::with_parents::<7>()),
 			MultiLocation0::X7(j0, j1, j2, j3, j4, j5, j6)
 				if j0.is_parent() &&
 					j1.is_parent() && j2.is_parent() &&
@@ -1006,7 +998,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 					j3.is_parent() && j4.is_parent() &&
 					j5.is_parent() && j6.is_parent() &&
 					j7.is_parent() =>
-				MultiLocation::with_parents(8),
+				Ok(MultiLocation::with_parents::<8>()),
 			MultiLocation0::X8(j0, j1, j2, j3, j4, j5, j6, j7)
 				if j0.is_parent() &&
 					j1.is_parent() && j2.is_parent() &&
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
index 78f3eb692b0c..2410223f8b3e 100644
--- a/xcm/src/v1/traits.rs
+++ b/xcm/src/v1/traits.rs
@@ -229,7 +229,7 @@ impl<C> ExecuteXcm<C> for () {
 /// # fn main() {
 /// let call: Vec<u8> = ().encode();
 /// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
-/// let destination = MultiLocation::with_parents(1).unwrap();
+/// let destination = MultiLocation::with_parents::<1>();
 ///
 /// assert!(
 ///     // Sender2 will block this.
diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs
index eef790de1a18..097010d2c889 100644
--- a/xcm/xcm-builder/src/currency_adapter.rs
+++ b/xcm/xcm-builder/src/currency_adapter.rs
@@ -61,7 +61,7 @@ impl From<Error> for XcmError {
 ///
 /// /// Our relay chain's location.
 /// parameter_types! {
-///     RelayChain: MultiLocation = MultiLocation::with_parents(1).unwrap();
+///     RelayChain: MultiLocation = MultiLocation::with_parents::<1>();
 ///     CheckingAccount: AccountId = Default::default();
 /// }
 ///
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 1c95a7fa269c..579b2eba3f78 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -37,11 +37,11 @@ use xcm_executor::traits::MatchesFungible;
 /// use xcm_executor::traits::MatchesFungible;
 ///
 /// frame_support::parameter_types! {
-/// 	pub TargetLocation: MultiLocation = MultiLocation::with_parents(1).unwrap();
+/// 	pub TargetLocation: MultiLocation = MultiLocation::with_parents::<1>();
 /// }
 ///
 /// # fn main() {
-/// let asset = (MultiLocation::with_parents(1).unwrap(), 999).into();
+/// let asset = (MultiLocation::with_parents::<1>(), 999).into();
 /// // match `asset` if it is a concrete asset in `TargetLocation`.
 /// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
 /// # }
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 118d65147ee9..0d6ddb4d5331 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -21,12 +21,12 @@ use xcm_executor::{traits::*, Config, XcmExecutor};
 #[test]
 fn basic_setup_works() {
 	add_reserve(
-		MultiLocation::with_parents(1).unwrap(),
-		Wild((MultiLocation::with_parents(1).unwrap(), WildFungible).into()),
+		MultiLocation::with_parents::<1>(),
+		Wild((MultiLocation::with_parents::<1>(), WildFungible).into()),
 	);
 	assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
-		&(MultiLocation::with_parents(1).unwrap(), 100).into(),
-		&MultiLocation::with_parents(1).unwrap(),
+		&(MultiLocation::with_parents::<1>(), 100).into(),
+		&MultiLocation::with_parents::<1>(),
 	));
 
 	assert_eq!(to_account(MultiLocation::with_parachain_interior(1)), Ok(1001));
@@ -47,10 +47,10 @@ fn basic_setup_works() {
 #[test]
 fn weigher_should_work() {
 	let mut message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::with_parents(1).unwrap(), 100).into(),
+		assets: (MultiLocation::with_parents::<1>(), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
-				fees: (MultiLocation::with_parents(1).unwrap(), 1).into(),
+				fees: (MultiLocation::with_parents::<1>(), 1).into(),
 				weight: 0,
 				debt: 30,
 				halt_on_error: true,
@@ -71,13 +71,13 @@ fn weigher_should_work() {
 #[test]
 fn take_weight_credit_barrier_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::with_parents(1).unwrap(), 100).into(),
+		assets: (MultiLocation::with_parents::<1>(), 100).into(),
 		beneficiary: MultiLocation::here(),
 	};
 
 	let mut weight_credit = 10;
 	let r = TakeWeightCredit::should_execute(
-		&MultiLocation::new(1, Null).unwrap(),
+		&MultiLocation::with_parents::<1>(),
 		true,
 		&mut message,
 		10,
@@ -87,7 +87,7 @@ fn take_weight_credit_barrier_should_work() {
 	assert_eq!(weight_credit, 0);
 
 	let r = TakeWeightCredit::should_execute(
-		&MultiLocation::new(1, Null).unwrap(),
+		&MultiLocation::with_parents::<1>(),
 		true,
 		&mut message,
 		10,
@@ -100,11 +100,11 @@ fn take_weight_credit_barrier_should_work() {
 #[test]
 fn allow_unpaid_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::with_parents(1).unwrap(), 100).into(),
+		assets: (MultiLocation::with_parents::<1>(), 100).into(),
 		beneficiary: MultiLocation::here(),
 	};
 
-	AllowUnpaidFrom::set(vec![MultiLocation::new(1, Null).unwrap()]);
+	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
 		&X1(Parachain(1)).into(),
@@ -116,7 +116,7 @@ fn allow_unpaid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
-		&MultiLocation::new(1, Null).unwrap(),
+		&MultiLocation::with_parents::<1>(),
 		true,
 		&mut message,
 		10,
@@ -127,10 +127,10 @@ fn allow_unpaid_should_work() {
 
 #[test]
 fn allow_paid_should_work() {
-	AllowPaidFrom::set(vec![MultiLocation::new(1, Null).unwrap()]);
+	AllowPaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
 
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::with_parents(1).unwrap(), 100).into(),
+		assets: (MultiLocation::with_parents::<1>(), 100).into(),
 		beneficiary: MultiLocation::here(),
 	};
 
@@ -143,9 +143,9 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let fees = (MultiLocation::with_parents(1).unwrap(), 1).into();
+	let fees = (MultiLocation::with_parents::<1>(), 1).into();
 	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::with_parents(1).unwrap(), 100).into(),
+		assets: (MultiLocation::with_parents::<1>(), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
 				fees,
@@ -164,7 +164,7 @@ fn allow_paid_should_work() {
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&MultiLocation::new(1, Null).unwrap(),
+		&MultiLocation::with_parents::<1>(),
 		true,
 		&mut underpaying_message,
 		30,
@@ -172,9 +172,9 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let fees = (MultiLocation::with_parents(1).unwrap(), 1).into();
+	let fees = (MultiLocation::with_parents::<1>(), 1).into();
 	let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::with_parents(1).unwrap(), 100).into(),
+		assets: (MultiLocation::with_parents::<1>(), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
 				fees,
@@ -202,7 +202,7 @@ fn allow_paid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&MultiLocation::new(1, Null).unwrap(),
+		&MultiLocation::with_parents::<1>(),
 		true,
 		&mut paying_message,
 		30,
@@ -213,17 +213,17 @@ fn allow_paid_should_work() {
 
 #[test]
 fn paying_reserve_deposit_should_work() {
-	AllowPaidFrom::set(vec![MultiLocation::with_parents(1).unwrap()]);
+	AllowPaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
 	add_reserve(
-		MultiLocation::with_parents(1).unwrap(),
-		(MultiLocation::with_parents(1).unwrap(), WildFungible).into(),
+		MultiLocation::with_parents::<1>(),
+		(MultiLocation::with_parents::<1>(), WildFungible).into(),
 	);
-	WeightPrice::set((MultiLocation::with_parents(1).unwrap().into(), 1_000_000_000_000));
+	WeightPrice::set((MultiLocation::with_parents::<1>().into(), 1_000_000_000_000));
 
-	let origin = MultiLocation::with_parents(1).unwrap();
-	let fees = (MultiLocation::with_parents(1).unwrap(), 30).into();
+	let origin = MultiLocation::with_parents::<1>();
+	let fees = (MultiLocation::with_parents::<1>(), 30).into();
 	let message = Xcm::<TestCall>::ReserveAssetDeposited {
-		assets: (MultiLocation::with_parents(1).unwrap(), 100).into(),
+		assets: (MultiLocation::with_parents::<1>(), 100).into(),
 		effects: vec![
 			Order::<TestCall>::BuyExecution {
 				fees,
@@ -243,7 +243,7 @@ fn paying_reserve_deposit_should_work() {
 	let weight_limit = 50;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(30));
-	assert_eq!(assets(3000), vec![(MultiLocation::with_parents(1).unwrap(), 70).into()]);
+	assert_eq!(assets(3000), vec![(MultiLocation::with_parents::<1>(), 70).into()]);
 }
 
 #[test]
@@ -298,7 +298,7 @@ fn reserve_transfer_should_work() {
 		vec![(
 			X1(Parachain(2)).into(),
 			Xcm::ReserveAssetDeposited {
-				assets: (MultiLocation::with_parents(1).unwrap(), 100).into(),
+				assets: (MultiLocation::with_parents::<1>(), 100).into(),
 				effects: vec![Order::DepositAsset {
 					assets: All.into(),
 					max_assets: 1,
@@ -311,9 +311,9 @@ fn reserve_transfer_should_work() {
 
 #[test]
 fn transacting_should_work() {
-	AllowUnpaidFrom::set(vec![MultiLocation::with_parents(1).unwrap()]);
+	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
 
-	let origin = MultiLocation::with_parents(1).unwrap();
+	let origin = MultiLocation::with_parents::<1>();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -326,9 +326,9 @@ fn transacting_should_work() {
 
 #[test]
 fn transacting_should_respect_max_weight_requirement() {
-	AllowUnpaidFrom::set(vec![MultiLocation::with_parents(1).unwrap()]);
+	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
 
-	let origin = MultiLocation::with_parents(1).unwrap();
+	let origin = MultiLocation::with_parents::<1>();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 40,
@@ -341,9 +341,9 @@ fn transacting_should_respect_max_weight_requirement() {
 
 #[test]
 fn transacting_should_refund_weight() {
-	AllowUnpaidFrom::set(vec![MultiLocation::with_parents(1).unwrap()]);
+	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
 
-	let origin = MultiLocation::with_parents(1).unwrap();
+	let origin = MultiLocation::with_parents::<1>();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -358,13 +358,13 @@ fn transacting_should_refund_weight() {
 fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let one: MultiLocation = X1(AccountIndex64 { index: 1, network: Any }).into();
 	AllowPaidFrom::set(vec![one.clone()]);
-	add_asset(1, (MultiLocation::with_parents(1).unwrap(), 100).into());
-	WeightPrice::set((MultiLocation::with_parents(1).unwrap().into(), 1_000_000_000_000));
+	add_asset(1, (MultiLocation::with_parents::<1>(), 100).into());
+	WeightPrice::set((MultiLocation::with_parents::<1>().into(), 1_000_000_000_000));
 
 	let origin = one.clone();
-	let fees = (MultiLocation::with_parents(1).unwrap(), 100).into();
+	let fees = (MultiLocation::with_parents::<1>(), 100).into();
 	let message = Xcm::<TestCall>::WithdrawAsset {
-		assets: (MultiLocation::with_parents(1).unwrap(), 100).into(), // enough for 100 units of weight.
+		assets: (MultiLocation::with_parents::<1>(), 100).into(), // enough for 100 units of weight.
 		effects: vec![
 			Order::<TestCall>::BuyExecution {
 				fees,
@@ -389,17 +389,17 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let weight_limit = 100;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(50));
-	assert_eq!(assets(1), vec![(MultiLocation::with_parents(1).unwrap(), 50).into()]);
+	assert_eq!(assets(1), vec![(MultiLocation::with_parents::<1>(), 50).into()]);
 }
 
 #[test]
 fn prepaid_result_of_query_should_get_free_execution() {
 	let query_id = 33;
-	let origin = MultiLocation::with_parents(1).unwrap();
+	let origin = MultiLocation::with_parents::<1>();
 	// We put this in manually here, but normally this would be done at the point of crafting the message.
 	expect_response(query_id, origin.clone());
 
-	let the_response = Response::Assets((MultiLocation::with_parents(1).unwrap(), 100).into());
+	let the_response = Response::Assets((MultiLocation::with_parents::<1>(), 100).into());
 	let message = Xcm::<TestCall>::QueryResponse { query_id, response: the_response.clone() };
 	let weight_limit = 10;
 
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 4c46090a37c1..dba08d2335be 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -139,7 +139,7 @@ mod tests {
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
 				MultiLocation::here(),
-				MultiLocation::with_parents(1).unwrap(),
+				MultiLocation::with_parents::<1>(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 33b97d26b165..2e85e86169f6 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -101,7 +101,7 @@ parameter_types! {
 }
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = MultiLocation::with_parents_const::<1>();
+	pub const KsmLocation: MultiLocation = MultiLocation::with_parents::<1>();
 	pub const RelayNetwork: NetworkId = NetworkId::Kusama;
 	pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
 }
@@ -120,7 +120,7 @@ pub type XcmOriginToCallOrigin = (
 
 parameter_types! {
 	pub const UnitWeightCost: Weight = 1;
-	pub KsmPerSecond: (AssetId, u128) = (Concrete(MultiLocation::with_parents(1).unwrap()), 1);
+	pub KsmPerSecond: (AssetId, u128) = (Concrete(MultiLocation::with_parents::<1>()), 1);
 }
 
 pub type LocalAssetTransactor =
@@ -267,7 +267,7 @@ pub mod mock_msg_queue {
 					},
 					Ok(Ok(x)) => {
 						let outcome = T::XcmExecutor::execute_xcm(
-							MultiLocation::with_parents(1).unwrap(),
+							MultiLocation::with_parents::<1>(),
 							x,
 							limit,
 						);

From 4de501bb1b4dcf20b49bf44b81cfed0cf14ec29b Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 12:43:31 -0700
Subject: [PATCH 104/166] Rename argument name from a to m

---
 xcm/src/v0/multi_asset.rs | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/xcm/src/v0/multi_asset.rs b/xcm/src/v0/multi_asset.rs
index 071ebd5bd90a..f3bfb2b2c60f 100644
--- a/xcm/src/v0/multi_asset.rs
+++ b/xcm/src/v0/multi_asset.rs
@@ -17,7 +17,7 @@
 //! Cross-Consensus Message format data structures.
 
 use super::MultiLocation;
-use crate::v1::{MultiAsset as MultiAsset1, MultiAssetFilter, MultiAssets, WildMultiAsset};
+use crate::v1::{MultiAssetFilter, MultiAssets, WildMultiAsset};
 use alloc::{vec, vec::Vec};
 use core::{
 	convert::{TryFrom, TryInto},
@@ -294,13 +294,13 @@ impl MultiAsset {
 	}
 }
 
-impl TryFrom<MultiAsset1> for MultiAsset {
+impl TryFrom<crate::v1::MultiAsset> for MultiAsset {
 	type Error = ();
 
-	fn try_from(a: MultiAsset1) -> result::Result<MultiAsset, ()> {
+	fn try_from(m: crate::v1::MultiAsset) -> result::Result<MultiAsset, ()> {
 		use crate::v1::{AssetId::*, Fungibility::*};
 		use MultiAsset::*;
-		Ok(match (a.id, a.fun) {
+		Ok(match (m.id, m.fun) {
 			(Concrete(id), Fungible(amount)) => ConcreteFungible { id: id.try_into()?, amount },
 			(Concrete(class), NonFungible(instance)) =>
 				ConcreteNonFungible { class: class.try_into()?, instance },
@@ -313,18 +313,18 @@ impl TryFrom<MultiAsset1> for MultiAsset {
 impl TryFrom<MultiAssets> for Vec<MultiAsset> {
 	type Error = ();
 
-	fn try_from(a: MultiAssets) -> result::Result<Vec<MultiAsset>, ()> {
-		a.drain().into_iter().map(MultiAsset::try_from).collect()
+	fn try_from(m: MultiAssets) -> result::Result<Vec<MultiAsset>, ()> {
+		m.drain().into_iter().map(MultiAsset::try_from).collect()
 	}
 }
 
 impl TryFrom<WildMultiAsset> for MultiAsset {
 	type Error = ();
 
-	fn try_from(a: WildMultiAsset) -> result::Result<MultiAsset, ()> {
+	fn try_from(m: WildMultiAsset) -> result::Result<MultiAsset, ()> {
 		use crate::v1::{AssetId::*, WildFungibility::*};
 		use MultiAsset::*;
-		Ok(match a {
+		Ok(match m {
 			WildMultiAsset::All => All,
 			WildMultiAsset::AllOf { id, fun } => match (id, fun) {
 				(Concrete(id), Fungible) => AllConcreteFungible { id: id.try_into()? },
@@ -340,16 +340,16 @@ impl TryFrom<WildMultiAsset> for MultiAsset {
 impl TryFrom<WildMultiAsset> for Vec<MultiAsset> {
 	type Error = ();
 
-	fn try_from(a: WildMultiAsset) -> result::Result<Vec<MultiAsset>, ()> {
-		Ok(vec![a.try_into()?])
+	fn try_from(m: WildMultiAsset) -> result::Result<Vec<MultiAsset>, ()> {
+		Ok(vec![m.try_into()?])
 	}
 }
 
 impl TryFrom<MultiAssetFilter> for Vec<MultiAsset> {
 	type Error = ();
 
-	fn try_from(a: MultiAssetFilter) -> result::Result<Vec<MultiAsset>, ()> {
-		match a {
+	fn try_from(m: MultiAssetFilter) -> result::Result<Vec<MultiAsset>, ()> {
+		match m {
 			MultiAssetFilter::Definite(assets) => assets.try_into(),
 			MultiAssetFilter::Wild(wildcard) => wildcard.try_into(),
 		}

From 393381d5ff7ee618e674d9550326ace350fadb16 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 12:45:26 -0700
Subject: [PATCH 105/166] Rename split_last to split_last_interior

---
 xcm/src/v1/multilocation.rs | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 2cd8d6b81a81..6c8fc3b7253b 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -142,9 +142,10 @@ impl MultiLocation {
 		(multilocation, first)
 	}
 
-	/// Splits off the last junction, returning the remaining prefix (first item in tuple) and the last element
-	/// (second item in tuple) or `None` if it was empty or if `self` only contains parents.
-	pub fn split_last(self) -> (MultiLocation, Option<Junction>) {
+	/// Splits off the last interior junction, returning the remaining prefix (first item in tuple)
+	/// and the last element (second item in tuple) or `None` if it was empty or if `self` only
+	/// contains parents.
+	pub fn split_last_interior(self) -> (MultiLocation, Option<Junction>) {
 		let MultiLocation { parents, interior: junctions } = self;
 		let (prefix, last) = junctions.split_last();
 		let multilocation = MultiLocation { parents, interior: prefix };

From a064c94476650f218161711f4ac52eb637109e85 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 12:55:24 -0700
Subject: [PATCH 106/166] Allow adding multiple parents in MultiLocation

---
 xcm/src/v1/multilocation.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 6c8fc3b7253b..c38690ddb829 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -152,12 +152,12 @@ impl MultiLocation {
 		(multilocation, last)
 	}
 
-	/// Bumps the parent count up by 1. Returns `Err` in case of overflow.
-	pub fn push_parent(&mut self) -> result::Result<(), ()> {
-		if self.len() >= MAX_MULTILOCATION_LENGTH {
+	/// Bumps the parent count up by `n`. Returns `Err` in case of overflow.
+	pub fn add_parents(&mut self, n: u8) -> result::Result<(), ()> {
+		if self.len() + (n as usize) > MAX_MULTILOCATION_LENGTH {
 			return Err(())
 		}
-		self.parents = self.parents.saturating_add(1);
+		self.parents = self.parents.saturating_add(n);
 		Ok(())
 	}
 
@@ -193,13 +193,13 @@ impl MultiLocation {
 		}
 	}
 
-	/// Consumes `self` and returns a `MultiLocation` with its parent count incremented by 1, or
+	/// Consumes `self` and returns a `MultiLocation` with its parent count incremented by `n`, or
 	/// an `Err` with the original value of `self` in case of overflow.
-	pub fn pushed_with_parent(self) -> result::Result<Self, Self> {
-		if self.len() >= MAX_MULTILOCATION_LENGTH {
+	pub fn added_with_parents(self, n: u8) -> result::Result<Self, Self> {
+		if self.len() + (n as usize) > MAX_MULTILOCATION_LENGTH {
 			return Err(self)
 		}
-		Ok(MultiLocation { parents: self.parents.saturating_add(1), ..self })
+		Ok(MultiLocation { parents: self.parents.saturating_add(n), ..self })
 	}
 
 	/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with the original value of

From 0b0c22b2e1b9093da61a92a260998b7bb4272f74 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 13:02:11 -0700
Subject: [PATCH 107/166] Rename pop_parent to dec_parent

---
 xcm/src/v1/multilocation.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index c38690ddb829..5d6c779b9019 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -250,7 +250,7 @@ impl MultiLocation {
 	}
 
 	/// Decrements the parent count by 1.
-	pub fn pop_parent(&mut self) {
+	pub fn dec_parent(&mut self) {
 		self.parents = self.parents.saturating_sub(1);
 	}
 
@@ -346,7 +346,7 @@ impl MultiLocation {
 				final_parent_count += self.parents;
 				break
 			}
-			self.pop_parent();
+			self.dec_parent();
 		}
 
 		self.parents = final_parent_count;

From 8df05d0619a617dcff2b290d829f84a73f88bc2c Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 13:05:40 -0700
Subject: [PATCH 108/166] Ensure relay chain XCM sender receives a
 MultiLocation without any parents

---
 runtime/common/src/xcm_sender.rs | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs
index f1d5aede1d73..aa190296904f 100644
--- a/runtime/common/src/xcm_sender.rs
+++ b/runtime/common/src/xcm_sender.rs
@@ -28,8 +28,12 @@ impl<T: configuration::Config + dmp::Config, W: xcm::WrapVersion> SendXcm
 	for ChildParachainRouter<T, W>
 {
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {
+		if dest.parent_count() > 0 {
+			return Err(Error::CannotReachDestination(dest, msg))
+		}
+
 		match dest.interior() {
-			Junctions::X1(Junction::Parachain(id)) if dest.parent_count() == 0 => {
+			Junctions::X1(Junction::Parachain(id)) => {
 				// Downward message passing.
 				let versioned_xcm =
 					W::wrap_version(&dest, msg).map_err(|()| Error::DestinationUnsupported)?;

From f8bbf77c44a5750a79db0b0c5054d7abc8d93b70 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 13:10:43 -0700
Subject: [PATCH 109/166] Block only when MultiLocation destination length is 8

---
 xcm/pallet-xcm/src/mock.rs                 | 2 +-
 xcm/xcm-builder/src/location_conversion.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index 845ced90b58e..db41796af2a2 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -75,7 +75,7 @@ impl SendXcm for TestSendXcm {
 pub struct TestSendXcmErrX8;
 impl SendXcm for TestSendXcmErrX8 {
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> XcmResult {
-		if dest.len() >= 8 {
+		if dest.len() == 8 {
 			Err(XcmError::Undefined)
 		} else {
 			SENT_XCM.with(|q| q.borrow_mut().push((dest, msg)));
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 05f07da0cfd2..7cf1063d29fa 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -51,7 +51,7 @@ impl<AccountId: Default + Eq + Clone> Convert<MultiLocation, AccountId>
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if who.borrow() == &AccountId::default() {
-			Ok(MultiLocation::with_parents(1).expect("well-formed MultiLocation; qed"))
+			Ok(MultiLocation::with_parents::<1>())
 		} else {
 			Err(())
 		}

From 9b12f9b565d091eb04ddbefc88b85fe3003587a8 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Fri, 6 Aug 2021 13:20:29 -0700
Subject: [PATCH 110/166] Cargo fmt

---
 xcm/pallet-xcm/src/tests.rs | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index b0785493f059..6cb0e8fe5f92 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -151,10 +151,7 @@ fn reserve_transfer_assets_works() {
 				Xcm::ReserveAssetDeposited {
 					assets: (MultiLocation::with_parents::<1>(), SEND_AMOUNT).into(),
 					effects: vec![
-						buy_execution(
-							(MultiLocation::with_parents::<1>(), SEND_AMOUNT),
-							weight
-						),
+						buy_execution((MultiLocation::with_parents::<1>(), SEND_AMOUNT), weight),
 						DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
 					]
 				}

From 5edf59c2e791fe337d9d98725532b356ba6e2620 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 04:42:43 -0700
Subject: [PATCH 111/166] Remove reverse iterators, implement
 DoubleEndedIterator and add tests

---
 xcm/src/v1/multilocation.rs | 91 +++++++++++++++++++++++++++++--------
 1 file changed, 71 insertions(+), 20 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 5d6c779b9019..f1845ba3bcef 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -350,7 +350,7 @@ impl MultiLocation {
 		}
 
 		self.parents = final_parent_count;
-		for j in prefix.interior.into_iter_rev() {
+		for j in prefix.interior.into_iter().rev() {
 			self.push_front_interior(j).expect(
 				"self junctions len + prefix parent count + prepend len is less than max length; qed"
 			);
@@ -515,30 +515,42 @@ impl Iterator for JunctionsIterator {
 	}
 }
 
-pub struct JunctionsReverseIterator(Junctions);
-impl Iterator for JunctionsReverseIterator {
-	type Item = Junction;
-	fn next(&mut self) -> Option<Junction> {
+impl DoubleEndedIterator for JunctionsIterator {
+	fn next_back(&mut self) -> Option<Junction> {
 		self.0.take_last()
 	}
 }
 
-pub struct JunctionsRefIterator<'a>(&'a Junctions, usize);
+pub struct JunctionsRefIterator<'a> {
+	junctions: &'a Junctions,
+	next: usize,
+	back: usize,
+}
+
 impl<'a> Iterator for JunctionsRefIterator<'a> {
 	type Item = &'a Junction;
 	fn next(&mut self) -> Option<&'a Junction> {
-		let result = self.0.at(self.1);
-		self.1 += 1;
+		if self.next.saturating_add(self.back) >= self.junctions.len() {
+			return None
+		}
+
+		let result = self.junctions.at(self.next);
+		self.next += 1;
 		result
 	}
 }
 
-pub struct JunctionsReverseRefIterator<'a>(&'a Junctions, usize);
-impl<'a> Iterator for JunctionsReverseRefIterator<'a> {
-	type Item = &'a Junction;
-	fn next(&mut self) -> Option<&'a Junction> {
-		self.1 += 1;
-		self.0.at(self.0.len().checked_sub(self.1)?)
+impl<'a> DoubleEndedIterator for JunctionsRefIterator<'a> {
+	fn next_back(&mut self) -> Option<&'a Junction> {
+		let next_back = self.back.saturating_add(1);
+		// checked_sub here, because if the result is less than 0, we end iteration
+		let index = self.junctions.len().checked_sub(next_back)?;
+		if self.next > index {
+			return None
+		}
+		self.back = next_back;
+
+		self.junctions.at(index)
 	}
 }
 
@@ -546,7 +558,11 @@ impl<'a> IntoIterator for &'a Junctions {
 	type Item = &'a Junction;
 	type IntoIter = JunctionsRefIterator<'a>;
 	fn into_iter(self) -> Self::IntoIter {
-		JunctionsRefIterator(self, 0)
+		JunctionsRefIterator {
+			junctions: self,
+			next: 0,
+			back: 0,
+		}
 	}
 }
 
@@ -775,17 +791,21 @@ impl Junctions {
 
 	/// Returns a reference iterator over the junctions.
 	pub fn iter(&self) -> JunctionsRefIterator {
-		JunctionsRefIterator(&self, 0)
+		JunctionsRefIterator {
+			junctions: self,
+			next: 0,
+			back: 0,
+		}
 	}
 
 	/// Returns a reference iterator over the junctions in reverse.
-	pub fn iter_rev(&self) -> JunctionsReverseRefIterator {
-		JunctionsReverseRefIterator(&self, 0)
+	pub fn iter_rev(&self) -> impl Iterator {
+		self.iter().rev()
 	}
 
 	/// Consumes `self` and returns an iterator over the junctions in reverse.
-	pub fn into_iter_rev(self) -> JunctionsReverseIterator {
-		JunctionsReverseIterator(self)
+	pub fn into_iter_rev(self) -> impl Iterator {
+		self.into_iter().rev()
 	}
 
 	/// Ensures that self begins with `prefix` and that it has a single `Junction` item following.
@@ -1155,4 +1175,35 @@ mod tests {
 		assert_eq!(m.prepend_with(prefix), Ok(()));
 		assert_eq!(m, MultiLocation { parents: 254, interior: X1(Parachain(42)) });
 	}
+
+	#[test]
+	fn double_ended_ref_iteration_works() {
+		let m = X3(Parachain(1000), Parachain(3), PalletInstance(5));
+		let mut iter = m.iter();
+
+		let first = iter.next().unwrap();
+		assert_eq!(first, &Parachain(1000));
+		let third = iter.next_back().unwrap();
+		assert_eq!(third, &PalletInstance(5));
+		let second = iter.next_back().unwrap();
+		assert_eq!(iter.next(), None);
+		assert_eq!(iter.next_back(), None);
+		assert_eq!(second, &Parachain(3));
+
+		let res = Null
+			.pushed_with(first.clone())
+			.unwrap()
+			.pushed_with(second.clone())
+			.unwrap()
+			.pushed_with(third.clone())
+			.unwrap();
+		assert_eq!(m, res);
+
+		// make sure there's no funny business with the 0 indexing
+		let m = Null;
+		let mut iter = m.iter();
+
+		assert_eq!(iter.next(), None);
+		assert_eq!(iter.next_back(), None);
+	}
 }

From e9128b928435162573b0e3ad0af8b7208eb80c0b Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 04:50:11 -0700
Subject: [PATCH 112/166] Fix iter_rev lifetime requirements

---
 xcm/src/v1/multilocation.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index f1845ba3bcef..685619fd21b6 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -799,7 +799,7 @@ impl Junctions {
 	}
 
 	/// Returns a reference iterator over the junctions in reverse.
-	pub fn iter_rev(&self) -> impl Iterator {
+	pub fn iter_rev(&self) -> impl Iterator + '_ {
 		self.iter().rev()
 	}
 

From 56cca551e2c00c3e38077aed30b44c6d92a3b5a1 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 05:03:32 -0700
Subject: [PATCH 113/166] Cargo fmt

---
 xcm/src/v1/multilocation.rs | 12 ++----------
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 685619fd21b6..7a42fef321be 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -558,11 +558,7 @@ impl<'a> IntoIterator for &'a Junctions {
 	type Item = &'a Junction;
 	type IntoIter = JunctionsRefIterator<'a>;
 	fn into_iter(self) -> Self::IntoIter {
-		JunctionsRefIterator {
-			junctions: self,
-			next: 0,
-			back: 0,
-		}
+		JunctionsRefIterator { junctions: self, next: 0, back: 0 }
 	}
 }
 
@@ -791,11 +787,7 @@ impl Junctions {
 
 	/// Returns a reference iterator over the junctions.
 	pub fn iter(&self) -> JunctionsRefIterator {
-		JunctionsRefIterator {
-			junctions: self,
-			next: 0,
-			back: 0,
-		}
+		JunctionsRefIterator { junctions: self, next: 0, back: 0 }
 	}
 
 	/// Returns a reference iterator over the junctions in reverse.

From 37262194fe081f716fe7a1fb9401f81659352dc7 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 05:15:00 -0700
Subject: [PATCH 114/166] Add an into() method for Junctions for conciseness in
 const context

---
 runtime/kusama/src/lib.rs   |  2 +-
 runtime/rococo/src/lib.rs   | 16 ++++++++--------
 runtime/westend/src/lib.rs  |  2 +-
 xcm/src/v1/multilocation.rs | 14 ++++++++++++++
 4 files changed, 24 insertions(+), 10 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index d56c07cc6348..d6365e355f30 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1263,7 +1263,7 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const Kusama: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(KsmLocation::get()) });
-	pub const KusamaForStatemint: (MultiAssetFilter, MultiLocation) = (Kusama::get(), MultiLocation::with_parachain_interior(1000));
+	pub const KusamaForStatemint: (MultiAssetFilter, MultiLocation) = (Kusama::get(), X1(Parachain(1000)).into());
 }
 pub type TrustedTeleporters = (xcm_builder::Case<KusamaForStatemint>,);
 
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 981bd3e28a56..bee3180a9187 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -625,10 +625,10 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const Rococo: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(RocLocation::get()) });
-	pub const RococoForTick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), MultiLocation::with_parachain_interior(100));
-	pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), MultiLocation::with_parachain_interior(110));
-	pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), MultiLocation::with_parachain_interior(120));
-	pub const RococoForStatemint: (MultiAssetFilter, MultiLocation) = (Rococo::get(), MultiLocation::with_parachain_interior(1001));
+	pub const RococoForTick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(100)).into());
+	pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(110)).into());
+	pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(120)).into());
+	pub const RococoForStatemint: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(1001)).into());
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<RococoForTick>,
@@ -640,10 +640,10 @@ pub type TrustedTeleporters = (
 parameter_types! {
 	pub AllowUnpaidFrom: Vec<MultiLocation> =
 		vec![
-			MultiLocation::with_parachain_interior(100),
-			MultiLocation::with_parachain_interior(110),
-			MultiLocation::with_parachain_interior(120),
-			MultiLocation::with_parachain_interior(1001),
+			X1(Parachain(100)).into(),
+			X1(Parachain(110)).into(),
+			X1(Parachain(120)).into(),
+			X1(Parachain(1001)).into(),
 		];
 }
 
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index b08de96b23c1..4ac81ad02b03 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -908,7 +908,7 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const WestendForWestmint: (MultiAssetFilter, MultiLocation) =
-		(Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), MultiLocation::with_parachain_interior(1000));
+		(Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), X1(Parachain(1000)).into());
 }
 pub type TrustedTeleporters = (xcm_builder::Case<WestendForWestmint>,);
 
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 7a42fef321be..1434ec56f9a3 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -571,6 +571,20 @@ impl IntoIterator for Junctions {
 }
 
 impl Junctions {
+	/// Convert `self` into a MultiLocation containing 0 parents.
+	///
+	/// Similar to `Into::into`, except that this method can be used in a const eval context.
+	pub const fn into(self) -> MultiLocation {
+		self.into_with_parents(0)
+	}
+
+	/// Convert `self` into a MultiLocation containing `n` parents.
+	///
+	/// Similar to `Self::into`, with the added ability to specify the number of parent junctions.
+	pub const fn into_with_parents(self, n: u8) -> MultiLocation {
+		MultiLocation { parents: n, interior: self }
+	}
+
 	/// Returns first junction, or `None` if the location is empty.
 	pub fn first(&self) -> Option<&Junction> {
 		match &self {

From 955b9e4289836769aaecefb751a89f7434490e1b Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 05:21:59 -0700
Subject: [PATCH 115/166] Ensure parent count is 0 while executing who in
 RelayedFrom

---
 xcm/xcm-executor/src/lib.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xcm/xcm-executor/src/lib.rs b/xcm/xcm-executor/src/lib.rs
index 4eb8a7b95314..13987461388c 100644
--- a/xcm/xcm-executor/src/lib.rs
+++ b/xcm/xcm-executor/src/lib.rs
@@ -234,6 +234,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
 				None
 			},
 			(origin, Xcm::RelayedFrom { who, message }) => {
+				ensure!(who.parent_count() == 0, XcmError::EscalationOfPrivilege);
 				let mut origin = origin;
 				origin.append_with(who).map_err(|_| XcmError::MultiLocationFull)?;
 				let surplus =

From da521d673189d3bd418c33e9e5f41bf066bbaa22 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 05:24:43 -0700
Subject: [PATCH 116/166] Appease spellchecker

---
 xcm/src/v1/multilocation.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 1434ec56f9a3..87894d5f8036 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -571,14 +571,14 @@ impl IntoIterator for Junctions {
 }
 
 impl Junctions {
-	/// Convert `self` into a MultiLocation containing 0 parents.
+	/// Convert `self` into a `MultiLocation` containing 0 parents.
 	///
-	/// Similar to `Into::into`, except that this method can be used in a const eval context.
+	/// Similar to `Into::into`, except that this method can be used in a const evaluation context.
 	pub const fn into(self) -> MultiLocation {
 		self.into_with_parents(0)
 	}
 
-	/// Convert `self` into a MultiLocation containing `n` parents.
+	/// Convert `self` into a `MultiLocation` containing `n` parents.
 	///
 	/// Similar to `Self::into`, with the added ability to specify the number of parent junctions.
 	pub const fn into_with_parents(self, n: u8) -> MultiLocation {

From a3b84f0f4469f4304709ec6f729fced0ec65c9ef Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 05:34:13 -0700
Subject: [PATCH 117/166] Use and_then instead of repeated map_err

---
 xcm/src/v0/multi_location.rs | 84 ++++++++++++------------------------
 1 file changed, 28 insertions(+), 56 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 9a63910fd128..b056e557b5d9 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -711,80 +711,52 @@ impl TryFrom<MultiLocation1> for MultiLocation {
 			X1(j0) => res.pushed_with(j0.into()).map_err(|_| ()),
 			X2(j0, j1) => res
 				.pushed_with(j0.into())
-				.map_err(|_| ())?
-				.pushed_with(j1.into())
+				.and_then(|res| res.pushed_with(j1.into()))
 				.map_err(|_| ()),
 			X3(j0, j1, j2) => res
 				.pushed_with(j0.into())
-				.map_err(|_| ())?
-				.pushed_with(j1.into())
-				.map_err(|_| ())?
-				.pushed_with(j2.into())
+				.and_then(|res| res.pushed_with(j1.into()))
+				.and_then(|res| res.pushed_with(j2.into()))
 				.map_err(|_| ()),
 			X4(j0, j1, j2, j3) => res
 				.pushed_with(j0.into())
-				.map_err(|_| ())?
-				.pushed_with(j1.into())
-				.map_err(|_| ())?
-				.pushed_with(j2.into())
-				.map_err(|_| ())?
-				.pushed_with(j3.into())
+				.and_then(|res| res.pushed_with(j1.into()))
+				.and_then(|res| res.pushed_with(j2.into()))
+				.and_then(|res| res.pushed_with(j3.into()))
 				.map_err(|_| ()),
 			X5(j0, j1, j2, j3, j4) => res
 				.pushed_with(j0.into())
-				.map_err(|_| ())?
-				.pushed_with(j1.into())
-				.map_err(|_| ())?
-				.pushed_with(j2.into())
-				.map_err(|_| ())?
-				.pushed_with(j3.into())
-				.map_err(|_| ())?
-				.pushed_with(j4.into())
+				.and_then(|res| res.pushed_with(j1.into()))
+				.and_then(|res| res.pushed_with(j2.into()))
+				.and_then(|res| res.pushed_with(j3.into()))
+				.and_then(|res| res.pushed_with(j4.into()))
 				.map_err(|_| ()),
 			X6(j0, j1, j2, j3, j4, j5) => res
 				.pushed_with(j0.into())
-				.map_err(|_| ())?
-				.pushed_with(j1.into())
-				.map_err(|_| ())?
-				.pushed_with(j2.into())
-				.map_err(|_| ())?
-				.pushed_with(j3.into())
-				.map_err(|_| ())?
-				.pushed_with(j4.into())
-				.map_err(|_| ())?
-				.pushed_with(j5.into())
+				.and_then(|res| res.pushed_with(j1.into()))
+				.and_then(|res| res.pushed_with(j2.into()))
+				.and_then(|res| res.pushed_with(j3.into()))
+				.and_then(|res| res.pushed_with(j4.into()))
+				.and_then(|res| res.pushed_with(j5.into()))
 				.map_err(|_| ()),
 			X7(j0, j1, j2, j3, j4, j5, j6) => res
 				.pushed_with(j0.into())
-				.map_err(|_| ())?
-				.pushed_with(j1.into())
-				.map_err(|_| ())?
-				.pushed_with(j2.into())
-				.map_err(|_| ())?
-				.pushed_with(j3.into())
-				.map_err(|_| ())?
-				.pushed_with(j4.into())
-				.map_err(|_| ())?
-				.pushed_with(j5.into())
-				.map_err(|_| ())?
-				.pushed_with(j6.into())
+				.and_then(|res| res.pushed_with(j1.into()))
+				.and_then(|res| res.pushed_with(j2.into()))
+				.and_then(|res| res.pushed_with(j3.into()))
+				.and_then(|res| res.pushed_with(j4.into()))
+				.and_then(|res| res.pushed_with(j5.into()))
+				.and_then(|res| res.pushed_with(j6.into()))
 				.map_err(|_| ()),
 			X8(j0, j1, j2, j3, j4, j5, j6, j7) => res
 				.pushed_with(j0.into())
-				.map_err(|_| ())?
-				.pushed_with(j1.into())
-				.map_err(|_| ())?
-				.pushed_with(j2.into())
-				.map_err(|_| ())?
-				.pushed_with(j3.into())
-				.map_err(|_| ())?
-				.pushed_with(j4.into())
-				.map_err(|_| ())?
-				.pushed_with(j5.into())
-				.map_err(|_| ())?
-				.pushed_with(j6.into())
-				.map_err(|_| ())?
-				.pushed_with(j7.into())
+				.and_then(|res| res.pushed_with(j1.into()))
+				.and_then(|res| res.pushed_with(j2.into()))
+				.and_then(|res| res.pushed_with(j3.into()))
+				.and_then(|res| res.pushed_with(j4.into()))
+				.and_then(|res| res.pushed_with(j5.into()))
+				.and_then(|res| res.pushed_with(j6.into()))
+				.and_then(|res| res.pushed_with(j7.into()))
 				.map_err(|_| ()),
 		}
 	}

From e0dcb8489c291dc521c3511eafeb0bdbb32543a3 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 05:35:40 -0700
Subject: [PATCH 118/166] Remove custom codec indices for v1 Junctions

---
 xcm/src/v1/junction.rs | 14 --------------
 1 file changed, 14 deletions(-)

diff --git a/xcm/src/v1/junction.rs b/xcm/src/v1/junction.rs
index 828e2a6ed4c1..34ad0f22a64a 100644
--- a/xcm/src/v1/junction.rs
+++ b/xcm/src/v1/junction.rs
@@ -118,29 +118,21 @@ impl BodyPart {
 /// A single item in a path to describe the relative location of a consensus system.
 ///
 /// Each item assumes a pre-existing location as its context and is defined in terms of it.
-///
-/// NOTE: The codec index starts at 1, because a previous iteration of `Junction` has a `Parent`
-///       variant occupying index 0. We deprecate `Junction::Parent` now by having a custom
-///       Encode/Decode implementation for `MultiLocation`. Refer to [`MultiLocation`] for more
-///       details.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
 pub enum Junction {
 	/// An indexed parachain belonging to and operated by the context.
 	///
 	/// Generally used when the context is a Polkadot Relay-chain.
-	#[codec(index = 1)]
 	Parachain(#[codec(compact)] u32),
 	/// A 32-byte identifier for an account of a specific network that is respected as a sovereign endpoint within
 	/// the context.
 	///
 	/// Generally used when the context is a Substrate-based chain.
-	#[codec(index = 2)]
 	AccountId32 { network: NetworkId, id: [u8; 32] },
 	/// An 8-byte index for an account of a specific network that is respected as a sovereign endpoint within
 	/// the context.
 	///
 	/// May be used when the context is a Frame-based chain and includes e.g. an indices pallet.
-	#[codec(index = 3)]
 	AccountIndex64 {
 		network: NetworkId,
 		#[codec(compact)]
@@ -150,19 +142,16 @@ pub enum Junction {
 	/// the context.
 	///
 	/// May be used when the context is an Ethereum or Bitcoin chain or smart-contract.
-	#[codec(index = 4)]
 	AccountKey20 { network: NetworkId, key: [u8; 20] },
 	/// An instanced, indexed pallet that forms a constituent part of the context.
 	///
 	/// Generally used when the context is a Frame-based chain.
-	#[codec(index = 5)]
 	PalletInstance(u8),
 	/// A non-descript index within the context location.
 	///
 	/// Usage will vary widely owing to its generality.
 	///
 	/// NOTE: Try to avoid using this and instead use a more specific item.
-	#[codec(index = 6)]
 	GeneralIndex {
 		#[codec(compact)]
 		id: u128,
@@ -172,18 +161,15 @@ pub enum Junction {
 	/// Usage will vary widely owing to its generality.
 	///
 	/// NOTE: Try to avoid using this and instead use a more specific item.
-	#[codec(index = 7)]
 	GeneralKey(Vec<u8>),
 	/// The unambiguous child.
 	///
 	/// Not currently used except as a fallback when deriving ancestry.
-	#[codec(index = 8)]
 	OnlyChild,
 	/// A pluralistic body existing within consensus.
 	///
 	/// Typical to be used to represent a governance origin of a chain, but could in principle be used to represent
 	/// things such as multisigs also.
-	#[codec(index = 9)]
 	Plurality { id: BodyId, part: BodyPart },
 }
 

From a3459883db99fa975148fbc1208c46875af72bd6 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 05:43:24 -0700
Subject: [PATCH 119/166] Add convenience 'contains_parents_only' method to
 MultiLocation

---
 xcm/src/v1/multilocation.rs              | 6 ++++++
 xcm/xcm-builder/src/origin_conversion.rs | 5 +----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 87894d5f8036..04bbe4c5b652 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -117,6 +117,12 @@ impl MultiLocation {
 		self.parents
 	}
 
+	/// Returns boolean indicating whether or not `self` contains only the specified amount of
+	/// parents and no interior junctions.
+	pub const fn contains_parents_only(&self, count: u8) -> bool {
+		matches!(self.interior, Junctions::Null) && self.parents == count
+	}
+
 	/// Returns the number of parents and junctions in `self`.
 	pub const fn len(&self) -> usize {
 		self.parent_count() as usize + self.interior.len()
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index 9db44e87d78a..7d724f0e54b8 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -45,10 +45,7 @@ where
 pub struct ParentAsSuperuser<Origin>(PhantomData<Origin>);
 impl<Origin: OriginTrait> ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		if kind == OriginKind::Superuser &&
-			origin.parent_count() == 1 &&
-			origin.interior().len() == 0
-		{
+		if kind == OriginKind::Superuser && origin.contains_parents_only(1) {
 			Ok(Origin::root())
 		} else {
 			Err(origin)

From bdbbd8f6862efee916c465c72f56901804d0ff1f Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 06:02:15 -0700
Subject: [PATCH 120/166] Fix merge conflict

---
 xcm/xcm-simulator/example/src/lib.rs | 10 ++--------
 1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 8d87512cc636..d1c0dabf1b35 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -190,15 +190,9 @@ mod tests {
 		Relay::execute_with(|| {
 			assert_ok!(RelayChainPalletXcm::reserve_transfer_assets(
 				relay_chain::Origin::signed(ALICE),
-<<<<<<< HEAD
-				X1(Parachain(1)).into(),
-				X1(AccountId32 { network: Any, id: ALICE.into() }).into(),
+				Box::new(X1(Parachain(1)).into()),
+				Box::new(X1(AccountId32 { network: Any, id: ALICE.into() }).into()),
 				(MultiLocation::here(), 123).into(),
-=======
-				Box::new(X1(Parachain(1))),
-				Box::new(X1(AccountId32 { network: Any, id: ALICE.into() })),
-				(Here, 123).into(),
->>>>>>> origin/master
 				0,
 				3,
 			));

From a1489cb54015b3193a559098e91d3f644b648cb5 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 06:03:29 -0700
Subject: [PATCH 121/166] Use more convenience methods

---
 xcm/xcm-builder/src/location_conversion.rs | 6 +++---
 xcm/xcm-builder/src/origin_conversion.rs   | 3 +--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 7cf1063d29fa..65c46264102c 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -42,7 +42,7 @@ impl<AccountId: Default + Eq + Clone> Convert<MultiLocation, AccountId>
 	for ParentIsDefault<AccountId>
 {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-		if location.borrow().parent_count() == 1 && location.borrow().interior().len() == 0 {
+		if location.borrow().contains_parents_only(1) {
 			Ok(AccountId::default())
 		} else {
 			Err(())
@@ -248,7 +248,7 @@ mod tests {
 			pub Ancestry: MultiLocation = X2(account20(), account20()).into();
 		}
 
-		let input = MultiLocation::new(2, Null).unwrap();
+		let input = MultiLocation::with_parents::<2>();
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
 		assert_eq!(inverted, X2(account20(), account20()).into());
 	}
@@ -263,7 +263,7 @@ mod tests {
 			pub Ancestry: MultiLocation = X1(PalletInstance(5)).into();
 		}
 
-		let input = MultiLocation::new(2, Null).unwrap();
+		let input = MultiLocation::with_parents::<2>();
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
 		assert_eq!(inverted, X2(PalletInstance(5), OnlyChild).into());
 	}
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index 7d724f0e54b8..a31d0f0ad115 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -116,8 +116,7 @@ impl<RelayOrigin: Get<Origin>, Origin> ConvertOrigin<Origin>
 	for RelayChainAsNative<RelayOrigin, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		if kind == OriginKind::Native && origin.parent_count() == 1 && origin.interior().len() == 0
-		{
+		if kind == OriginKind::Native && origin.contains_parents_only(1) {
 			Ok(RelayOrigin::get())
 		} else {
 			Err(origin)

From e6e4509f8ba2ed475c9f3d00be81aa9203ed05c0 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 06:11:03 -0700
Subject: [PATCH 122/166] Remove with_parachain_interior

---
 xcm/pallet-xcm/src/lib.rs    | 2 +-
 xcm/src/v1/multilocation.rs  | 9 ---------
 xcm/xcm-builder/src/tests.rs | 4 ++--
 3 files changed, 3 insertions(+), 12 deletions(-)

diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 9ccce1cde797..1d7c4650833a 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -102,7 +102,7 @@ pub mod pallet {
 		UnweighableMessage,
 		/// The assets to be sent are empty.
 		Empty,
-		/// Could not reanchor the assets to declare the fees for the destination chain.
+		/// Could not re-anchor the assets to declare the fees for the destination chain.
 		CannotReanchor,
 		/// Too many assets have been attempted for transfer.
 		TooManyAssets,
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 04bbe4c5b652..c870f017e5a8 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -88,15 +88,6 @@ impl MultiLocation {
 		MultiLocation { parents: P, interior: Junctions::Null }
 	}
 
-	/// Creates a new `MultiLocation` with no parents and a single `Parachain` interior junction
-	/// specified by `para_id`.
-	///
-	/// The resulting `MultiLocation` can be interpreted as the child-parachain of the current
-	/// consensus system.
-	pub const fn with_parachain_interior(para_id: u32) -> MultiLocation {
-		MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(para_id)) }
-	}
-
 	/// Whether or not the `MultiLocation` has no parents and has a `Null` interior.
 	pub const fn is_here(&self) -> bool {
 		self.parents == 0 && self.interior.len() == 0
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 0d6ddb4d5331..8bbdcf386023 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -29,8 +29,8 @@ fn basic_setup_works() {
 		&MultiLocation::with_parents::<1>(),
 	));
 
-	assert_eq!(to_account(MultiLocation::with_parachain_interior(1)), Ok(1001));
-	assert_eq!(to_account(MultiLocation::with_parachain_interior(50)), Ok(1050));
+	assert_eq!(to_account(X1(Parachain(1)).into()), Ok(1001));
+	assert_eq!(to_account(X1(Parachain(50)).into()), Ok(1050));
 	assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(1))).unwrap()), Ok(2001));
 	assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(50))).unwrap()), Ok(2050));
 	assert_eq!(

From 139b8b158c1149a9e7f9bc3a9a97e11460adf433 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 06:14:26 -0700
Subject: [PATCH 123/166] Prefer matching against tuple instead of using match
 guards

---
 xcm/xcm-builder/src/location_conversion.rs | 20 ++++++++------------
 1 file changed, 8 insertions(+), 12 deletions(-)

diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 65c46264102c..bab5ee615e41 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -109,12 +109,10 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone
 	Convert<MultiLocation, AccountId> for AccountId32Aliases<Network, AccountId>
 {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
-		let id = match location.interior() {
-			Junctions::X1(Junction::AccountId32 { id, network: NetworkId::Any })
-				if location.parent_count() == 0 =>
-				*id,
-			Junctions::X1(Junction::AccountId32 { id, network })
-				if network == &Network::get() && location.parent_count() == 0 =>
+		let id = match (location.parent_count(), location.interior()) {
+			(0, Junctions::X1(Junction::AccountId32 { id, network: NetworkId::Any })) => *id,
+			(0, Junctions::X1(Junction::AccountId32 { id, network }))
+				if network == &Network::get() =>
 				*id,
 			_ => return Err(location),
 		};
@@ -131,12 +129,10 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
 	Convert<MultiLocation, AccountId> for AccountKey20Aliases<Network, AccountId>
 {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
-		let key = match location.interior() {
-			Junctions::X1(Junction::AccountKey20 { key, network: NetworkId::Any })
-				if location.parent_count() == 0 =>
-				*key,
-			Junctions::X1(Junction::AccountKey20 { key, network })
-				if network == &Network::get() && location.parent_count() == 0 =>
+		let key = match (location.parent_count(), location.interior()) {
+			(0, Junctions::X1(Junction::AccountKey20 { key, network: NetworkId::Any })) => *key,
+			(0, Junctions::X1(Junction::AccountKey20 { key, network }))
+				if network == &Network::get() =>
 				*key,
 			_ => return Err(location),
 		};

From 2b8a97d72dbf45426d587953149aca7ae027b255 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 06:20:49 -0700
Subject: [PATCH 124/166] Match against tuple instead of using more match
 guards

---
 xcm/xcm-builder/src/origin_conversion.rs | 35 +++++++++++-------------
 1 file changed, 16 insertions(+), 19 deletions(-)

diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index a31d0f0ad115..dc01e9efde1c 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -58,9 +58,9 @@ impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
 	for ChildSystemParachainAsSuperuser<ParaId, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.interior()) {
-			(OriginKind::Superuser, Junctions::X1(Junction::Parachain(id)))
-				if ParaId::from(*id).is_system() && origin.parent_count() == 0 =>
+		match (kind, origin.parent_count(), origin.interior()) {
+			(OriginKind::Superuser, 0, Junctions::X1(Junction::Parachain(id)))
+				if ParaId::from(*id).is_system() =>
 				Ok(Origin::root()),
 			_ => Err(origin),
 		}
@@ -72,9 +72,9 @@ impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
 	for SiblingSystemParachainAsSuperuser<ParaId, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.interior()) {
-			(OriginKind::Superuser, Junctions::X1(Junction::Parachain(id)))
-				if ParaId::from(*id).is_system() && origin.parent_count() == 1 =>
+		match (kind, origin.parent_count(), origin.interior()) {
+			(OriginKind::Superuser, 1, Junctions::X1(Junction::Parachain(id)))
+				if ParaId::from(*id).is_system() =>
 				Ok(Origin::root()),
 			_ => Err(origin),
 		}
@@ -86,8 +86,8 @@ impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Or
 	for ChildParachainAsNative<ParachainOrigin, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.interior()) {
-			(OriginKind::Native, Junctions::X1(Junction::Parachain(id))) =>
+		match (kind, origin.parent_count(), origin.interior()) {
+			(OriginKind::Native, 0, Junctions::X1(Junction::Parachain(id))) =>
 				Ok(Origin::from(ParachainOrigin::from(*id))),
 			_ => Err(origin),
 		}
@@ -101,9 +101,8 @@ impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Or
 	for SiblingParachainAsNative<ParachainOrigin, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.interior()) {
-			(OriginKind::Native, Junctions::X1(Junction::Parachain(id)))
-				if origin.parent_count() == 1 =>
+		match (kind, origin.parent_count(), origin.interior()) {
+			(OriginKind::Native, 1, Junctions::X1(Junction::Parachain(id))) =>
 				Ok(Origin::from(ParachainOrigin::from(*id))),
 			_ => Err(origin),
 		}
@@ -131,10 +130,9 @@ where
 	Origin::AccountId: From<[u8; 32]>,
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.interior()) {
-			(OriginKind::Native, Junctions::X1(Junction::AccountId32 { id, network }))
-				if (matches!(network, NetworkId::Any) || network == &Network::get()) &&
-					origin.parent_count() == 0 =>
+		match (kind, origin.parent_count(), origin.interior()) {
+			(OriginKind::Native, 0, Junctions::X1(Junction::AccountId32 { id, network }))
+				if matches!(network, NetworkId::Any) || network == &Network::get() =>
 				Ok(Origin::signed((*id).into())),
 			_ => Err(origin),
 		}
@@ -148,10 +146,9 @@ where
 	Origin::AccountId: From<[u8; 20]>,
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.interior()) {
-			(OriginKind::Native, Junctions::X1(Junction::AccountKey20 { key, network }))
-				if (matches!(network, NetworkId::Any) || network == &Network::get()) &&
-					origin.parent_count() == 0 =>
+		match (kind, origin.parent_count(), origin.interior()) {
+			(OriginKind::Native, 0, Junctions::X1(Junction::AccountKey20 { key, network }))
+				if (matches!(network, NetworkId::Any) || network == &Network::get()) =>
 				Ok(Origin::signed((*key).into())),
 			_ => Err(origin),
 		}

From db5c466fc70f5e6120af9faac85df9c893b4999c Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sat, 7 Aug 2021 07:26:21 -0700
Subject: [PATCH 125/166] Update encode/decode test for MultiLocation

---
 xcm/src/v1/multilocation.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index c870f017e5a8..1ac29cc56c2d 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -1115,7 +1115,7 @@ mod tests {
 			interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }),
 		};
 		let encoded = m.encode();
-		assert_eq!(encoded, [1, 2, 1, 168, 3, 0, 92].to_vec());
+		assert_eq!(encoded, [1, 2, 0, 168, 2, 0, 92].to_vec());
 		let decoded = MultiLocation::decode(&mut &encoded[..]);
 		assert_eq!(decoded, Ok(m));
 	}

From c3f372db40bb29bd0502115615a1723f1b7802b9 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sat, 7 Aug 2021 21:47:03 +0200
Subject: [PATCH 126/166] Minor tweaks

---
 runtime/kusama/src/lib.rs                     |  6 ++--
 runtime/rococo/src/lib.rs                     | 20 ++++++-------
 runtime/westend/src/lib.rs                    |  6 ++--
 xcm/pallet-xcm/src/lib.rs                     |  2 +-
 xcm/pallet-xcm/src/mock.rs                    |  4 +--
 xcm/pallet-xcm/src/tests.rs                   | 12 ++++----
 xcm/src/v1/junction.rs                        | 24 +++++++++++----
 xcm/src/v1/multilocation.rs                   |  8 ++---
 xcm/xcm-builder/src/mock.rs                   |  2 +-
 xcm/xcm-builder/src/origin_conversion.rs      |  2 +-
 xcm/xcm-builder/src/tests.rs                  | 30 +++++++++----------
 xcm/xcm-executor/src/assets.rs                | 18 +++++------
 xcm/xcm-executor/src/traits/transact_asset.rs | 16 +++++-----
 xcm/xcm-simulator/example/src/lib.rs          |  8 ++---
 xcm/xcm-simulator/example/src/relay_chain.rs  |  4 +--
 15 files changed, 88 insertions(+), 74 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index d6365e355f30..23b4d5543145 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1201,12 +1201,12 @@ parameter_types! {
 	/// The location of the KSM token, from the context of this chain. Since this token is native to this
 	/// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to
 	/// the context".
-	pub const KsmLocation: MultiLocation = MultiLocation::here();
+	pub const KsmLocation: MultiLocation = Here.into();
 	/// The Kusama network ID. This is named.
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	/// Our XCM location ancestry - i.e. what, if anything, `Parent` means evaluated in our context. Since
 	/// Kusama is a top-level relay-chain, there is no ancestry.
-	pub const Ancestry: MultiLocation = MultiLocation::here();
+	pub const Ancestry: MultiLocation = Here.into();
 	/// The check account, which holds any native assets that have been teleported out and not back in (yet).
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
@@ -1263,7 +1263,7 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const Kusama: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(KsmLocation::get()) });
-	pub const KusamaForStatemint: (MultiAssetFilter, MultiLocation) = (Kusama::get(), X1(Parachain(1000)).into());
+	pub const KusamaForStatemint: (MultiAssetFilter, MultiLocation) = (Kusama::get(), Parachain(1000).into());
 }
 pub type TrustedTeleporters = (xcm_builder::Case<KusamaForStatemint>,);
 
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index bee3180a9187..2c8eecbaac17 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -583,9 +583,9 @@ impl parachains_paras::Config for Runtime {
 }
 
 parameter_types! {
-	pub const RocLocation: MultiLocation = MultiLocation::here();
+	pub const RocLocation: MultiLocation = Here.into();
 	pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
-	pub const Ancestry: MultiLocation = MultiLocation::here();
+	pub const Ancestry: MultiLocation = Here.into();
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
 
@@ -625,10 +625,10 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const Rococo: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: Concrete(RocLocation::get()) });
-	pub const RococoForTick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(100)).into());
-	pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(110)).into());
-	pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(120)).into());
-	pub const RococoForStatemint: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(1001)).into());
+	pub const RococoForTick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), Parachain(100).into());
+	pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), Parachain(110).into());
+	pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), Parachain(120).into());
+	pub const RococoForStatemint: (MultiAssetFilter, MultiLocation) = (Rococo::get(), Parachain(1001).into());
 }
 pub type TrustedTeleporters = (
 	xcm_builder::Case<RococoForTick>,
@@ -640,10 +640,10 @@ pub type TrustedTeleporters = (
 parameter_types! {
 	pub AllowUnpaidFrom: Vec<MultiLocation> =
 		vec![
-			X1(Parachain(100)).into(),
-			X1(Parachain(110)).into(),
-			X1(Parachain(120)).into(),
-			X1(Parachain(1001)).into(),
+			Parachain(100).into(),
+			Parachain(110).into(),
+			Parachain(120).into(),
+			Parachain(1001).into(),
 		];
 }
 
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index 4ac81ad02b03..52c601beeffc 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -866,8 +866,8 @@ impl auctions::Config for Runtime {
 }
 
 parameter_types! {
-	pub const WndLocation: MultiLocation = MultiLocation::here();
-	pub const Ancestry: MultiLocation = MultiLocation::here();
+	pub const WndLocation: MultiLocation = Here.into();
+	pub const Ancestry: MultiLocation = Here.into();
 	pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
@@ -908,7 +908,7 @@ pub type XcmRouter = (
 
 parameter_types! {
 	pub const WestendForWestmint: (MultiAssetFilter, MultiLocation) =
-		(Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), X1(Parachain(1000)).into());
+		(Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), Parachain(1000).into());
 }
 pub type TrustedTeleporters = (xcm_builder::Case<WestendForWestmint>,);
 
diff --git a/xcm/pallet-xcm/src/lib.rs b/xcm/pallet-xcm/src/lib.rs
index 1d7c4650833a..824b652227f3 100644
--- a/xcm/pallet-xcm/src/lib.rs
+++ b/xcm/pallet-xcm/src/lib.rs
@@ -385,7 +385,7 @@ where
 
 	#[cfg(feature = "runtime-benchmarks")]
 	fn successful_origin() -> O {
-		O::from(Origin::Xcm(MultiLocation::here()))
+		O::from(Origin::Xcm(Here.into()))
 	}
 }
 
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index db41796af2a2..2ee2a8b3958b 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -133,9 +133,9 @@ impl pallet_balances::Config for Test {
 }
 
 parameter_types! {
-	pub const RelayLocation: MultiLocation = MultiLocation::here();
+	pub const RelayLocation: MultiLocation = Here.into();
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = MultiLocation::here();
+	pub Ancestry: MultiLocation = Here.into();
 	pub UnitWeightCost: Weight = 1_000;
 }
 
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 4ef1bf17fcdb..1ca2a2579133 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -54,7 +54,7 @@ fn send_works() {
 		assert_eq!(
 			sent_xcm(),
 			vec![(
-				MultiLocation::here(),
+				Here.into(),
 				RelayedFrom { who: sender.clone(), message: Box::new(message.clone()) }
 			)]
 		);
@@ -109,8 +109,8 @@ fn teleport_assets_works() {
 		assert_ok!(XcmPallet::teleport_assets(
 			Origin::signed(ALICE),
 			Box::new(RelayLocation::get()),
-			Box::new(X1(AccountId32 { network: Any, id: BOB.into() }).into()),
-			(MultiLocation::here(), SEND_AMOUNT).into(),
+			Box::new(AccountId32 { network: Any, id: BOB.into() }.into()),
+			(Here.into(), SEND_AMOUNT).into(),
 			0,
 			weight,
 		));
@@ -139,7 +139,7 @@ fn reserve_transfer_assets_works() {
 			Origin::signed(ALICE),
 			Box::new(Parachain(PARA_ID).into()),
 			Box::new(dest.clone()),
-			(MultiLocation::here(), SEND_AMOUNT).into(),
+			(Here.into(), SEND_AMOUNT).into(),
 			0,
 			weight
 		));
@@ -184,9 +184,9 @@ fn execute_withdraw_to_deposit_works() {
 		assert_ok!(XcmPallet::execute(
 			Origin::signed(ALICE),
 			Box::new(Xcm::WithdrawAsset {
-				assets: (MultiLocation::here(), SEND_AMOUNT).into(),
+				assets: (Here.into(), SEND_AMOUNT).into(),
 				effects: vec![
-					buy_execution((MultiLocation::here(), SEND_AMOUNT), weight),
+					buy_execution((Here.into(), SEND_AMOUNT), weight),
 					DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }
 				],
 			}),
diff --git a/xcm/src/v1/junction.rs b/xcm/src/v1/junction.rs
index 34ad0f22a64a..ff820610dab8 100644
--- a/xcm/src/v1/junction.rs
+++ b/xcm/src/v1/junction.rs
@@ -20,6 +20,7 @@ use crate::v0::{BodyId as BodyId0, Junction as Junction0};
 use alloc::vec::Vec;
 use core::convert::TryFrom;
 use parity_scale_codec::{self, Decode, Encode};
+use super::{MultiLocation, Junctions};
 
 /// A global identifier of an account-bearing consensus system.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
@@ -152,10 +153,7 @@ pub enum Junction {
 	/// Usage will vary widely owing to its generality.
 	///
 	/// NOTE: Try to avoid using this and instead use a more specific item.
-	GeneralIndex {
-		#[codec(compact)]
-		id: u128,
-	},
+	GeneralIndex(#[codec(compact)] u128),
 	/// A nondescript datum acting as a key within the context location.
 	///
 	/// Usage will vary widely owing to its generality.
@@ -185,10 +183,26 @@ impl TryFrom<Junction0> for Junction {
 				Ok(Self::AccountIndex64 { network, index }),
 			Junction0::AccountKey20 { network, key } => Ok(Self::AccountKey20 { network, key }),
 			Junction0::PalletInstance(index) => Ok(Self::PalletInstance(index)),
-			Junction0::GeneralIndex { id } => Ok(Self::GeneralIndex { id }),
+			Junction0::GeneralIndex { id } => Ok(Self::GeneralIndex(id)),
 			Junction0::GeneralKey(key) => Ok(Self::GeneralKey(key)),
 			Junction0::OnlyChild => Ok(Self::OnlyChild),
 			Junction0::Plurality { id, part } => Ok(Self::Plurality { id: id.into(), part }),
 		}
 	}
 }
+
+impl Junction {
+	/// Convert `self` into a `MultiLocation` containing 0 parents.
+	///
+	/// Similar to `Into::into`, except that this method can be used in a const evaluation context.
+	pub const fn into(self) -> MultiLocation {
+		MultiLocation { parents: 0, interior: Junctions::X1(self) }
+	}
+
+	/// Convert `self` into a `MultiLocation` containing `n` parents.
+	///
+	/// Similar to `Self::into`, with the added ability to specify the number of parent junctions.
+	pub const fn into_exterior(self, n: u8) -> MultiLocation {
+		MultiLocation { parents: n, interior: Junctions::X1(self) }
+	}
+}
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 1ac29cc56c2d..3481be4fdf99 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -485,7 +485,7 @@ impl From<[Junction; 8]> for MultiLocation {
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
 pub enum Junctions {
 	/// The interpreting consensus system.
-	Null,
+	Here,
 	/// A relative path comprising 1 junction.
 	X1(Junction),
 	/// A relative path comprising 2 junctions.
@@ -572,13 +572,13 @@ impl Junctions {
 	///
 	/// Similar to `Into::into`, except that this method can be used in a const evaluation context.
 	pub const fn into(self) -> MultiLocation {
-		self.into_with_parents(0)
+		MultiLocation { parents: 0, interior: self }
 	}
 
 	/// Convert `self` into a `MultiLocation` containing `n` parents.
 	///
 	/// Similar to `Self::into`, with the added ability to specify the number of parent junctions.
-	pub const fn into_with_parents(self, n: u8) -> MultiLocation {
+	pub const fn into_exterior(self, n: u8) -> MultiLocation {
 		MultiLocation { parents: n, interior: self }
 	}
 
@@ -852,7 +852,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 	fn try_from(old: MultiLocation0) -> result::Result<Self, ()> {
 		use Junctions::*;
 		match old {
-			MultiLocation0::Null => Ok(MultiLocation::here()),
+			MultiLocation0::Null => Ok(Here.into()),
 			MultiLocation0::X1(j0) if j0.is_parent() => Ok(MultiLocation::with_parents::<1>()),
 			MultiLocation0::X1(j0) => Ok(X1(j0.try_into()?).into()),
 			MultiLocation0::X2(j0, j1) if j0.is_parent() && j1.is_parent() =>
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 84d514731664..e290241fcf48 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -257,7 +257,7 @@ parameter_types! {
 	pub static AllowUnpaidFrom: Vec<MultiLocation> = vec![];
 	pub static AllowPaidFrom: Vec<MultiLocation> = vec![];
 	// 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight.
-	pub static WeightPrice: (AssetId, u128) = (MultiLocation::here().into(), 1_000_000_000_000);
+	pub static WeightPrice: (AssetId, u128) = (Here.into().into(), 1_000_000_000_000);
 }
 
 pub type TestBarrier = (
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index dc01e9efde1c..f4dfaf65a693 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -171,7 +171,7 @@ where
 		// We institute a root fallback so root can always represent the context. This
 		// guarantees that `successful_origin` will work.
 		if o.caller() == Origin::root().caller() {
-			Ok(MultiLocation::here())
+			Ok(Here.into())
 		} else {
 			Err(o)
 		}
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 8bbdcf386023..fffcffaeb1e3 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -41,7 +41,7 @@ fn basic_setup_works() {
 		to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 42, network: Any })).unwrap()),
 		Ok(42),
 	);
-	assert_eq!(to_account(MultiLocation::here()), Ok(3000));
+	assert_eq!(to_account(Here.into()), Ok(3000));
 }
 
 #[test]
@@ -60,7 +60,7 @@ fn weigher_should_work() {
 			Order::DepositAsset {
 				assets: All.into(),
 				max_assets: 1,
-				beneficiary: MultiLocation::here(),
+				beneficiary: Here.into(),
 			},
 		],
 	}
@@ -72,7 +72,7 @@ fn weigher_should_work() {
 fn take_weight_credit_barrier_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
 		assets: (MultiLocation::with_parents::<1>(), 100).into(),
-		beneficiary: MultiLocation::here(),
+		beneficiary: Here.into(),
 	};
 
 	let mut weight_credit = 10;
@@ -101,7 +101,7 @@ fn take_weight_credit_barrier_should_work() {
 fn allow_unpaid_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
 		assets: (MultiLocation::with_parents::<1>(), 100).into(),
-		beneficiary: MultiLocation::here(),
+		beneficiary: Here.into(),
 	};
 
 	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
@@ -131,7 +131,7 @@ fn allow_paid_should_work() {
 
 	let mut message = opaque::Xcm::TransferAsset {
 		assets: (MultiLocation::with_parents::<1>(), 100).into(),
-		beneficiary: MultiLocation::here(),
+		beneficiary: Here.into(),
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
@@ -158,7 +158,7 @@ fn allow_paid_should_work() {
 			Order::DepositAsset {
 				assets: All.into(),
 				max_assets: 1,
-				beneficiary: MultiLocation::here(),
+				beneficiary: Here.into(),
 			},
 		],
 	};
@@ -187,7 +187,7 @@ fn allow_paid_should_work() {
 			Order::DepositAsset {
 				assets: All.into(),
 				max_assets: 1,
-				beneficiary: MultiLocation::here(),
+				beneficiary: Here.into(),
 			},
 		],
 	};
@@ -236,7 +236,7 @@ fn paying_reserve_deposit_should_work() {
 			Order::<TestCall>::DepositAsset {
 				assets: All.into(),
 				max_assets: 1,
-				beneficiary: MultiLocation::here(),
+				beneficiary: Here.into(),
 			},
 		],
 	};
@@ -251,19 +251,19 @@ fn transfer_should_work() {
 	// we'll let them have message execution for free.
 	AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, (MultiLocation::here(), 1000).into());
+	add_asset(1001, (Here.into(), 1000).into());
 	// They want to transfer 100 of them to their sibling parachain #2
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
 		X1(Parachain(1)).into(),
 		Xcm::TransferAsset {
-			assets: (MultiLocation::here(), 100).into(),
+			assets: (Here.into(), 100).into(),
 			beneficiary: X1(AccountIndex64 { index: 3, network: Any }).into(),
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
-	assert_eq!(assets(3), vec![(MultiLocation::here(), 100).into()]);
-	assert_eq!(assets(1001), vec![(MultiLocation::here(), 900).into()]);
+	assert_eq!(assets(3), vec![(Here.into(), 100).into()]);
+	assert_eq!(assets(1001), vec![(Here.into(), 900).into()]);
 	assert_eq!(sent_xcm(), vec![]);
 }
 
@@ -271,7 +271,7 @@ fn transfer_should_work() {
 fn reserve_transfer_should_work() {
 	AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, (MultiLocation::here(), 1000).into());
+	add_asset(1001, (Here.into(), 1000).into());
 	// The remote account owned by gav.
 	let three: MultiLocation = X1(AccountIndex64 { index: 3, network: Any }).into();
 
@@ -280,7 +280,7 @@ fn reserve_transfer_should_work() {
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
 		X1(Parachain(1)).into(),
 		Xcm::TransferReserveAsset {
-			assets: (MultiLocation::here(), 100).into(),
+			assets: (Here.into(), 100).into(),
 			dest: X1(Parachain(2)).into(),
 			effects: vec![Order::DepositAsset {
 				assets: All.into(),
@@ -292,7 +292,7 @@ fn reserve_transfer_should_work() {
 	);
 	assert_eq!(r, Outcome::Complete(10));
 
-	assert_eq!(assets(1002), vec![(MultiLocation::here(), 100).into()]);
+	assert_eq!(assets(1002), vec![(Here.into(), 100).into()]);
 	assert_eq!(
 		sent_xcm(),
 		vec![(
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index b05664d8d45b..824f419c4f5c 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -381,12 +381,12 @@ impl Assets {
 	/// ```
 	/// use xcm_executor::Assets;
 	/// use xcm::latest::prelude::*;
-	/// let assets_i_have: Assets = vec![ (MultiLocation::here(), 100).into(), (vec![0], 100).into() ].into();
-	/// let assets_they_want: MultiAssetFilter = vec![ (MultiLocation::here(), 200).into(), (vec![0], 50).into() ].into();
+	/// let assets_i_have: Assets = vec![ (Here.into(), 100).into(), (vec![0], 100).into() ].into();
+	/// let assets_they_want: MultiAssetFilter = vec![ (Here.into(), 200).into(), (vec![0], 50).into() ].into();
 	///
 	/// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want);
 	/// assert_eq!(assets_we_can_trade.into_assets_iter().collect::<Vec<_>>(), vec![
-	/// 	(MultiLocation::here(), 100).into(), (vec![0], 50).into(),
+	/// 	(Here.into(), 100).into(), (vec![0], 50).into(),
 	/// ]);
 	/// ```
 	pub fn min(&self, mask: &MultiAssetFilter) -> Assets {
@@ -443,12 +443,12 @@ mod tests {
 	#[allow(non_snake_case)]
 	/// Concrete fungible constructor
 	fn CF(amount: u128) -> MultiAsset {
-		(MultiLocation::here(), amount).into()
+		(Here.into(), amount).into()
 	}
 	#[allow(non_snake_case)]
 	/// Concrete non-fungible constructor
 	fn CNF(instance_id: u8) -> MultiAsset {
-		(MultiLocation::here(), [instance_id; 4]).into()
+		(Here.into(), [instance_id; 4]).into()
 	}
 
 	fn test_assets() -> Assets {
@@ -562,8 +562,8 @@ mod tests {
 	#[test]
 	fn min_all_concrete_works() {
 		let assets = test_assets();
-		let fungible = Wild((MultiLocation::here(), WildFungible).into());
-		let non_fungible = Wild((MultiLocation::here(), WildNonFungible).into());
+		let fungible = Wild((Here.into(), WildFungible).into());
+		let non_fungible = Wild((Here.into(), WildNonFungible).into());
 
 		let fungible = assets.min(&fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
@@ -626,8 +626,8 @@ mod tests {
 	#[test]
 	fn saturating_take_all_concrete_works() {
 		let mut assets = test_assets();
-		let fungible = Wild((MultiLocation::here(), WildFungible).into());
-		let non_fungible = Wild((MultiLocation::here(), WildNonFungible).into());
+		let fungible = Wild((Here.into(), WildFungible).into());
+		let non_fungible = Wild((Here.into(), WildNonFungible).into());
 
 		let fungible = assets.saturating_take(fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index 608498fd2dd9..9f7adda568b5 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -273,8 +273,8 @@ mod tests {
 
 		assert_eq!(
 			MultiTransactor::deposit_asset(
-				&(MultiLocation::here(), 1).into(),
-				&MultiLocation::here()
+				&(Here.into(), 1).into(),
+				&Here.into()
 			),
 			Err(XcmError::AssetNotFound)
 		);
@@ -286,8 +286,8 @@ mod tests {
 
 		assert_eq!(
 			MultiTransactor::deposit_asset(
-				&(MultiLocation::here(), 1).into(),
-				&MultiLocation::here()
+				&(Here.into(), 1).into(),
+				&Here.into()
 			),
 			Ok(()),
 		);
@@ -299,8 +299,8 @@ mod tests {
 
 		assert_eq!(
 			MultiTransactor::deposit_asset(
-				&(MultiLocation::here(), 1).into(),
-				&MultiLocation::here()
+				&(Here.into(), 1).into(),
+				&Here.into()
 			),
 			Err(XcmError::Overflow)
 		);
@@ -312,8 +312,8 @@ mod tests {
 
 		assert_eq!(
 			MultiTransactor::deposit_asset(
-				&(MultiLocation::here(), 1).into(),
-				&MultiLocation::here()
+				&(Here.into(), 1).into(),
+				&Here.into()
 			),
 			Ok(()),
 		);
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index d1c0dabf1b35..9bd86a60829d 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -111,7 +111,7 @@ mod tests {
 		);
 		Relay::execute_with(|| {
 			assert_ok!(RelayChainPalletXcm::send_xcm(
-				MultiLocation::here(),
+				Here.into(),
 				X1(Parachain(1)).into(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
@@ -138,7 +138,7 @@ mod tests {
 		);
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
-				MultiLocation::here(),
+				Here.into(),
 				MultiLocation::with_parents::<1>(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
@@ -165,7 +165,7 @@ mod tests {
 		);
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
-				MultiLocation::here(),
+				Here.into(),
 				MultiLocation::new(1, X1(Parachain(2))).unwrap(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
@@ -192,7 +192,7 @@ mod tests {
 				relay_chain::Origin::signed(ALICE),
 				Box::new(X1(Parachain(1)).into()),
 				Box::new(X1(AccountId32 { network: Any, id: ALICE.into() }).into()),
-				(MultiLocation::here(), 123).into(),
+				(Here.into(), 123).into(),
 				0,
 				3,
 			));
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index 1d447db741ff..76d528f4be64 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -91,10 +91,10 @@ impl shared::Config for Runtime {}
 impl configuration::Config for Runtime {}
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = MultiLocation::here();
+	pub const KsmLocation: MultiLocation = Here.into();
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = MultiLocation::here();
+	pub Ancestry: MultiLocation = Here.into();
 	pub UnitWeightCost: Weight = 1_000;
 }
 

From a6059965d00f17cdde638d99ecacfc36942e1ca9 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sat, 7 Aug 2021 22:14:57 +0200
Subject: [PATCH 127/166] Fixes

---
 xcm/pallet-xcm/src/tests.rs                | 14 ++--
 xcm/src/v0/junction.rs                     |  2 +-
 xcm/src/v0/multi_location.rs               | 74 +++++++++----------
 xcm/src/v1/multilocation.rs                | 80 +++++++++++----------
 xcm/src/v1/traits.rs                       |  4 +-
 xcm/xcm-builder/src/currency_adapter.rs    |  2 +-
 xcm/xcm-builder/src/location_conversion.rs |  8 +--
 xcm/xcm-builder/src/matches_fungible.rs    |  4 +-
 xcm/xcm-builder/src/tests.rs               | 84 +++++++++++-----------
 xcm/xcm-simulator/example/src/lib.rs       |  2 +-
 xcm/xcm-simulator/example/src/parachain.rs |  6 +-
 xcm/xcm-simulator/src/lib.rs               |  2 +-
 12 files changed, 145 insertions(+), 137 deletions(-)

diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 1ca2a2579133..448bb71724cf 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -40,9 +40,9 @@ fn send_works() {
 		let sender: MultiLocation =
 			AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (MultiLocation::with_parents::<1>(), SEND_AMOUNT).into(),
+			assets: (MultiLocation::ancestor(1), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((MultiLocation::with_parents::<1>(), SEND_AMOUNT), weight),
+				buy_execution((MultiLocation::ancestor(1), SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -78,16 +78,16 @@ fn send_fails_when_xcm_router_blocks() {
 		let sender: MultiLocation =
 			Junction::AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (MultiLocation::with_parents::<1>(), SEND_AMOUNT).into(),
+			assets: (MultiLocation::ancestor(1), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((MultiLocation::with_parents::<1>(), SEND_AMOUNT), weight),
+				buy_execution((MultiLocation::ancestor(1), SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
 		assert_noop!(
 			XcmPallet::send(
 				Origin::signed(ALICE),
-				Box::new(MultiLocation::with_parents::<8>()),
+				Box::new(MultiLocation::ancestor(8)),
 				Box::new(message.clone())
 			),
 			crate::Error::<Test>::SendFailure
@@ -153,9 +153,9 @@ fn reserve_transfer_assets_works() {
 			vec![(
 				Parachain(PARA_ID).into(),
 				Xcm::ReserveAssetDeposited {
-					assets: (MultiLocation::with_parents::<1>(), SEND_AMOUNT).into(),
+					assets: (MultiLocation::ancestor(1), SEND_AMOUNT).into(),
 					effects: vec![
-						buy_execution((MultiLocation::with_parents::<1>(), SEND_AMOUNT), weight),
+						buy_execution((MultiLocation::ancestor(1), SEND_AMOUNT), weight),
 						DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
 					]
 				}
diff --git a/xcm/src/v0/junction.rs b/xcm/src/v0/junction.rs
index 9ccc3424028c..cee1799081e5 100644
--- a/xcm/src/v0/junction.rs
+++ b/xcm/src/v0/junction.rs
@@ -159,7 +159,7 @@ impl From<Junction1> for Junction {
 			Junction1::AccountIndex64 { network, index } => Self::AccountIndex64 { network, index },
 			Junction1::AccountKey20 { network, key } => Self::AccountKey20 { network, key },
 			Junction1::PalletInstance(index) => Self::PalletInstance(index),
-			Junction1::GeneralIndex { id } => Self::GeneralIndex { id },
+			Junction1::GeneralIndex(id) => Self::GeneralIndex { id },
 			Junction1::GeneralKey(key) => Self::GeneralKey(key),
 			Junction1::OnlyChild => Self::OnlyChild,
 			Junction1::Plurality { id, part } => Self::Plurality { id: id.into(), part },
diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index b056e557b5d9..9e9514539621 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -707,56 +707,56 @@ impl TryFrom<MultiLocation1> for MultiLocation {
 		}
 
 		match v1.interior {
-			Null => Ok(res),
-			X1(j0) => res.pushed_with(j0.into()).map_err(|_| ()),
+			Here => Ok(res),
+			X1(j0) => res.pushed_with(Junction::from(j0)).map_err(|_| ()),
 			X2(j0, j1) => res
-				.pushed_with(j0.into())
-				.and_then(|res| res.pushed_with(j1.into()))
+				.pushed_with(Junction::from(j0))
+				.and_then(|res| res.pushed_with(Junction::from(j1)))
 				.map_err(|_| ()),
 			X3(j0, j1, j2) => res
-				.pushed_with(j0.into())
-				.and_then(|res| res.pushed_with(j1.into()))
-				.and_then(|res| res.pushed_with(j2.into()))
+				.pushed_with(Junction::from(j0))
+				.and_then(|res| res.pushed_with(Junction::from(j1)))
+				.and_then(|res| res.pushed_with(Junction::from(j2)))
 				.map_err(|_| ()),
 			X4(j0, j1, j2, j3) => res
-				.pushed_with(j0.into())
-				.and_then(|res| res.pushed_with(j1.into()))
-				.and_then(|res| res.pushed_with(j2.into()))
-				.and_then(|res| res.pushed_with(j3.into()))
+				.pushed_with(Junction::from(j0))
+				.and_then(|res| res.pushed_with(Junction::from(j1)))
+				.and_then(|res| res.pushed_with(Junction::from(j2)))
+				.and_then(|res| res.pushed_with(Junction::from(j3)))
 				.map_err(|_| ()),
 			X5(j0, j1, j2, j3, j4) => res
-				.pushed_with(j0.into())
-				.and_then(|res| res.pushed_with(j1.into()))
-				.and_then(|res| res.pushed_with(j2.into()))
-				.and_then(|res| res.pushed_with(j3.into()))
-				.and_then(|res| res.pushed_with(j4.into()))
+				.pushed_with(Junction::from(j0))
+				.and_then(|res| res.pushed_with(Junction::from(j1)))
+				.and_then(|res| res.pushed_with(Junction::from(j2)))
+				.and_then(|res| res.pushed_with(Junction::from(j3)))
+				.and_then(|res| res.pushed_with(Junction::from(j4)))
 				.map_err(|_| ()),
 			X6(j0, j1, j2, j3, j4, j5) => res
-				.pushed_with(j0.into())
-				.and_then(|res| res.pushed_with(j1.into()))
-				.and_then(|res| res.pushed_with(j2.into()))
-				.and_then(|res| res.pushed_with(j3.into()))
-				.and_then(|res| res.pushed_with(j4.into()))
-				.and_then(|res| res.pushed_with(j5.into()))
+				.pushed_with(Junction::from(j0))
+				.and_then(|res| res.pushed_with(Junction::from(j1)))
+				.and_then(|res| res.pushed_with(Junction::from(j2)))
+				.and_then(|res| res.pushed_with(Junction::from(j3)))
+				.and_then(|res| res.pushed_with(Junction::from(j4)))
+				.and_then(|res| res.pushed_with(Junction::from(j5)))
 				.map_err(|_| ()),
 			X7(j0, j1, j2, j3, j4, j5, j6) => res
-				.pushed_with(j0.into())
-				.and_then(|res| res.pushed_with(j1.into()))
-				.and_then(|res| res.pushed_with(j2.into()))
-				.and_then(|res| res.pushed_with(j3.into()))
-				.and_then(|res| res.pushed_with(j4.into()))
-				.and_then(|res| res.pushed_with(j5.into()))
-				.and_then(|res| res.pushed_with(j6.into()))
+				.pushed_with(Junction::from(j0))
+				.and_then(|res| res.pushed_with(Junction::from(j1)))
+				.and_then(|res| res.pushed_with(Junction::from(j2)))
+				.and_then(|res| res.pushed_with(Junction::from(j3)))
+				.and_then(|res| res.pushed_with(Junction::from(j4)))
+				.and_then(|res| res.pushed_with(Junction::from(j5)))
+				.and_then(|res| res.pushed_with(Junction::from(j6)))
 				.map_err(|_| ()),
 			X8(j0, j1, j2, j3, j4, j5, j6, j7) => res
-				.pushed_with(j0.into())
-				.and_then(|res| res.pushed_with(j1.into()))
-				.and_then(|res| res.pushed_with(j2.into()))
-				.and_then(|res| res.pushed_with(j3.into()))
-				.and_then(|res| res.pushed_with(j4.into()))
-				.and_then(|res| res.pushed_with(j5.into()))
-				.and_then(|res| res.pushed_with(j6.into()))
-				.and_then(|res| res.pushed_with(j7.into()))
+				.pushed_with(Junction::from(j0))
+				.and_then(|res| res.pushed_with(Junction::from(j1)))
+				.and_then(|res| res.pushed_with(Junction::from(j2)))
+				.and_then(|res| res.pushed_with(Junction::from(j3)))
+				.and_then(|res| res.pushed_with(Junction::from(j4)))
+				.and_then(|res| res.pushed_with(Junction::from(j5)))
+				.and_then(|res| res.pushed_with(Junction::from(j6)))
+				.and_then(|res| res.pushed_with(Junction::from(j7)))
 				.map_err(|_| ()),
 		}
 	}
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 3481be4fdf99..108329ff95ca 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -77,15 +77,23 @@ impl MultiLocation {
 	///
 	/// The resulting `MultiLocation` can be interpreted as the "current consensus system".
 	pub const fn here() -> MultiLocation {
-		MultiLocation { parents: 0, interior: Junctions::Null }
+		MultiLocation { parents: 0, interior: Junctions::Here }
 	}
 
-	/// Creates a new `MultiLocation` with the specified number of parents in the `P` const generic
-	/// parameter and a `Null` interior.
-	pub const fn with_parents<const P: u8>() -> MultiLocation {
-		// If this condition does not hold, then P may overflow MAX_MULTILOCATION_LENGTH.
+	/// Creates a new `MultiLocation` which evaluates to the parent context.
+	pub const fn parent() -> MultiLocation {
+		MultiLocation { parents: 1, interior: Junctions::Here }
+	}
+
+	/// Creates a new `MultiLocation` which evaluates to the grand parent context.
+	pub const fn grandparent() -> MultiLocation {
+		MultiLocation { parents: 2, interior: Junctions::Here }
+	}
+
+	/// Creates a new `MultiLocation` with `parents` and an empty (`Here`) interior.
+	pub const fn ancestor(parents: u8) -> MultiLocation {
 		const_assert!(MAX_MULTILOCATION_LENGTH >= 255);
-		MultiLocation { parents: P, interior: Junctions::Null }
+		MultiLocation { parents, interior: Junctions::Here }
 	}
 
 	/// Whether or not the `MultiLocation` has no parents and has a `Null` interior.
@@ -111,7 +119,7 @@ impl MultiLocation {
 	/// Returns boolean indicating whether or not `self` contains only the specified amount of
 	/// parents and no interior junctions.
 	pub const fn contains_parents_only(&self, count: u8) -> bool {
-		matches!(self.interior, Junctions::Null) && self.parents == count
+		matches!(self.interior, Junctions::Here) && self.parents == count
 	}
 
 	/// Returns the number of parents and junctions in `self`.
@@ -160,7 +168,7 @@ impl MultiLocation {
 
 	/// Mutates `self`, suffixing its interior junctions with `new`. Returns `Err` in case of overflow.
 	pub fn push_interior(&mut self, new: Junction) -> result::Result<(), ()> {
-		let mut n = Junctions::Null;
+		let mut n = Junctions::Here;
 		mem::swap(&mut self.interior, &mut n);
 		match n.pushed_with(new) {
 			Ok(result) => {
@@ -176,7 +184,7 @@ impl MultiLocation {
 
 	/// Mutates `self`, prefixing its interior junctions with `new`. Returns `Err` in case of overflow.
 	pub fn push_front_interior(&mut self, new: Junction) -> result::Result<(), ()> {
-		let mut n = Junctions::Null;
+		let mut n = Junctions::Here;
 		mem::swap(&mut self.interior, &mut n);
 		match n.pushed_front_with(new) {
 			Ok(result) => {
@@ -276,7 +284,7 @@ impl MultiLocation {
 	///     m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3))).unwrap()),
 	///     Some(&OnlyChild),
 	/// );
-	/// assert_eq!(m.match_and_split(&MultiLocation::new(1, Null).unwrap()), None);
+	/// assert_eq!(m.match_and_split(&MultiLocation::new(1, Here).unwrap()), None);
 	/// # }
 	/// ```
 	pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> {
@@ -370,7 +378,7 @@ impl From<Junction> for MultiLocation {
 
 impl From<()> for MultiLocation {
 	fn from(_: ()) -> Self {
-		MultiLocation { parents: 0, interior: Junctions::Null }
+		MultiLocation { parents: 0, interior: Junctions::Here }
 	}
 }
 impl From<(Junction,)> for MultiLocation {
@@ -425,7 +433,7 @@ impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction,
 
 impl From<[Junction; 0]> for MultiLocation {
 	fn from(_: [Junction; 0]) -> Self {
-		MultiLocation { parents: 0, interior: Junctions::Null }
+		MultiLocation { parents: 0, interior: Junctions::Here }
 	}
 }
 impl From<[Junction; 1]> for MultiLocation {
@@ -585,7 +593,7 @@ impl Junctions {
 	/// Returns first junction, or `None` if the location is empty.
 	pub fn first(&self) -> Option<&Junction> {
 		match &self {
-			Junctions::Null => None,
+			Junctions::Here => None,
 			Junctions::X1(ref a) => Some(a),
 			Junctions::X2(ref a, ..) => Some(a),
 			Junctions::X3(ref a, ..) => Some(a),
@@ -600,7 +608,7 @@ impl Junctions {
 	/// Returns last junction, or `None` if the location is empty.
 	pub fn last(&self) -> Option<&Junction> {
 		match &self {
-			Junctions::Null => None,
+			Junctions::Here => None,
 			Junctions::X1(ref a) => Some(a),
 			Junctions::X2(.., ref a) => Some(a),
 			Junctions::X3(.., ref a) => Some(a),
@@ -616,8 +624,8 @@ impl Junctions {
 	/// (second item in tuple) or `None` if it was empty.
 	pub fn split_first(self) -> (Junctions, Option<Junction>) {
 		match self {
-			Junctions::Null => (Junctions::Null, None),
-			Junctions::X1(a) => (Junctions::Null, Some(a)),
+			Junctions::Here => (Junctions::Here, None),
+			Junctions::X1(a) => (Junctions::Here, Some(a)),
 			Junctions::X2(a, b) => (Junctions::X1(b), Some(a)),
 			Junctions::X3(a, b, c) => (Junctions::X2(b, c), Some(a)),
 			Junctions::X4(a, b, c, d) => (Junctions::X3(b, c, d), Some(a)),
@@ -632,8 +640,8 @@ impl Junctions {
 	/// (second item in tuple) or `None` if it was empty.
 	pub fn split_last(self) -> (Junctions, Option<Junction>) {
 		match self {
-			Junctions::Null => (Junctions::Null, None),
-			Junctions::X1(a) => (Junctions::Null, Some(a)),
+			Junctions::Here => (Junctions::Here, None),
+			Junctions::X1(a) => (Junctions::Here, Some(a)),
 			Junctions::X2(a, b) => (Junctions::X1(a), Some(b)),
 			Junctions::X3(a, b, c) => (Junctions::X2(a, b), Some(c)),
 			Junctions::X4(a, b, c, d) => (Junctions::X3(a, b, c), Some(d)),
@@ -646,7 +654,7 @@ impl Junctions {
 
 	/// Removes the first element from `self`, returning it (or `None` if it was empty).
 	pub fn take_first(&mut self) -> Option<Junction> {
-		let mut d = Junctions::Null;
+		let mut d = Junctions::Here;
 		mem::swap(&mut *self, &mut d);
 		let (tail, head) = d.split_first();
 		*self = tail;
@@ -655,7 +663,7 @@ impl Junctions {
 
 	/// Removes the last element from `self`, returning it (or `None` if it was empty).
 	pub fn take_last(&mut self) -> Option<Junction> {
-		let mut d = Junctions::Null;
+		let mut d = Junctions::Here;
 		mem::swap(&mut *self, &mut d);
 		let (head, tail) = d.split_last();
 		*self = head;
@@ -666,7 +674,7 @@ impl Junctions {
 	/// `self` in case of overflow.
 	pub fn pushed_with(self, new: Junction) -> result::Result<Self, Self> {
 		Ok(match self {
-			Junctions::Null => Junctions::X1(new),
+			Junctions::Here => Junctions::X1(new),
 			Junctions::X1(a) => Junctions::X2(a, new),
 			Junctions::X2(a, b) => Junctions::X3(a, b, new),
 			Junctions::X3(a, b, c) => Junctions::X4(a, b, c, new),
@@ -682,7 +690,7 @@ impl Junctions {
 	/// `self` in case of overflow.
 	pub fn pushed_front_with(self, new: Junction) -> result::Result<Self, Self> {
 		Ok(match self {
-			Junctions::Null => Junctions::X1(new),
+			Junctions::Here => Junctions::X1(new),
 			Junctions::X1(a) => Junctions::X2(new, a),
 			Junctions::X2(a, b) => Junctions::X3(new, a, b),
 			Junctions::X3(a, b, c) => Junctions::X4(new, a, b, c),
@@ -697,7 +705,7 @@ impl Junctions {
 	/// Returns the number of junctions in `self`.
 	pub const fn len(&self) -> usize {
 		match &self {
-			Junctions::Null => 0,
+			Junctions::Here => 0,
 			Junctions::X1(..) => 1,
 			Junctions::X2(..) => 2,
 			Junctions::X3(..) => 3,
@@ -853,16 +861,16 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 		use Junctions::*;
 		match old {
 			MultiLocation0::Null => Ok(Here.into()),
-			MultiLocation0::X1(j0) if j0.is_parent() => Ok(MultiLocation::with_parents::<1>()),
+			MultiLocation0::X1(j0) if j0.is_parent() => Ok(MultiLocation::ancestor(1)),
 			MultiLocation0::X1(j0) => Ok(X1(j0.try_into()?).into()),
 			MultiLocation0::X2(j0, j1) if j0.is_parent() && j1.is_parent() =>
-				Ok(MultiLocation::with_parents::<2>()),
+				Ok(MultiLocation::ancestor(2)),
 			MultiLocation0::X2(j0, j1) if j0.is_parent() =>
 				Ok(MultiLocation { parents: 1, interior: X1(j1.try_into()?) }),
 			MultiLocation0::X2(j0, j1) => Ok(X2(j0.try_into()?, j1.try_into()?).into()),
 			MultiLocation0::X3(j0, j1, j2)
 				if j0.is_parent() && j1.is_parent() && j2.is_parent() =>
-				Ok(MultiLocation::with_parents::<3>()),
+				Ok(MultiLocation::ancestor(3)),
 			MultiLocation0::X3(j0, j1, j2) if j0.is_parent() && j1.is_parent() =>
 				Ok(MultiLocation { parents: 2, interior: X1(j2.try_into()?) }),
 			MultiLocation0::X3(j0, j1, j2) if j0.is_parent() =>
@@ -871,7 +879,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 				Ok(X3(j0.try_into()?, j1.try_into()?, j2.try_into()?).into()),
 			MultiLocation0::X4(j0, j1, j2, j3)
 				if j0.is_parent() && j1.is_parent() && j2.is_parent() && j3.is_parent() =>
-				Ok(MultiLocation::with_parents::<4>()),
+				Ok(MultiLocation::ancestor(4)),
 			MultiLocation0::X4(j0, j1, j2, j3)
 				if j0.is_parent() && j1.is_parent() && j2.is_parent() =>
 				Ok(MultiLocation { parents: 3, interior: X1(j3.try_into()?) }),
@@ -887,7 +895,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 				if j0.is_parent() &&
 					j1.is_parent() && j2.is_parent() &&
 					j3.is_parent() && j4.is_parent() =>
-				Ok(MultiLocation::with_parents::<5>()),
+				Ok(MultiLocation::ancestor(5)),
 			MultiLocation0::X5(j0, j1, j2, j3, j4)
 				if j0.is_parent() && j1.is_parent() && j2.is_parent() && j3.is_parent() =>
 				Ok(MultiLocation { parents: 4, interior: X1(j4.try_into()?) }),
@@ -916,7 +924,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 					j1.is_parent() && j2.is_parent() &&
 					j3.is_parent() && j4.is_parent() &&
 					j5.is_parent() =>
-				Ok(MultiLocation::with_parents::<6>()),
+				Ok(MultiLocation::ancestor(6)),
 			MultiLocation0::X6(j0, j1, j2, j3, j4, j5)
 				if j0.is_parent() &&
 					j1.is_parent() && j2.is_parent() &&
@@ -960,7 +968,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 					j1.is_parent() && j2.is_parent() &&
 					j3.is_parent() && j4.is_parent() &&
 					j5.is_parent() && j6.is_parent() =>
-				Ok(MultiLocation::with_parents::<7>()),
+				Ok(MultiLocation::ancestor(7)),
 			MultiLocation0::X7(j0, j1, j2, j3, j4, j5, j6)
 				if j0.is_parent() &&
 					j1.is_parent() && j2.is_parent() &&
@@ -1022,7 +1030,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 					j3.is_parent() && j4.is_parent() &&
 					j5.is_parent() && j6.is_parent() &&
 					j7.is_parent() =>
-				Ok(MultiLocation::with_parents::<8>()),
+				Ok(MultiLocation::ancestor(8)),
 			MultiLocation0::X8(j0, j1, j2, j3, j4, j5, j6, j7)
 				if j0.is_parent() &&
 					j1.is_parent() && j2.is_parent() &&
@@ -1126,7 +1134,7 @@ mod tests {
 			parents: 1,
 			interior: X2(Parachain(42), AccountIndex64 { network: Any, index: 23 }),
 		};
-		assert_eq!(m.match_and_split(&MultiLocation { parents: 1, interior: Null }), None);
+		assert_eq!(m.match_and_split(&MultiLocation { parents: 1, interior: Here }), None);
 		assert_eq!(
 			m.match_and_split(&MultiLocation { parents: 1, interior: X1(Parachain(42)) }),
 			Some(&AccountIndex64 { network: Any, index: 23 })
@@ -1171,10 +1179,10 @@ mod tests {
 
 		// cannot prepend to create overly long multilocation
 		let mut m = MultiLocation { parents: 253, interior: X1(Parachain(42)) };
-		let prefix = MultiLocation { parents: 2, interior: Null };
+		let prefix = MultiLocation { parents: 2, interior: Here };
 		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
 
-		let prefix = MultiLocation { parents: 1, interior: Null };
+		let prefix = MultiLocation { parents: 1, interior: Here };
 		assert_eq!(m.prepend_with(prefix), Ok(()));
 		assert_eq!(m, MultiLocation { parents: 254, interior: X1(Parachain(42)) });
 	}
@@ -1193,7 +1201,7 @@ mod tests {
 		assert_eq!(iter.next_back(), None);
 		assert_eq!(second, &Parachain(3));
 
-		let res = Null
+		let res = Here
 			.pushed_with(first.clone())
 			.unwrap()
 			.pushed_with(second.clone())
@@ -1203,7 +1211,7 @@ mod tests {
 		assert_eq!(m, res);
 
 		// make sure there's no funny business with the 0 indexing
-		let m = Null;
+		let m = Here;
 		let mut iter = m.iter();
 
 		assert_eq!(iter.next(), None);
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
index 2410223f8b3e..3e5d33d51313 100644
--- a/xcm/src/v1/traits.rs
+++ b/xcm/src/v1/traits.rs
@@ -215,7 +215,7 @@ impl<C> ExecuteXcm<C> for () {
 /// struct Sender3;
 /// impl SendXcm for Sender3 {
 ///     fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
-///         if matches!(destination.interior(), Junctions::Null)
+///         if matches!(destination.interior(), Junctions::Here)
 ///             && destination.parent_count() == 1
 ///         {
 ///             Ok(())
@@ -229,7 +229,7 @@ impl<C> ExecuteXcm<C> for () {
 /// # fn main() {
 /// let call: Vec<u8> = ().encode();
 /// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
-/// let destination = MultiLocation::with_parents::<1>();
+/// let destination = MultiLocation::ancestor(1);
 ///
 /// assert!(
 ///     // Sender2 will block this.
diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs
index 097010d2c889..9335ab9e4d7c 100644
--- a/xcm/xcm-builder/src/currency_adapter.rs
+++ b/xcm/xcm-builder/src/currency_adapter.rs
@@ -61,7 +61,7 @@ impl From<Error> for XcmError {
 ///
 /// /// Our relay chain's location.
 /// parameter_types! {
-///     RelayChain: MultiLocation = MultiLocation::with_parents::<1>();
+///     RelayChain: MultiLocation = MultiLocation::ancestor(1);
 ///     CheckingAccount: AccountId = Default::default();
 /// }
 ///
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index bab5ee615e41..2895fc4cc4f7 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -51,7 +51,7 @@ impl<AccountId: Default + Eq + Clone> Convert<MultiLocation, AccountId>
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if who.borrow() == &AccountId::default() {
-			Ok(MultiLocation::with_parents::<1>())
+			Ok(MultiLocation::ancestor(1))
 		} else {
 			Err(())
 		}
@@ -181,7 +181,7 @@ pub struct LocationInverter<Ancestry>(PhantomData<Ancestry>);
 impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry> {
 	fn invert_location(location: &MultiLocation) -> MultiLocation {
 		let mut ancestry = Ancestry::get();
-		let mut junctions = Junctions::Null;
+		let mut junctions = Junctions::Here;
 		for _ in 0..location.parent_count() {
 			junctions = junctions
 				.pushed_with(ancestry.take_first_interior().unwrap_or(Junction::OnlyChild))
@@ -244,7 +244,7 @@ mod tests {
 			pub Ancestry: MultiLocation = X2(account20(), account20()).into();
 		}
 
-		let input = MultiLocation::with_parents::<2>();
+		let input = MultiLocation::ancestor(2);
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
 		assert_eq!(inverted, X2(account20(), account20()).into());
 	}
@@ -259,7 +259,7 @@ mod tests {
 			pub Ancestry: MultiLocation = X1(PalletInstance(5)).into();
 		}
 
-		let input = MultiLocation::with_parents::<2>();
+		let input = MultiLocation::ancestor(2);
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
 		assert_eq!(inverted, X2(PalletInstance(5), OnlyChild).into());
 	}
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 579b2eba3f78..5240d341d1f5 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -37,11 +37,11 @@ use xcm_executor::traits::MatchesFungible;
 /// use xcm_executor::traits::MatchesFungible;
 ///
 /// frame_support::parameter_types! {
-/// 	pub TargetLocation: MultiLocation = MultiLocation::with_parents::<1>();
+/// 	pub TargetLocation: MultiLocation = MultiLocation::ancestor(1);
 /// }
 ///
 /// # fn main() {
-/// let asset = (MultiLocation::with_parents::<1>(), 999).into();
+/// let asset = (MultiLocation::ancestor(1), 999).into();
 /// // match `asset` if it is a concrete asset in `TargetLocation`.
 /// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
 /// # }
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index fffcffaeb1e3..a7551143b998 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -21,12 +21,12 @@ use xcm_executor::{traits::*, Config, XcmExecutor};
 #[test]
 fn basic_setup_works() {
 	add_reserve(
-		MultiLocation::with_parents::<1>(),
-		Wild((MultiLocation::with_parents::<1>(), WildFungible).into()),
+		MultiLocation::ancestor(1),
+		Wild((MultiLocation::ancestor(1), WildFungible).into()),
 	);
 	assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
-		&(MultiLocation::with_parents::<1>(), 100).into(),
-		&MultiLocation::with_parents::<1>(),
+		&(MultiLocation::ancestor(1), 100).into(),
+		&MultiLocation::ancestor(1),
 	));
 
 	assert_eq!(to_account(X1(Parachain(1)).into()), Ok(1001));
@@ -47,10 +47,10 @@ fn basic_setup_works() {
 #[test]
 fn weigher_should_work() {
 	let mut message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::with_parents::<1>(), 100).into(),
+		assets: (MultiLocation::ancestor(1), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
-				fees: (MultiLocation::with_parents::<1>(), 1).into(),
+				fees: (MultiLocation::ancestor(1), 1).into(),
 				weight: 0,
 				debt: 30,
 				halt_on_error: true,
@@ -71,13 +71,13 @@ fn weigher_should_work() {
 #[test]
 fn take_weight_credit_barrier_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::with_parents::<1>(), 100).into(),
+		assets: (MultiLocation::ancestor(1), 100).into(),
 		beneficiary: Here.into(),
 	};
 
 	let mut weight_credit = 10;
 	let r = TakeWeightCredit::should_execute(
-		&MultiLocation::with_parents::<1>(),
+		&MultiLocation::ancestor(1),
 		true,
 		&mut message,
 		10,
@@ -87,7 +87,7 @@ fn take_weight_credit_barrier_should_work() {
 	assert_eq!(weight_credit, 0);
 
 	let r = TakeWeightCredit::should_execute(
-		&MultiLocation::with_parents::<1>(),
+		&MultiLocation::ancestor(1),
 		true,
 		&mut message,
 		10,
@@ -100,11 +100,11 @@ fn take_weight_credit_barrier_should_work() {
 #[test]
 fn allow_unpaid_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::with_parents::<1>(), 100).into(),
+		assets: (MultiLocation::ancestor(1), 100).into(),
 		beneficiary: Here.into(),
 	};
 
-	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
+	AllowUnpaidFrom::set(vec![MultiLocation::ancestor(1)]);
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
 		&X1(Parachain(1)).into(),
@@ -116,7 +116,7 @@ fn allow_unpaid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
-		&MultiLocation::with_parents::<1>(),
+		&MultiLocation::ancestor(1),
 		true,
 		&mut message,
 		10,
@@ -127,10 +127,10 @@ fn allow_unpaid_should_work() {
 
 #[test]
 fn allow_paid_should_work() {
-	AllowPaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
+	AllowPaidFrom::set(vec![MultiLocation::ancestor(1)]);
 
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::with_parents::<1>(), 100).into(),
+		assets: (MultiLocation::ancestor(1), 100).into(),
 		beneficiary: Here.into(),
 	};
 
@@ -143,9 +143,9 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let fees = (MultiLocation::with_parents::<1>(), 1).into();
+	let fees = (MultiLocation::ancestor(1), 1).into();
 	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::with_parents::<1>(), 100).into(),
+		assets: (MultiLocation::ancestor(1), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
 				fees,
@@ -164,7 +164,7 @@ fn allow_paid_should_work() {
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&MultiLocation::with_parents::<1>(),
+		&MultiLocation::ancestor(1),
 		true,
 		&mut underpaying_message,
 		30,
@@ -172,9 +172,9 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let fees = (MultiLocation::with_parents::<1>(), 1).into();
+	let fees = (MultiLocation::ancestor(1), 1).into();
 	let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::with_parents::<1>(), 100).into(),
+		assets: (MultiLocation::ancestor(1), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
 				fees,
@@ -202,7 +202,7 @@ fn allow_paid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&MultiLocation::with_parents::<1>(),
+		&MultiLocation::ancestor(1),
 		true,
 		&mut paying_message,
 		30,
@@ -213,17 +213,17 @@ fn allow_paid_should_work() {
 
 #[test]
 fn paying_reserve_deposit_should_work() {
-	AllowPaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
+	AllowPaidFrom::set(vec![MultiLocation::ancestor(1)]);
 	add_reserve(
-		MultiLocation::with_parents::<1>(),
-		(MultiLocation::with_parents::<1>(), WildFungible).into(),
+		MultiLocation::ancestor(1),
+		(MultiLocation::ancestor(1), WildFungible).into(),
 	);
-	WeightPrice::set((MultiLocation::with_parents::<1>().into(), 1_000_000_000_000));
+	WeightPrice::set((MultiLocation::ancestor(1).into(), 1_000_000_000_000));
 
-	let origin = MultiLocation::with_parents::<1>();
-	let fees = (MultiLocation::with_parents::<1>(), 30).into();
+	let origin = MultiLocation::ancestor(1);
+	let fees = (MultiLocation::ancestor(1), 30).into();
 	let message = Xcm::<TestCall>::ReserveAssetDeposited {
-		assets: (MultiLocation::with_parents::<1>(), 100).into(),
+		assets: (MultiLocation::ancestor(1), 100).into(),
 		effects: vec![
 			Order::<TestCall>::BuyExecution {
 				fees,
@@ -243,7 +243,7 @@ fn paying_reserve_deposit_should_work() {
 	let weight_limit = 50;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(30));
-	assert_eq!(assets(3000), vec![(MultiLocation::with_parents::<1>(), 70).into()]);
+	assert_eq!(assets(3000), vec![(MultiLocation::ancestor(1), 70).into()]);
 }
 
 #[test]
@@ -298,7 +298,7 @@ fn reserve_transfer_should_work() {
 		vec![(
 			X1(Parachain(2)).into(),
 			Xcm::ReserveAssetDeposited {
-				assets: (MultiLocation::with_parents::<1>(), 100).into(),
+				assets: (MultiLocation::ancestor(1), 100).into(),
 				effects: vec![Order::DepositAsset {
 					assets: All.into(),
 					max_assets: 1,
@@ -311,9 +311,9 @@ fn reserve_transfer_should_work() {
 
 #[test]
 fn transacting_should_work() {
-	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
+	AllowUnpaidFrom::set(vec![MultiLocation::ancestor(1)]);
 
-	let origin = MultiLocation::with_parents::<1>();
+	let origin = MultiLocation::ancestor(1);
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -326,9 +326,9 @@ fn transacting_should_work() {
 
 #[test]
 fn transacting_should_respect_max_weight_requirement() {
-	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
+	AllowUnpaidFrom::set(vec![MultiLocation::ancestor(1)]);
 
-	let origin = MultiLocation::with_parents::<1>();
+	let origin = MultiLocation::ancestor(1);
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 40,
@@ -341,9 +341,9 @@ fn transacting_should_respect_max_weight_requirement() {
 
 #[test]
 fn transacting_should_refund_weight() {
-	AllowUnpaidFrom::set(vec![MultiLocation::with_parents::<1>()]);
+	AllowUnpaidFrom::set(vec![MultiLocation::ancestor(1)]);
 
-	let origin = MultiLocation::with_parents::<1>();
+	let origin = MultiLocation::ancestor(1);
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -358,13 +358,13 @@ fn transacting_should_refund_weight() {
 fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let one: MultiLocation = X1(AccountIndex64 { index: 1, network: Any }).into();
 	AllowPaidFrom::set(vec![one.clone()]);
-	add_asset(1, (MultiLocation::with_parents::<1>(), 100).into());
-	WeightPrice::set((MultiLocation::with_parents::<1>().into(), 1_000_000_000_000));
+	add_asset(1, (MultiLocation::ancestor(1), 100).into());
+	WeightPrice::set((MultiLocation::ancestor(1).into(), 1_000_000_000_000));
 
 	let origin = one.clone();
-	let fees = (MultiLocation::with_parents::<1>(), 100).into();
+	let fees = (MultiLocation::ancestor(1), 100).into();
 	let message = Xcm::<TestCall>::WithdrawAsset {
-		assets: (MultiLocation::with_parents::<1>(), 100).into(), // enough for 100 units of weight.
+		assets: (MultiLocation::ancestor(1), 100).into(), // enough for 100 units of weight.
 		effects: vec![
 			Order::<TestCall>::BuyExecution {
 				fees,
@@ -389,17 +389,17 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let weight_limit = 100;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(50));
-	assert_eq!(assets(1), vec![(MultiLocation::with_parents::<1>(), 50).into()]);
+	assert_eq!(assets(1), vec![(MultiLocation::ancestor(1), 50).into()]);
 }
 
 #[test]
 fn prepaid_result_of_query_should_get_free_execution() {
 	let query_id = 33;
-	let origin = MultiLocation::with_parents::<1>();
+	let origin = MultiLocation::ancestor(1);
 	// We put this in manually here, but normally this would be done at the point of crafting the message.
 	expect_response(query_id, origin.clone());
 
-	let the_response = Response::Assets((MultiLocation::with_parents::<1>(), 100).into());
+	let the_response = Response::Assets((MultiLocation::ancestor(1), 100).into());
 	let message = Xcm::<TestCall>::QueryResponse { query_id, response: the_response.clone() };
 	let weight_limit = 10;
 
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 9bd86a60829d..bdefffe4144b 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -139,7 +139,7 @@ mod tests {
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
 				Here.into(),
-				MultiLocation::with_parents::<1>(),
+				MultiLocation::ancestor(1),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 2e85e86169f6..d066d3cd16e2 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -101,7 +101,7 @@ parameter_types! {
 }
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = MultiLocation::with_parents::<1>();
+	pub const KsmLocation: MultiLocation = MultiLocation::ancestor(1);
 	pub const RelayNetwork: NetworkId = NetworkId::Kusama;
 	pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
 }
@@ -120,7 +120,7 @@ pub type XcmOriginToCallOrigin = (
 
 parameter_types! {
 	pub const UnitWeightCost: Weight = 1;
-	pub KsmPerSecond: (AssetId, u128) = (Concrete(MultiLocation::with_parents::<1>()), 1);
+	pub KsmPerSecond: (AssetId, u128) = (Concrete(MultiLocation::ancestor(1)), 1);
 }
 
 pub type LocalAssetTransactor =
@@ -267,7 +267,7 @@ pub mod mock_msg_queue {
 					},
 					Ok(Ok(x)) => {
 						let outcome = T::XcmExecutor::execute_xcm(
-							MultiLocation::with_parents::<1>(),
+							MultiLocation::ancestor(1),
 							x,
 							limit,
 						);
diff --git a/xcm/xcm-simulator/src/lib.rs b/xcm/xcm-simulator/src/lib.rs
index 96669d880e4e..aed9635cff7f 100644
--- a/xcm/xcm-simulator/src/lib.rs
+++ b/xcm/xcm-simulator/src/lib.rs
@@ -196,7 +196,7 @@ macro_rules! decl_test_network {
 				use $crate::{UmpSink, XcmpMessageHandlerT};
 
 				match destination.interior() {
-					$crate::Junctions::Null if destination.parent_count() == 1 => {
+					$crate::Junctions::Here if destination.parent_count() == 1 => {
 						let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump);
 						let _ = <$relay_chain>::process_upward_message(
 							T::get(), &encoded[..],

From 0d21a4452bd85edd4f3cc7e9b86c3a50ff69dc24 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sat, 7 Aug 2021 22:16:14 +0200
Subject: [PATCH 128/166] Fixes

---
 xcm/pallet-xcm/src/tests.rs                | 12 ++--
 xcm/src/v1/multilocation.rs                |  4 +-
 xcm/src/v1/traits.rs                       |  2 +-
 xcm/xcm-builder/src/currency_adapter.rs    |  2 +-
 xcm/xcm-builder/src/location_conversion.rs |  6 +-
 xcm/xcm-builder/src/matches_fungible.rs    |  4 +-
 xcm/xcm-builder/src/tests.rs               | 84 +++++++++++-----------
 xcm/xcm-simulator/example/src/lib.rs       |  2 +-
 xcm/xcm-simulator/example/src/parachain.rs |  6 +-
 9 files changed, 61 insertions(+), 61 deletions(-)

diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 448bb71724cf..5bd3eb69f5ff 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -40,9 +40,9 @@ fn send_works() {
 		let sender: MultiLocation =
 			AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (MultiLocation::ancestor(1), SEND_AMOUNT).into(),
+			assets: (MultiLocation::parent(), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((MultiLocation::ancestor(1), SEND_AMOUNT), weight),
+				buy_execution((MultiLocation::parent(), SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -78,9 +78,9 @@ fn send_fails_when_xcm_router_blocks() {
 		let sender: MultiLocation =
 			Junction::AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (MultiLocation::ancestor(1), SEND_AMOUNT).into(),
+			assets: (MultiLocation::parent(), SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((MultiLocation::ancestor(1), SEND_AMOUNT), weight),
+				buy_execution((MultiLocation::parent(), SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -153,9 +153,9 @@ fn reserve_transfer_assets_works() {
 			vec![(
 				Parachain(PARA_ID).into(),
 				Xcm::ReserveAssetDeposited {
-					assets: (MultiLocation::ancestor(1), SEND_AMOUNT).into(),
+					assets: (MultiLocation::parent(), SEND_AMOUNT).into(),
 					effects: vec![
-						buy_execution((MultiLocation::ancestor(1), SEND_AMOUNT), weight),
+						buy_execution((MultiLocation::parent(), SEND_AMOUNT), weight),
 						DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
 					]
 				}
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 108329ff95ca..8e3bc1060c35 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -861,10 +861,10 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 		use Junctions::*;
 		match old {
 			MultiLocation0::Null => Ok(Here.into()),
-			MultiLocation0::X1(j0) if j0.is_parent() => Ok(MultiLocation::ancestor(1)),
+			MultiLocation0::X1(j0) if j0.is_parent() => Ok(MultiLocation::parent()),
 			MultiLocation0::X1(j0) => Ok(X1(j0.try_into()?).into()),
 			MultiLocation0::X2(j0, j1) if j0.is_parent() && j1.is_parent() =>
-				Ok(MultiLocation::ancestor(2)),
+				Ok(MultiLocation::grandparent()),
 			MultiLocation0::X2(j0, j1) if j0.is_parent() =>
 				Ok(MultiLocation { parents: 1, interior: X1(j1.try_into()?) }),
 			MultiLocation0::X2(j0, j1) => Ok(X2(j0.try_into()?, j1.try_into()?).into()),
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
index 3e5d33d51313..338ca55521de 100644
--- a/xcm/src/v1/traits.rs
+++ b/xcm/src/v1/traits.rs
@@ -229,7 +229,7 @@ impl<C> ExecuteXcm<C> for () {
 /// # fn main() {
 /// let call: Vec<u8> = ().encode();
 /// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
-/// let destination = MultiLocation::ancestor(1);
+/// let destination = MultiLocation::parent();
 ///
 /// assert!(
 ///     // Sender2 will block this.
diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs
index 9335ab9e4d7c..cd6e03c365db 100644
--- a/xcm/xcm-builder/src/currency_adapter.rs
+++ b/xcm/xcm-builder/src/currency_adapter.rs
@@ -61,7 +61,7 @@ impl From<Error> for XcmError {
 ///
 /// /// Our relay chain's location.
 /// parameter_types! {
-///     RelayChain: MultiLocation = MultiLocation::ancestor(1);
+///     RelayChain: MultiLocation = MultiLocation::parent();
 ///     CheckingAccount: AccountId = Default::default();
 /// }
 ///
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 2895fc4cc4f7..7dde7acfe7ee 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -51,7 +51,7 @@ impl<AccountId: Default + Eq + Clone> Convert<MultiLocation, AccountId>
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if who.borrow() == &AccountId::default() {
-			Ok(MultiLocation::ancestor(1))
+			Ok(MultiLocation::parent())
 		} else {
 			Err(())
 		}
@@ -244,7 +244,7 @@ mod tests {
 			pub Ancestry: MultiLocation = X2(account20(), account20()).into();
 		}
 
-		let input = MultiLocation::ancestor(2);
+		let input = MultiLocation::grandparent();
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
 		assert_eq!(inverted, X2(account20(), account20()).into());
 	}
@@ -259,7 +259,7 @@ mod tests {
 			pub Ancestry: MultiLocation = X1(PalletInstance(5)).into();
 		}
 
-		let input = MultiLocation::ancestor(2);
+		let input = MultiLocation::grandparent();
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
 		assert_eq!(inverted, X2(PalletInstance(5), OnlyChild).into());
 	}
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index 5240d341d1f5..e14fcdaa9409 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -37,11 +37,11 @@ use xcm_executor::traits::MatchesFungible;
 /// use xcm_executor::traits::MatchesFungible;
 ///
 /// frame_support::parameter_types! {
-/// 	pub TargetLocation: MultiLocation = MultiLocation::ancestor(1);
+/// 	pub TargetLocation: MultiLocation = MultiLocation::parent();
 /// }
 ///
 /// # fn main() {
-/// let asset = (MultiLocation::ancestor(1), 999).into();
+/// let asset = (MultiLocation::parent(), 999).into();
 /// // match `asset` if it is a concrete asset in `TargetLocation`.
 /// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
 /// # }
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index a7551143b998..0a4b966c6acf 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -21,12 +21,12 @@ use xcm_executor::{traits::*, Config, XcmExecutor};
 #[test]
 fn basic_setup_works() {
 	add_reserve(
-		MultiLocation::ancestor(1),
-		Wild((MultiLocation::ancestor(1), WildFungible).into()),
+		MultiLocation::parent(),
+		Wild((MultiLocation::parent(), WildFungible).into()),
 	);
 	assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
-		&(MultiLocation::ancestor(1), 100).into(),
-		&MultiLocation::ancestor(1),
+		&(MultiLocation::parent(), 100).into(),
+		&MultiLocation::parent(),
 	));
 
 	assert_eq!(to_account(X1(Parachain(1)).into()), Ok(1001));
@@ -47,10 +47,10 @@ fn basic_setup_works() {
 #[test]
 fn weigher_should_work() {
 	let mut message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::ancestor(1), 100).into(),
+		assets: (MultiLocation::parent(), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
-				fees: (MultiLocation::ancestor(1), 1).into(),
+				fees: (MultiLocation::parent(), 1).into(),
 				weight: 0,
 				debt: 30,
 				halt_on_error: true,
@@ -71,13 +71,13 @@ fn weigher_should_work() {
 #[test]
 fn take_weight_credit_barrier_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::ancestor(1), 100).into(),
+		assets: (MultiLocation::parent(), 100).into(),
 		beneficiary: Here.into(),
 	};
 
 	let mut weight_credit = 10;
 	let r = TakeWeightCredit::should_execute(
-		&MultiLocation::ancestor(1),
+		&MultiLocation::parent(),
 		true,
 		&mut message,
 		10,
@@ -87,7 +87,7 @@ fn take_weight_credit_barrier_should_work() {
 	assert_eq!(weight_credit, 0);
 
 	let r = TakeWeightCredit::should_execute(
-		&MultiLocation::ancestor(1),
+		&MultiLocation::parent(),
 		true,
 		&mut message,
 		10,
@@ -100,11 +100,11 @@ fn take_weight_credit_barrier_should_work() {
 #[test]
 fn allow_unpaid_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::ancestor(1), 100).into(),
+		assets: (MultiLocation::parent(), 100).into(),
 		beneficiary: Here.into(),
 	};
 
-	AllowUnpaidFrom::set(vec![MultiLocation::ancestor(1)]);
+	AllowUnpaidFrom::set(vec![MultiLocation::parent()]);
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
 		&X1(Parachain(1)).into(),
@@ -116,7 +116,7 @@ fn allow_unpaid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
-		&MultiLocation::ancestor(1),
+		&MultiLocation::parent(),
 		true,
 		&mut message,
 		10,
@@ -127,10 +127,10 @@ fn allow_unpaid_should_work() {
 
 #[test]
 fn allow_paid_should_work() {
-	AllowPaidFrom::set(vec![MultiLocation::ancestor(1)]);
+	AllowPaidFrom::set(vec![MultiLocation::parent()]);
 
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::ancestor(1), 100).into(),
+		assets: (MultiLocation::parent(), 100).into(),
 		beneficiary: Here.into(),
 	};
 
@@ -143,9 +143,9 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let fees = (MultiLocation::ancestor(1), 1).into();
+	let fees = (MultiLocation::parent(), 1).into();
 	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::ancestor(1), 100).into(),
+		assets: (MultiLocation::parent(), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
 				fees,
@@ -164,7 +164,7 @@ fn allow_paid_should_work() {
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&MultiLocation::ancestor(1),
+		&MultiLocation::parent(),
 		true,
 		&mut underpaying_message,
 		30,
@@ -172,9 +172,9 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let fees = (MultiLocation::ancestor(1), 1).into();
+	let fees = (MultiLocation::parent(), 1).into();
 	let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::ancestor(1), 100).into(),
+		assets: (MultiLocation::parent(), 100).into(),
 		effects: vec![
 			Order::BuyExecution {
 				fees,
@@ -202,7 +202,7 @@ fn allow_paid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&MultiLocation::ancestor(1),
+		&MultiLocation::parent(),
 		true,
 		&mut paying_message,
 		30,
@@ -213,17 +213,17 @@ fn allow_paid_should_work() {
 
 #[test]
 fn paying_reserve_deposit_should_work() {
-	AllowPaidFrom::set(vec![MultiLocation::ancestor(1)]);
+	AllowPaidFrom::set(vec![MultiLocation::parent()]);
 	add_reserve(
-		MultiLocation::ancestor(1),
-		(MultiLocation::ancestor(1), WildFungible).into(),
+		MultiLocation::parent(),
+		(MultiLocation::parent(), WildFungible).into(),
 	);
-	WeightPrice::set((MultiLocation::ancestor(1).into(), 1_000_000_000_000));
+	WeightPrice::set((MultiLocation::parent().into(), 1_000_000_000_000));
 
-	let origin = MultiLocation::ancestor(1);
-	let fees = (MultiLocation::ancestor(1), 30).into();
+	let origin = MultiLocation::parent();
+	let fees = (MultiLocation::parent(), 30).into();
 	let message = Xcm::<TestCall>::ReserveAssetDeposited {
-		assets: (MultiLocation::ancestor(1), 100).into(),
+		assets: (MultiLocation::parent(), 100).into(),
 		effects: vec![
 			Order::<TestCall>::BuyExecution {
 				fees,
@@ -243,7 +243,7 @@ fn paying_reserve_deposit_should_work() {
 	let weight_limit = 50;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(30));
-	assert_eq!(assets(3000), vec![(MultiLocation::ancestor(1), 70).into()]);
+	assert_eq!(assets(3000), vec![(MultiLocation::parent(), 70).into()]);
 }
 
 #[test]
@@ -298,7 +298,7 @@ fn reserve_transfer_should_work() {
 		vec![(
 			X1(Parachain(2)).into(),
 			Xcm::ReserveAssetDeposited {
-				assets: (MultiLocation::ancestor(1), 100).into(),
+				assets: (MultiLocation::parent(), 100).into(),
 				effects: vec![Order::DepositAsset {
 					assets: All.into(),
 					max_assets: 1,
@@ -311,9 +311,9 @@ fn reserve_transfer_should_work() {
 
 #[test]
 fn transacting_should_work() {
-	AllowUnpaidFrom::set(vec![MultiLocation::ancestor(1)]);
+	AllowUnpaidFrom::set(vec![MultiLocation::parent()]);
 
-	let origin = MultiLocation::ancestor(1);
+	let origin = MultiLocation::parent();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -326,9 +326,9 @@ fn transacting_should_work() {
 
 #[test]
 fn transacting_should_respect_max_weight_requirement() {
-	AllowUnpaidFrom::set(vec![MultiLocation::ancestor(1)]);
+	AllowUnpaidFrom::set(vec![MultiLocation::parent()]);
 
-	let origin = MultiLocation::ancestor(1);
+	let origin = MultiLocation::parent();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 40,
@@ -341,9 +341,9 @@ fn transacting_should_respect_max_weight_requirement() {
 
 #[test]
 fn transacting_should_refund_weight() {
-	AllowUnpaidFrom::set(vec![MultiLocation::ancestor(1)]);
+	AllowUnpaidFrom::set(vec![MultiLocation::parent()]);
 
-	let origin = MultiLocation::ancestor(1);
+	let origin = MultiLocation::parent();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -358,13 +358,13 @@ fn transacting_should_refund_weight() {
 fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let one: MultiLocation = X1(AccountIndex64 { index: 1, network: Any }).into();
 	AllowPaidFrom::set(vec![one.clone()]);
-	add_asset(1, (MultiLocation::ancestor(1), 100).into());
-	WeightPrice::set((MultiLocation::ancestor(1).into(), 1_000_000_000_000));
+	add_asset(1, (MultiLocation::parent(), 100).into());
+	WeightPrice::set((MultiLocation::parent().into(), 1_000_000_000_000));
 
 	let origin = one.clone();
-	let fees = (MultiLocation::ancestor(1), 100).into();
+	let fees = (MultiLocation::parent(), 100).into();
 	let message = Xcm::<TestCall>::WithdrawAsset {
-		assets: (MultiLocation::ancestor(1), 100).into(), // enough for 100 units of weight.
+		assets: (MultiLocation::parent(), 100).into(), // enough for 100 units of weight.
 		effects: vec![
 			Order::<TestCall>::BuyExecution {
 				fees,
@@ -389,17 +389,17 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let weight_limit = 100;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(50));
-	assert_eq!(assets(1), vec![(MultiLocation::ancestor(1), 50).into()]);
+	assert_eq!(assets(1), vec![(MultiLocation::parent(), 50).into()]);
 }
 
 #[test]
 fn prepaid_result_of_query_should_get_free_execution() {
 	let query_id = 33;
-	let origin = MultiLocation::ancestor(1);
+	let origin = MultiLocation::parent();
 	// We put this in manually here, but normally this would be done at the point of crafting the message.
 	expect_response(query_id, origin.clone());
 
-	let the_response = Response::Assets((MultiLocation::ancestor(1), 100).into());
+	let the_response = Response::Assets((MultiLocation::parent(), 100).into());
 	let message = Xcm::<TestCall>::QueryResponse { query_id, response: the_response.clone() };
 	let weight_limit = 10;
 
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index bdefffe4144b..cbff1672a544 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -139,7 +139,7 @@ mod tests {
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
 				Here.into(),
-				MultiLocation::ancestor(1),
+				MultiLocation::parent(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index d066d3cd16e2..2feb89fe499b 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -101,7 +101,7 @@ parameter_types! {
 }
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = MultiLocation::ancestor(1);
+	pub const KsmLocation: MultiLocation = MultiLocation::parent();
 	pub const RelayNetwork: NetworkId = NetworkId::Kusama;
 	pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
 }
@@ -120,7 +120,7 @@ pub type XcmOriginToCallOrigin = (
 
 parameter_types! {
 	pub const UnitWeightCost: Weight = 1;
-	pub KsmPerSecond: (AssetId, u128) = (Concrete(MultiLocation::ancestor(1)), 1);
+	pub KsmPerSecond: (AssetId, u128) = (Concrete(MultiLocation::parent()), 1);
 }
 
 pub type LocalAssetTransactor =
@@ -267,7 +267,7 @@ pub mod mock_msg_queue {
 					},
 					Ok(Ok(x)) => {
 						let outcome = T::XcmExecutor::execute_xcm(
-							MultiLocation::ancestor(1),
+							MultiLocation::parent(),
 							x,
 							limit,
 						);

From da7731298753cde49777238fba1835830522d912 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sat, 7 Aug 2021 22:21:17 +0200
Subject: [PATCH 129/166] Fixes

---
 xcm/xcm-builder/src/fungibles_adapter.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/xcm-builder/src/fungibles_adapter.rs b/xcm/xcm-builder/src/fungibles_adapter.rs
index 2647c36b5f22..2107acdb4a36 100644
--- a/xcm/xcm-builder/src/fungibles_adapter.rs
+++ b/xcm/xcm-builder/src/fungibles_adapter.rs
@@ -48,14 +48,14 @@ impl<Prefix: Get<MultiLocation>, AssetId: Clone, ConvertAssetId: Convert<u128, A
 			return Err(())
 		}
 		match id.interior().at(prefix.interior().len()) {
-			Some(Junction::GeneralIndex { id }) => ConvertAssetId::convert_ref(id),
+			Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert_ref(id),
 			_ => Err(()),
 		}
 	}
 	fn reverse_ref(what: impl Borrow<AssetId>) -> result::Result<MultiLocation, ()> {
 		let mut location = Prefix::get();
 		let id = ConvertAssetId::reverse_ref(what)?;
-		location.push_interior(Junction::GeneralIndex { id })?;
+		location.push_interior(Junction::GeneralIndex(id))?;
 		Ok(location)
 	}
 }

From 7d3a238c0c2711658803dccf9507335c565f7155 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Sat, 7 Aug 2021 23:14:59 +0200
Subject: [PATCH 130/166] Fix MultiLocation

---
 xcm/src/v1/multilocation.rs | 120 +++++++++++++++---------------------
 1 file changed, 49 insertions(+), 71 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 8e3bc1060c35..37055550ea41 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -22,7 +22,6 @@ use core::{
 	mem, result,
 };
 use parity_scale_codec::{self, Decode, Encode};
-use static_assertions::const_assert;
 
 /// A relative path between state-bearing consensus systems.
 ///
@@ -60,17 +59,11 @@ impl Default for MultiLocation {
 	}
 }
 
-/// Maximum number of junctions a `MultiLocation` can contain.
-pub const MAX_MULTILOCATION_LENGTH: usize = 255;
-
 impl MultiLocation {
 	/// Creates a new `MultiLocation`, ensuring that the length of it does not exceed the maximum,
 	/// otherwise returns `Err`.
-	pub fn new(parents: u8, junctions: Junctions) -> result::Result<MultiLocation, ()> {
-		if parents as usize + junctions.len() > MAX_MULTILOCATION_LENGTH {
-			return Err(())
-		}
-		Ok(MultiLocation { parents, interior: junctions })
+	pub fn new(parents: u8, junctions: Junctions) -> MultiLocation {
+		MultiLocation { parents, interior: junctions }
 	}
 
 	/// Creates a new `MultiLocation` with 0 parents and a `Null` interior.
@@ -92,7 +85,6 @@ impl MultiLocation {
 
 	/// Creates a new `MultiLocation` with `parents` and an empty (`Here`) interior.
 	pub const fn ancestor(parents: u8) -> MultiLocation {
-		const_assert!(MAX_MULTILOCATION_LENGTH >= 255);
 		MultiLocation { parents, interior: Junctions::Here }
 	}
 
@@ -157,15 +149,6 @@ impl MultiLocation {
 		(multilocation, last)
 	}
 
-	/// Bumps the parent count up by `n`. Returns `Err` in case of overflow.
-	pub fn add_parents(&mut self, n: u8) -> result::Result<(), ()> {
-		if self.len() + (n as usize) > MAX_MULTILOCATION_LENGTH {
-			return Err(())
-		}
-		self.parents = self.parents.saturating_add(n);
-		Ok(())
-	}
-
 	/// Mutates `self`, suffixing its interior junctions with `new`. Returns `Err` in case of overflow.
 	pub fn push_interior(&mut self, new: Junction) -> result::Result<(), ()> {
 		let mut n = Junctions::Here;
@@ -198,40 +181,22 @@ impl MultiLocation {
 		}
 	}
 
-	/// Consumes `self` and returns a `MultiLocation` with its parent count incremented by `n`, or
-	/// an `Err` with the original value of `self` in case of overflow.
-	pub fn added_with_parents(self, n: u8) -> result::Result<Self, Self> {
-		if self.len() + (n as usize) > MAX_MULTILOCATION_LENGTH {
-			return Err(self)
-		}
-		Ok(MultiLocation { parents: self.parents.saturating_add(n), ..self })
-	}
-
 	/// Consumes `self` and returns a `MultiLocation` suffixed with `new`, or an `Err` with the original value of
 	/// `self` in case of overflow.
 	pub fn pushed_with_interior(self, new: Junction) -> result::Result<Self, Self> {
-		if self.len() >= MAX_MULTILOCATION_LENGTH {
-			return Err(self)
+		match self.interior.pushed_with(new) {
+			Ok(i) => Ok(MultiLocation { interior: i, parents: self.parents }),
+			Err(i) => Err(MultiLocation { interior: i, parents: self.parents }),
 		}
-		Ok(MultiLocation {
-			parents: self.parents,
-			interior: self.interior.pushed_with(new).expect("length is less than max length; qed"),
-		})
 	}
 
 	/// Consumes `self` and returns a `MultiLocation` prefixed with `new`, or an `Err` with the original value of
 	/// `self` in case of overflow.
 	pub fn pushed_front_with_interior(self, new: Junction) -> result::Result<Self, Self> {
-		if self.len() >= MAX_MULTILOCATION_LENGTH {
-			return Err(self)
+		match self.interior.pushed_front_with(new) {
+			Ok(i) => Ok(MultiLocation { interior: i, parents: self.parents }),
+			Err(i) => Err(MultiLocation { interior: i, parents: self.parents }),
 		}
-		Ok(MultiLocation {
-			parents: self.parents,
-			interior: self
-				.interior
-				.pushed_front_with(new)
-				.expect("length is less than max length; qed"),
-		})
 	}
 
 	/// Returns the junction at index `i`, or `None` if the location is a parent or if the location
@@ -279,12 +244,12 @@ impl MultiLocation {
 	/// ```rust
 	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
 	/// # fn main() {
-	/// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild)).unwrap();
+	/// let mut m = MultiLocation::new(1, X2(PalletInstance(3), OnlyChild));
 	/// assert_eq!(
-	///     m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3))).unwrap()),
+	///     m.match_and_split(&MultiLocation::new(1, X1(PalletInstance(3)))),
 	///     Some(&OnlyChild),
 	/// );
-	/// assert_eq!(m.match_and_split(&MultiLocation::new(1, Here).unwrap()), None);
+	/// assert_eq!(m.match_and_split(&MultiLocation::new(1, Here)), None);
 	/// # }
 	/// ```
 	pub fn match_and_split(&self, prefix: &MultiLocation) -> Option<&Junction> {
@@ -303,9 +268,9 @@ impl MultiLocation {
 	/// ```rust
 	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
 	/// # fn main() {
-	/// let mut m = MultiLocation::new(1, X2(Parachain(21), OnlyChild)).unwrap();
-	/// assert_eq!(m.append_with(MultiLocation::new(1, X1(PalletInstance(3))).unwrap()), Ok(()));
-	/// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3))).unwrap());
+	/// let mut m = MultiLocation::new(1, X2(Parachain(21), OnlyChild));
+	/// assert_eq!(m.append_with(MultiLocation::new(1, X1(PalletInstance(3)))), Ok(()));
+	/// assert_eq!(m, MultiLocation::new(1, X2(Parachain(21), PalletInstance(3))));
 	/// # }
 	/// ```
 	pub fn append_with(&mut self, suffix: MultiLocation) -> Result<(), MultiLocation> {
@@ -329,35 +294,42 @@ impl MultiLocation {
 	/// ```rust
 	/// # use xcm::v1::{Junctions::*, Junction::*, MultiLocation};
 	/// # fn main() {
-	/// let mut m = MultiLocation::new(2, X1(PalletInstance(3))).unwrap();
-	/// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild)).unwrap()), Ok(()));
-	/// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3))).unwrap());
+	/// let mut m = MultiLocation::new(2, X1(PalletInstance(3)));
+	/// assert_eq!(m.prepend_with(MultiLocation::new(1, X2(Parachain(21), OnlyChild))), Ok(()));
+	/// assert_eq!(m, MultiLocation::new(1, X1(PalletInstance(3))));
 	/// # }
 	/// ```
 	pub fn prepend_with(&mut self, mut prefix: MultiLocation) -> Result<(), MultiLocation> {
-		let self_parents = self.parent_count();
-		let prepend_len = (self_parents as isize - prefix.interior.len() as isize).abs() as usize;
-		if self.interior.len() + prefix.parent_count() as usize + prepend_len >
-			MAX_MULTILOCATION_LENGTH
-		{
+		//     prefix     self (suffix)
+		// P .. P I .. I  p .. p i .. i
+		let prepend_interior = prefix.interior.len().saturating_sub(self.parents as usize);
+		let final_interior = self.interior.len().saturating_add(prepend_interior);
+		if final_interior > MAX_JUNCTIONS {
+			return Err(prefix)
+		}
+		let suffix_parents = (self.parents as usize).saturating_sub(prefix.interior.len());
+		let final_parents = (prefix.parents as usize).saturating_add(suffix_parents);
+		if final_parents > 255 {
 			return Err(prefix)
 		}
 
-		let mut final_parent_count = prefix.parents;
-		for _ in 0..self_parents {
-			if prefix.take_last().is_none() {
-				// If true, this means self parent count is greater than prefix junctions length;
-				// add the resulting self parent count to final_parent_count
-				final_parent_count += self.parents;
-				break
-			}
+		// cancel out the final item on the prefix interior for one of the suffix's parents.
+		while self.parents > 0 && prefix.take_last().is_some() {
 			self.dec_parent();
 		}
 
-		self.parents = final_parent_count;
+		// now we have either removed all suffix's parents or prefix interior.
+		// this means we can combine the prefix's and suffix's remaining parents/interior since
+		// we know that with at least one empty, the overall order will be respected:
+		//     prefix     self (suffix)
+		// P .. P   (I)   p .. p i .. i => P + p .. (no I) i
+		//  -- or --
+		// P .. P I .. I    (p)  i .. i => P (no p) .. I + i
+
+		self.parents = self.parents.saturating_add(prefix.parents);
 		for j in prefix.interior.into_iter().rev() {
 			self.push_front_interior(j).expect(
-				"self junctions len + prefix parent count + prepend len is less than max length; qed"
+				"final_interior no greater than MAX_JUNCTIONS; qed"
 			);
 		}
 		Ok(())
@@ -485,6 +457,9 @@ impl From<[Junction; 8]> for MultiLocation {
 	}
 }
 
+/// Maximum number of `Junction`s that a `Junctions` can contain.
+const MAX_JUNCTIONS: usize = 8;
+
 /// Non-parent junctions that can be constructed, up to the length of 8. This specific `Junctions`
 /// implementation uses a Rust `enum` in order to make pattern matching easier.
 ///
@@ -1157,8 +1132,11 @@ mod tests {
 
 		// cannot append to create overly long multilocation
 		let acc = AccountIndex64 { network: Any, index: 23 };
-		let mut m = MultiLocation { parents: 254, interior: X1(Parachain(42)) };
-		let suffix = MultiLocation::from(X2(PalletInstance(3), acc.clone()));
+		let mut m = MultiLocation {
+			parents: 254,
+			interior: X5(Parachain(42), OnlyChild, OnlyChild, OnlyChild, OnlyChild)
+		};
+		let suffix = MultiLocation::from(X4(PalletInstance(3), acc.clone(), OnlyChild, OnlyChild));
 		assert_eq!(m.append_with(suffix.clone()), Err(suffix));
 	}
 
@@ -1178,13 +1156,13 @@ mod tests {
 		);
 
 		// cannot prepend to create overly long multilocation
-		let mut m = MultiLocation { parents: 253, interior: X1(Parachain(42)) };
+		let mut m = MultiLocation { parents: 254, interior: X1(Parachain(42)) };
 		let prefix = MultiLocation { parents: 2, interior: Here };
 		assert_eq!(m.prepend_with(prefix.clone()), Err(prefix));
 
 		let prefix = MultiLocation { parents: 1, interior: Here };
 		assert_eq!(m.prepend_with(prefix), Ok(()));
-		assert_eq!(m, MultiLocation { parents: 254, interior: X1(Parachain(42)) });
+		assert_eq!(m, MultiLocation { parents: 255, interior: X1(Parachain(42)) });
 	}
 
 	#[test]

From cf1482047f8ff592a6ab728fc004ec0f827ffde2 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 02:15:46 -0700
Subject: [PATCH 131/166] Add deprecation note for iter_rev and into_iter_rev

---
 xcm/src/v1/multilocation.rs | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 37055550ea41..685a9430fe79 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -785,11 +785,13 @@ impl Junctions {
 	}
 
 	/// Returns a reference iterator over the junctions in reverse.
+	#[deprecated(note = "Please use iter().rev()")]
 	pub fn iter_rev(&self) -> impl Iterator + '_ {
 		self.iter().rev()
 	}
 
 	/// Consumes `self` and returns an iterator over the junctions in reverse.
+	#[deprecated(note = "Please use into_iter().rev()")]
 	pub fn into_iter_rev(self) -> impl Iterator {
 		self.into_iter().rev()
 	}

From a2839cf7c5cd1e01a3af94406b3360dd0516ca4f Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 02:23:01 -0700
Subject: [PATCH 132/166] Update some rustdocs

---
 xcm/src/v1/multilocation.rs | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 685a9430fe79..465d9a121303 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -60,13 +60,12 @@ impl Default for MultiLocation {
 }
 
 impl MultiLocation {
-	/// Creates a new `MultiLocation`, ensuring that the length of it does not exceed the maximum,
-	/// otherwise returns `Err`.
+	/// Creates a new `MultiLocation` with the given number of parents and interior junctions.
 	pub fn new(parents: u8, junctions: Junctions) -> MultiLocation {
 		MultiLocation { parents, interior: junctions }
 	}
 
-	/// Creates a new `MultiLocation` with 0 parents and a `Null` interior.
+	/// Creates a new `MultiLocation` with 0 parents and a `Here` interior.
 	///
 	/// The resulting `MultiLocation` can be interpreted as the "current consensus system".
 	pub const fn here() -> MultiLocation {
@@ -88,7 +87,7 @@ impl MultiLocation {
 		MultiLocation { parents, interior: Junctions::Here }
 	}
 
-	/// Whether or not the `MultiLocation` has no parents and has a `Null` interior.
+	/// Whether or not the `MultiLocation` has no parents and has a `Here` interior.
 	pub const fn is_here(&self) -> bool {
 		self.parents == 0 && self.interior.len() == 0
 	}

From 4970fff1072f980854660b63646eb028533003a6 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 02:24:38 -0700
Subject: [PATCH 133/166] cargo fmt

---
 xcm/xcm-builder/src/tests.rs                  | 28 ++++---------------
 xcm/xcm-executor/src/traits/transact_asset.rs | 26 +++--------------
 2 files changed, 9 insertions(+), 45 deletions(-)

diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 0a4b966c6acf..df778fe3559d 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -20,10 +20,7 @@ use xcm_executor::{traits::*, Config, XcmExecutor};
 
 #[test]
 fn basic_setup_works() {
-	add_reserve(
-		MultiLocation::parent(),
-		Wild((MultiLocation::parent(), WildFungible).into()),
-	);
+	add_reserve(MultiLocation::parent(), Wild((MultiLocation::parent(), WildFungible).into()));
 	assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
 		&(MultiLocation::parent(), 100).into(),
 		&MultiLocation::parent(),
@@ -57,11 +54,7 @@ fn weigher_should_work() {
 				orders: vec![],
 				instructions: vec![],
 			},
-			Order::DepositAsset {
-				assets: All.into(),
-				max_assets: 1,
-				beneficiary: Here.into(),
-			},
+			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here.into() },
 		],
 	}
 	.into();
@@ -155,11 +148,7 @@ fn allow_paid_should_work() {
 				orders: vec![],
 				instructions: vec![],
 			},
-			Order::DepositAsset {
-				assets: All.into(),
-				max_assets: 1,
-				beneficiary: Here.into(),
-			},
+			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here.into() },
 		],
 	};
 
@@ -184,11 +173,7 @@ fn allow_paid_should_work() {
 				orders: vec![],
 				instructions: vec![],
 			},
-			Order::DepositAsset {
-				assets: All.into(),
-				max_assets: 1,
-				beneficiary: Here.into(),
-			},
+			Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here.into() },
 		],
 	};
 
@@ -214,10 +199,7 @@ fn allow_paid_should_work() {
 #[test]
 fn paying_reserve_deposit_should_work() {
 	AllowPaidFrom::set(vec![MultiLocation::parent()]);
-	add_reserve(
-		MultiLocation::parent(),
-		(MultiLocation::parent(), WildFungible).into(),
-	);
+	add_reserve(MultiLocation::parent(), (MultiLocation::parent(), WildFungible).into());
 	WeightPrice::set((MultiLocation::parent().into(), 1_000_000_000_000));
 
 	let origin = MultiLocation::parent();
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index 9f7adda568b5..c7bac9d9bf09 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -272,10 +272,7 @@ mod tests {
 			(UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
 
 		assert_eq!(
-			MultiTransactor::deposit_asset(
-				&(Here.into(), 1).into(),
-				&Here.into()
-			),
+			MultiTransactor::deposit_asset(&(Here.into(), 1).into(), &Here.into()),
 			Err(XcmError::AssetNotFound)
 		);
 	}
@@ -284,13 +281,7 @@ mod tests {
 	fn unimplemented_and_not_found_continue_iteration() {
 		type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, SuccessfulTransactor);
 
-		assert_eq!(
-			MultiTransactor::deposit_asset(
-				&(Here.into(), 1).into(),
-				&Here.into()
-			),
-			Ok(()),
-		);
+		assert_eq!(MultiTransactor::deposit_asset(&(Here.into(), 1).into(), &Here.into()), Ok(()),);
 	}
 
 	#[test]
@@ -298,10 +289,7 @@ mod tests {
 		type MultiTransactor = (OverflowTransactor, SuccessfulTransactor);
 
 		assert_eq!(
-			MultiTransactor::deposit_asset(
-				&(Here.into(), 1).into(),
-				&Here.into()
-			),
+			MultiTransactor::deposit_asset(&(Here.into(), 1).into(), &Here.into()),
 			Err(XcmError::Overflow)
 		);
 	}
@@ -310,12 +298,6 @@ mod tests {
 	fn success_stops_iteration() {
 		type MultiTransactor = (SuccessfulTransactor, OverflowTransactor);
 
-		assert_eq!(
-			MultiTransactor::deposit_asset(
-				&(Here.into(), 1).into(),
-				&Here.into()
-			),
-			Ok(()),
-		);
+		assert_eq!(MultiTransactor::deposit_asset(&(Here.into(), 1).into(), &Here.into()), Ok(()),);
 	}
 }

From 9644979c0a5c353cd112caf61acb9c3eb90f4990 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 02:30:35 -0700
Subject: [PATCH 134/166] Fix xcm-executor unit tests

---
 xcm/xcm-executor/src/traits/transact_asset.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index c7bac9d9bf09..b46a5e9b8d5e 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -193,6 +193,7 @@ impl TransactAsset for Tuple {
 #[cfg(test)]
 mod tests {
 	use super::*;
+	use xcm::latest::Junctions::Here;
 
 	pub struct UnimplementedTransactor;
 	impl TransactAsset for UnimplementedTransactor {}

From a71cb28ce60da02fd3ed8a1b875cb282fe985511 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 02:57:21 -0700
Subject: [PATCH 135/166] Fix compilation and unit tests in xcm-builder

---
 xcm/xcm-builder/src/location_conversion.rs | 38 ++++++++++------------
 xcm/xcm-builder/src/mock.rs                |  6 ++--
 xcm/xcm-builder/src/origin_conversion.rs   | 14 ++++----
 xcm/xcm-builder/src/tests.rs               |  8 ++---
 4 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 7dde7acfe7ee..d1c129998210 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -19,7 +19,7 @@ use parity_scale_codec::Encode;
 use sp_io::hashing::blake2_256;
 use sp_runtime::traits::AccountIdConversion;
 use sp_std::{borrow::Borrow, marker::PhantomData};
-use xcm::latest::{Junction, Junctions, MultiLocation, NetworkId};
+use xcm::latest::{Junction::*, Junctions::*, MultiLocation, NetworkId};
 use xcm_executor::traits::{Convert, InvertLocation};
 
 pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
@@ -65,7 +65,7 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
 		let location = location.borrow();
 		match location.interior() {
-			Junctions::X1(Junction::Parachain(id)) if location.parent_count() == 0 =>
+			X1(Parachain(id)) if location.parent_count() == 0 =>
 				Ok(ParaId::from(*id).into_account()),
 			_ => Err(()),
 		}
@@ -73,7 +73,7 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if let Some(id) = ParaId::try_from_account(who.borrow()) {
-			Ok(Junction::Parachain(id.into()).into())
+			Ok(Parachain(id.into()).into())
 		} else {
 			Err(())
 		}
@@ -87,7 +87,7 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
 		let location = location.borrow();
 		match location.interior() {
-			Junctions::X1(Junction::Parachain(id)) if location.parent_count() == 1 =>
+			X1(Parachain(id)) if location.parent_count() == 1 =>
 				Ok(ParaId::from(*id).into_account()),
 			_ => Err(()),
 		}
@@ -95,8 +95,7 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if let Some(id) = ParaId::try_from_account(who.borrow()) {
-			Ok(MultiLocation::new(1, Junctions::X1(Junction::Parachain(id.into())))
-				.expect("well-formed MultiLocation; qed"))
+			Ok(MultiLocation::new(1, X1(Parachain(id.into()))))
 		} else {
 			Err(())
 		}
@@ -110,8 +109,8 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone
 {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
 		let id = match (location.parent_count(), location.interior()) {
-			(0, Junctions::X1(Junction::AccountId32 { id, network: NetworkId::Any })) => *id,
-			(0, Junctions::X1(Junction::AccountId32 { id, network }))
+			(0, X1(AccountId32 { id, network: NetworkId::Any })) => *id,
+			(0, X1(AccountId32 { id, network }))
 				if network == &Network::get() =>
 				*id,
 			_ => return Err(location),
@@ -120,7 +119,7 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone
 	}
 
 	fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
-		Ok(Junction::AccountId32 { id: who.into(), network: Network::get() }.into())
+		Ok(AccountId32 { id: who.into(), network: Network::get() }.into())
 	}
 }
 
@@ -130,8 +129,8 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
 {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
 		let key = match (location.parent_count(), location.interior()) {
-			(0, Junctions::X1(Junction::AccountKey20 { key, network: NetworkId::Any })) => *key,
-			(0, Junctions::X1(Junction::AccountKey20 { key, network }))
+			(0, X1(AccountKey20 { key, network: NetworkId::Any })) => *key,
+			(0, X1(AccountKey20 { key, network }))
 				if network == &Network::get() =>
 				*key,
 			_ => return Err(location),
@@ -140,7 +139,7 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
 	}
 
 	fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
-		let j = Junction::AccountKey20 { key: who.into(), network: Network::get() };
+		let j = AccountKey20 { key: who.into(), network: Network::get() };
 		Ok(j.into())
 	}
 }
@@ -169,27 +168,26 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
 ///     ).into();
 /// }
 ///
-/// let input = MultiLocation::new(2, X2(Parachain(2), AccountId32 { network: Any, id: Default::default() })).unwrap();
+/// let input = MultiLocation::new(2, X2(Parachain(2), AccountId32 { network: Any, id: Default::default() }));
 /// let inverted = LocationInverter::<Ancestry>::invert_location(&input);
 /// assert_eq!(inverted, MultiLocation::new(
 ///     2,
 ///     X2(Parachain(1), AccountKey20 { network: Any, key: Default::default() }),
-/// ).unwrap());
+/// ));
 /// # }
 /// ```
 pub struct LocationInverter<Ancestry>(PhantomData<Ancestry>);
 impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry> {
 	fn invert_location(location: &MultiLocation) -> MultiLocation {
 		let mut ancestry = Ancestry::get();
-		let mut junctions = Junctions::Here;
+		let mut junctions = Here;
 		for _ in 0..location.parent_count() {
 			junctions = junctions
-				.pushed_with(ancestry.take_first_interior().unwrap_or(Junction::OnlyChild))
+				.pushed_with(ancestry.take_first_interior().unwrap_or(OnlyChild))
 				.expect("ancestry is well-formed and has less than 8 non-parent junctions; qed");
 		}
 		let parents = location.interior().len() as u8;
 		MultiLocation::new(parents, junctions)
-			.expect("parents + junctions len must equal location len; qed")
 	}
 }
 
@@ -198,7 +196,7 @@ mod tests {
 	use super::*;
 
 	use frame_support::parameter_types;
-	use xcm::latest::{Junction::*, Junctions::*, MultiLocation, NetworkId::Any};
+	use xcm::latest::{Junction, NetworkId::Any};
 
 	fn account20() -> Junction {
 		AccountKey20 { network: Any, key: Default::default() }
@@ -226,11 +224,11 @@ mod tests {
 			pub Ancestry: MultiLocation = X3(Parachain(1), account20(), account20()).into();
 		}
 
-		let input = MultiLocation::new(3, X2(Parachain(2), account32())).unwrap();
+		let input = MultiLocation::new(3, X2(Parachain(2), account32()));
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
 		assert_eq!(
 			inverted,
-			MultiLocation::new(2, X3(Parachain(1), account20(), account20())).unwrap()
+			MultiLocation::new(2, X3(Parachain(1), account20(), account20()))
 		);
 	}
 
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index e290241fcf48..1a4c31fe199e 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -152,9 +152,9 @@ pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
 		// Children at 1000+id
 		X1(Parachain(id)) if l.parent_count() == 0 => 1000 + *id as u64,
 		// Self at 3000
-		Null if l.parent_count() == 0 => 3000,
+		Here if l.parent_count() == 0 => 3000,
 		// Parent at 3001
-		Null if l.parent_count() == 1 => 3001,
+		Here if l.parent_count() == 1 => 3001,
 		_ => return Err(l),
 	})
 }
@@ -171,7 +171,7 @@ impl ConvertOrigin<TestOrigin> for TestOriginConverter {
 			(SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)),
 			(Native, X1(Parachain(id))) if origin.parent_count() == 0 =>
 				Ok(TestOrigin::Parachain(*id)),
-			(Native, Null) if origin.parent_count() == 1 => Ok(TestOrigin::Relay),
+			(Native, Here) if origin.parent_count() == 1 => Ok(TestOrigin::Relay),
 			(Native, X1(AccountIndex64 { index, .. })) if origin.parent_count() == 0 =>
 				Ok(TestOrigin::Signed(*index)),
 			_ => Err(origin),
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index f4dfaf65a693..614e2ffd39c3 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -20,7 +20,7 @@ use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait};
 use frame_system::RawOrigin as SystemRawOrigin;
 use polkadot_parachain::primitives::IsSystem;
 use sp_std::{convert::TryInto, marker::PhantomData};
-use xcm::latest::{BodyId, BodyPart, Junction, Junctions, MultiLocation, NetworkId, OriginKind};
+use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, MultiLocation, NetworkId, OriginKind};
 use xcm_executor::traits::{Convert, ConvertOrigin};
 
 /// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
@@ -59,7 +59,7 @@ impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
 		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Superuser, 0, Junctions::X1(Junction::Parachain(id)))
+			(OriginKind::Superuser, 0, X1(Junction::Parachain(id)))
 				if ParaId::from(*id).is_system() =>
 				Ok(Origin::root()),
 			_ => Err(origin),
@@ -73,7 +73,7 @@ impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
 		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Superuser, 1, Junctions::X1(Junction::Parachain(id)))
+			(OriginKind::Superuser, 1, X1(Junction::Parachain(id)))
 				if ParaId::from(*id).is_system() =>
 				Ok(Origin::root()),
 			_ => Err(origin),
@@ -87,7 +87,7 @@ impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Or
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
 		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Native, 0, Junctions::X1(Junction::Parachain(id))) =>
+			(OriginKind::Native, 0, X1(Junction::Parachain(id))) =>
 				Ok(Origin::from(ParachainOrigin::from(*id))),
 			_ => Err(origin),
 		}
@@ -102,7 +102,7 @@ impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Or
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
 		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Native, 1, Junctions::X1(Junction::Parachain(id))) =>
+			(OriginKind::Native, 1, X1(Junction::Parachain(id))) =>
 				Ok(Origin::from(ParachainOrigin::from(*id))),
 			_ => Err(origin),
 		}
@@ -131,7 +131,7 @@ where
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
 		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Native, 0, Junctions::X1(Junction::AccountId32 { id, network }))
+			(OriginKind::Native, 0, X1(Junction::AccountId32 { id, network }))
 				if matches!(network, NetworkId::Any) || network == &Network::get() =>
 				Ok(Origin::signed((*id).into())),
 			_ => Err(origin),
@@ -147,7 +147,7 @@ where
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
 		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Native, 0, Junctions::X1(Junction::AccountKey20 { key, network }))
+			(OriginKind::Native, 0, X1(Junction::AccountKey20 { key, network }))
 				if (matches!(network, NetworkId::Any) || network == &Network::get()) =>
 				Ok(Origin::signed((*key).into())),
 			_ => Err(origin),
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index df778fe3559d..bf65fd9cf63a 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -28,14 +28,14 @@ fn basic_setup_works() {
 
 	assert_eq!(to_account(X1(Parachain(1)).into()), Ok(1001));
 	assert_eq!(to_account(X1(Parachain(50)).into()), Ok(1050));
-	assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(1))).unwrap()), Ok(2001));
-	assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(50))).unwrap()), Ok(2050));
+	assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(1)))), Ok(2001));
+	assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(50)))), Ok(2050));
 	assert_eq!(
-		to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 1, network: Any })).unwrap()),
+		to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 1, network: Any }))),
 		Ok(1),
 	);
 	assert_eq!(
-		to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 42, network: Any })).unwrap()),
+		to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 42, network: Any }))),
 		Ok(42),
 	);
 	assert_eq!(to_account(Here.into()), Ok(3000));

From 74d4db953ca72e6c271368921b584ff82058660a Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 03:05:52 -0700
Subject: [PATCH 136/166] cargo fmt

---
 xcm/xcm-builder/src/location_conversion.rs | 13 +++----------
 xcm/xcm-simulator/example/src/parachain.rs |  7 ++-----
 2 files changed, 5 insertions(+), 15 deletions(-)

diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index d1c129998210..cf7f87e238a4 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -110,9 +110,7 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
 		let id = match (location.parent_count(), location.interior()) {
 			(0, X1(AccountId32 { id, network: NetworkId::Any })) => *id,
-			(0, X1(AccountId32 { id, network }))
-				if network == &Network::get() =>
-				*id,
+			(0, X1(AccountId32 { id, network })) if network == &Network::get() => *id,
 			_ => return Err(location),
 		};
 		Ok(id.into())
@@ -130,9 +128,7 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
 		let key = match (location.parent_count(), location.interior()) {
 			(0, X1(AccountKey20 { key, network: NetworkId::Any })) => *key,
-			(0, X1(AccountKey20 { key, network }))
-				if network == &Network::get() =>
-				*key,
+			(0, X1(AccountKey20 { key, network })) if network == &Network::get() => *key,
 			_ => return Err(location),
 		};
 		Ok(key.into())
@@ -226,10 +222,7 @@ mod tests {
 
 		let input = MultiLocation::new(3, X2(Parachain(2), account32()));
 		let inverted = LocationInverter::<Ancestry>::invert_location(&input);
-		assert_eq!(
-			inverted,
-			MultiLocation::new(2, X3(Parachain(1), account20(), account20()))
-		);
+		assert_eq!(inverted, MultiLocation::new(2, X3(Parachain(1), account20(), account20())));
 	}
 
 	// Network Topology
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 2feb89fe499b..6380bebb6fee 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -266,11 +266,8 @@ pub mod mock_msg_queue {
 						Self::deposit_event(Event::UnsupportedVersion(id));
 					},
 					Ok(Ok(x)) => {
-						let outcome = T::XcmExecutor::execute_xcm(
-							MultiLocation::parent(),
-							x,
-							limit,
-						);
+						let outcome =
+							T::XcmExecutor::execute_xcm(MultiLocation::parent(), x, limit);
 						Self::deposit_event(Event::ExecutedDownward(id, outcome));
 					},
 				}

From b72f1272ab1dea4ee5d587b78cdaf0fde35bd78e Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 03:07:32 -0700
Subject: [PATCH 137/166] Fix tests in xcm-simulator-example

---
 xcm/xcm-simulator/example/src/lib.rs       | 2 +-
 xcm/xcm-simulator/example/src/parachain.rs | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index cbff1672a544..6e48ecc250bd 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -166,7 +166,7 @@ mod tests {
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
 				Here.into(),
-				MultiLocation::new(1, X1(Parachain(2))).unwrap(),
+				MultiLocation::new(1, X1(Parachain(2))),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 6380bebb6fee..7536a4ccc728 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -210,7 +210,7 @@ pub mod mock_msg_queue {
 			let hash = Encode::using_encoded(&xcm, T::Hashing::hash);
 			let (result, event) = match Xcm::<T::Call>::try_from(xcm) {
 				Ok(xcm) => {
-					let location = MultiLocation::new(1, X1(Parachain(sender.into()))).unwrap();
+					let location = MultiLocation::new(1, X1(Parachain(sender.into())));
 					match T::XcmExecutor::execute_xcm(location, xcm, max_weight) {
 						Outcome::Error(e) => (Err(e.clone()), Event::Fail(Some(hash), e)),
 						Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))),

From 1112e0e7a2430ad758e59b358aaa60313d879726 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 03:08:15 -0700
Subject: [PATCH 138/166] Publicize MultiLocation fields

---
 xcm/src/v1/multilocation.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 465d9a121303..ed56cf8afb1c 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -21,7 +21,7 @@ use core::{
 	convert::{TryFrom, TryInto},
 	mem, result,
 };
-use parity_scale_codec::{self, Decode, Encode};
+use parity_scale_codec::{Decode, Encode};
 
 /// A relative path between state-bearing consensus systems.
 ///
@@ -48,9 +48,9 @@ use parity_scale_codec::{self, Decode, Encode};
 #[derive(Clone, Decode, Encode, Eq, PartialEq, Ord, PartialOrd, Debug)]
 pub struct MultiLocation {
 	/// The number of parent junctions at the beginning of this `MultiLocation`.
-	pub(crate) parents: u8,
+	pub parents: u8,
 	/// The interior (i.e. non-parent) junctions that this `MultiLocation` contains.
-	pub(crate) interior: Junctions,
+	pub interior: Junctions,
 }
 
 impl Default for MultiLocation {

From b444e2354983728fbd2bb2de82fffbc24b273b72 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 04:16:37 -0700
Subject: [PATCH 139/166] Match on the MultiLocation struct directly in
 xcm-builder

---
 xcm/src/v1/junction.rs                     |  2 +-
 xcm/src/v1/multilocation.rs                |  7 +--
 xcm/xcm-builder/src/location_conversion.rs | 32 +++++++----
 xcm/xcm-builder/src/mock.rs                | 20 +++----
 xcm/xcm-builder/src/origin_conversion.rs   | 66 +++++++++++++---------
 5 files changed, 72 insertions(+), 55 deletions(-)

diff --git a/xcm/src/v1/junction.rs b/xcm/src/v1/junction.rs
index ff820610dab8..cbf9419e64d9 100644
--- a/xcm/src/v1/junction.rs
+++ b/xcm/src/v1/junction.rs
@@ -16,11 +16,11 @@
 
 //! Support data structures for `MultiLocation`, primarily the `Junction` datatype.
 
+use super::{Junctions, MultiLocation};
 use crate::v0::{BodyId as BodyId0, Junction as Junction0};
 use alloc::vec::Vec;
 use core::convert::TryFrom;
 use parity_scale_codec::{self, Decode, Encode};
-use super::{MultiLocation, Junctions};
 
 /// A global identifier of an account-bearing consensus system.
 #[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index ed56cf8afb1c..5c58ce8418e9 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -327,9 +327,8 @@ impl MultiLocation {
 
 		self.parents = self.parents.saturating_add(prefix.parents);
 		for j in prefix.interior.into_iter().rev() {
-			self.push_front_interior(j).expect(
-				"final_interior no greater than MAX_JUNCTIONS; qed"
-			);
+			self.push_front_interior(j)
+				.expect("final_interior no greater than MAX_JUNCTIONS; qed");
 		}
 		Ok(())
 	}
@@ -1135,7 +1134,7 @@ mod tests {
 		let acc = AccountIndex64 { network: Any, index: 23 };
 		let mut m = MultiLocation {
 			parents: 254,
-			interior: X5(Parachain(42), OnlyChild, OnlyChild, OnlyChild, OnlyChild)
+			interior: X5(Parachain(42), OnlyChild, OnlyChild, OnlyChild, OnlyChild),
 		};
 		let suffix = MultiLocation::from(X4(PalletInstance(3), acc.clone(), OnlyChild, OnlyChild));
 		assert_eq!(m.append_with(suffix.clone()), Err(suffix));
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index cf7f87e238a4..5f8363c1546f 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -63,9 +63,8 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
 	Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId>
 {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-		let location = location.borrow();
-		match location.interior() {
-			X1(Parachain(id)) if location.parent_count() == 0 =>
+		match location.borrow() {
+			MultiLocation { parents: 0, interior: X1(Parachain(id)) } =>
 				Ok(ParaId::from(*id).into_account()),
 			_ => Err(()),
 		}
@@ -85,9 +84,8 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
 	Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId>
 {
 	fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
-		let location = location.borrow();
-		match location.interior() {
-			X1(Parachain(id)) if location.parent_count() == 1 =>
+		match location.borrow() {
+			MultiLocation { parents: 1, interior: X1(Parachain(id)) } =>
 				Ok(ParaId::from(*id).into_account()),
 			_ => Err(()),
 		}
@@ -108,9 +106,14 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone
 	Convert<MultiLocation, AccountId> for AccountId32Aliases<Network, AccountId>
 {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
-		let id = match (location.parent_count(), location.interior()) {
-			(0, X1(AccountId32 { id, network: NetworkId::Any })) => *id,
-			(0, X1(AccountId32 { id, network })) if network == &Network::get() => *id,
+		let id = match location {
+			MultiLocation {
+				parents: 0,
+				interior: X1(AccountId32 { id, network: NetworkId::Any }),
+			} => id,
+			MultiLocation { parents: 0, interior: X1(AccountId32 { id, network }) }
+				if network == Network::get() =>
+				id,
 			_ => return Err(location),
 		};
 		Ok(id.into())
@@ -126,9 +129,14 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
 	Convert<MultiLocation, AccountId> for AccountKey20Aliases<Network, AccountId>
 {
 	fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
-		let key = match (location.parent_count(), location.interior()) {
-			(0, X1(AccountKey20 { key, network: NetworkId::Any })) => *key,
-			(0, X1(AccountKey20 { key, network })) if network == &Network::get() => *key,
+		let key = match location {
+			MultiLocation {
+				parents: 0,
+				interior: X1(AccountKey20 { key, network: NetworkId::Any }),
+			} => key,
+			MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network }) }
+				if network == Network::get() =>
+				key,
 			_ => return Err(location),
 		};
 		Ok(key.into())
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 1a4c31fe199e..1db39793619c 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -144,17 +144,17 @@ impl TransactAsset for TestAssetTransactor {
 }
 
 pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
-	Ok(match l.interior() {
+	Ok(match l {
 		// Siblings at 2000+id
-		X1(Parachain(id)) if l.parent_count() == 1 => 2000 + *id as u64,
+		MultiLocation { parents: 1, interior: X1(Parachain(id)) } => 2000 + id as u64,
 		// Accounts are their number
-		X1(AccountIndex64 { index, .. }) if l.parent_count() == 0 => *index,
+		MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) } => index,
 		// Children at 1000+id
-		X1(Parachain(id)) if l.parent_count() == 0 => 1000 + *id as u64,
+		MultiLocation { parents: 0, interior: X1(Parachain(id)) } => 1000 + id as u64,
 		// Self at 3000
-		Here if l.parent_count() == 0 => 3000,
+		MultiLocation { parents: 0, interior: Here } => 3000,
 		// Parent at 3001
-		Here if l.parent_count() == 1 => 3001,
+		MultiLocation { parents: 1, interior: Here } => 3001,
 		_ => return Err(l),
 	})
 }
@@ -166,13 +166,13 @@ impl ConvertOrigin<TestOrigin> for TestOriginConverter {
 		kind: OriginKind,
 	) -> Result<TestOrigin, MultiLocation> {
 		use OriginKind::*;
-		match (kind, origin.interior()) {
+		match (kind, origin) {
 			(Superuser, _) => Ok(TestOrigin::Root),
 			(SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)),
-			(Native, X1(Parachain(id))) if origin.parent_count() == 0 =>
+			(Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) =>
 				Ok(TestOrigin::Parachain(*id)),
-			(Native, Here) if origin.parent_count() == 1 => Ok(TestOrigin::Relay),
-			(Native, X1(AccountIndex64 { index, .. })) if origin.parent_count() == 0 =>
+			(Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay),
+			(Native, MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) }) =>
 				Ok(TestOrigin::Signed(*index)),
 			_ => Err(origin),
 		}
diff --git a/xcm/xcm-builder/src/origin_conversion.rs b/xcm/xcm-builder/src/origin_conversion.rs
index 614e2ffd39c3..b1800de2c6c8 100644
--- a/xcm/xcm-builder/src/origin_conversion.rs
+++ b/xcm/xcm-builder/src/origin_conversion.rs
@@ -58,11 +58,12 @@ impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
 	for ChildSystemParachainAsSuperuser<ParaId, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Superuser, 0, X1(Junction::Parachain(id)))
-				if ParaId::from(*id).is_system() =>
-				Ok(Origin::root()),
-			_ => Err(origin),
+		match (kind, origin) {
+			(
+				OriginKind::Superuser,
+				MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) },
+			) if ParaId::from(id).is_system() => Ok(Origin::root()),
+			(_, origin) => Err(origin),
 		}
 	}
 }
@@ -72,11 +73,12 @@ impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
 	for SiblingSystemParachainAsSuperuser<ParaId, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Superuser, 1, X1(Junction::Parachain(id)))
-				if ParaId::from(*id).is_system() =>
-				Ok(Origin::root()),
-			_ => Err(origin),
+		match (kind, origin) {
+			(
+				OriginKind::Superuser,
+				MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) },
+			) if ParaId::from(id).is_system() => Ok(Origin::root()),
+			(_, origin) => Err(origin),
 		}
 	}
 }
@@ -86,10 +88,12 @@ impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Or
 	for ChildParachainAsNative<ParachainOrigin, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Native, 0, X1(Junction::Parachain(id))) =>
-				Ok(Origin::from(ParachainOrigin::from(*id))),
-			_ => Err(origin),
+		match (kind, origin) {
+			(
+				OriginKind::Native,
+				MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) },
+			) => Ok(Origin::from(ParachainOrigin::from(id))),
+			(_, origin) => Err(origin),
 		}
 	}
 }
@@ -101,10 +105,12 @@ impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Or
 	for SiblingParachainAsNative<ParachainOrigin, Origin>
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Native, 1, X1(Junction::Parachain(id))) =>
-				Ok(Origin::from(ParachainOrigin::from(*id))),
-			_ => Err(origin),
+		match (kind, origin) {
+			(
+				OriginKind::Native,
+				MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) },
+			) => Ok(Origin::from(ParachainOrigin::from(id))),
+			(_, origin) => Err(origin),
 		}
 	}
 }
@@ -130,11 +136,13 @@ where
 	Origin::AccountId: From<[u8; 32]>,
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Native, 0, X1(Junction::AccountId32 { id, network }))
-				if matches!(network, NetworkId::Any) || network == &Network::get() =>
-				Ok(Origin::signed((*id).into())),
-			_ => Err(origin),
+		match (kind, origin) {
+			(
+				OriginKind::Native,
+				MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, network }) },
+			) if matches!(network, NetworkId::Any) || network == Network::get() =>
+				Ok(Origin::signed(id.into())),
+			(_, origin) => Err(origin),
 		}
 	}
 }
@@ -146,11 +154,13 @@ where
 	Origin::AccountId: From<[u8; 20]>,
 {
 	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
-		match (kind, origin.parent_count(), origin.interior()) {
-			(OriginKind::Native, 0, X1(Junction::AccountKey20 { key, network }))
-				if (matches!(network, NetworkId::Any) || network == &Network::get()) =>
-				Ok(Origin::signed((*key).into())),
-			_ => Err(origin),
+		match (kind, origin) {
+			(
+				OriginKind::Native,
+				MultiLocation { parents: 0, interior: X1(Junction::AccountKey20 { key, network }) },
+			) if (matches!(network, NetworkId::Any) || network == Network::get()) =>
+				Ok(Origin::signed(key.into())),
+			(_, origin) => Err(origin),
 		}
 	}
 }

From cdbaccc0a4739b5daad94589925631b969f5b0a0 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 04:34:18 -0700
Subject: [PATCH 140/166] Do not dereference undereferenceable types

---
 xcm/xcm-builder/src/mock.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 1db39793619c..47150685f851 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -170,10 +170,10 @@ impl ConvertOrigin<TestOrigin> for TestOriginConverter {
 			(Superuser, _) => Ok(TestOrigin::Root),
 			(SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)),
 			(Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) =>
-				Ok(TestOrigin::Parachain(*id)),
+				Ok(TestOrigin::Parachain(id)),
 			(Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay),
 			(Native, MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) }) =>
-				Ok(TestOrigin::Signed(*index)),
+				Ok(TestOrigin::Signed(index)),
 			_ => Err(origin),
 		}
 	}

From 18a82ecde21c855ae87c7a3f5e839e5ccb2cc041 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 04:55:31 -0700
Subject: [PATCH 141/166] Add convenience MultiLocation conversions for tuples

---
 xcm/src/v1/multilocation.rs | 91 +++++++++++++++++++++++++++++++++++++
 1 file changed, 91 insertions(+)

diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 5c58ce8418e9..4d9cb0d2d4b8 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -340,6 +340,12 @@ impl From<Junctions> for MultiLocation {
 	}
 }
 
+impl From<(u8, Junctions)> for MultiLocation {
+	fn from((parents, interior): (u8, Junctions)) -> Self {
+		MultiLocation { parents, interior }
+	}
+}
+
 impl From<Junction> for MultiLocation {
 	fn from(x: Junction) -> Self {
 		MultiLocation { parents: 0, interior: Junctions::X1(x) }
@@ -401,6 +407,91 @@ impl From<(Junction, Junction, Junction, Junction, Junction, Junction, Junction,
 	}
 }
 
+impl From<(u8,)> for MultiLocation {
+	fn from((parents,): (u8,)) -> Self {
+		MultiLocation { parents, interior: Junctions::Here }
+	}
+}
+impl From<(u8, Junction)> for MultiLocation {
+	fn from((parents, j0): (u8, Junction)) -> Self {
+		MultiLocation { parents, interior: Junctions::X1(j0) }
+	}
+}
+impl From<(u8, Junction, Junction)> for MultiLocation {
+	fn from((parents, j0, j1): (u8, Junction, Junction)) -> Self {
+		MultiLocation { parents, interior: Junctions::X2(j0, j1) }
+	}
+}
+impl From<(u8, Junction, Junction, Junction)> for MultiLocation {
+	fn from((parents, j0, j1, j2): (u8, Junction, Junction, Junction)) -> Self {
+		MultiLocation { parents, interior: Junctions::X3(j0, j1, j2) }
+	}
+}
+impl From<(u8, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from((parents, j0, j1, j2, j3): (u8, Junction, Junction, Junction, Junction)) -> Self {
+		MultiLocation { parents, interior: Junctions::X4(j0, j1, j2, j3) }
+	}
+}
+impl From<(u8, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(
+		(parents, j0, j1, j2, j3, j4): (u8, Junction, Junction, Junction, Junction, Junction),
+	) -> Self {
+		MultiLocation { parents, interior: Junctions::X5(j0, j1, j2, j3, j4) }
+	}
+}
+impl From<(u8, Junction, Junction, Junction, Junction, Junction, Junction)> for MultiLocation {
+	fn from(
+		(parents, j0, j1, j2, j3, j4, j5): (
+			u8,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+		),
+	) -> Self {
+		MultiLocation { parents, interior: Junctions::X6(j0, j1, j2, j3, j4, j5) }
+	}
+}
+impl From<(u8, Junction, Junction, Junction, Junction, Junction, Junction, Junction)>
+	for MultiLocation
+{
+	fn from(
+		(parents, j0, j1, j2, j3, j4, j5, j6): (
+			u8,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+		),
+	) -> Self {
+		MultiLocation { parents, interior: Junctions::X7(j0, j1, j2, j3, j4, j5, j6) }
+	}
+}
+impl From<(u8, Junction, Junction, Junction, Junction, Junction, Junction, Junction, Junction)>
+	for MultiLocation
+{
+	fn from(
+		(parents, j0, j1, j2, j3, j4, j5, j6, j7): (
+			u8,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+			Junction,
+		),
+	) -> Self {
+		MultiLocation { parents, interior: Junctions::X8(j0, j1, j2, j3, j4, j5, j6, j7) }
+	}
+}
+
 impl From<[Junction; 0]> for MultiLocation {
 	fn from(_: [Junction; 0]) -> Self {
 		MultiLocation { parents: 0, interior: Junctions::Here }

From d82fb6bf4f1a19f86bc4c000ab579ac5a94f65a5 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 05:10:58 -0700
Subject: [PATCH 142/166] Use clearer import paths

---
 xcm/src/v0/multi_location.rs | 4 ++--
 xcm/src/v1/multilocation.rs  | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/xcm/src/v0/multi_location.rs b/xcm/src/v0/multi_location.rs
index 9e9514539621..2aa296a0de9c 100644
--- a/xcm/src/v0/multi_location.rs
+++ b/xcm/src/v0/multi_location.rs
@@ -16,9 +16,9 @@
 
 //! Cross-Consensus Message format data structures.
 
+use super::Junction;
+use crate::v1::MultiLocation as MultiLocation1;
 use core::{convert::TryFrom, mem, result};
-
-use super::{super::v1::MultiLocation as MultiLocation1, Junction};
 use parity_scale_codec::{self, Decode, Encode};
 
 /// A relative path between state-bearing consensus systems.
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index 4d9cb0d2d4b8..e333e70e494e 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -16,7 +16,8 @@
 
 //! Cross-Consensus Message format data structures.
 
-use super::{super::v0::MultiLocation as MultiLocation0, Junction};
+use super::Junction;
+use crate::v0::MultiLocation as MultiLocation0;
 use core::{
 	convert::{TryFrom, TryInto},
 	mem, result,

From 2281325a580dc7bb00af1392d4f16d03a6ee59b9 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 05:11:51 -0700
Subject: [PATCH 143/166] Remove unused dependency

---
 Cargo.lock     | 1 -
 xcm/Cargo.toml | 1 -
 2 files changed, 2 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock
index f9a7c97a4ac8..83554af1c532 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -12267,7 +12267,6 @@ dependencies = [
  "impl-trait-for-tuples",
  "log",
  "parity-scale-codec",
- "static_assertions",
 ]
 
 [[package]]
diff --git a/xcm/Cargo.toml b/xcm/Cargo.toml
index 67865f32f929..a1bfa76130a7 100644
--- a/xcm/Cargo.toml
+++ b/xcm/Cargo.toml
@@ -10,7 +10,6 @@ impl-trait-for-tuples = "0.2.0"
 parity-scale-codec = { version = "2.0.0", default-features = false, features = [ "derive" ] }
 derivative = {version = "2.2.0", default-features = false, features = [ "use_core" ] }
 log = { version = "0.4.14", default-features = false }
-static_assertions = "1.1.0"
 
 [features]
 default = ["std"]

From fe78be8bbd5880c0ce6c6308dc33c9cc97572a6c Mon Sep 17 00:00:00 2001
From: Shawn Tabrizi <shawntabrizi@gmail.com>
Date: Sun, 8 Aug 2021 14:36:37 +0200
Subject: [PATCH 144/166] fix junction + response

---
 xcm/src/{v1 => v0}/junction.rs |  0
 xcm/src/v0/mod.rs              | 48 +++++++++++++++++++++++++++++++---
 xcm/src/v1/mod.rs              | 44 ++++++++++---------------------
 3 files changed, 59 insertions(+), 33 deletions(-)
 rename xcm/src/{v1 => v0}/junction.rs (100%)

diff --git a/xcm/src/v1/junction.rs b/xcm/src/v0/junction.rs
similarity index 100%
rename from xcm/src/v1/junction.rs
rename to xcm/src/v0/junction.rs
diff --git a/xcm/src/v0/mod.rs b/xcm/src/v0/mod.rs
index ad2f70e31cf5..626353abf275 100644
--- a/xcm/src/v0/mod.rs
+++ b/xcm/src/v0/mod.rs
@@ -25,11 +25,13 @@ use core::{
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
+mod junction;
 mod multi_asset;
 mod multi_location;
 mod order;
 mod traits;
-use super::v1::Xcm as Xcm1;
+use super::v1::{Response as Response1, Xcm as Xcm1};
+pub use junction::{BodyId, BodyPart, Junction, NetworkId};
 pub use multi_asset::{AssetInstance, MultiAsset};
 pub use multi_location::MultiLocation;
 pub use order::Order;
@@ -52,7 +54,38 @@ pub mod prelude {
 	};
 }
 
-pub use super::v1::{BodyId, BodyPart, Junction, NetworkId, OriginKind, Response};
+// TODO: #2841 #XCMENCODE Efficient encodings for MultiAssets, Vec<Order>, using initial byte values 128+ to encode
+//   the number of items in the vector.
+
+/// Basically just the XCM (more general) version of `ParachainDispatchOrigin`.
+#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug)]
+pub enum OriginKind {
+	/// Origin should just be the native dispatch origin representation for the sender in the
+	/// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin
+	/// if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a
+	/// primary/native dispatch origin form.
+	Native,
+
+	/// Origin should just be the standard account-based origin with the sovereign account of
+	/// the sender. For Cumulus/Frame chains, this is the `Signed` origin.
+	SovereignAccount,
+
+	/// Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin.
+	/// This will not usually be an available option.
+	Superuser,
+
+	/// Origin should be interpreted as an XCM native origin and the `MultiLocation` should be
+	/// encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be
+	/// the `pallet_xcm::Origin::Xcm` type.
+	Xcm,
+}
+
+/// Response data to a query.
+#[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
+pub enum Response {
+	/// Some assets.
+	Assets(Vec<MultiAsset>),
+}
 
 /// Cross-Consensus Message: A message from one consensus system to another.
 ///
@@ -287,6 +320,15 @@ pub mod opaque {
 	pub use super::order::opaque::*;
 }
 
+// Convert from a v1 response to a v0 response
+impl From<Response1> for Response {
+	fn from(new_response: Response1) -> Self {
+		match new_response {
+			Response1::Assets(assets) => Self::Assets(assets.into()),
+		}
+	}
+}
+
 impl<Call> TryFrom<Xcm1<Call>> for Xcm<Call> {
 	type Error = ();
 	fn try_from(x: Xcm1<Call>) -> result::Result<Xcm<Call>, ()> {
@@ -314,7 +356,7 @@ impl<Call> TryFrom<Xcm1<Call>> for Xcm<Call> {
 					.collect::<result::Result<_, _>>()?,
 			},
 			Xcm1::QueryResponse { query_id: u64, response } =>
-				QueryResponse { query_id: u64, response },
+				QueryResponse { query_id: u64, response: response.into() },
 			Xcm1::TransferAsset { assets, beneficiary } =>
 				TransferAsset { assets: assets.into(), dest: beneficiary.into() },
 			Xcm1::TransferReserveAsset { assets, dest, effects } => TransferReserveAsset {
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index 6b7b4d4f2aea..2933c03cdfe9 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -16,7 +16,7 @@
 
 //! Version 1 of the Cross-Consensus Message format data structures.
 
-use super::v0::Xcm as Xcm0;
+use super::v0::{Response as Response0, Xcm as Xcm0};
 use crate::DoubleEncoded;
 use alloc::vec::Vec;
 use core::{
@@ -27,13 +27,11 @@ use core::{
 use derivative::Derivative;
 use parity_scale_codec::{self, Decode, Encode};
 
-mod junction;
 pub mod multiasset;
 mod multilocation;
 mod order;
 mod traits; // the new multiasset.
 
-pub use junction::{BodyId, BodyPart, Junction, NetworkId};
 pub use multiasset::{
 	AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
 	WildFungibility, WildMultiAsset,
@@ -45,7 +43,7 @@ pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
 	pub use super::{
-		junction::{
+		super::v0::{
 			BodyId, BodyPart,
 			Junction::*,
 			NetworkId::{self, *},
@@ -69,31 +67,7 @@ pub mod prelude {
 	};
 }
 
-// TODO: #2841 #XCMENCODE Efficient encodings for MultiAssets, Vec<Order>, using initial byte values 128+ to encode
-//   the number of items in the vector.
-
-/// Basically just the XCM (more general) version of `ParachainDispatchOrigin`.
-#[derive(Copy, Clone, Eq, PartialEq, Encode, Decode, Debug)]
-pub enum OriginKind {
-	/// Origin should just be the native dispatch origin representation for the sender in the
-	/// local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin
-	/// if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a
-	/// primary/native dispatch origin form.
-	Native,
-
-	/// Origin should just be the standard account-based origin with the sovereign account of
-	/// the sender. For Cumulus/Frame chains, this is the `Signed` origin.
-	SovereignAccount,
-
-	/// Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin.
-	/// This will not usually be an available option.
-	Superuser,
-
-	/// Origin should be interpreted as an XCM native origin and the `MultiLocation` should be
-	/// encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be
-	/// the `pallet_xcm::Origin::Xcm` type.
-	Xcm,
-}
+pub use super::v0::{BodyId, BodyPart, Junction, NetworkId, OriginKind};
 
 /// Response data to a query.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
@@ -338,6 +312,16 @@ pub mod opaque {
 	pub use super::order::opaque::*;
 }
 
+// Convert from a v0 response to a v1 response
+impl TryFrom<Response0> for Response {
+	type Error = ();
+	fn try_from(old_response: Response0) -> result::Result<Self, ()> {
+		match old_response {
+			Response0::Assets(assets) => Ok(Self::Assets(assets.try_into()?)),
+		}
+	}
+}
+
 impl<Call> TryFrom<Xcm0<Call>> for Xcm<Call> {
 	type Error = ();
 	fn try_from(old: Xcm0<Call>) -> result::Result<Xcm<Call>, ()> {
@@ -365,7 +349,7 @@ impl<Call> TryFrom<Xcm0<Call>> for Xcm<Call> {
 					.collect::<result::Result<_, _>>()?,
 			},
 			Xcm0::QueryResponse { query_id: u64, response } =>
-				QueryResponse { query_id: u64, response },
+				QueryResponse { query_id: u64, response: response.try_into()? },
 			Xcm0::TransferAsset { assets, dest } =>
 				TransferAsset { assets: assets.try_into()?, beneficiary: dest.into() },
 			Xcm0::TransferReserveAsset { assets, dest, effects } => TransferReserveAsset {

From 5d581055818a77c0a8cf851a53313d71765a880e Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 06:19:39 -0700
Subject: [PATCH 145/166] Import from latest opaque xcm module

---
 runtime/common/src/xcm_sender.rs | 14 +++++---------
 xcm/xcm-builder/src/mock.rs      |  2 +-
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/runtime/common/src/xcm_sender.rs b/runtime/common/src/xcm_sender.rs
index aa190296904f..602f45bbadf6 100644
--- a/runtime/common/src/xcm_sender.rs
+++ b/runtime/common/src/xcm_sender.rs
@@ -19,7 +19,7 @@
 use parity_scale_codec::Encode;
 use runtime_parachains::{configuration, dmp};
 use sp_std::marker::PhantomData;
-use xcm::opaque::v1::{Error, Junction, Junctions, MultiLocation, Result, SendXcm, Xcm};
+use xcm::opaque::latest::*;
 
 /// XCM sender for relay chain. It only sends downward message.
 pub struct ChildParachainRouter<T, W>(PhantomData<(T, W)>);
@@ -28,25 +28,21 @@ impl<T: configuration::Config + dmp::Config, W: xcm::WrapVersion> SendXcm
 	for ChildParachainRouter<T, W>
 {
 	fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {
-		if dest.parent_count() > 0 {
-			return Err(Error::CannotReachDestination(dest, msg))
-		}
-
-		match dest.interior() {
-			Junctions::X1(Junction::Parachain(id)) => {
+		match dest {
+			MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } => {
 				// Downward message passing.
 				let versioned_xcm =
 					W::wrap_version(&dest, msg).map_err(|()| Error::DestinationUnsupported)?;
 				let config = <configuration::Pallet<T>>::config();
 				<dmp::Pallet<T>>::queue_downward_message(
 					&config,
-					(*id).into(),
+					id.into(),
 					versioned_xcm.encode(),
 				)
 				.map_err(Into::<Error>::into)?;
 				Ok(())
 			},
-			_ => Err(Error::CannotReachDestination(dest, msg)),
+			dest => Err(Error::CannotReachDestination(dest, msg)),
 		}
 	}
 }
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 47150685f851..f7ebbc8a1cd8 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -168,7 +168,7 @@ impl ConvertOrigin<TestOrigin> for TestOriginConverter {
 		use OriginKind::*;
 		match (kind, origin) {
 			(Superuser, _) => Ok(TestOrigin::Root),
-			(SovereignAccount, _) => Ok(TestOrigin::Signed(to_account(origin)?)),
+			(SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)),
 			(Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) =>
 				Ok(TestOrigin::Parachain(id)),
 			(Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay),

From 1ab9719f0ce063fce55d4a8b283adc429a833ef4 Mon Sep 17 00:00:00 2001
From: Shawn Tabrizi <shawntabrizi@gmail.com>
Date: Sun, 8 Aug 2021 16:13:45 +0200
Subject: [PATCH 146/166] Update xcm/src/v1/mod.rs

---
 xcm/src/v1/mod.rs | 1 +
 1 file changed, 1 insertion(+)

diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index 2933c03cdfe9..a8921ce1dd35 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -43,6 +43,7 @@ pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
 	pub use super::{
+		// These parts of XCM v0 have been unchanged in XCM v1
 		super::v0::{
 			BodyId, BodyPart,
 			Junction::*,

From 7d6dabac7b0ab3f2865836aeaeff9992dc15e637 Mon Sep 17 00:00:00 2001
From: Shawn Tabrizi <shawntabrizi@gmail.com>
Date: Sun, 8 Aug 2021 16:15:53 +0200
Subject: [PATCH 147/166] better comment

---
 xcm/src/v1/mod.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index a8921ce1dd35..94bdef024af9 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -40,10 +40,12 @@ pub use multilocation::MultiLocation;
 pub use order::Order;
 pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 
+// These parts of XCM v0 have been unchanged in XCM v1, and are re-imported here.
+pub use super::v0::{BodyId, BodyPart, Junction, NetworkId, OriginKind};
+
 /// A prelude for importing all types typically used when interacting with XCM messages.
 pub mod prelude {
 	pub use super::{
-		// These parts of XCM v0 have been unchanged in XCM v1
 		super::v0::{
 			BodyId, BodyPart,
 			Junction::*,
@@ -68,8 +70,6 @@ pub mod prelude {
 	};
 }
 
-pub use super::v0::{BodyId, BodyPart, Junction, NetworkId, OriginKind};
-
 /// Response data to a query.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Debug)]
 pub enum Response {

From dbc412b4328d768e1fa2121dd92d082ae7bc2c24 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 07:37:32 -0700
Subject: [PATCH 148/166] Fix ownership transfer

---
 xcm/xcm-builder/src/mock.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index f7ebbc8a1cd8..2e6237e7528a 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -174,7 +174,7 @@ impl ConvertOrigin<TestOrigin> for TestOriginConverter {
 			(Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay),
 			(Native, MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) }) =>
 				Ok(TestOrigin::Signed(index)),
-			_ => Err(origin),
+			(_, origin) => Err(origin),
 		}
 	}
 }

From 7727c4b09d235dfe0c68d7342404ccf0ddeefa32 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 07:56:48 -0700
Subject: [PATCH 149/166] Fix merge

---
 runtime/test-runtime/src/xcm_config.rs | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index a87e8730c746..0ebb555a5a0c 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -16,8 +16,8 @@
 
 use frame_support::{parameter_types, traits::Everything, weights::Weight};
 use xcm::latest::{
-	Error as XcmError, Junction::*, MultiAsset, MultiLocation, MultiLocation::*, NetworkId,
-	Result as XcmResult, SendXcm, Xcm,
+	Error as XcmError, Junction::*, MultiAsset, MultiLocation, NetworkId, Result as XcmResult,
+	SendXcm, Xcm,
 };
 use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
 use xcm_executor::{
@@ -52,7 +52,7 @@ impl TransactAsset for DummyAssetTransactor {
 	}
 
 	fn withdraw_asset(_what: &MultiAsset, _who: &MultiLocation) -> Result<Assets, XcmError> {
-		let asset: MultiAsset = (X1(Parent), 100_000).into();
+		let asset: MultiAsset = (MultiLocation::parent(), 100_000).into();
 		Ok(asset.into())
 	}
 }

From e6a2160bc201359fa28eaade25ad01b8d557500c Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 08:47:10 -0700
Subject: [PATCH 150/166] Fix merge

---
 runtime/test-runtime/src/xcm_config.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index 0ebb555a5a0c..ae89d96e6d76 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -16,7 +16,7 @@
 
 use frame_support::{parameter_types, traits::Everything, weights::Weight};
 use xcm::latest::{
-	Error as XcmError, Junction::*, MultiAsset, MultiLocation, NetworkId, Result as XcmResult,
+	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult,
 	SendXcm, Xcm,
 };
 use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
@@ -71,7 +71,7 @@ impl WeightTrader for DummyWeightTrader {
 pub struct InvertNothing;
 impl InvertLocation for InvertNothing {
 	fn invert_location(_: &MultiLocation) -> MultiLocation {
-		MultiLocation::Here
+		MultiLocation::here()
 	}
 }
 

From aa4933398444aea4b05a3695c97b410242b06e3f Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 08:57:30 -0700
Subject: [PATCH 151/166] cargo fmt

---
 runtime/test-runtime/src/xcm_config.rs | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index ae89d96e6d76..b9ea1318ae0f 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -16,8 +16,7 @@
 
 use frame_support::{parameter_types, traits::Everything, weights::Weight};
 use xcm::latest::{
-	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult,
-	SendXcm, Xcm,
+	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult, SendXcm, Xcm,
 };
 use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
 use xcm_executor::{

From c3c000530fa00c3774011341599241265aa5bd7d Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 09:42:31 -0700
Subject: [PATCH 152/166] Fix merge

---
 xcm/src/v1/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index 2f4f125e7887..bf9b4c890f87 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -50,9 +50,9 @@ pub mod prelude {
 	pub use super::{
 		super::v0::{
 			BodyId, BodyPart,
-			Junction::*,
 			NetworkId::{self, *},
 		},
+		junction::Junction::*,
 		multiasset::{
 			AssetId::{self, *},
 			AssetInstance::{self, *},

From 15f83c326652349cece9061f25753416afd2560f Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 09:43:32 -0700
Subject: [PATCH 153/166] Fix merge

---
 xcm/src/v1/mod.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index bf9b4c890f87..da616896b8dc 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -52,7 +52,7 @@ pub mod prelude {
 			BodyId, BodyPart,
 			NetworkId::{self, *},
 		},
-		junction::Junction::*,
+		junction::Junction::{self, *},
 		multiasset::{
 			AssetId::{self, *},
 			AssetInstance::{self, *},

From d73fd905d98a2f022dd6b784a5041694ff0b256b Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Sun, 8 Aug 2021 10:09:09 -0700
Subject: [PATCH 154/166] Fix integration test

---
 xcm/xcm-executor/integration-tests/src/lib.rs | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/xcm/xcm-executor/integration-tests/src/lib.rs b/xcm/xcm-executor/integration-tests/src/lib.rs
index 209b44b8981e..c1b2b6b31072 100644
--- a/xcm/xcm-executor/integration-tests/src/lib.rs
+++ b/xcm/xcm-executor/integration-tests/src/lib.rs
@@ -24,7 +24,7 @@ use polkadot_test_client::{
 use polkadot_test_service::construct_extrinsic;
 use sp_runtime::{generic::BlockId, traits::Block};
 use sp_state_machine::InspectState;
-use xcm::latest::{Error as XcmError, Junction::*, MultiLocation::*, Order, Outcome, Xcm::*};
+use xcm::latest::{Error as XcmError, MultiLocation, Order, Outcome, Xcm::*};
 use xcm_executor::MAX_RECURSION_LIMIT;
 
 // This is the inflection point where the test should either fail or pass.
@@ -37,12 +37,12 @@ fn execute_within_recursion_limit() {
 		.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
 		.build();
 
-	let mut msg = WithdrawAsset { assets: (X1(Parent), 100).into(), effects: vec![] };
+	let mut msg = WithdrawAsset { assets: (MultiLocation::parent(), 100).into(), effects: vec![] };
 	for _ in 0..MAX_RECURSION_CHECK {
 		msg = WithdrawAsset {
-			assets: (X1(Parent), 100).into(),
+			assets: (MultiLocation::parent(), 100).into(),
 			effects: vec![Order::BuyExecution {
-				fees: (X1(Parent), 1).into(),
+				fees: (MultiLocation::parent(), 1).into(),
 				weight: 0,
 				debt: 0,
 				halt_on_error: true,
@@ -92,12 +92,12 @@ fn exceed_recursion_limit() {
 		.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
 		.build();
 
-	let mut msg = WithdrawAsset { assets: (X1(Parent), 100).into(), effects: vec![] };
+	let mut msg = WithdrawAsset { assets: (MultiLocation::parent(), 100).into(), effects: vec![] };
 	for _ in 0..(MAX_RECURSION_CHECK + 1) {
 		msg = WithdrawAsset {
-			assets: (X1(Parent), 100).into(),
+			assets: (MultiLocation::parent(), 100).into(),
 			effects: vec![Order::BuyExecution {
-				fees: (X1(Parent), 1).into(),
+				fees: (MultiLocation::parent(), 1).into(),
 				weight: 0,
 				debt: 0,
 				halt_on_error: true,

From 1a1708c78c0ffa42c3c5900d50ee91d1e6d59b36 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:03:12 +0200
Subject: [PATCH 155/166] More readable Parent syntax

---
 runtime/test-runtime/src/xcm_config.rs        |  4 +-
 xcm/pallet-xcm/src/tests.rs                   | 12 +--
 xcm/src/v1/mod.rs                             |  4 +-
 xcm/src/v1/multiasset.rs                      | 14 +---
 xcm/src/v1/multilocation.rs                   | 34 +++++++-
 xcm/src/v1/traits.rs                          |  2 +-
 xcm/xcm-builder/src/currency_adapter.rs       |  2 +-
 xcm/xcm-builder/src/location_conversion.rs    |  4 +-
 xcm/xcm-builder/src/matches_fungible.rs       |  4 +-
 xcm/xcm-builder/src/mock.rs                   |  2 +-
 xcm/xcm-builder/src/tests.rs                  | 80 +++++++++----------
 xcm/xcm-executor/integration-tests/src/lib.rs | 14 ++--
 xcm/xcm-simulator/example/src/lib.rs          |  2 +-
 xcm/xcm-simulator/example/src/parachain.rs    |  4 +-
 14 files changed, 104 insertions(+), 78 deletions(-)

diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index b9ea1318ae0f..8466d49445f8 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -16,7 +16,7 @@
 
 use frame_support::{parameter_types, traits::Everything, weights::Weight};
 use xcm::latest::{
-	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult, SendXcm, Xcm,
+	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult, SendXcm, Xcm, Parent,
 };
 use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
 use xcm_executor::{
@@ -51,7 +51,7 @@ impl TransactAsset for DummyAssetTransactor {
 	}
 
 	fn withdraw_asset(_what: &MultiAsset, _who: &MultiLocation) -> Result<Assets, XcmError> {
-		let asset: MultiAsset = (MultiLocation::parent(), 100_000).into();
+		let asset: MultiAsset = (Parent, 100_000).into();
 		Ok(asset.into())
 	}
 }
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 5bd3eb69f5ff..2d8ef67c0e00 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -40,9 +40,9 @@ fn send_works() {
 		let sender: MultiLocation =
 			AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (MultiLocation::parent(), SEND_AMOUNT).into(),
+			assets: (Parent, SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((MultiLocation::parent(), SEND_AMOUNT), weight),
+				buy_execution((Parent, SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -78,9 +78,9 @@ fn send_fails_when_xcm_router_blocks() {
 		let sender: MultiLocation =
 			Junction::AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
 		let message = Xcm::ReserveAssetDeposited {
-			assets: (MultiLocation::parent(), SEND_AMOUNT).into(),
+			assets: (Parent, SEND_AMOUNT).into(),
 			effects: vec![
-				buy_execution((MultiLocation::parent(), SEND_AMOUNT), weight),
+				buy_execution((Parent, SEND_AMOUNT), weight),
 				DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
 			],
 		};
@@ -153,9 +153,9 @@ fn reserve_transfer_assets_works() {
 			vec![(
 				Parachain(PARA_ID).into(),
 				Xcm::ReserveAssetDeposited {
-					assets: (MultiLocation::parent(), SEND_AMOUNT).into(),
+					assets: (Parent, SEND_AMOUNT).into(),
 					effects: vec![
-						buy_execution((MultiLocation::parent(), SEND_AMOUNT), weight),
+						buy_execution((Parent, SEND_AMOUNT), weight),
 						DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
 					]
 				}
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index da616896b8dc..ad2fa40a9123 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -38,7 +38,7 @@ pub use multiasset::{
 	AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
 	WildFungibility, WildMultiAsset,
 };
-pub use multilocation::{Junctions, MultiLocation};
+pub use multilocation::{Junctions, MultiLocation, Parent, ParentThen, Ancestor, AncestorThen};
 pub use order::Order;
 pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 
@@ -65,7 +65,7 @@ pub mod prelude {
 		},
 		multilocation::{
 			Junctions::{self, *},
-			MultiLocation,
+			MultiLocation, Parent, ParentThen, Ancestor, AncestorThen,
 		},
 		opaque,
 		order::Order::{self, *},
diff --git a/xcm/src/v1/multiasset.rs b/xcm/src/v1/multiasset.rs
index b1bb2b98d9d4..9d4fa945edff 100644
--- a/xcm/src/v1/multiasset.rs
+++ b/xcm/src/v1/multiasset.rs
@@ -23,7 +23,7 @@
 //! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
 //!   account.
 
-use super::{Junction, Junctions::X1, MultiLocation};
+use super::MultiLocation;
 use alloc::{vec, vec::Vec};
 use core::{
 	cmp::Ordering,
@@ -101,15 +101,9 @@ pub enum AssetId {
 	Abstract(Vec<u8>),
 }
 
-impl From<MultiLocation> for AssetId {
-	fn from(x: MultiLocation) -> Self {
-		Self::Concrete(x)
-	}
-}
-
-impl From<Junction> for AssetId {
-	fn from(x: Junction) -> Self {
-		Self::Concrete(X1(x).into())
+impl<T: Into<MultiLocation>> From<T> for AssetId {
+	fn from(x: T) -> Self {
+		Self::Concrete(x.into())
 	}
 }
 
diff --git a/xcm/src/v1/multilocation.rs b/xcm/src/v1/multilocation.rs
index e333e70e494e..165d1941956c 100644
--- a/xcm/src/v1/multilocation.rs
+++ b/xcm/src/v1/multilocation.rs
@@ -335,6 +335,38 @@ impl MultiLocation {
 	}
 }
 
+/// A unit struct which can be converted into a `MultiLocation` of `parents` value 1.
+pub struct Parent;
+impl From<Parent> for MultiLocation {
+	fn from(_: Parent) -> Self {
+		MultiLocation { parents: 1, interior: Junctions::Here }
+	}
+}
+
+/// A tuple struct which can be converted into a `MultiLocation` of `parents` value 1 with the inner interior.
+pub struct ParentThen(Junctions);
+impl From<ParentThen> for MultiLocation {
+	fn from(x: ParentThen) -> Self {
+		MultiLocation { parents: 1, interior: x.0 }
+	}
+}
+
+/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value.
+pub struct Ancestor(u8);
+impl From<Ancestor> for MultiLocation {
+	fn from(x: Ancestor) -> Self {
+		MultiLocation { parents: x.0, interior: Junctions::Here }
+	}
+}
+
+/// A unit struct which can be converted into a `MultiLocation` of the inner `parents` value and the inner interior.
+pub struct AncestorThen(u8, Junctions);
+impl From<AncestorThen> for MultiLocation {
+	fn from(x: AncestorThen) -> Self {
+		MultiLocation { parents: x.0, interior: x.1 }
+	}
+}
+
 impl From<Junctions> for MultiLocation {
 	fn from(junctions: Junctions) -> Self {
 		MultiLocation { parents: 0, interior: junctions }
@@ -928,7 +960,7 @@ impl TryFrom<MultiLocation0> for MultiLocation {
 		use Junctions::*;
 		match old {
 			MultiLocation0::Null => Ok(Here.into()),
-			MultiLocation0::X1(j0) if j0.is_parent() => Ok(MultiLocation::parent()),
+			MultiLocation0::X1(j0) if j0.is_parent() => Ok(Parent.into()),
 			MultiLocation0::X1(j0) => Ok(X1(j0.try_into()?).into()),
 			MultiLocation0::X2(j0, j1) if j0.is_parent() && j1.is_parent() =>
 				Ok(MultiLocation::grandparent()),
diff --git a/xcm/src/v1/traits.rs b/xcm/src/v1/traits.rs
index 1632408c5846..13c5f3cda0cf 100644
--- a/xcm/src/v1/traits.rs
+++ b/xcm/src/v1/traits.rs
@@ -231,7 +231,7 @@ impl<C> ExecuteXcm<C> for () {
 /// # fn main() {
 /// let call: Vec<u8> = ().encode();
 /// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
-/// let destination = MultiLocation::parent();
+/// let destination = Parent.into();
 ///
 /// assert!(
 ///     // Sender2 will block this.
diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs
index cd6e03c365db..feea36707684 100644
--- a/xcm/xcm-builder/src/currency_adapter.rs
+++ b/xcm/xcm-builder/src/currency_adapter.rs
@@ -61,7 +61,7 @@ impl From<Error> for XcmError {
 ///
 /// /// Our relay chain's location.
 /// parameter_types! {
-///     RelayChain: MultiLocation = MultiLocation::parent();
+///     RelayChain: MultiLocation = Parent.into();
 ///     CheckingAccount: AccountId = Default::default();
 /// }
 ///
diff --git a/xcm/xcm-builder/src/location_conversion.rs b/xcm/xcm-builder/src/location_conversion.rs
index 5f8363c1546f..b067d98b8ede 100644
--- a/xcm/xcm-builder/src/location_conversion.rs
+++ b/xcm/xcm-builder/src/location_conversion.rs
@@ -19,7 +19,7 @@ use parity_scale_codec::Encode;
 use sp_io::hashing::blake2_256;
 use sp_runtime::traits::AccountIdConversion;
 use sp_std::{borrow::Borrow, marker::PhantomData};
-use xcm::latest::{Junction::*, Junctions::*, MultiLocation, NetworkId};
+use xcm::latest::{Junction::*, Junctions::*, MultiLocation, NetworkId, Parent};
 use xcm_executor::traits::{Convert, InvertLocation};
 
 pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
@@ -51,7 +51,7 @@ impl<AccountId: Default + Eq + Clone> Convert<MultiLocation, AccountId>
 
 	fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
 		if who.borrow() == &AccountId::default() {
-			Ok(MultiLocation::parent())
+			Ok(Parent.into())
 		} else {
 			Err(())
 		}
diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index e14fcdaa9409..accb4aa75256 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -37,11 +37,11 @@ use xcm_executor::traits::MatchesFungible;
 /// use xcm_executor::traits::MatchesFungible;
 ///
 /// frame_support::parameter_types! {
-/// 	pub TargetLocation: MultiLocation = MultiLocation::parent();
+/// 	pub TargetLocation: MultiLocation = Parent.into();
 /// }
 ///
 /// # fn main() {
-/// let asset = (MultiLocation::parent(), 999).into();
+/// let asset = (Parent, 999).into();
 /// // match `asset` if it is a concrete asset in `TargetLocation`.
 /// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
 /// # }
diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 2e6237e7528a..21ce7d26ccf5 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -257,7 +257,7 @@ parameter_types! {
 	pub static AllowUnpaidFrom: Vec<MultiLocation> = vec![];
 	pub static AllowPaidFrom: Vec<MultiLocation> = vec![];
 	// 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight.
-	pub static WeightPrice: (AssetId, u128) = (Here.into().into(), 1_000_000_000_000);
+	pub static WeightPrice: (AssetId, u128) = (AssetId::from(Here), 1_000_000_000_000);
 }
 
 pub type TestBarrier = (
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index bf65fd9cf63a..d56b0ffb0538 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -20,10 +20,10 @@ use xcm_executor::{traits::*, Config, XcmExecutor};
 
 #[test]
 fn basic_setup_works() {
-	add_reserve(MultiLocation::parent(), Wild((MultiLocation::parent(), WildFungible).into()));
+	add_reserve(Parent.into(), Wild((Parent, WildFungible).into()));
 	assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
-		&(MultiLocation::parent(), 100).into(),
-		&MultiLocation::parent(),
+		&(Parent, 100).into(),
+		&Parent.into(),
 	));
 
 	assert_eq!(to_account(X1(Parachain(1)).into()), Ok(1001));
@@ -44,10 +44,10 @@ fn basic_setup_works() {
 #[test]
 fn weigher_should_work() {
 	let mut message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::parent(), 100).into(),
+		assets: (Parent, 100).into(),
 		effects: vec![
 			Order::BuyExecution {
-				fees: (MultiLocation::parent(), 1).into(),
+				fees: (Parent, 1).into(),
 				weight: 0,
 				debt: 30,
 				halt_on_error: true,
@@ -64,13 +64,13 @@ fn weigher_should_work() {
 #[test]
 fn take_weight_credit_barrier_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::parent(), 100).into(),
+		assets: (Parent, 100).into(),
 		beneficiary: Here.into(),
 	};
 
 	let mut weight_credit = 10;
 	let r = TakeWeightCredit::should_execute(
-		&MultiLocation::parent(),
+		&Parent.into(),
 		true,
 		&mut message,
 		10,
@@ -80,7 +80,7 @@ fn take_weight_credit_barrier_should_work() {
 	assert_eq!(weight_credit, 0);
 
 	let r = TakeWeightCredit::should_execute(
-		&MultiLocation::parent(),
+		&Parent.into(),
 		true,
 		&mut message,
 		10,
@@ -93,11 +93,11 @@ fn take_weight_credit_barrier_should_work() {
 #[test]
 fn allow_unpaid_should_work() {
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::parent(), 100).into(),
+		assets: (Parent, 100).into(),
 		beneficiary: Here.into(),
 	};
 
-	AllowUnpaidFrom::set(vec![MultiLocation::parent()]);
+	AllowUnpaidFrom::set(vec![Parent.into()]);
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
 		&X1(Parachain(1)).into(),
@@ -109,7 +109,7 @@ fn allow_unpaid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
-		&MultiLocation::parent(),
+		&Parent.into(),
 		true,
 		&mut message,
 		10,
@@ -120,10 +120,10 @@ fn allow_unpaid_should_work() {
 
 #[test]
 fn allow_paid_should_work() {
-	AllowPaidFrom::set(vec![MultiLocation::parent()]);
+	AllowPaidFrom::set(vec![Parent.into()]);
 
 	let mut message = opaque::Xcm::TransferAsset {
-		assets: (MultiLocation::parent(), 100).into(),
+		assets: (Parent, 100).into(),
 		beneficiary: Here.into(),
 	};
 
@@ -136,9 +136,9 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let fees = (MultiLocation::parent(), 1).into();
+	let fees = (Parent, 1).into();
 	let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::parent(), 100).into(),
+		assets: (Parent, 100).into(),
 		effects: vec![
 			Order::BuyExecution {
 				fees,
@@ -153,7 +153,7 @@ fn allow_paid_should_work() {
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&MultiLocation::parent(),
+		&Parent.into(),
 		true,
 		&mut underpaying_message,
 		30,
@@ -161,9 +161,9 @@ fn allow_paid_should_work() {
 	);
 	assert_eq!(r, Err(()));
 
-	let fees = (MultiLocation::parent(), 1).into();
+	let fees = (Parent, 1).into();
 	let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
-		assets: (MultiLocation::parent(), 100).into(),
+		assets: (Parent, 100).into(),
 		effects: vec![
 			Order::BuyExecution {
 				fees,
@@ -187,7 +187,7 @@ fn allow_paid_should_work() {
 	assert_eq!(r, Err(()));
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&MultiLocation::parent(),
+		&Parent.into(),
 		true,
 		&mut paying_message,
 		30,
@@ -198,14 +198,14 @@ fn allow_paid_should_work() {
 
 #[test]
 fn paying_reserve_deposit_should_work() {
-	AllowPaidFrom::set(vec![MultiLocation::parent()]);
-	add_reserve(MultiLocation::parent(), (MultiLocation::parent(), WildFungible).into());
-	WeightPrice::set((MultiLocation::parent().into(), 1_000_000_000_000));
+	AllowPaidFrom::set(vec![Parent.into()]);
+	add_reserve(Parent.into(), (Parent, WildFungible).into());
+	WeightPrice::set((Parent.into(), 1_000_000_000_000));
 
-	let origin = MultiLocation::parent();
-	let fees = (MultiLocation::parent(), 30).into();
+	let origin = Parent.into();
+	let fees = (Parent, 30).into();
 	let message = Xcm::<TestCall>::ReserveAssetDeposited {
-		assets: (MultiLocation::parent(), 100).into(),
+		assets: (Parent, 100).into(),
 		effects: vec![
 			Order::<TestCall>::BuyExecution {
 				fees,
@@ -225,7 +225,7 @@ fn paying_reserve_deposit_should_work() {
 	let weight_limit = 50;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(30));
-	assert_eq!(assets(3000), vec![(MultiLocation::parent(), 70).into()]);
+	assert_eq!(assets(3000), vec![(Parent, 70).into()]);
 }
 
 #[test]
@@ -280,7 +280,7 @@ fn reserve_transfer_should_work() {
 		vec![(
 			X1(Parachain(2)).into(),
 			Xcm::ReserveAssetDeposited {
-				assets: (MultiLocation::parent(), 100).into(),
+				assets: (Parent, 100).into(),
 				effects: vec![Order::DepositAsset {
 					assets: All.into(),
 					max_assets: 1,
@@ -293,9 +293,9 @@ fn reserve_transfer_should_work() {
 
 #[test]
 fn transacting_should_work() {
-	AllowUnpaidFrom::set(vec![MultiLocation::parent()]);
+	AllowUnpaidFrom::set(vec![Parent.into()]);
 
-	let origin = MultiLocation::parent();
+	let origin = Parent.into();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -308,9 +308,9 @@ fn transacting_should_work() {
 
 #[test]
 fn transacting_should_respect_max_weight_requirement() {
-	AllowUnpaidFrom::set(vec![MultiLocation::parent()]);
+	AllowUnpaidFrom::set(vec![Parent.into()]);
 
-	let origin = MultiLocation::parent();
+	let origin = Parent.into();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 40,
@@ -323,9 +323,9 @@ fn transacting_should_respect_max_weight_requirement() {
 
 #[test]
 fn transacting_should_refund_weight() {
-	AllowUnpaidFrom::set(vec![MultiLocation::parent()]);
+	AllowUnpaidFrom::set(vec![Parent.into()]);
 
-	let origin = MultiLocation::parent();
+	let origin = Parent.into();
 	let message = Xcm::<TestCall>::Transact {
 		origin_type: OriginKind::Native,
 		require_weight_at_most: 50,
@@ -340,13 +340,13 @@ fn transacting_should_refund_weight() {
 fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let one: MultiLocation = X1(AccountIndex64 { index: 1, network: Any }).into();
 	AllowPaidFrom::set(vec![one.clone()]);
-	add_asset(1, (MultiLocation::parent(), 100).into());
-	WeightPrice::set((MultiLocation::parent().into(), 1_000_000_000_000));
+	add_asset(1, (Parent, 100).into());
+	WeightPrice::set((Parent.into(), 1_000_000_000_000));
 
 	let origin = one.clone();
-	let fees = (MultiLocation::parent(), 100).into();
+	let fees = (Parent, 100).into();
 	let message = Xcm::<TestCall>::WithdrawAsset {
-		assets: (MultiLocation::parent(), 100).into(), // enough for 100 units of weight.
+		assets: (Parent, 100).into(), // enough for 100 units of weight.
 		effects: vec![
 			Order::<TestCall>::BuyExecution {
 				fees,
@@ -371,17 +371,17 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
 	let weight_limit = 100;
 	let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
 	assert_eq!(r, Outcome::Complete(50));
-	assert_eq!(assets(1), vec![(MultiLocation::parent(), 50).into()]);
+	assert_eq!(assets(1), vec![(Parent, 50).into()]);
 }
 
 #[test]
 fn prepaid_result_of_query_should_get_free_execution() {
 	let query_id = 33;
-	let origin = MultiLocation::parent();
+	let origin: MultiLocation = Parent.into();
 	// We put this in manually here, but normally this would be done at the point of crafting the message.
 	expect_response(query_id, origin.clone());
 
-	let the_response = Response::Assets((MultiLocation::parent(), 100).into());
+	let the_response = Response::Assets((Parent, 100).into());
 	let message = Xcm::<TestCall>::QueryResponse { query_id, response: the_response.clone() };
 	let weight_limit = 10;
 
diff --git a/xcm/xcm-executor/integration-tests/src/lib.rs b/xcm/xcm-executor/integration-tests/src/lib.rs
index c1b2b6b31072..4b4c9d499525 100644
--- a/xcm/xcm-executor/integration-tests/src/lib.rs
+++ b/xcm/xcm-executor/integration-tests/src/lib.rs
@@ -24,7 +24,7 @@ use polkadot_test_client::{
 use polkadot_test_service::construct_extrinsic;
 use sp_runtime::{generic::BlockId, traits::Block};
 use sp_state_machine::InspectState;
-use xcm::latest::{Error as XcmError, MultiLocation, Order, Outcome, Xcm::*};
+use xcm::latest::prelude::*;
 use xcm_executor::MAX_RECURSION_LIMIT;
 
 // This is the inflection point where the test should either fail or pass.
@@ -37,12 +37,12 @@ fn execute_within_recursion_limit() {
 		.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
 		.build();
 
-	let mut msg = WithdrawAsset { assets: (MultiLocation::parent(), 100).into(), effects: vec![] };
+	let mut msg = WithdrawAsset { assets: (Parent, 100).into(), effects: vec![] };
 	for _ in 0..MAX_RECURSION_CHECK {
 		msg = WithdrawAsset {
-			assets: (MultiLocation::parent(), 100).into(),
+			assets: (Parent, 100).into(),
 			effects: vec![Order::BuyExecution {
-				fees: (MultiLocation::parent(), 1).into(),
+				fees: (Parent, 1).into(),
 				weight: 0,
 				debt: 0,
 				halt_on_error: true,
@@ -92,12 +92,12 @@ fn exceed_recursion_limit() {
 		.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
 		.build();
 
-	let mut msg = WithdrawAsset { assets: (MultiLocation::parent(), 100).into(), effects: vec![] };
+	let mut msg = WithdrawAsset { assets: (Parent, 100).into(), effects: vec![] };
 	for _ in 0..(MAX_RECURSION_CHECK + 1) {
 		msg = WithdrawAsset {
-			assets: (MultiLocation::parent(), 100).into(),
+			assets: (Parent, 100).into(),
 			effects: vec![Order::BuyExecution {
-				fees: (MultiLocation::parent(), 1).into(),
+				fees: (Parent, 1).into(),
 				weight: 0,
 				debt: 0,
 				halt_on_error: true,
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 6e48ecc250bd..fd17891c1820 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -139,7 +139,7 @@ mod tests {
 		ParaA::execute_with(|| {
 			assert_ok!(ParachainPalletXcm::send_xcm(
 				Here.into(),
-				MultiLocation::parent(),
+				Parent.into(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 3ff3ea1e540b..87fe111e57a6 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -120,7 +120,7 @@ pub type XcmOriginToCallOrigin = (
 
 parameter_types! {
 	pub const UnitWeightCost: Weight = 1;
-	pub KsmPerSecond: (AssetId, u128) = (Concrete(MultiLocation::parent()), 1);
+	pub KsmPerSecond: (AssetId, u128) = (Concrete(Parent.into()), 1);
 }
 
 pub type LocalAssetTransactor =
@@ -267,7 +267,7 @@ pub mod mock_msg_queue {
 					},
 					Ok(Ok(x)) => {
 						let outcome =
-							T::XcmExecutor::execute_xcm(MultiLocation::parent(), x, limit);
+							T::XcmExecutor::execute_xcm(Parent.into(), x, limit);
 						Self::deposit_event(Event::ExecutedDownward(id, outcome));
 					},
 				}

From 102b9d9707751ce4751a8772a04529a43507fd31 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:10:08 +0200
Subject: [PATCH 156/166] cleanup

---
 runtime/kusama/src/lib.rs                    | 4 ++--
 runtime/rococo/src/lib.rs                    | 4 ++--
 runtime/westend/src/lib.rs                   | 4 ++--
 xcm/pallet-xcm/src/mock.rs                   | 4 ++--
 xcm/xcm-simulator/example/src/relay_chain.rs | 4 ++--
 5 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index fdbf7ccdecfa..3a57fd3b2750 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1203,12 +1203,12 @@ parameter_types! {
 	/// The location of the KSM token, from the context of this chain. Since this token is native to this
 	/// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to
 	/// the context".
-	pub const KsmLocation: MultiLocation = Here.into();
+	pub const KsmLocation: MultiLocation = Here;
 	/// The Kusama network ID. This is named.
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	/// Our XCM location ancestry - i.e. what, if anything, `Parent` means evaluated in our context. Since
 	/// Kusama is a top-level relay-chain, there is no ancestry.
-	pub const Ancestry: MultiLocation = Here.into();
+	pub const Ancestry: MultiLocation = Here;
 	/// The check account, which holds any native assets that have been teleported out and not back in (yet).
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index b0f412eb1c68..0a3afd96c8b2 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -583,9 +583,9 @@ impl parachains_paras::Config for Runtime {
 }
 
 parameter_types! {
-	pub const RocLocation: MultiLocation = Here.into();
+	pub const RocLocation: MultiLocation = Here;
 	pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
-	pub const Ancestry: MultiLocation = Here.into();
+	pub const Ancestry: MultiLocation = Here;
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
 
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index 93fd23c48f08..e54d6c0136b3 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -866,8 +866,8 @@ impl auctions::Config for Runtime {
 }
 
 parameter_types! {
-	pub const WndLocation: MultiLocation = Here.into();
-	pub const Ancestry: MultiLocation = Here.into();
+	pub const WndLocation: MultiLocation = Here;
+	pub const Ancestry: MultiLocation = Here;
 	pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index 4dd6537cc1d7..6cd2768fc5a8 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -129,9 +129,9 @@ impl pallet_balances::Config for Test {
 }
 
 parameter_types! {
-	pub const RelayLocation: MultiLocation = Here.into();
+	pub const RelayLocation: MultiLocation = Here;
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = Here.into();
+	pub Ancestry: MultiLocation = Here;
 	pub UnitWeightCost: Weight = 1_000;
 }
 
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index 8dd543d428fd..b20e2d5204cb 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -87,10 +87,10 @@ impl shared::Config for Runtime {}
 impl configuration::Config for Runtime {}
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = Here.into();
+	pub const KsmLocation: MultiLocation = Here;
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = Here.into();
+	pub Ancestry: MultiLocation = Here;
 	pub UnitWeightCost: Weight = 1_000;
 }
 

From 36b10f376d08aae08b7657b93be2650d6f8db864 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:12:35 +0200
Subject: [PATCH 157/166] cleanup

---
 runtime/kusama/src/lib.rs                    | 4 ++--
 runtime/rococo/src/lib.rs                    | 4 ++--
 runtime/test-runtime/src/xcm_config.rs       | 2 +-
 runtime/westend/src/lib.rs                   | 4 ++--
 xcm/pallet-xcm/src/mock.rs                   | 4 ++--
 xcm/xcm-simulator/example/src/relay_chain.rs | 4 ++--
 6 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/runtime/kusama/src/lib.rs b/runtime/kusama/src/lib.rs
index 3a57fd3b2750..fdbf7ccdecfa 100644
--- a/runtime/kusama/src/lib.rs
+++ b/runtime/kusama/src/lib.rs
@@ -1203,12 +1203,12 @@ parameter_types! {
 	/// The location of the KSM token, from the context of this chain. Since this token is native to this
 	/// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to
 	/// the context".
-	pub const KsmLocation: MultiLocation = Here;
+	pub const KsmLocation: MultiLocation = Here.into();
 	/// The Kusama network ID. This is named.
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	/// Our XCM location ancestry - i.e. what, if anything, `Parent` means evaluated in our context. Since
 	/// Kusama is a top-level relay-chain, there is no ancestry.
-	pub const Ancestry: MultiLocation = Here;
+	pub const Ancestry: MultiLocation = Here.into();
 	/// The check account, which holds any native assets that have been teleported out and not back in (yet).
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
diff --git a/runtime/rococo/src/lib.rs b/runtime/rococo/src/lib.rs
index 0a3afd96c8b2..b0f412eb1c68 100644
--- a/runtime/rococo/src/lib.rs
+++ b/runtime/rococo/src/lib.rs
@@ -583,9 +583,9 @@ impl parachains_paras::Config for Runtime {
 }
 
 parameter_types! {
-	pub const RocLocation: MultiLocation = Here;
+	pub const RocLocation: MultiLocation = Here.into();
 	pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
-	pub const Ancestry: MultiLocation = Here;
+	pub const Ancestry: MultiLocation = Here.into();
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
 
diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index 8466d49445f8..5355e03c9184 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -70,7 +70,7 @@ impl WeightTrader for DummyWeightTrader {
 pub struct InvertNothing;
 impl InvertLocation for InvertNothing {
 	fn invert_location(_: &MultiLocation) -> MultiLocation {
-		MultiLocation::here()
+		Junction::Here.into()
 	}
 }
 
diff --git a/runtime/westend/src/lib.rs b/runtime/westend/src/lib.rs
index e54d6c0136b3..93fd23c48f08 100644
--- a/runtime/westend/src/lib.rs
+++ b/runtime/westend/src/lib.rs
@@ -866,8 +866,8 @@ impl auctions::Config for Runtime {
 }
 
 parameter_types! {
-	pub const WndLocation: MultiLocation = Here;
-	pub const Ancestry: MultiLocation = Here;
+	pub const WndLocation: MultiLocation = Here.into();
+	pub const Ancestry: MultiLocation = Here.into();
 	pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
 	pub CheckAccount: AccountId = XcmPallet::check_account();
 }
diff --git a/xcm/pallet-xcm/src/mock.rs b/xcm/pallet-xcm/src/mock.rs
index 6cd2768fc5a8..4dd6537cc1d7 100644
--- a/xcm/pallet-xcm/src/mock.rs
+++ b/xcm/pallet-xcm/src/mock.rs
@@ -129,9 +129,9 @@ impl pallet_balances::Config for Test {
 }
 
 parameter_types! {
-	pub const RelayLocation: MultiLocation = Here;
+	pub const RelayLocation: MultiLocation = Here.into();
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = Here;
+	pub Ancestry: MultiLocation = Here.into();
 	pub UnitWeightCost: Weight = 1_000;
 }
 
diff --git a/xcm/xcm-simulator/example/src/relay_chain.rs b/xcm/xcm-simulator/example/src/relay_chain.rs
index b20e2d5204cb..8dd543d428fd 100644
--- a/xcm/xcm-simulator/example/src/relay_chain.rs
+++ b/xcm/xcm-simulator/example/src/relay_chain.rs
@@ -87,10 +87,10 @@ impl shared::Config for Runtime {}
 impl configuration::Config for Runtime {}
 
 parameter_types! {
-	pub const KsmLocation: MultiLocation = Here;
+	pub const KsmLocation: MultiLocation = Here.into();
 	pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
 	pub const AnyNetwork: NetworkId = NetworkId::Any;
-	pub Ancestry: MultiLocation = Here;
+	pub Ancestry: MultiLocation = Here.into();
 	pub UnitWeightCost: Weight = 1_000;
 }
 

From 92c97853fc526f3f3327a5fbc18c4e9d24d4c352 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:13:29 +0200
Subject: [PATCH 158/166] cleanup

---
 runtime/test-runtime/src/xcm_config.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index 5355e03c9184..caa313b8c6ff 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -16,7 +16,7 @@
 
 use frame_support::{parameter_types, traits::Everything, weights::Weight};
 use xcm::latest::{
-	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult, SendXcm, Xcm, Parent,
+	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult, SendXcm, Xcm, Parent, Junction::Here,
 };
 use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
 use xcm_executor::{
@@ -70,7 +70,7 @@ impl WeightTrader for DummyWeightTrader {
 pub struct InvertNothing;
 impl InvertLocation for InvertNothing {
 	fn invert_location(_: &MultiLocation) -> MultiLocation {
-		Junction::Here.into()
+		Here.into()
 	}
 }
 

From 30c404c5a6bb89185cef6e45bfd9f956c11ce096 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:18:37 +0200
Subject: [PATCH 159/166] cleanup

---
 runtime/test-runtime/src/xcm_config.rs | 2 +-
 xcm/pallet-xcm/src/tests.rs            | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index caa313b8c6ff..7380f68584b1 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -16,7 +16,7 @@
 
 use frame_support::{parameter_types, traits::Everything, weights::Weight};
 use xcm::latest::{
-	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult, SendXcm, Xcm, Parent, Junction::Here,
+	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult, SendXcm, Xcm, Parent, Junctions::Here,
 };
 use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
 use xcm_executor::{
diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 2d8ef67c0e00..424adb7caba8 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -110,7 +110,7 @@ fn teleport_assets_works() {
 			Origin::signed(ALICE),
 			Box::new(RelayLocation::get()),
 			Box::new(AccountId32 { network: Any, id: BOB.into() }.into()),
-			(Here.into(), SEND_AMOUNT).into(),
+			(Here, SEND_AMOUNT).into(),
 			0,
 			weight,
 		));
@@ -139,7 +139,7 @@ fn reserve_transfer_assets_works() {
 			Origin::signed(ALICE),
 			Box::new(Parachain(PARA_ID).into()),
 			Box::new(dest.clone()),
-			(Here.into(), SEND_AMOUNT).into(),
+			(Here, SEND_AMOUNT).into(),
 			0,
 			weight
 		));
@@ -184,7 +184,7 @@ fn execute_withdraw_to_deposit_works() {
 		assert_ok!(XcmPallet::execute(
 			Origin::signed(ALICE),
 			Box::new(Xcm::WithdrawAsset {
-				assets: (Here.into(), SEND_AMOUNT).into(),
+				assets: (Here, SEND_AMOUNT).into(),
 				effects: vec![
 					buy_execution((Here.into(), SEND_AMOUNT), weight),
 					DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }

From 4e9f95830b5ace7984cb5c5f09b835f016f58f05 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:19:55 +0200
Subject: [PATCH 160/166] cleanup

---
 xcm/pallet-xcm/src/tests.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/pallet-xcm/src/tests.rs b/xcm/pallet-xcm/src/tests.rs
index 424adb7caba8..1e9d9acb42dc 100644
--- a/xcm/pallet-xcm/src/tests.rs
+++ b/xcm/pallet-xcm/src/tests.rs
@@ -186,7 +186,7 @@ fn execute_withdraw_to_deposit_works() {
 			Box::new(Xcm::WithdrawAsset {
 				assets: (Here, SEND_AMOUNT).into(),
 				effects: vec![
-					buy_execution((Here.into(), SEND_AMOUNT), weight),
+					buy_execution((Here, SEND_AMOUNT), weight),
 					DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest }
 				],
 			}),

From 52c0621dc0e4bd4c6ace4cb8b7236909b0bc36c9 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:24:12 +0200
Subject: [PATCH 161/166] cleanup

---
 xcm/xcm-builder/src/mock.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-builder/src/mock.rs b/xcm/xcm-builder/src/mock.rs
index 21ce7d26ccf5..7c1e93a2b9dd 100644
--- a/xcm/xcm-builder/src/mock.rs
+++ b/xcm/xcm-builder/src/mock.rs
@@ -257,7 +257,7 @@ parameter_types! {
 	pub static AllowUnpaidFrom: Vec<MultiLocation> = vec![];
 	pub static AllowPaidFrom: Vec<MultiLocation> = vec![];
 	// 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight.
-	pub static WeightPrice: (AssetId, u128) = (AssetId::from(Here), 1_000_000_000_000);
+	pub static WeightPrice: (AssetId, u128) = (From::from(Here), 1_000_000_000_000);
 }
 
 pub type TestBarrier = (

From 623039b36636fc26add89d5add18b74c7573b0d5 Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:30:22 +0200
Subject: [PATCH 162/166] cleanup

---
 xcm/xcm-builder/src/tests.rs                  | 14 +++++++-------
 xcm/xcm-executor/src/assets.rs                | 18 +++++++++---------
 xcm/xcm-executor/src/traits/transact_asset.rs |  8 ++++----
 xcm/xcm-simulator/example/src/lib.rs          |  2 +-
 4 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index d56b0ffb0538..0db2424b90b6 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -233,19 +233,19 @@ fn transfer_should_work() {
 	// we'll let them have message execution for free.
 	AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, (Here.into(), 1000).into());
+	add_asset(1001, (Here, 1000).into());
 	// They want to transfer 100 of them to their sibling parachain #2
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
 		X1(Parachain(1)).into(),
 		Xcm::TransferAsset {
-			assets: (Here.into(), 100).into(),
+			assets: (Here, 100).into(),
 			beneficiary: X1(AccountIndex64 { index: 3, network: Any }).into(),
 		},
 		50,
 	);
 	assert_eq!(r, Outcome::Complete(10));
-	assert_eq!(assets(3), vec![(Here.into(), 100).into()]);
-	assert_eq!(assets(1001), vec![(Here.into(), 900).into()]);
+	assert_eq!(assets(3), vec![(Here, 100).into()]);
+	assert_eq!(assets(1001), vec![(Here, 900).into()]);
 	assert_eq!(sent_xcm(), vec![]);
 }
 
@@ -253,7 +253,7 @@ fn transfer_should_work() {
 fn reserve_transfer_should_work() {
 	AllowUnpaidFrom::set(vec![X1(Parachain(1)).into()]);
 	// Child parachain #1 owns 1000 tokens held by us in reserve.
-	add_asset(1001, (Here.into(), 1000).into());
+	add_asset(1001, (Here, 1000).into());
 	// The remote account owned by gav.
 	let three: MultiLocation = X1(AccountIndex64 { index: 3, network: Any }).into();
 
@@ -262,7 +262,7 @@ fn reserve_transfer_should_work() {
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
 		X1(Parachain(1)).into(),
 		Xcm::TransferReserveAsset {
-			assets: (Here.into(), 100).into(),
+			assets: (Here, 100).into(),
 			dest: X1(Parachain(2)).into(),
 			effects: vec![Order::DepositAsset {
 				assets: All.into(),
@@ -274,7 +274,7 @@ fn reserve_transfer_should_work() {
 	);
 	assert_eq!(r, Outcome::Complete(10));
 
-	assert_eq!(assets(1002), vec![(Here.into(), 100).into()]);
+	assert_eq!(assets(1002), vec![(Here, 100).into()]);
 	assert_eq!(
 		sent_xcm(),
 		vec![(
diff --git a/xcm/xcm-executor/src/assets.rs b/xcm/xcm-executor/src/assets.rs
index 824f419c4f5c..8b87cc7ca5c4 100644
--- a/xcm/xcm-executor/src/assets.rs
+++ b/xcm/xcm-executor/src/assets.rs
@@ -381,12 +381,12 @@ impl Assets {
 	/// ```
 	/// use xcm_executor::Assets;
 	/// use xcm::latest::prelude::*;
-	/// let assets_i_have: Assets = vec![ (Here.into(), 100).into(), (vec![0], 100).into() ].into();
-	/// let assets_they_want: MultiAssetFilter = vec![ (Here.into(), 200).into(), (vec![0], 50).into() ].into();
+	/// let assets_i_have: Assets = vec![ (Here, 100).into(), (vec![0], 100).into() ].into();
+	/// let assets_they_want: MultiAssetFilter = vec![ (Here, 200).into(), (vec![0], 50).into() ].into();
 	///
 	/// let assets_we_can_trade: Assets = assets_i_have.min(&assets_they_want);
 	/// assert_eq!(assets_we_can_trade.into_assets_iter().collect::<Vec<_>>(), vec![
-	/// 	(Here.into(), 100).into(), (vec![0], 50).into(),
+	/// 	(Here, 100).into(), (vec![0], 50).into(),
 	/// ]);
 	/// ```
 	pub fn min(&self, mask: &MultiAssetFilter) -> Assets {
@@ -443,12 +443,12 @@ mod tests {
 	#[allow(non_snake_case)]
 	/// Concrete fungible constructor
 	fn CF(amount: u128) -> MultiAsset {
-		(Here.into(), amount).into()
+		(Here, amount).into()
 	}
 	#[allow(non_snake_case)]
 	/// Concrete non-fungible constructor
 	fn CNF(instance_id: u8) -> MultiAsset {
-		(Here.into(), [instance_id; 4]).into()
+		(Here, [instance_id; 4]).into()
 	}
 
 	fn test_assets() -> Assets {
@@ -562,8 +562,8 @@ mod tests {
 	#[test]
 	fn min_all_concrete_works() {
 		let assets = test_assets();
-		let fungible = Wild((Here.into(), WildFungible).into());
-		let non_fungible = Wild((Here.into(), WildNonFungible).into());
+		let fungible = Wild((Here, WildFungible).into());
+		let non_fungible = Wild((Here, WildNonFungible).into());
 
 		let fungible = assets.min(&fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
@@ -626,8 +626,8 @@ mod tests {
 	#[test]
 	fn saturating_take_all_concrete_works() {
 		let mut assets = test_assets();
-		let fungible = Wild((Here.into(), WildFungible).into());
-		let non_fungible = Wild((Here.into(), WildNonFungible).into());
+		let fungible = Wild((Here, WildFungible).into());
+		let non_fungible = Wild((Here, WildNonFungible).into());
 
 		let fungible = assets.saturating_take(fungible);
 		let fungible = fungible.assets_iter().collect::<Vec<_>>();
diff --git a/xcm/xcm-executor/src/traits/transact_asset.rs b/xcm/xcm-executor/src/traits/transact_asset.rs
index b46a5e9b8d5e..80ee2de660c3 100644
--- a/xcm/xcm-executor/src/traits/transact_asset.rs
+++ b/xcm/xcm-executor/src/traits/transact_asset.rs
@@ -273,7 +273,7 @@ mod tests {
 			(UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
 
 		assert_eq!(
-			MultiTransactor::deposit_asset(&(Here.into(), 1).into(), &Here.into()),
+			MultiTransactor::deposit_asset(&(Here, 1).into(), &Here.into()),
 			Err(XcmError::AssetNotFound)
 		);
 	}
@@ -282,7 +282,7 @@ mod tests {
 	fn unimplemented_and_not_found_continue_iteration() {
 		type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, SuccessfulTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&(Here.into(), 1).into(), &Here.into()), Ok(()),);
+		assert_eq!(MultiTransactor::deposit_asset(&(Here, 1).into(), &Here.into()), Ok(()),);
 	}
 
 	#[test]
@@ -290,7 +290,7 @@ mod tests {
 		type MultiTransactor = (OverflowTransactor, SuccessfulTransactor);
 
 		assert_eq!(
-			MultiTransactor::deposit_asset(&(Here.into(), 1).into(), &Here.into()),
+			MultiTransactor::deposit_asset(&(Here, 1).into(), &Here.into()),
 			Err(XcmError::Overflow)
 		);
 	}
@@ -299,6 +299,6 @@ mod tests {
 	fn success_stops_iteration() {
 		type MultiTransactor = (SuccessfulTransactor, OverflowTransactor);
 
-		assert_eq!(MultiTransactor::deposit_asset(&(Here.into(), 1).into(), &Here.into()), Ok(()),);
+		assert_eq!(MultiTransactor::deposit_asset(&(Here, 1).into(), &Here.into()), Ok(()),);
 	}
 }
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index fd17891c1820..2d67419dc524 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -192,7 +192,7 @@ mod tests {
 				relay_chain::Origin::signed(ALICE),
 				Box::new(X1(Parachain(1)).into()),
 				Box::new(X1(AccountId32 { network: Any, id: ALICE.into() }).into()),
-				(Here.into(), 123).into(),
+				(Here, 123).into(),
 				0,
 				3,
 			));

From 1c97d0f9096a02ad893ad9b92bcbb701f240faaa Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 13:32:52 +0200
Subject: [PATCH 163/166] cleanup

---
 xcm/xcm-builder/src/tests.rs         | 14 +++++++-------
 xcm/xcm-simulator/example/src/lib.rs |  2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index 0db2424b90b6..de46744bb455 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -100,7 +100,7 @@ fn allow_unpaid_should_work() {
 	AllowUnpaidFrom::set(vec![Parent.into()]);
 
 	let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
-		&X1(Parachain(1)).into(),
+		&Parachain(1).into(),
 		true,
 		&mut message,
 		10,
@@ -128,7 +128,7 @@ fn allow_paid_should_work() {
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&X1(Parachain(1)).into(),
+		&Parachain(1).into(),
 		true,
 		&mut message,
 		10,
@@ -178,7 +178,7 @@ fn allow_paid_should_work() {
 	};
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
-		&X1(Parachain(1)).into(),
+		&Parachain(1).into(),
 		true,
 		&mut paying_message,
 		30,
@@ -236,7 +236,7 @@ fn transfer_should_work() {
 	add_asset(1001, (Here, 1000).into());
 	// They want to transfer 100 of them to their sibling parachain #2
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
-		X1(Parachain(1)).into(),
+		Parachain(1).into(),
 		Xcm::TransferAsset {
 			assets: (Here, 100).into(),
 			beneficiary: X1(AccountIndex64 { index: 3, network: Any }).into(),
@@ -260,10 +260,10 @@ fn reserve_transfer_should_work() {
 	// They want to transfer 100 of our native asset from sovereign account of parachain #1 into #2
 	// and let them know to hand it to account #3.
 	let r = XcmExecutor::<TestConfig>::execute_xcm(
-		X1(Parachain(1)).into(),
+		Parachain(1).into(),
 		Xcm::TransferReserveAsset {
 			assets: (Here, 100).into(),
-			dest: X1(Parachain(2)).into(),
+			dest: Parachain(2).into(),
 			effects: vec![Order::DepositAsset {
 				assets: All.into(),
 				max_assets: 1,
@@ -278,7 +278,7 @@ fn reserve_transfer_should_work() {
 	assert_eq!(
 		sent_xcm(),
 		vec![(
-			X1(Parachain(2)).into(),
+			Parachain(2).into(),
 			Xcm::ReserveAssetDeposited {
 				assets: (Parent, 100).into(),
 				effects: vec![Order::DepositAsset {
diff --git a/xcm/xcm-simulator/example/src/lib.rs b/xcm/xcm-simulator/example/src/lib.rs
index 2d67419dc524..547c6f1858be 100644
--- a/xcm/xcm-simulator/example/src/lib.rs
+++ b/xcm/xcm-simulator/example/src/lib.rs
@@ -112,7 +112,7 @@ mod tests {
 		Relay::execute_with(|| {
 			assert_ok!(RelayChainPalletXcm::send_xcm(
 				Here.into(),
-				X1(Parachain(1)).into(),
+				Parachain(1).into(),
 				Transact {
 					origin_type: OriginKind::SovereignAccount,
 					require_weight_at_most: INITIAL_BALANCE as u64,

From 425116f35fc307e2440a4e3cb36a06b4bd590e32 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Mon, 9 Aug 2021 04:52:43 -0700
Subject: [PATCH 164/166] cargo fmt

---
 runtime/test-runtime/src/xcm_config.rs     |  3 ++-
 xcm/src/v1/mod.rs                          |  5 +++--
 xcm/xcm-builder/src/tests.rs               | 18 ++++++------------
 xcm/xcm-simulator/example/src/parachain.rs |  3 +--
 4 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/runtime/test-runtime/src/xcm_config.rs b/runtime/test-runtime/src/xcm_config.rs
index 7380f68584b1..7748d55e1875 100644
--- a/runtime/test-runtime/src/xcm_config.rs
+++ b/runtime/test-runtime/src/xcm_config.rs
@@ -16,7 +16,8 @@
 
 use frame_support::{parameter_types, traits::Everything, weights::Weight};
 use xcm::latest::{
-	Error as XcmError, MultiAsset, MultiLocation, NetworkId, Result as XcmResult, SendXcm, Xcm, Parent, Junctions::Here,
+	Error as XcmError, Junctions::Here, MultiAsset, MultiLocation, NetworkId, Parent,
+	Result as XcmResult, SendXcm, Xcm,
 };
 use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
 use xcm_executor::{
diff --git a/xcm/src/v1/mod.rs b/xcm/src/v1/mod.rs
index ad2fa40a9123..acf60252a1f2 100644
--- a/xcm/src/v1/mod.rs
+++ b/xcm/src/v1/mod.rs
@@ -38,7 +38,7 @@ pub use multiasset::{
 	AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
 	WildFungibility, WildMultiAsset,
 };
-pub use multilocation::{Junctions, MultiLocation, Parent, ParentThen, Ancestor, AncestorThen};
+pub use multilocation::{Ancestor, AncestorThen, Junctions, MultiLocation, Parent, ParentThen};
 pub use order::Order;
 pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
 
@@ -64,8 +64,9 @@ pub mod prelude {
 			WildMultiAsset::{self, *},
 		},
 		multilocation::{
+			Ancestor, AncestorThen,
 			Junctions::{self, *},
-			MultiLocation, Parent, ParentThen, Ancestor, AncestorThen,
+			MultiLocation, Parent, ParentThen,
 		},
 		opaque,
 		order::Order::{self, *},
diff --git a/xcm/xcm-builder/src/tests.rs b/xcm/xcm-builder/src/tests.rs
index de46744bb455..5ed3d3c49600 100644
--- a/xcm/xcm-builder/src/tests.rs
+++ b/xcm/xcm-builder/src/tests.rs
@@ -63,10 +63,8 @@ fn weigher_should_work() {
 
 #[test]
 fn take_weight_credit_barrier_should_work() {
-	let mut message = opaque::Xcm::TransferAsset {
-		assets: (Parent, 100).into(),
-		beneficiary: Here.into(),
-	};
+	let mut message =
+		opaque::Xcm::TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() };
 
 	let mut weight_credit = 10;
 	let r = TakeWeightCredit::should_execute(
@@ -92,10 +90,8 @@ fn take_weight_credit_barrier_should_work() {
 
 #[test]
 fn allow_unpaid_should_work() {
-	let mut message = opaque::Xcm::TransferAsset {
-		assets: (Parent, 100).into(),
-		beneficiary: Here.into(),
-	};
+	let mut message =
+		opaque::Xcm::TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() };
 
 	AllowUnpaidFrom::set(vec![Parent.into()]);
 
@@ -122,10 +118,8 @@ fn allow_unpaid_should_work() {
 fn allow_paid_should_work() {
 	AllowPaidFrom::set(vec![Parent.into()]);
 
-	let mut message = opaque::Xcm::TransferAsset {
-		assets: (Parent, 100).into(),
-		beneficiary: Here.into(),
-	};
+	let mut message =
+		opaque::Xcm::TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() };
 
 	let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
 		&Parachain(1).into(),
diff --git a/xcm/xcm-simulator/example/src/parachain.rs b/xcm/xcm-simulator/example/src/parachain.rs
index 87fe111e57a6..79c2f6e2947d 100644
--- a/xcm/xcm-simulator/example/src/parachain.rs
+++ b/xcm/xcm-simulator/example/src/parachain.rs
@@ -266,8 +266,7 @@ pub mod mock_msg_queue {
 						Self::deposit_event(Event::UnsupportedVersion(id));
 					},
 					Ok(Ok(x)) => {
-						let outcome =
-							T::XcmExecutor::execute_xcm(Parent.into(), x, limit);
+						let outcome = T::XcmExecutor::execute_xcm(Parent.into(), x, limit);
 						Self::deposit_event(Event::ExecutedDownward(id, outcome));
 					},
 				}

From 9ed00fc03072fea7d53e2ea60c2b8966927ef1ca Mon Sep 17 00:00:00 2001
From: Gav Wood <gavin@parity.io>
Date: Mon, 9 Aug 2021 19:03:00 +0200
Subject: [PATCH 165/166] Fixes

---
 xcm/xcm-builder/src/currency_adapter.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-builder/src/currency_adapter.rs b/xcm/xcm-builder/src/currency_adapter.rs
index feea36707684..074ae91c244a 100644
--- a/xcm/xcm-builder/src/currency_adapter.rs
+++ b/xcm/xcm-builder/src/currency_adapter.rs
@@ -53,7 +53,7 @@ impl From<Error> for XcmError {
 /// # Example
 /// ```
 /// use frame_support::parameter_types;
-/// use xcm::latest::MultiLocation;
+/// use xcm::latest::prelude::*;
 /// use xcm_builder::{ParentIsDefault, CurrencyAdapter, IsConcrete};
 ///
 /// /// Our chain's account id.

From 38f6e3c6fe316640f450afe5370a743b0a7b8416 Mon Sep 17 00:00:00 2001
From: Keith Yeung <kungfukeith11@gmail.com>
Date: Mon, 9 Aug 2021 11:10:00 -0700
Subject: [PATCH 166/166] Fix doc test

---
 xcm/xcm-builder/src/matches_fungible.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/xcm/xcm-builder/src/matches_fungible.rs b/xcm/xcm-builder/src/matches_fungible.rs
index accb4aa75256..6c33e18fe97c 100644
--- a/xcm/xcm-builder/src/matches_fungible.rs
+++ b/xcm/xcm-builder/src/matches_fungible.rs
@@ -32,7 +32,7 @@ use xcm_executor::traits::MatchesFungible;
 /// # Example
 ///
 /// ```
-/// use xcm::latest::MultiLocation;
+/// use xcm::latest::{MultiLocation, Parent};
 /// use xcm_builder::IsConcrete;
 /// use xcm_executor::traits::MatchesFungible;
 ///