mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 07:01:03 +00:00
Ensure MultiLocation always has a canonical representation (#3404)
* MultiAsset TWO * Ensure MultiLocation always has a canonical representation * Remove v1 module * Draft next MultiAsset API. * Implement custom encoding/decoding scheme for MultiLocation * Properly implement IntoIterator for Junctions * Implement TryFrom<MultiLocation> for Junctions * Fix spelling mistakes * Fix tests in xcm-executor * XCM core builds * XCM Executor builds * XCM Builder builds * Fix xcm-builder tests and compilation * Make pallet-xcm compile * Use MultiLocation::default() * Make polkadot-runtime-common compile * Make rococo-runtime compile * Change return type of parent_count to u8 * Change MAX_MULTILOCATION_LENGTH to 255 * Make kusama-runtime compile * Fix logic in pallet-xcm * Use MultiLocation::empty() * Fix logic in location_conversion * Fix logic in origin_conversion.rs * Make westend-runtime compile * Rename prefixes and suffixes variables * Rename non_parent to interior * Rename non_parent to interior * Add test for encode/decode roundtrip and fix decode algorithm * API changes making their way throughout * Some TODOs * Further build fixes * Rename non_parent/junctions to interior * Basic compile builds * First test fixed * All executor tests fixed * Typo * Optimize subsume_assets and add test * Optimize checked_sub * XCM Builder first test fixed * Fix builder tests * Fix doc test * Make xcm-simulator compile * Make xcm-simulator-example compile * Make spellcheck happy * cargo fmt * fix some doc tests * spelling * named fields for AllOf * Fix subtle bug where Null is treated as an identifier * Add FIXME comment awaiting for const generics eval stabilization * Update xcm/src/v0/multiasset.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/src/v0/multiasset.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/src/v0/multiasset.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Update xcm/src/v0/multiasset.rs Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> * Reformat * Move to XCM version 1 * Spelling * warnings * Replace some more v0->v1s * warnings * format * Add max_assets param * building * test fixes * tests * another test * final test * Update rustdocs and add debug_assert where sensible * Revert debug_assert in const fn len() * tests * Rename Null -> Here * Introduce * More ergonomics * More ergonomics * test fix * test fixes * docs * BuyExecution includes * Fix XCM extrinsics * fmt * Make Vec<MultiAsset>/MultiAssets conversions safe * More MultiAssets conversion safety * spelling * fix doc test * Apply suggestions from code review Co-authored-by: Amar Singh <asinghchrony@protonmail.com> * Apply suggestions from code review Co-authored-by: Amar Singh <asinghchrony@protonmail.com> * fmt * Add v0, remove VersionedMultiAsset * Remove VersionedMultiLocation * Update xcm/src/v1/order.rs Co-authored-by: Amar Singh <asinghchrony@protonmail.com> * Update xcm/src/v1/mod.rs Co-authored-by: Amar Singh <asinghchrony@protonmail.com> * XCM v0 backwards compatibility * Full compatibility * fmt * Update xcm/pallet-xcm/src/lib.rs * Update xcm/src/v0/order.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * Tweaks to versioning system * Fixes * fmt * Fix pallet-xcm tests * fix * Substitute with_parent with with_parents_const * Rename argument name from a to m * Rename split_last to split_last_interior * Allow adding multiple parents in MultiLocation * Rename pop_parent to dec_parent * Ensure relay chain XCM sender receives a MultiLocation without any parents * Block only when MultiLocation destination length is 8 * Cargo fmt * Remove reverse iterators, implement DoubleEndedIterator and add tests * Fix iter_rev lifetime requirements * Cargo fmt * Add an into() method for Junctions for conciseness in const context * Ensure parent count is 0 while executing who in RelayedFrom * Appease spellchecker * Use and_then instead of repeated map_err * Remove custom codec indices for v1 Junctions * Add convenience 'contains_parents_only' method to MultiLocation * Fix merge conflict * Use more convenience methods * Remove with_parachain_interior * Prefer matching against tuple instead of using match guards * Match against tuple instead of using more match guards * Update encode/decode test for MultiLocation * Minor tweaks * Fixes * Fixes * Fixes * Fix MultiLocation * Add deprecation note for iter_rev and into_iter_rev * Update some rustdocs * cargo fmt * Fix xcm-executor unit tests * Fix compilation and unit tests in xcm-builder * cargo fmt * Fix tests in xcm-simulator-example * Publicize MultiLocation fields * Match on the MultiLocation struct directly in xcm-builder * Do not dereference undereferenceable types * Add convenience MultiLocation conversions for tuples * Use clearer import paths * Remove unused dependency * fix junction + response * Import from latest opaque xcm module * Update xcm/src/v1/mod.rs * better comment * Fix ownership transfer * Fix merge * Fix merge * cargo fmt * Fix merge * Fix merge * Fix integration test * More readable Parent syntax * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * cleanup * cargo fmt * Fixes * Fix doc test Co-authored-by: Gav Wood <gavin@parity.io> Co-authored-by: Alexander Popiak <alexander.popiak@parity.io> Co-authored-by: Amar Singh <asinghchrony@protonmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
@@ -19,7 +19,7 @@
|
|||||||
use parity_scale_codec::Encode;
|
use parity_scale_codec::Encode;
|
||||||
use runtime_parachains::{configuration, dmp};
|
use runtime_parachains::{configuration, dmp};
|
||||||
use sp_std::marker::PhantomData;
|
use sp_std::marker::PhantomData;
|
||||||
use xcm::opaque::v1::{Error, Junction, MultiLocation, Result, SendXcm, Xcm};
|
use xcm::opaque::latest::*;
|
||||||
|
|
||||||
/// XCM sender for relay chain. It only sends downward message.
|
/// XCM sender for relay chain. It only sends downward message.
|
||||||
pub struct ChildParachainRouter<T, W>(PhantomData<(T, W)>);
|
pub struct ChildParachainRouter<T, W>(PhantomData<(T, W)>);
|
||||||
@@ -28,21 +28,21 @@ impl<T: configuration::Config + dmp::Config, W: xcm::WrapVersion> SendXcm
|
|||||||
for ChildParachainRouter<T, W>
|
for ChildParachainRouter<T, W>
|
||||||
{
|
{
|
||||||
fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {
|
fn send_xcm(dest: MultiLocation, msg: Xcm) -> Result {
|
||||||
match &dest {
|
match dest {
|
||||||
MultiLocation::X1(Junction::Parachain(id)) => {
|
MultiLocation { parents: 0, interior: Junctions::X1(Junction::Parachain(id)) } => {
|
||||||
// Downward message passing.
|
// Downward message passing.
|
||||||
let versioned_xcm =
|
let versioned_xcm =
|
||||||
W::wrap_version(&dest, msg).map_err(|()| Error::DestinationUnsupported)?;
|
W::wrap_version(&dest, msg).map_err(|()| Error::DestinationUnsupported)?;
|
||||||
let config = <configuration::Pallet<T>>::config();
|
let config = <configuration::Pallet<T>>::config();
|
||||||
<dmp::Pallet<T>>::queue_downward_message(
|
<dmp::Pallet<T>>::queue_downward_message(
|
||||||
&config,
|
&config,
|
||||||
(*id).into(),
|
id.into(),
|
||||||
versioned_xcm.encode(),
|
versioned_xcm.encode(),
|
||||||
)
|
)
|
||||||
.map_err(Into::<Error>::into)?;
|
.map_err(Into::<Error>::into)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
_ => Err(Error::CannotReachDestination(dest, msg)),
|
dest => Err(Error::CannotReachDestination(dest, msg)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
/// 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
|
/// chain, we make it synonymous with it and thus it is the `Here` location, which means "equivalent to
|
||||||
/// the context".
|
/// the context".
|
||||||
pub const KsmLocation: MultiLocation = MultiLocation::Here;
|
pub const KsmLocation: MultiLocation = Here.into();
|
||||||
/// The Kusama network ID. This is named.
|
/// The Kusama network ID. This is named.
|
||||||
pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
|
pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
|
||||||
/// Our XCM location ancestry - i.e. what, if anything, `Parent` means evaluated in our context. Since
|
/// 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.
|
/// 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).
|
/// The check account, which holds any native assets that have been teleported out and not back in (yet).
|
||||||
pub CheckAccount: AccountId = XcmPallet::check_account();
|
pub CheckAccount: AccountId = XcmPallet::check_account();
|
||||||
}
|
}
|
||||||
@@ -1265,7 +1265,7 @@ pub type XcmRouter = (
|
|||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const Kusama: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: 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 const KusamaForStatemint: (MultiAssetFilter, MultiLocation) = (Kusama::get(), Parachain(1000).into());
|
||||||
}
|
}
|
||||||
pub type TrustedTeleporters = (xcm_builder::Case<KusamaForStatemint>,);
|
pub type TrustedTeleporters = (xcm_builder::Case<KusamaForStatemint>,);
|
||||||
|
|
||||||
|
|||||||
@@ -583,9 +583,9 @@ impl parachains_paras::Config for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const RocLocation: MultiLocation = MultiLocation::Here;
|
pub const RocLocation: MultiLocation = Here.into();
|
||||||
pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
|
pub const RococoNetwork: NetworkId = NetworkId::Polkadot;
|
||||||
pub const Ancestry: MultiLocation = MultiLocation::Here;
|
pub const Ancestry: MultiLocation = Here.into();
|
||||||
pub CheckAccount: AccountId = XcmPallet::check_account();
|
pub CheckAccount: AccountId = XcmPallet::check_account();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,10 +625,10 @@ pub type XcmRouter = (
|
|||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const Rococo: MultiAssetFilter = Wild(AllOf { fun: WildFungible, id: 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 RococoForTick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), Parachain(100).into());
|
||||||
pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(110)));
|
pub const RococoForTrick: (MultiAssetFilter, MultiLocation) = (Rococo::get(), Parachain(110).into());
|
||||||
pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(120)));
|
pub const RococoForTrack: (MultiAssetFilter, MultiLocation) = (Rococo::get(), Parachain(120).into());
|
||||||
pub const RococoForStatemint: (MultiAssetFilter, MultiLocation) = (Rococo::get(), X1(Parachain(1001)));
|
pub const RococoForStatemint: (MultiAssetFilter, MultiLocation) = (Rococo::get(), Parachain(1001).into());
|
||||||
}
|
}
|
||||||
pub type TrustedTeleporters = (
|
pub type TrustedTeleporters = (
|
||||||
xcm_builder::Case<RococoForTick>,
|
xcm_builder::Case<RococoForTick>,
|
||||||
@@ -640,10 +640,10 @@ pub type TrustedTeleporters = (
|
|||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub AllowUnpaidFrom: Vec<MultiLocation> =
|
pub AllowUnpaidFrom: Vec<MultiLocation> =
|
||||||
vec![
|
vec![
|
||||||
X1(Parachain(100)),
|
Parachain(100).into(),
|
||||||
X1(Parachain(110)),
|
Parachain(110).into(),
|
||||||
X1(Parachain(120)),
|
Parachain(120).into(),
|
||||||
X1(Parachain(1001))
|
Parachain(1001).into(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
use frame_support::{parameter_types, traits::Everything, weights::Weight};
|
use frame_support::{parameter_types, traits::Everything, weights::Weight};
|
||||||
use xcm::latest::{
|
use xcm::latest::{
|
||||||
Error as XcmError, Junction::*, MultiAsset, MultiLocation, MultiLocation::*, NetworkId,
|
Error as XcmError, Junctions::Here, MultiAsset, MultiLocation, NetworkId, Parent,
|
||||||
Result as XcmResult, SendXcm, Xcm,
|
Result as XcmResult, SendXcm, Xcm,
|
||||||
};
|
};
|
||||||
use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
|
use xcm_builder::{AllowUnpaidExecutionFrom, FixedWeightBounds, SignedToAccountId32};
|
||||||
@@ -52,7 +52,7 @@ impl TransactAsset for DummyAssetTransactor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn withdraw_asset(_what: &MultiAsset, _who: &MultiLocation) -> Result<Assets, XcmError> {
|
fn withdraw_asset(_what: &MultiAsset, _who: &MultiLocation) -> Result<Assets, XcmError> {
|
||||||
let asset: MultiAsset = (X1(Parent), 100_000).into();
|
let asset: MultiAsset = (Parent, 100_000).into();
|
||||||
Ok(asset.into())
|
Ok(asset.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ impl WeightTrader for DummyWeightTrader {
|
|||||||
pub struct InvertNothing;
|
pub struct InvertNothing;
|
||||||
impl InvertLocation for InvertNothing {
|
impl InvertLocation for InvertNothing {
|
||||||
fn invert_location(_: &MultiLocation) -> MultiLocation {
|
fn invert_location(_: &MultiLocation) -> MultiLocation {
|
||||||
MultiLocation::Here
|
Here.into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -866,8 +866,8 @@ impl auctions::Config for Runtime {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const WndLocation: MultiLocation = MultiLocation::Here;
|
pub const WndLocation: MultiLocation = Here.into();
|
||||||
pub const Ancestry: MultiLocation = MultiLocation::Here;
|
pub const Ancestry: MultiLocation = Here.into();
|
||||||
pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
|
pub WestendNetwork: NetworkId = NetworkId::Named(b"Westend".to_vec());
|
||||||
pub CheckAccount: AccountId = XcmPallet::check_account();
|
pub CheckAccount: AccountId = XcmPallet::check_account();
|
||||||
}
|
}
|
||||||
@@ -908,7 +908,7 @@ pub type XcmRouter = (
|
|||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const WestendForWestmint: (MultiAssetFilter, MultiLocation) =
|
pub const WestendForWestmint: (MultiAssetFilter, MultiLocation) =
|
||||||
(Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), X1(Parachain(1000)));
|
(Wild(AllOf { fun: WildFungible, id: Concrete(WndLocation::get()) }), Parachain(1000).into());
|
||||||
}
|
}
|
||||||
pub type TrustedTeleporters = (xcm_builder::Case<WestendForWestmint>,);
|
pub type TrustedTeleporters = (xcm_builder::Case<WestendForWestmint>,);
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ pub mod pallet {
|
|||||||
UnweighableMessage,
|
UnweighableMessage,
|
||||||
/// The assets to be sent are empty.
|
/// The assets to be sent are empty.
|
||||||
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,
|
CannotReanchor,
|
||||||
/// Too many assets have been attempted for transfer.
|
/// Too many assets have been attempted for transfer.
|
||||||
TooManyAssets,
|
TooManyAssets,
|
||||||
@@ -306,9 +306,10 @@ pub mod pallet {
|
|||||||
dest: MultiLocation,
|
dest: MultiLocation,
|
||||||
message: Xcm<()>,
|
message: Xcm<()>,
|
||||||
) -> Result<(), XcmError> {
|
) -> Result<(), XcmError> {
|
||||||
let message = match interior {
|
let message = if interior.is_here() {
|
||||||
MultiLocation::Here => message,
|
message
|
||||||
who => Xcm::<()>::RelayedFrom { who, message: Box::new(message) },
|
} else {
|
||||||
|
Xcm::<()>::RelayedFrom { who: interior, message: Box::new(message) }
|
||||||
};
|
};
|
||||||
log::trace!(target: "xcm::send_xcm", "dest: {:?}, message: {:?}", &dest, &message);
|
log::trace!(target: "xcm::send_xcm", "dest: {:?}, message: {:?}", &dest, &message);
|
||||||
T::XcmRouter::send_xcm(dest, message)
|
T::XcmRouter::send_xcm(dest, message)
|
||||||
@@ -384,7 +385,7 @@ where
|
|||||||
|
|
||||||
#[cfg(feature = "runtime-benchmarks")]
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
fn successful_origin() -> O {
|
fn successful_origin() -> O {
|
||||||
O::from(Origin::Xcm(MultiLocation::Here))
|
O::from(Origin::Xcm(Here.into()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -393,9 +394,9 @@ where
|
|||||||
pub struct XcmPassthrough<Origin>(PhantomData<Origin>);
|
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> {
|
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||||
match (kind, origin) {
|
match kind {
|
||||||
(OriginKind::Xcm, l) => Ok(crate::Origin::Xcm(l).into()),
|
OriginKind::Xcm => Ok(crate::Origin::Xcm(origin).into()),
|
||||||
(_, origin) => Err(origin),
|
_ => Err(origin),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ impl SendXcm for TestSendXcm {
|
|||||||
pub struct TestSendXcmErrX8;
|
pub struct TestSendXcmErrX8;
|
||||||
impl SendXcm for TestSendXcmErrX8 {
|
impl SendXcm for TestSendXcmErrX8 {
|
||||||
fn send_xcm(dest: MultiLocation, msg: Xcm) -> XcmResult {
|
fn send_xcm(dest: MultiLocation, msg: Xcm) -> XcmResult {
|
||||||
if let MultiLocation::X8(..) = dest {
|
if dest.len() == 8 {
|
||||||
Err(XcmError::Undefined)
|
Err(XcmError::Undefined)
|
||||||
} else {
|
} else {
|
||||||
SENT_XCM.with(|q| q.borrow_mut().push((dest, msg)));
|
SENT_XCM.with(|q| q.borrow_mut().push((dest, msg)));
|
||||||
@@ -129,9 +129,9 @@ impl pallet_balances::Config for Test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const RelayLocation: MultiLocation = MultiLocation::Here;
|
pub const RelayLocation: MultiLocation = Here.into();
|
||||||
pub const AnyNetwork: NetworkId = NetworkId::Any;
|
pub const AnyNetwork: NetworkId = NetworkId::Any;
|
||||||
pub Ancestry: MultiLocation = MultiLocation::Here;
|
pub Ancestry: MultiLocation = Here.into();
|
||||||
pub UnitWeightCost: Weight = 1_000;
|
pub UnitWeightCost: Weight = 1_000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ fn send_works() {
|
|||||||
let sender: MultiLocation =
|
let sender: MultiLocation =
|
||||||
AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
|
AccountId32 { network: AnyNetwork::get(), id: ALICE.into() }.into();
|
||||||
let message = Xcm::ReserveAssetDeposited {
|
let message = Xcm::ReserveAssetDeposited {
|
||||||
assets: (X1(Parent), SEND_AMOUNT).into(),
|
assets: (Parent, SEND_AMOUNT).into(),
|
||||||
effects: vec![
|
effects: vec![
|
||||||
buy_execution((Parent, SEND_AMOUNT), weight),
|
buy_execution((Parent, SEND_AMOUNT), weight),
|
||||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
|
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: sender.clone() },
|
||||||
@@ -54,7 +54,7 @@ fn send_works() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
sent_xcm(),
|
sent_xcm(),
|
||||||
vec![(
|
vec![(
|
||||||
MultiLocation::Here,
|
Here.into(),
|
||||||
RelayedFrom { who: sender.clone(), message: Box::new(message.clone()) }
|
RelayedFrom { who: sender.clone(), message: Box::new(message.clone()) }
|
||||||
)]
|
)]
|
||||||
);
|
);
|
||||||
@@ -87,16 +87,7 @@ fn send_fails_when_xcm_router_blocks() {
|
|||||||
assert_noop!(
|
assert_noop!(
|
||||||
XcmPallet::send(
|
XcmPallet::send(
|
||||||
Origin::signed(ALICE),
|
Origin::signed(ALICE),
|
||||||
Box::new(X8(
|
Box::new(MultiLocation::ancestor(8)),
|
||||||
Junction::Parent,
|
|
||||||
Junction::Parent,
|
|
||||||
Junction::Parent,
|
|
||||||
Junction::Parent,
|
|
||||||
Junction::Parent,
|
|
||||||
Junction::Parent,
|
|
||||||
Junction::Parent,
|
|
||||||
Junction::Parent
|
|
||||||
)),
|
|
||||||
Box::new(message.clone())
|
Box::new(message.clone())
|
||||||
),
|
),
|
||||||
crate::Error::<Test>::SendFailure
|
crate::Error::<Test>::SendFailure
|
||||||
@@ -118,7 +109,7 @@ fn teleport_assets_works() {
|
|||||||
assert_ok!(XcmPallet::teleport_assets(
|
assert_ok!(XcmPallet::teleport_assets(
|
||||||
Origin::signed(ALICE),
|
Origin::signed(ALICE),
|
||||||
Box::new(RelayLocation::get()),
|
Box::new(RelayLocation::get()),
|
||||||
Box::new(X1(AccountId32 { network: Any, id: BOB.into() })),
|
Box::new(AccountId32 { network: Any, id: BOB.into() }.into()),
|
||||||
(Here, SEND_AMOUNT).into(),
|
(Here, SEND_AMOUNT).into(),
|
||||||
0,
|
0,
|
||||||
weight,
|
weight,
|
||||||
@@ -162,7 +153,7 @@ fn reserve_transfer_assets_works() {
|
|||||||
vec![(
|
vec![(
|
||||||
Parachain(PARA_ID).into(),
|
Parachain(PARA_ID).into(),
|
||||||
Xcm::ReserveAssetDeposited {
|
Xcm::ReserveAssetDeposited {
|
||||||
assets: (X1(Parent), SEND_AMOUNT).into(),
|
assets: (Parent, SEND_AMOUNT).into(),
|
||||||
effects: vec![
|
effects: vec![
|
||||||
buy_execution((Parent, SEND_AMOUNT), weight),
|
buy_execution((Parent, SEND_AMOUNT), weight),
|
||||||
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
DepositAsset { assets: All.into(), max_assets: 1, beneficiary: dest },
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
//! Support data structures for `MultiLocation`, primarily the `Junction` datatype.
|
//! Support data structures for `MultiLocation`, primarily the `Junction` datatype.
|
||||||
|
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use parity_scale_codec::{self, Decode, Encode};
|
use parity_scale_codec::{Decode, Encode};
|
||||||
|
|
||||||
/// A global identifier of an account-bearing consensus system.
|
/// A global identifier of an account-bearing consensus system.
|
||||||
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
|
#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Encode, Decode, Debug)]
|
||||||
@@ -140,10 +140,7 @@ pub enum Junction {
|
|||||||
/// Usage will vary widely owing to its generality.
|
/// Usage will vary widely owing to its generality.
|
||||||
///
|
///
|
||||||
/// NOTE: Try to avoid using this and instead use a more specific item.
|
/// NOTE: Try to avoid using this and instead use a more specific item.
|
||||||
GeneralIndex {
|
GeneralIndex(#[codec(compact)] u128),
|
||||||
#[codec(compact)]
|
|
||||||
id: u128,
|
|
||||||
},
|
|
||||||
/// A nondescript datum acting as a key within the context location.
|
/// A nondescript datum acting as a key within the context location.
|
||||||
///
|
///
|
||||||
/// Usage will vary widely owing to its generality.
|
/// Usage will vary widely owing to its generality.
|
||||||
@@ -161,6 +158,23 @@ pub enum Junction {
|
|||||||
Plurality { id: BodyId, part: BodyPart },
|
Plurality { id: BodyId, part: BodyPart },
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<crate::v1::Junction> for Junction {
|
||||||
|
fn from(v1: crate::v1::Junction) -> Junction {
|
||||||
|
use crate::v1::Junction::*;
|
||||||
|
match v1 {
|
||||||
|
Parachain(id) => Self::Parachain(id),
|
||||||
|
AccountId32 { network, id } => Self::AccountId32 { network, id },
|
||||||
|
AccountIndex64 { network, index } => Self::AccountIndex64 { network, index },
|
||||||
|
AccountKey20 { network, key } => Self::AccountKey20 { network, key },
|
||||||
|
PalletInstance(index) => Self::PalletInstance(index),
|
||||||
|
GeneralIndex(index) => Self::GeneralIndex(index),
|
||||||
|
GeneralKey(key) => Self::GeneralKey(key),
|
||||||
|
OnlyChild => Self::OnlyChild,
|
||||||
|
Plurality { id, part } => Self::Plurality { id, part },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Junction {
|
impl Junction {
|
||||||
/// Returns true if this junction is a `Parent` item.
|
/// Returns true if this junction is a `Parent` item.
|
||||||
pub fn is_parent(&self) -> bool {
|
pub fn is_parent(&self) -> bool {
|
||||||
|
|||||||
+17
-16
@@ -33,13 +33,14 @@ mod traits;
|
|||||||
use super::v1::{Response as Response1, Xcm as Xcm1};
|
use super::v1::{Response as Response1, Xcm as Xcm1};
|
||||||
pub use junction::{BodyId, BodyPart, Junction, NetworkId};
|
pub use junction::{BodyId, BodyPart, Junction, NetworkId};
|
||||||
pub use multi_asset::{AssetInstance, MultiAsset};
|
pub use multi_asset::{AssetInstance, MultiAsset};
|
||||||
pub use multi_location::MultiLocation;
|
pub use multi_location::MultiLocation::{self, *};
|
||||||
pub use order::Order;
|
pub use order::Order;
|
||||||
pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
|
pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
|
||||||
|
|
||||||
/// A prelude for importing all types typically used when interacting with XCM messages.
|
/// A prelude for importing all types typically used when interacting with XCM messages.
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use super::{
|
pub use super::{
|
||||||
|
junction::{BodyId, Junction::*},
|
||||||
multi_asset::{
|
multi_asset::{
|
||||||
AssetInstance::{self, *},
|
AssetInstance::{self, *},
|
||||||
MultiAsset::{self, *},
|
MultiAsset::{self, *},
|
||||||
@@ -47,9 +48,8 @@ pub mod prelude {
|
|||||||
multi_location::MultiLocation::{self, *},
|
multi_location::MultiLocation::{self, *},
|
||||||
order::Order::{self, *},
|
order::Order::{self, *},
|
||||||
traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
|
traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
|
||||||
BodyId, BodyPart,
|
|
||||||
Junction::*,
|
Junction::*,
|
||||||
NetworkId, OriginKind,
|
OriginKind,
|
||||||
Xcm::{self, *},
|
Xcm::{self, *},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -321,11 +321,12 @@ pub mod opaque {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Convert from a v1 response to a v0 response
|
// Convert from a v1 response to a v0 response
|
||||||
impl From<Response1> for Response {
|
impl TryFrom<Response1> for Response {
|
||||||
fn from(new_response: Response1) -> Self {
|
type Error = ();
|
||||||
match new_response {
|
fn try_from(new_response: Response1) -> result::Result<Self, ()> {
|
||||||
Response1::Assets(assets) => Self::Assets(assets.into()),
|
Ok(match new_response {
|
||||||
}
|
Response1::Assets(assets) => Self::Assets(assets.try_into()?),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,33 +336,33 @@ impl<Call> TryFrom<Xcm1<Call>> for Xcm<Call> {
|
|||||||
use Xcm::*;
|
use Xcm::*;
|
||||||
Ok(match x {
|
Ok(match x {
|
||||||
Xcm1::WithdrawAsset { assets, effects } => WithdrawAsset {
|
Xcm1::WithdrawAsset { assets, effects } => WithdrawAsset {
|
||||||
assets: assets.into(),
|
assets: assets.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::try_from)
|
.map(Order::try_from)
|
||||||
.collect::<result::Result<_, _>>()?,
|
.collect::<result::Result<_, _>>()?,
|
||||||
},
|
},
|
||||||
Xcm1::ReserveAssetDeposited { assets, effects } => ReserveAssetDeposit {
|
Xcm1::ReserveAssetDeposited { assets, effects } => ReserveAssetDeposit {
|
||||||
assets: assets.into(),
|
assets: assets.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::try_from)
|
.map(Order::try_from)
|
||||||
.collect::<result::Result<_, _>>()?,
|
.collect::<result::Result<_, _>>()?,
|
||||||
},
|
},
|
||||||
Xcm1::ReceiveTeleportedAsset { assets, effects } => TeleportAsset {
|
Xcm1::ReceiveTeleportedAsset { assets, effects } => TeleportAsset {
|
||||||
assets: assets.into(),
|
assets: assets.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::try_from)
|
.map(Order::try_from)
|
||||||
.collect::<result::Result<_, _>>()?,
|
.collect::<result::Result<_, _>>()?,
|
||||||
},
|
},
|
||||||
Xcm1::QueryResponse { query_id: u64, response } =>
|
Xcm1::QueryResponse { query_id: u64, response } =>
|
||||||
QueryResponse { query_id: u64, response: response.into() },
|
QueryResponse { query_id: u64, response: response.try_into()? },
|
||||||
Xcm1::TransferAsset { assets, beneficiary } =>
|
Xcm1::TransferAsset { assets, beneficiary } =>
|
||||||
TransferAsset { assets: assets.into(), dest: beneficiary.into() },
|
TransferAsset { assets: assets.try_into()?, dest: beneficiary.try_into()? },
|
||||||
Xcm1::TransferReserveAsset { assets, dest, effects } => TransferReserveAsset {
|
Xcm1::TransferReserveAsset { assets, dest, effects } => TransferReserveAsset {
|
||||||
assets: assets.into(),
|
assets: assets.try_into()?,
|
||||||
dest: dest.into(),
|
dest: dest.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::try_from)
|
.map(Order::try_from)
|
||||||
@@ -375,7 +376,7 @@ impl<Call> TryFrom<Xcm1<Call>> for Xcm<Call> {
|
|||||||
Xcm1::Transact { origin_type, require_weight_at_most, call } =>
|
Xcm1::Transact { origin_type, require_weight_at_most, call } =>
|
||||||
Transact { origin_type, require_weight_at_most, call: call.into() },
|
Transact { origin_type, require_weight_at_most, call: call.into() },
|
||||||
Xcm1::RelayedFrom { who, message } => RelayedFrom {
|
Xcm1::RelayedFrom { who, message } => RelayedFrom {
|
||||||
who: who.into(),
|
who: who.try_into()?,
|
||||||
message: alloc::boxed::Box::new((*message).try_into()?),
|
message: alloc::boxed::Box::new((*message).try_into()?),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -17,8 +17,12 @@
|
|||||||
//! Cross-Consensus Message format data structures.
|
//! Cross-Consensus Message format data structures.
|
||||||
|
|
||||||
use super::MultiLocation;
|
use super::MultiLocation;
|
||||||
use crate::v1::{MultiAsset as MultiAsset1, MultiAssetFilter, MultiAssets, WildMultiAsset};
|
use crate::v1::{MultiAssetFilter, MultiAssets, WildMultiAsset};
|
||||||
use alloc::{vec, vec::Vec};
|
use alloc::{vec, vec::Vec};
|
||||||
|
use core::{
|
||||||
|
convert::{TryFrom, TryInto},
|
||||||
|
result,
|
||||||
|
};
|
||||||
use parity_scale_codec::{self, Decode, Encode};
|
use parity_scale_codec::{self, Decode, Encode};
|
||||||
|
|
||||||
pub use crate::v1::AssetInstance;
|
pub use crate::v1::AssetInstance;
|
||||||
@@ -290,53 +294,64 @@ impl MultiAsset {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MultiAsset1> for MultiAsset {
|
impl TryFrom<crate::v1::MultiAsset> for MultiAsset {
|
||||||
fn from(a: MultiAsset1) -> MultiAsset {
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(m: crate::v1::MultiAsset) -> result::Result<MultiAsset, ()> {
|
||||||
use crate::v1::{AssetId::*, Fungibility::*};
|
use crate::v1::{AssetId::*, Fungibility::*};
|
||||||
use MultiAsset::*;
|
use MultiAsset::*;
|
||||||
match (a.id, a.fun) {
|
Ok(match (m.id, m.fun) {
|
||||||
(Concrete(id), Fungible(amount)) => ConcreteFungible { id: id.into(), amount },
|
(Concrete(id), Fungible(amount)) => ConcreteFungible { id: id.try_into()?, amount },
|
||||||
(Concrete(class), NonFungible(instance)) =>
|
(Concrete(class), NonFungible(instance)) =>
|
||||||
ConcreteNonFungible { class: class.into(), instance },
|
ConcreteNonFungible { class: class.try_into()?, instance },
|
||||||
(Abstract(id), Fungible(amount)) => AbstractFungible { id, amount },
|
(Abstract(id), Fungible(amount)) => AbstractFungible { id, amount },
|
||||||
(Abstract(class), NonFungible(instance)) => AbstractNonFungible { class, instance },
|
(Abstract(class), NonFungible(instance)) => AbstractNonFungible { class, instance },
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MultiAssets> for Vec<MultiAsset> {
|
impl TryFrom<MultiAssets> for Vec<MultiAsset> {
|
||||||
fn from(a: MultiAssets) -> Vec<MultiAsset> {
|
type Error = ();
|
||||||
a.drain().into_iter().map(MultiAsset::from).collect()
|
|
||||||
|
fn try_from(m: MultiAssets) -> result::Result<Vec<MultiAsset>, ()> {
|
||||||
|
m.drain().into_iter().map(MultiAsset::try_from).collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WildMultiAsset> for MultiAsset {
|
impl TryFrom<WildMultiAsset> for MultiAsset {
|
||||||
fn from(a: WildMultiAsset) -> MultiAsset {
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(m: WildMultiAsset) -> result::Result<MultiAsset, ()> {
|
||||||
use crate::v1::{AssetId::*, WildFungibility::*};
|
use crate::v1::{AssetId::*, WildFungibility::*};
|
||||||
use MultiAsset::*;
|
use MultiAsset::*;
|
||||||
match a {
|
Ok(match m {
|
||||||
WildMultiAsset::All => All,
|
WildMultiAsset::All => All,
|
||||||
WildMultiAsset::AllOf { id, fun } => match (id, fun) {
|
WildMultiAsset::AllOf { id, fun } => match (id, fun) {
|
||||||
(Concrete(id), Fungible) => AllConcreteFungible { id: id.into() },
|
(Concrete(id), Fungible) => AllConcreteFungible { id: id.try_into()? },
|
||||||
(Concrete(class), NonFungible) => AllConcreteNonFungible { class: class.into() },
|
(Concrete(class), NonFungible) =>
|
||||||
|
AllConcreteNonFungible { class: class.try_into()? },
|
||||||
(Abstract(id), Fungible) => AllAbstractFungible { id },
|
(Abstract(id), Fungible) => AllAbstractFungible { id },
|
||||||
(Abstract(class), NonFungible) => AllAbstractNonFungible { class },
|
(Abstract(class), NonFungible) => AllAbstractNonFungible { class },
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<WildMultiAsset> for Vec<MultiAsset> {
|
impl TryFrom<WildMultiAsset> for Vec<MultiAsset> {
|
||||||
fn from(a: WildMultiAsset) -> Vec<MultiAsset> {
|
type Error = ();
|
||||||
vec![a.into()]
|
|
||||||
|
fn try_from(m: WildMultiAsset) -> result::Result<Vec<MultiAsset>, ()> {
|
||||||
|
Ok(vec![m.try_into()?])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MultiAssetFilter> for Vec<MultiAsset> {
|
impl TryFrom<MultiAssetFilter> for Vec<MultiAsset> {
|
||||||
fn from(a: MultiAssetFilter) -> Vec<MultiAsset> {
|
type Error = ();
|
||||||
match a {
|
|
||||||
MultiAssetFilter::Definite(assets) => assets.into(),
|
fn try_from(m: MultiAssetFilter) -> result::Result<Vec<MultiAsset>, ()> {
|
||||||
MultiAssetFilter::Wild(wildcard) => wildcard.into(),
|
match m {
|
||||||
|
MultiAssetFilter::Definite(assets) => assets.try_into(),
|
||||||
|
MultiAssetFilter::Wild(wildcard) => wildcard.try_into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
//! Cross-Consensus Message format data structures.
|
//! Cross-Consensus Message format data structures.
|
||||||
|
|
||||||
use core::{mem, result};
|
use super::Junction;
|
||||||
|
use crate::v1::MultiLocation as MultiLocation1;
|
||||||
use super::{super::v1::MultiLocation as MultiLocation1, Junction};
|
use core::{convert::TryFrom, mem, result};
|
||||||
use parity_scale_codec::{self, Decode, Encode};
|
use parity_scale_codec::{self, Decode, Encode};
|
||||||
|
|
||||||
/// A relative path between state-bearing consensus systems.
|
/// A relative path between state-bearing consensus systems.
|
||||||
@@ -696,20 +696,68 @@ impl MultiLocation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MultiLocation1> for MultiLocation {
|
impl TryFrom<MultiLocation1> for MultiLocation {
|
||||||
fn from(old: MultiLocation1) -> Self {
|
type Error = ();
|
||||||
use MultiLocation::*;
|
fn try_from(v1: MultiLocation1) -> result::Result<Self, ()> {
|
||||||
match old {
|
use crate::v1::Junctions::*;
|
||||||
MultiLocation1::Here => Null,
|
let mut res = Self::Null;
|
||||||
MultiLocation1::X1(j0) => X1(j0),
|
|
||||||
MultiLocation1::X2(j0, j1) => X2(j0, j1),
|
for _ in 0..v1.parents {
|
||||||
MultiLocation1::X3(j0, j1, j2) => X3(j0, j1, j2),
|
res.push(Junction::Parent)?;
|
||||||
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),
|
match v1.interior {
|
||||||
MultiLocation1::X7(j0, j1, j2, j3, j4, j5, j6) => X7(j0, j1, j2, j3, j4, j5, j6),
|
Here => Ok(res),
|
||||||
MultiLocation1::X8(j0, j1, j2, j3, j4, j5, j6, j7) =>
|
X1(j0) => res.pushed_with(Junction::from(j0)).map_err(|_| ()),
|
||||||
X8(j0, j1, j2, j3, j4, j5, j6, j7),
|
X2(j0, j1) => res
|
||||||
|
.pushed_with(Junction::from(j0))
|
||||||
|
.and_then(|res| res.pushed_with(Junction::from(j1)))
|
||||||
|
.map_err(|_| ()),
|
||||||
|
X3(j0, j1, j2) => res
|
||||||
|
.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(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(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(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(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(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(|_| ()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,10 @@
|
|||||||
|
|
||||||
use super::{super::v1::Order as Order1, MultiAsset, MultiLocation, Xcm};
|
use super::{super::v1::Order as Order1, MultiAsset, MultiLocation, Xcm};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use core::{convert::TryFrom, result};
|
use core::{
|
||||||
|
convert::{TryFrom, TryInto},
|
||||||
|
result,
|
||||||
|
};
|
||||||
use derivative::Derivative;
|
use derivative::Derivative;
|
||||||
use parity_scale_codec::{self, Decode, Encode};
|
use parity_scale_codec::{self, Decode, Encode};
|
||||||
|
|
||||||
@@ -161,36 +164,36 @@ impl<Call> TryFrom<Order1<Call>> for Order<Call> {
|
|||||||
Ok(match old {
|
Ok(match old {
|
||||||
Order1::Noop => Null,
|
Order1::Noop => Null,
|
||||||
Order1::DepositAsset { assets, beneficiary, .. } =>
|
Order1::DepositAsset { assets, beneficiary, .. } =>
|
||||||
DepositAsset { assets: assets.into(), dest: beneficiary.into() },
|
DepositAsset { assets: assets.try_into()?, dest: beneficiary.try_into()? },
|
||||||
Order1::DepositReserveAsset { assets, dest, effects, .. } => DepositReserveAsset {
|
Order1::DepositReserveAsset { assets, dest, effects, .. } => DepositReserveAsset {
|
||||||
assets: assets.into(),
|
assets: assets.try_into()?,
|
||||||
dest: dest.into(),
|
dest: dest.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::<()>::try_from)
|
.map(Order::<()>::try_from)
|
||||||
.collect::<result::Result<_, _>>()?,
|
.collect::<result::Result<_, _>>()?,
|
||||||
},
|
},
|
||||||
Order1::ExchangeAsset { give, receive } =>
|
Order1::ExchangeAsset { give, receive } =>
|
||||||
ExchangeAsset { give: give.into(), receive: receive.into() },
|
ExchangeAsset { give: give.try_into()?, receive: receive.try_into()? },
|
||||||
Order1::InitiateReserveWithdraw { assets, reserve, effects } =>
|
Order1::InitiateReserveWithdraw { assets, reserve, effects } =>
|
||||||
InitiateReserveWithdraw {
|
InitiateReserveWithdraw {
|
||||||
assets: assets.into(),
|
assets: assets.try_into()?,
|
||||||
reserve: reserve.into(),
|
reserve: reserve.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::<()>::try_from)
|
.map(Order::<()>::try_from)
|
||||||
.collect::<result::Result<_, _>>()?,
|
.collect::<result::Result<_, _>>()?,
|
||||||
},
|
},
|
||||||
Order1::InitiateTeleport { assets, dest, effects } => InitiateTeleport {
|
Order1::InitiateTeleport { assets, dest, effects } => InitiateTeleport {
|
||||||
assets: assets.into(),
|
assets: assets.try_into()?,
|
||||||
dest: dest.into(),
|
dest: dest.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::<()>::try_from)
|
.map(Order::<()>::try_from)
|
||||||
.collect::<result::Result<_, _>>()?,
|
.collect::<result::Result<_, _>>()?,
|
||||||
},
|
},
|
||||||
Order1::QueryHolding { query_id, dest, assets } =>
|
Order1::QueryHolding { query_id, dest, assets } =>
|
||||||
QueryHolding { query_id, dest: dest.into(), assets: assets.into() },
|
QueryHolding { query_id, dest: dest.try_into()?, assets: assets.try_into()? },
|
||||||
Order1::BuyExecution { fees, weight, debt, halt_on_error, orders, instructions } => {
|
Order1::BuyExecution { fees, weight, debt, halt_on_error, orders, instructions } => {
|
||||||
if !orders.is_empty() {
|
if !orders.is_empty() {
|
||||||
return Err(())
|
return Err(())
|
||||||
@@ -199,7 +202,7 @@ impl<Call> TryFrom<Order1<Call>> for Order<Call> {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Xcm::<Call>::try_from)
|
.map(Xcm::<Call>::try_from)
|
||||||
.collect::<result::Result<_, _>>()?;
|
.collect::<result::Result<_, _>>()?;
|
||||||
BuyExecution { fees: fees.into(), weight, debt, halt_on_error, xcm }
|
BuyExecution { fees: fees.try_into()?, weight, debt, halt_on_error, xcm }
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
// 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 super::{BodyId, BodyPart, Junctions, MultiLocation, NetworkId};
|
||||||
|
use crate::v0::Junction as Junction0;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use core::convert::TryFrom;
|
||||||
|
use parity_scale_codec::{self, Decode, Encode};
|
||||||
|
|
||||||
|
/// 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)] 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 TryFrom<Junction0> for Junction {
|
||||||
|
type Error = ();
|
||||||
|
|
||||||
|
fn try_from(value: Junction0) -> Result<Self, Self::Error> {
|
||||||
|
match value {
|
||||||
|
Junction0::Parent => Err(()),
|
||||||
|
Junction0::Parachain(id) => Ok(Self::Parachain(id)),
|
||||||
|
Junction0::AccountId32 { network, id } => Ok(Self::AccountId32 { network, id }),
|
||||||
|
Junction0::AccountIndex64 { network, index } =>
|
||||||
|
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::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) }
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,30 +27,32 @@ use core::{
|
|||||||
use derivative::Derivative;
|
use derivative::Derivative;
|
||||||
use parity_scale_codec::{self, Decode, Encode};
|
use parity_scale_codec::{self, Decode, Encode};
|
||||||
|
|
||||||
|
mod junction;
|
||||||
pub mod multiasset;
|
pub mod multiasset;
|
||||||
mod multilocation;
|
mod multilocation;
|
||||||
mod order;
|
mod order;
|
||||||
mod traits; // the new multiasset.
|
mod traits; // the new multiasset.
|
||||||
|
|
||||||
|
pub use junction::Junction;
|
||||||
pub use multiasset::{
|
pub use multiasset::{
|
||||||
AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
|
AssetId, AssetInstance, Fungibility, MultiAsset, MultiAssetFilter, MultiAssets,
|
||||||
WildFungibility, WildMultiAsset,
|
WildFungibility, WildMultiAsset,
|
||||||
};
|
};
|
||||||
pub use multilocation::MultiLocation;
|
pub use multilocation::{Ancestor, AncestorThen, Junctions, MultiLocation, Parent, ParentThen};
|
||||||
pub use order::Order;
|
pub use order::Order;
|
||||||
pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
|
pub use traits::{Error, ExecuteXcm, Outcome, Result, SendXcm};
|
||||||
|
|
||||||
// These parts of XCM v0 have been unchanged in XCM v1, and are re-imported here.
|
// 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};
|
pub use super::v0::{BodyId, BodyPart, NetworkId, OriginKind};
|
||||||
|
|
||||||
/// A prelude for importing all types typically used when interacting with XCM messages.
|
/// A prelude for importing all types typically used when interacting with XCM messages.
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use super::{
|
pub use super::{
|
||||||
super::v0::{
|
super::v0::{
|
||||||
BodyId, BodyPart,
|
BodyId, BodyPart,
|
||||||
Junction::*,
|
|
||||||
NetworkId::{self, *},
|
NetworkId::{self, *},
|
||||||
},
|
},
|
||||||
|
junction::Junction::{self, *},
|
||||||
multiasset::{
|
multiasset::{
|
||||||
AssetId::{self, *},
|
AssetId::{self, *},
|
||||||
AssetInstance::{self, *},
|
AssetInstance::{self, *},
|
||||||
@@ -61,7 +63,11 @@ pub mod prelude {
|
|||||||
WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible},
|
WildFungibility::{self, Fungible as WildFungible, NonFungible as WildNonFungible},
|
||||||
WildMultiAsset::{self, *},
|
WildMultiAsset::{self, *},
|
||||||
},
|
},
|
||||||
multilocation::MultiLocation::{self, *},
|
multilocation::{
|
||||||
|
Ancestor, AncestorThen,
|
||||||
|
Junctions::{self, *},
|
||||||
|
MultiLocation, Parent, ParentThen,
|
||||||
|
},
|
||||||
opaque,
|
opaque,
|
||||||
order::Order::{self, *},
|
order::Order::{self, *},
|
||||||
traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
|
traits::{Error as XcmError, ExecuteXcm, Outcome, Result as XcmResult, SendXcm},
|
||||||
@@ -352,10 +358,10 @@ impl<Call> TryFrom<Xcm0<Call>> for Xcm<Call> {
|
|||||||
Xcm0::QueryResponse { query_id: u64, response } =>
|
Xcm0::QueryResponse { query_id: u64, response } =>
|
||||||
QueryResponse { query_id: u64, response: response.try_into()? },
|
QueryResponse { query_id: u64, response: response.try_into()? },
|
||||||
Xcm0::TransferAsset { assets, dest } =>
|
Xcm0::TransferAsset { assets, dest } =>
|
||||||
TransferAsset { assets: assets.try_into()?, beneficiary: dest.into() },
|
TransferAsset { assets: assets.try_into()?, beneficiary: dest.try_into()? },
|
||||||
Xcm0::TransferReserveAsset { assets, dest, effects } => TransferReserveAsset {
|
Xcm0::TransferReserveAsset { assets, dest, effects } => TransferReserveAsset {
|
||||||
assets: assets.try_into()?,
|
assets: assets.try_into()?,
|
||||||
dest: dest.into(),
|
dest: dest.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::try_from)
|
.map(Order::try_from)
|
||||||
@@ -369,7 +375,7 @@ impl<Call> TryFrom<Xcm0<Call>> for Xcm<Call> {
|
|||||||
Xcm0::Transact { origin_type, require_weight_at_most, call } =>
|
Xcm0::Transact { origin_type, require_weight_at_most, call } =>
|
||||||
Transact { origin_type, require_weight_at_most, call: call.into() },
|
Transact { origin_type, require_weight_at_most, call: call.into() },
|
||||||
Xcm0::RelayedFrom { who, message } => RelayedFrom {
|
Xcm0::RelayedFrom { who, message } => RelayedFrom {
|
||||||
who: who.into(),
|
who: who.try_into()?,
|
||||||
message: alloc::boxed::Box::new((*message).try_into()?),
|
message: alloc::boxed::Box::new((*message).try_into()?),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -23,10 +23,7 @@
|
|||||||
//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
|
//! - `MultiAssetFilter`: A combination of `Wild` and `MultiAssets` designed for efficiently filtering an XCM holding
|
||||||
//! account.
|
//! account.
|
||||||
|
|
||||||
use super::{
|
use super::MultiLocation;
|
||||||
Junction,
|
|
||||||
MultiLocation::{self, X1},
|
|
||||||
};
|
|
||||||
use alloc::{vec, vec::Vec};
|
use alloc::{vec, vec::Vec};
|
||||||
use core::{
|
use core::{
|
||||||
cmp::Ordering,
|
cmp::Ordering,
|
||||||
@@ -104,15 +101,9 @@ pub enum AssetId {
|
|||||||
Abstract(Vec<u8>),
|
Abstract(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<MultiLocation> for AssetId {
|
impl<T: Into<MultiLocation>> From<T> for AssetId {
|
||||||
fn from(x: MultiLocation) -> Self {
|
fn from(x: T) -> Self {
|
||||||
Self::Concrete(x)
|
Self::Concrete(x.into())
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Junction> for AssetId {
|
|
||||||
fn from(x: Junction) -> Self {
|
|
||||||
Self::Concrete(X1(x))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,9 +233,9 @@ impl TryFrom<super::super::v0::MultiAsset> for MultiAsset {
|
|||||||
use AssetId::*;
|
use AssetId::*;
|
||||||
use Fungibility::*;
|
use Fungibility::*;
|
||||||
let (id, fun) = match old {
|
let (id, fun) = match old {
|
||||||
V0::ConcreteFungible { id, amount } => (Concrete(id.into()), Fungible(amount)),
|
V0::ConcreteFungible { id, amount } => (Concrete(id.try_into()?), Fungible(amount)),
|
||||||
V0::ConcreteNonFungible { class, instance } =>
|
V0::ConcreteNonFungible { class, instance } =>
|
||||||
(Concrete(class.into()), NonFungible(instance)),
|
(Concrete(class.try_into()?), NonFungible(instance)),
|
||||||
V0::AbstractFungible { id, amount } => (Abstract(id), Fungible(amount)),
|
V0::AbstractFungible { id, amount } => (Abstract(id), Fungible(amount)),
|
||||||
V0::AbstractNonFungible { class, instance } => (Abstract(class), NonFungible(instance)),
|
V0::AbstractNonFungible { class, instance } => (Abstract(class), NonFungible(instance)),
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
@@ -456,8 +447,8 @@ impl TryFrom<super::super::v0::MultiAsset> for WildMultiAsset {
|
|||||||
use WildFungibility::*;
|
use WildFungibility::*;
|
||||||
let (id, fun) = match old {
|
let (id, fun) = match old {
|
||||||
V0::All => return Ok(WildMultiAsset::All),
|
V0::All => return Ok(WildMultiAsset::All),
|
||||||
V0::AllConcreteFungible { id } => (Concrete(id.into()), Fungible),
|
V0::AllConcreteFungible { id } => (Concrete(id.try_into()?), Fungible),
|
||||||
V0::AllConcreteNonFungible { class } => (Concrete(class.into()), NonFungible),
|
V0::AllConcreteNonFungible { class } => (Concrete(class.try_into()?), NonFungible),
|
||||||
V0::AllAbstractFungible { id } => (Abstract(id), Fungible),
|
V0::AllAbstractFungible { id } => (Abstract(id), Fungible),
|
||||||
V0::AllAbstractNonFungible { class } => (Abstract(class), NonFungible),
|
V0::AllAbstractNonFungible { class } => (Abstract(class), NonFungible),
|
||||||
_ => return Err(()),
|
_ => return Err(()),
|
||||||
|
|||||||
+1099
-598
File diff suppressed because it is too large
Load Diff
@@ -194,12 +194,15 @@ impl<Call> TryFrom<Order0<Call>> for Order<Call> {
|
|||||||
use Order::*;
|
use Order::*;
|
||||||
Ok(match old {
|
Ok(match old {
|
||||||
Order0::Null => Noop,
|
Order0::Null => Noop,
|
||||||
Order0::DepositAsset { assets, dest } =>
|
Order0::DepositAsset { assets, dest } => DepositAsset {
|
||||||
DepositAsset { assets: assets.try_into()?, max_assets: 1, beneficiary: dest.into() },
|
assets: assets.try_into()?,
|
||||||
|
max_assets: 1,
|
||||||
|
beneficiary: dest.try_into()?,
|
||||||
|
},
|
||||||
Order0::DepositReserveAsset { assets, dest, effects } => DepositReserveAsset {
|
Order0::DepositReserveAsset { assets, dest, effects } => DepositReserveAsset {
|
||||||
assets: assets.try_into()?,
|
assets: assets.try_into()?,
|
||||||
max_assets: 1,
|
max_assets: 1,
|
||||||
dest: dest.into(),
|
dest: dest.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::<()>::try_from)
|
.map(Order::<()>::try_from)
|
||||||
@@ -210,7 +213,7 @@ impl<Call> TryFrom<Order0<Call>> for Order<Call> {
|
|||||||
Order0::InitiateReserveWithdraw { assets, reserve, effects } =>
|
Order0::InitiateReserveWithdraw { assets, reserve, effects } =>
|
||||||
InitiateReserveWithdraw {
|
InitiateReserveWithdraw {
|
||||||
assets: assets.try_into()?,
|
assets: assets.try_into()?,
|
||||||
reserve: reserve.into(),
|
reserve: reserve.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::<()>::try_from)
|
.map(Order::<()>::try_from)
|
||||||
@@ -218,14 +221,14 @@ impl<Call> TryFrom<Order0<Call>> for Order<Call> {
|
|||||||
},
|
},
|
||||||
Order0::InitiateTeleport { assets, dest, effects } => InitiateTeleport {
|
Order0::InitiateTeleport { assets, dest, effects } => InitiateTeleport {
|
||||||
assets: assets.try_into()?,
|
assets: assets.try_into()?,
|
||||||
dest: dest.into(),
|
dest: dest.try_into()?,
|
||||||
effects: effects
|
effects: effects
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Order::<()>::try_from)
|
.map(Order::<()>::try_from)
|
||||||
.collect::<result::Result<_, _>>()?,
|
.collect::<result::Result<_, _>>()?,
|
||||||
},
|
},
|
||||||
Order0::QueryHolding { query_id, dest, assets } =>
|
Order0::QueryHolding { query_id, dest, assets } =>
|
||||||
QueryHolding { query_id, dest: dest.into(), assets: assets.try_into()? },
|
QueryHolding { query_id, dest: dest.try_into()?, assets: assets.try_into()? },
|
||||||
Order0::BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
|
Order0::BuyExecution { fees, weight, debt, halt_on_error, xcm } => {
|
||||||
let instructions =
|
let instructions =
|
||||||
xcm.into_iter().map(Xcm::<Call>::try_from).collect::<result::Result<_, _>>()?;
|
xcm.into_iter().map(Xcm::<Call>::try_from).collect::<result::Result<_, _>>()?;
|
||||||
|
|||||||
@@ -188,7 +188,7 @@ impl<C> ExecuteXcm<C> for () {
|
|||||||
///
|
///
|
||||||
/// # Example
|
/// # Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use xcm::v1::{MultiLocation, Xcm, Junction, Error, OriginKind, SendXcm, Result};
|
/// # use xcm::v1::{MultiLocation, Xcm, Junction, Junctions, Error, OriginKind, SendXcm, Result, Parent};
|
||||||
/// # use parity_scale_codec::Encode;
|
/// # use parity_scale_codec::Encode;
|
||||||
///
|
///
|
||||||
/// /// A sender that only passes the message through and does nothing.
|
/// /// A sender that only passes the message through and does nothing.
|
||||||
@@ -203,7 +203,9 @@ impl<C> ExecuteXcm<C> for () {
|
|||||||
/// struct Sender2;
|
/// struct Sender2;
|
||||||
/// impl SendXcm for Sender2 {
|
/// impl SendXcm for Sender2 {
|
||||||
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
|
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
|
||||||
/// if let MultiLocation::X2(j1, j2) = destination {
|
/// if matches!(destination.interior(), Junctions::X2(j1, j2))
|
||||||
|
/// && destination.parent_count() == 0
|
||||||
|
/// {
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
/// } else {
|
/// } else {
|
||||||
/// Err(Error::Undefined)
|
/// Err(Error::Undefined)
|
||||||
@@ -215,9 +217,12 @@ impl<C> ExecuteXcm<C> for () {
|
|||||||
/// struct Sender3;
|
/// struct Sender3;
|
||||||
/// impl SendXcm for Sender3 {
|
/// impl SendXcm for Sender3 {
|
||||||
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
|
/// fn send_xcm(destination: MultiLocation, message: Xcm<()>) -> Result {
|
||||||
/// match destination {
|
/// if matches!(destination.interior(), Junctions::Here)
|
||||||
/// MultiLocation::X1(j) if j == Junction::Parent => Ok(()),
|
/// && destination.parent_count() == 1
|
||||||
/// _ => Err(Error::CannotReachDestination(destination, message)),
|
/// {
|
||||||
|
/// Ok(())
|
||||||
|
/// } else {
|
||||||
|
/// Err(Error::CannotReachDestination(destination, message))
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
@@ -226,7 +231,7 @@ impl<C> ExecuteXcm<C> for () {
|
|||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let call: Vec<u8> = ().encode();
|
/// let call: Vec<u8> = ().encode();
|
||||||
/// let message = Xcm::Transact { origin_type: OriginKind::Superuser, require_weight_at_most: 0, call: call.into() };
|
/// 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 = Parent.into();
|
||||||
///
|
///
|
||||||
/// assert!(
|
/// assert!(
|
||||||
/// // Sender2 will block this.
|
/// // Sender2 will block this.
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
use frame_support::{ensure, traits::Contains, weights::Weight};
|
use frame_support::{ensure, traits::Contains, weights::Weight};
|
||||||
use polkadot_parachain::primitives::IsSystem;
|
use polkadot_parachain::primitives::IsSystem;
|
||||||
use sp_std::{marker::PhantomData, result::Result};
|
use sp_std::{marker::PhantomData, result::Result};
|
||||||
use xcm::latest::{Junction, MultiLocation, Order, Xcm};
|
use xcm::latest::{Junction, Junctions, MultiLocation, Order, Xcm};
|
||||||
use xcm_executor::traits::{OnResponse, ShouldExecute};
|
use xcm_executor::traits::{OnResponse, ShouldExecute};
|
||||||
|
|
||||||
/// Execution barrier that just takes `shallow_weight` from `weight_credit`.
|
/// Execution barrier that just takes `shallow_weight` from `weight_credit`.
|
||||||
@@ -84,7 +84,11 @@ impl<T: Contains<MultiLocation>> ShouldExecute for AllowUnpaidExecutionFrom<T> {
|
|||||||
pub struct IsChildSystemParachain<ParaId>(PhantomData<ParaId>);
|
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 {
|
fn contains(l: &MultiLocation) -> bool {
|
||||||
matches!(l, MultiLocation::X1(Junction::Parachain(id)) if ParaId::from(*id).is_system())
|
matches!(
|
||||||
|
l.interior(),
|
||||||
|
Junctions::X1(Junction::Parachain(id))
|
||||||
|
if ParaId::from(*id).is_system() && l.parent_count() == 0,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ impl From<Error> for XcmError {
|
|||||||
/// # Example
|
/// # Example
|
||||||
/// ```
|
/// ```
|
||||||
/// use frame_support::parameter_types;
|
/// use frame_support::parameter_types;
|
||||||
/// use xcm::latest::{MultiLocation, Junction};
|
/// use xcm::latest::prelude::*;
|
||||||
/// use xcm_builder::{ParentIsDefault, CurrencyAdapter, IsConcrete};
|
/// use xcm_builder::{ParentIsDefault, CurrencyAdapter, IsConcrete};
|
||||||
///
|
///
|
||||||
/// /// Our chain's account id.
|
/// /// Our chain's account id.
|
||||||
@@ -61,7 +61,7 @@ impl From<Error> for XcmError {
|
|||||||
///
|
///
|
||||||
/// /// Our relay chain's location.
|
/// /// Our relay chain's location.
|
||||||
/// parameter_types! {
|
/// parameter_types! {
|
||||||
/// RelayChain: MultiLocation = MultiLocation::X1(Junction::Parent);
|
/// RelayChain: MultiLocation = Parent.into();
|
||||||
/// CheckingAccount: AccountId = Default::default();
|
/// CheckingAccount: AccountId = Default::default();
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -38,18 +38,24 @@ impl<Prefix: Get<MultiLocation>, AssetId: Clone, ConvertAssetId: Convert<u128, A
|
|||||||
fn convert_ref(id: impl Borrow<MultiLocation>) -> result::Result<AssetId, ()> {
|
fn convert_ref(id: impl Borrow<MultiLocation>) -> result::Result<AssetId, ()> {
|
||||||
let prefix = Prefix::get();
|
let prefix = Prefix::get();
|
||||||
let id = id.borrow();
|
let id = id.borrow();
|
||||||
if !prefix.iter().enumerate().all(|(index, item)| id.at(index) == Some(item)) {
|
if prefix.parent_count() != id.parent_count() ||
|
||||||
|
prefix
|
||||||
|
.interior()
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.any(|(index, junction)| id.interior().at(index) != Some(junction))
|
||||||
|
{
|
||||||
return Err(())
|
return Err(())
|
||||||
}
|
}
|
||||||
match id.at(prefix.len()) {
|
match id.interior().at(prefix.interior().len()) {
|
||||||
Some(Junction::GeneralIndex { id }) => ConvertAssetId::convert_ref(id),
|
Some(Junction::GeneralIndex(id)) => ConvertAssetId::convert_ref(id),
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn reverse_ref(what: impl Borrow<AssetId>) -> result::Result<MultiLocation, ()> {
|
fn reverse_ref(what: impl Borrow<AssetId>) -> result::Result<MultiLocation, ()> {
|
||||||
let mut location = Prefix::get();
|
let mut location = Prefix::get();
|
||||||
let id = ConvertAssetId::reverse_ref(what)?;
|
let id = ConvertAssetId::reverse_ref(what)?;
|
||||||
location.push(Junction::GeneralIndex { id }).map_err(|_| ())?;
|
location.push_interior(Junction::GeneralIndex(id))?;
|
||||||
Ok(location)
|
Ok(location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use parity_scale_codec::Encode;
|
|||||||
use sp_io::hashing::blake2_256;
|
use sp_io::hashing::blake2_256;
|
||||||
use sp_runtime::traits::AccountIdConversion;
|
use sp_runtime::traits::AccountIdConversion;
|
||||||
use sp_std::{borrow::Borrow, marker::PhantomData};
|
use sp_std::{borrow::Borrow, marker::PhantomData};
|
||||||
use xcm::latest::{Junction, MultiLocation, NetworkId};
|
use xcm::latest::{Junction::*, Junctions::*, MultiLocation, NetworkId, Parent};
|
||||||
use xcm_executor::traits::{Convert, InvertLocation};
|
use xcm_executor::traits::{Convert, InvertLocation};
|
||||||
|
|
||||||
pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||||
@@ -42,7 +42,7 @@ impl<AccountId: Default + Eq + Clone> Convert<MultiLocation, AccountId>
|
|||||||
for ParentIsDefault<AccountId>
|
for ParentIsDefault<AccountId>
|
||||||
{
|
{
|
||||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||||
if let &MultiLocation::X1(Junction::Parent) = location.borrow() {
|
if location.borrow().contains_parents_only(1) {
|
||||||
Ok(AccountId::default())
|
Ok(AccountId::default())
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
@@ -51,7 +51,7 @@ impl<AccountId: Default + Eq + Clone> Convert<MultiLocation, AccountId>
|
|||||||
|
|
||||||
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
||||||
if who.borrow() == &AccountId::default() {
|
if who.borrow() == &AccountId::default() {
|
||||||
Ok(Junction::Parent.into())
|
Ok(Parent.into())
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
@@ -63,16 +63,16 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
|
|||||||
Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId>
|
Convert<MultiLocation, AccountId> for ChildParachainConvertsVia<ParaId, AccountId>
|
||||||
{
|
{
|
||||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||||
if let &MultiLocation::X1(Junction::Parachain(id)) = location.borrow() {
|
match location.borrow() {
|
||||||
Ok(ParaId::from(id).into_account())
|
MultiLocation { parents: 0, interior: X1(Parachain(id)) } =>
|
||||||
} else {
|
Ok(ParaId::from(*id).into_account()),
|
||||||
Err(())
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
||||||
if let Some(id) = ParaId::try_from_account(who.borrow()) {
|
if let Some(id) = ParaId::try_from_account(who.borrow()) {
|
||||||
Ok(Junction::Parachain(id.into()).into())
|
Ok(Parachain(id.into()).into())
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
@@ -84,16 +84,16 @@ impl<ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>, AccountId:
|
|||||||
Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId>
|
Convert<MultiLocation, AccountId> for SiblingParachainConvertsVia<ParaId, AccountId>
|
||||||
{
|
{
|
||||||
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
fn convert_ref(location: impl Borrow<MultiLocation>) -> Result<AccountId, ()> {
|
||||||
if let &MultiLocation::X2(Junction::Parent, Junction::Parachain(id)) = location.borrow() {
|
match location.borrow() {
|
||||||
Ok(ParaId::from(id).into_account())
|
MultiLocation { parents: 1, interior: X1(Parachain(id)) } =>
|
||||||
} else {
|
Ok(ParaId::from(*id).into_account()),
|
||||||
Err(())
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
fn reverse_ref(who: impl Borrow<AccountId>) -> Result<MultiLocation, ()> {
|
||||||
if let Some(id) = ParaId::try_from_account(who.borrow()) {
|
if let Some(id) = ParaId::try_from_account(who.borrow()) {
|
||||||
Ok([Junction::Parent, Junction::Parachain(id.into())].into())
|
Ok(MultiLocation::new(1, X1(Parachain(id.into()))))
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
@@ -107,17 +107,20 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 32]> + Into<[u8; 32]> + Clone
|
|||||||
{
|
{
|
||||||
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
|
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
|
||||||
let id = match location {
|
let id = match location {
|
||||||
MultiLocation::X1(Junction::AccountId32 { id, network: NetworkId::Any }) => id,
|
MultiLocation {
|
||||||
MultiLocation::X1(Junction::AccountId32 { id, network })
|
parents: 0,
|
||||||
if &network == &Network::get() =>
|
interior: X1(AccountId32 { id, network: NetworkId::Any }),
|
||||||
|
} => id,
|
||||||
|
MultiLocation { parents: 0, interior: X1(AccountId32 { id, network }) }
|
||||||
|
if network == Network::get() =>
|
||||||
id,
|
id,
|
||||||
l => return Err(l),
|
_ => return Err(location),
|
||||||
};
|
};
|
||||||
Ok(id.into())
|
Ok(id.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
|
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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,17 +130,20 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
|
|||||||
{
|
{
|
||||||
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
|
fn convert(location: MultiLocation) -> Result<AccountId, MultiLocation> {
|
||||||
let key = match location {
|
let key = match location {
|
||||||
MultiLocation::X1(Junction::AccountKey20 { key, network: NetworkId::Any }) => key,
|
MultiLocation {
|
||||||
MultiLocation::X1(Junction::AccountKey20 { key, network })
|
parents: 0,
|
||||||
if &network == &Network::get() =>
|
interior: X1(AccountKey20 { key, network: NetworkId::Any }),
|
||||||
|
} => key,
|
||||||
|
MultiLocation { parents: 0, interior: X1(AccountKey20 { key, network }) }
|
||||||
|
if network == Network::get() =>
|
||||||
key,
|
key,
|
||||||
l => return Err(l),
|
_ => return Err(location),
|
||||||
};
|
};
|
||||||
Ok(key.into())
|
Ok(key.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reverse(who: AccountId) -> Result<MultiLocation, AccountId> {
|
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())
|
Ok(j.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -155,7 +161,7 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
|
|||||||
/// ```
|
/// ```
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use frame_support::parameter_types;
|
/// # use frame_support::parameter_types;
|
||||||
/// # use xcm::latest::{MultiLocation::{self, *}, Junction::*, NetworkId::Any};
|
/// # use xcm::latest::{MultiLocation, Junction::*, Junctions::{self, *}, NetworkId::Any};
|
||||||
/// # use xcm_builder::LocationInverter;
|
/// # use xcm_builder::LocationInverter;
|
||||||
/// # use xcm_executor::traits::InvertLocation;
|
/// # use xcm_executor::traits::InvertLocation;
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
@@ -163,16 +169,14 @@ impl<Network: Get<NetworkId>, AccountId: From<[u8; 20]> + Into<[u8; 20]> + Clone
|
|||||||
/// pub Ancestry: MultiLocation = X2(
|
/// pub Ancestry: MultiLocation = X2(
|
||||||
/// Parachain(1),
|
/// Parachain(1),
|
||||||
/// AccountKey20 { network: Any, key: Default::default() },
|
/// 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() }));
|
||||||
/// let inverted = LocationInverter::<Ancestry>::invert_location(&input);
|
/// let inverted = LocationInverter::<Ancestry>::invert_location(&input);
|
||||||
/// assert_eq!(inverted, X4(
|
/// assert_eq!(inverted, MultiLocation::new(
|
||||||
/// Parent,
|
/// 2,
|
||||||
/// Parent,
|
/// X2(Parachain(1), AccountKey20 { network: Any, key: Default::default() }),
|
||||||
/// Parachain(1),
|
|
||||||
/// AccountKey20 { network: Any, key: Default::default() },
|
|
||||||
/// ));
|
/// ));
|
||||||
/// # }
|
/// # }
|
||||||
/// ```
|
/// ```
|
||||||
@@ -180,18 +184,14 @@ pub struct LocationInverter<Ancestry>(PhantomData<Ancestry>);
|
|||||||
impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry> {
|
impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry> {
|
||||||
fn invert_location(location: &MultiLocation) -> MultiLocation {
|
fn invert_location(location: &MultiLocation) -> MultiLocation {
|
||||||
let mut ancestry = Ancestry::get();
|
let mut ancestry = Ancestry::get();
|
||||||
let mut result = location.clone();
|
let mut junctions = Here;
|
||||||
for (i, j) in location
|
for _ in 0..location.parent_count() {
|
||||||
.iter_rev()
|
junctions = junctions
|
||||||
.map(|j| match j {
|
.pushed_with(ancestry.take_first_interior().unwrap_or(OnlyChild))
|
||||||
Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild),
|
.expect("ancestry is well-formed and has less than 8 non-parent junctions; qed");
|
||||||
_ => Junction::Parent,
|
|
||||||
})
|
|
||||||
.enumerate()
|
|
||||||
{
|
|
||||||
*result.at_mut(i).expect("location and result begin equal; same size; qed") = j;
|
|
||||||
}
|
}
|
||||||
result
|
let parents = location.interior().len() as u8;
|
||||||
|
MultiLocation::new(parents, junctions)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -200,7 +200,7 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use frame_support::parameter_types;
|
use frame_support::parameter_types;
|
||||||
use xcm::latest::{Junction::*, MultiLocation::*, NetworkId::Any};
|
use xcm::latest::{Junction, NetworkId::Any};
|
||||||
|
|
||||||
fn account20() -> Junction {
|
fn account20() -> Junction {
|
||||||
AccountKey20 { network: Any, key: Default::default() }
|
AccountKey20 { network: Any, key: Default::default() }
|
||||||
@@ -225,12 +225,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn inverter_works_in_tree() {
|
fn inverter_works_in_tree() {
|
||||||
parameter_types! {
|
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()));
|
||||||
let inverted = LocationInverter::<Ancestry>::invert_location(&input);
|
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())));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network Topology
|
// Network Topology
|
||||||
@@ -240,12 +240,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn inverter_uses_ancestry_as_inverted_location() {
|
fn inverter_uses_ancestry_as_inverted_location() {
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub Ancestry: MultiLocation = X2(account20(), account20());
|
pub Ancestry: MultiLocation = X2(account20(), account20()).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
let input = X2(Parent, Parent);
|
let input = MultiLocation::grandparent();
|
||||||
let inverted = LocationInverter::<Ancestry>::invert_location(&input);
|
let inverted = LocationInverter::<Ancestry>::invert_location(&input);
|
||||||
assert_eq!(inverted, X2(account20(), account20()));
|
assert_eq!(inverted, X2(account20(), account20()).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Network Topology
|
// Network Topology
|
||||||
@@ -255,11 +255,11 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn inverter_uses_only_child_on_missing_ancestry() {
|
fn inverter_uses_only_child_on_missing_ancestry() {
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub Ancestry: MultiLocation = X1(PalletInstance(5));
|
pub Ancestry: MultiLocation = X1(PalletInstance(5)).into();
|
||||||
}
|
}
|
||||||
|
|
||||||
let input = X2(Parent, Parent);
|
let input = MultiLocation::grandparent();
|
||||||
let inverted = LocationInverter::<Ancestry>::invert_location(&input);
|
let inverted = LocationInverter::<Ancestry>::invert_location(&input);
|
||||||
assert_eq!(inverted, X2(PalletInstance(5), OnlyChild));
|
assert_eq!(inverted, X2(PalletInstance(5), OnlyChild).into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,16 +32,16 @@ use xcm_executor::traits::MatchesFungible;
|
|||||||
/// # Example
|
/// # Example
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use xcm::latest::prelude::*;
|
/// use xcm::latest::{MultiLocation, Parent};
|
||||||
/// use xcm_builder::IsConcrete;
|
/// use xcm_builder::IsConcrete;
|
||||||
/// use xcm_executor::traits::MatchesFungible;
|
/// use xcm_executor::traits::MatchesFungible;
|
||||||
///
|
///
|
||||||
/// frame_support::parameter_types! {
|
/// frame_support::parameter_types! {
|
||||||
/// pub TargetLocation: MultiLocation = X1(Parent);
|
/// pub TargetLocation: MultiLocation = Parent.into();
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let asset = (X1(Parent), 999).into();
|
/// let asset = (Parent, 999).into();
|
||||||
/// // match `asset` if it is a concrete asset in `TargetLocation`.
|
/// // match `asset` if it is a concrete asset in `TargetLocation`.
|
||||||
/// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
|
/// assert_eq!(<IsConcrete<TargetLocation> as MatchesFungible<u128>>::matches_fungible(&asset), Some(999));
|
||||||
/// # }
|
/// # }
|
||||||
|
|||||||
@@ -146,16 +146,16 @@ impl TransactAsset for TestAssetTransactor {
|
|||||||
pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
|
pub fn to_account(l: MultiLocation) -> Result<u64, MultiLocation> {
|
||||||
Ok(match l {
|
Ok(match l {
|
||||||
// Siblings at 2000+id
|
// Siblings at 2000+id
|
||||||
X2(Parent, Parachain(id)) => 2000 + id as u64,
|
MultiLocation { parents: 1, interior: X1(Parachain(id)) } => 2000 + id as u64,
|
||||||
// Accounts are their number
|
// Accounts are their number
|
||||||
X1(AccountIndex64 { index, .. }) => index,
|
MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) } => index,
|
||||||
// Children at 1000+id
|
// Children at 1000+id
|
||||||
X1(Parachain(id)) => 1000 + id as u64,
|
MultiLocation { parents: 0, interior: X1(Parachain(id)) } => 1000 + id as u64,
|
||||||
// Self at 3000
|
// Self at 3000
|
||||||
Here => 3000,
|
MultiLocation { parents: 0, interior: Here } => 3000,
|
||||||
// Parent at 3001
|
// Parent at 3001
|
||||||
X1(Parent) => 3001,
|
MultiLocation { parents: 1, interior: Here } => 3001,
|
||||||
l => return Err(l),
|
_ => return Err(l),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,9 +169,11 @@ impl ConvertOrigin<TestOrigin> for TestOriginConverter {
|
|||||||
match (kind, origin) {
|
match (kind, origin) {
|
||||||
(Superuser, _) => Ok(TestOrigin::Root),
|
(Superuser, _) => Ok(TestOrigin::Root),
|
||||||
(SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)),
|
(SovereignAccount, l) => Ok(TestOrigin::Signed(to_account(l)?)),
|
||||||
(Native, X1(Parachain(id))) => Ok(TestOrigin::Parachain(id)),
|
(Native, MultiLocation { parents: 0, interior: X1(Parachain(id)) }) =>
|
||||||
(Native, X1(Parent)) => Ok(TestOrigin::Relay),
|
Ok(TestOrigin::Parachain(id)),
|
||||||
(Native, X1(AccountIndex64 { index, .. })) => Ok(TestOrigin::Signed(index)),
|
(Native, MultiLocation { parents: 1, interior: Here }) => Ok(TestOrigin::Relay),
|
||||||
|
(Native, MultiLocation { parents: 0, interior: X1(AccountIndex64 { index, .. }) }) =>
|
||||||
|
Ok(TestOrigin::Signed(index)),
|
||||||
(_, origin) => Err(origin),
|
(_, origin) => Err(origin),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,7 +249,7 @@ pub fn response(query_id: u64) -> Option<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub TestAncestry: MultiLocation = X1(Parachain(42));
|
pub TestAncestry: MultiLocation = X1(Parachain(42)).into();
|
||||||
pub UnitWeightCost: Weight = 10;
|
pub UnitWeightCost: Weight = 10;
|
||||||
}
|
}
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
@@ -255,7 +257,7 @@ parameter_types! {
|
|||||||
pub static AllowUnpaidFrom: Vec<MultiLocation> = vec![];
|
pub static AllowUnpaidFrom: Vec<MultiLocation> = vec![];
|
||||||
pub static AllowPaidFrom: Vec<MultiLocation> = vec![];
|
pub static AllowPaidFrom: Vec<MultiLocation> = vec![];
|
||||||
// 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight.
|
// 1_000_000_000_000 => 1 unit of asset for 1 unit of Weight.
|
||||||
pub static WeightPrice: (AssetId, u128) = (Here.into(), 1_000_000_000_000);
|
pub static WeightPrice: (AssetId, u128) = (From::from(Here), 1_000_000_000_000);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type TestBarrier = (
|
pub type TestBarrier = (
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ use frame_support::traits::{EnsureOrigin, Get, GetBacking, OriginTrait};
|
|||||||
use frame_system::RawOrigin as SystemRawOrigin;
|
use frame_system::RawOrigin as SystemRawOrigin;
|
||||||
use polkadot_parachain::primitives::IsSystem;
|
use polkadot_parachain::primitives::IsSystem;
|
||||||
use sp_std::{convert::TryInto, marker::PhantomData};
|
use sp_std::{convert::TryInto, marker::PhantomData};
|
||||||
use xcm::latest::{BodyId, BodyPart, Junction, MultiLocation, NetworkId, OriginKind};
|
use xcm::latest::{BodyId, BodyPart, Junction, Junctions::*, MultiLocation, NetworkId, OriginKind};
|
||||||
use xcm_executor::traits::{Convert, ConvertOrigin};
|
use xcm_executor::traits::{Convert, ConvertOrigin};
|
||||||
|
|
||||||
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
|
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the `LocationConverter`.
|
||||||
@@ -45,9 +45,10 @@ where
|
|||||||
pub struct ParentAsSuperuser<Origin>(PhantomData<Origin>);
|
pub struct ParentAsSuperuser<Origin>(PhantomData<Origin>);
|
||||||
impl<Origin: OriginTrait> ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
|
impl<Origin: OriginTrait> ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
|
||||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||||
match (kind, origin) {
|
if kind == OriginKind::Superuser && origin.contains_parents_only(1) {
|
||||||
(OriginKind::Superuser, MultiLocation::X1(Junction::Parent)) => Ok(Origin::root()),
|
Ok(Origin::root())
|
||||||
(_, origin) => Err(origin),
|
} else {
|
||||||
|
Err(origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -58,9 +59,10 @@ impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
|
|||||||
{
|
{
|
||||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||||
match (kind, origin) {
|
match (kind, origin) {
|
||||||
(OriginKind::Superuser, MultiLocation::X1(Junction::Parachain(id)))
|
(
|
||||||
if ParaId::from(id).is_system() =>
|
OriginKind::Superuser,
|
||||||
Ok(Origin::root()),
|
MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) },
|
||||||
|
) if ParaId::from(id).is_system() => Ok(Origin::root()),
|
||||||
(_, origin) => Err(origin),
|
(_, origin) => Err(origin),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +76,7 @@ impl<ParaId: IsSystem + From<u32>, Origin: OriginTrait> ConvertOrigin<Origin>
|
|||||||
match (kind, origin) {
|
match (kind, origin) {
|
||||||
(
|
(
|
||||||
OriginKind::Superuser,
|
OriginKind::Superuser,
|
||||||
MultiLocation::X2(Junction::Parent, Junction::Parachain(id)),
|
MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) },
|
||||||
) if ParaId::from(id).is_system() => Ok(Origin::root()),
|
) if ParaId::from(id).is_system() => Ok(Origin::root()),
|
||||||
(_, origin) => Err(origin),
|
(_, origin) => Err(origin),
|
||||||
}
|
}
|
||||||
@@ -87,8 +89,10 @@ impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Or
|
|||||||
{
|
{
|
||||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||||
match (kind, origin) {
|
match (kind, origin) {
|
||||||
(OriginKind::Native, MultiLocation::X1(Junction::Parachain(id))) =>
|
(
|
||||||
Ok(Origin::from(ParachainOrigin::from(id))),
|
OriginKind::Native,
|
||||||
|
MultiLocation { parents: 0, interior: X1(Junction::Parachain(id)) },
|
||||||
|
) => Ok(Origin::from(ParachainOrigin::from(id))),
|
||||||
(_, origin) => Err(origin),
|
(_, origin) => Err(origin),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -102,8 +106,10 @@ impl<ParachainOrigin: From<u32>, Origin: From<ParachainOrigin>> ConvertOrigin<Or
|
|||||||
{
|
{
|
||||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||||
match (kind, origin) {
|
match (kind, origin) {
|
||||||
(OriginKind::Native, MultiLocation::X2(Junction::Parent, Junction::Parachain(id))) =>
|
(
|
||||||
Ok(Origin::from(ParachainOrigin::from(id))),
|
OriginKind::Native,
|
||||||
|
MultiLocation { parents: 1, interior: X1(Junction::Parachain(id)) },
|
||||||
|
) => Ok(Origin::from(ParachainOrigin::from(id))),
|
||||||
(_, origin) => Err(origin),
|
(_, origin) => Err(origin),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,9 +121,10 @@ impl<RelayOrigin: Get<Origin>, Origin> ConvertOrigin<Origin>
|
|||||||
for RelayChainAsNative<RelayOrigin, Origin>
|
for RelayChainAsNative<RelayOrigin, Origin>
|
||||||
{
|
{
|
||||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||||
match (kind, origin) {
|
if kind == OriginKind::Native && origin.contains_parents_only(1) {
|
||||||
(OriginKind::Native, MultiLocation::X1(Junction::Parent)) => Ok(RelayOrigin::get()),
|
Ok(RelayOrigin::get())
|
||||||
(_, origin) => Err(origin),
|
} else {
|
||||||
|
Err(origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -130,8 +137,10 @@ where
|
|||||||
{
|
{
|
||||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||||
match (kind, origin) {
|
match (kind, origin) {
|
||||||
(OriginKind::Native, MultiLocation::X1(Junction::AccountId32 { id, network }))
|
(
|
||||||
if matches!(network, NetworkId::Any) || network == Network::get() =>
|
OriginKind::Native,
|
||||||
|
MultiLocation { parents: 0, interior: X1(Junction::AccountId32 { id, network }) },
|
||||||
|
) if matches!(network, NetworkId::Any) || network == Network::get() =>
|
||||||
Ok(Origin::signed(id.into())),
|
Ok(Origin::signed(id.into())),
|
||||||
(_, origin) => Err(origin),
|
(_, origin) => Err(origin),
|
||||||
}
|
}
|
||||||
@@ -146,8 +155,10 @@ where
|
|||||||
{
|
{
|
||||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||||
match (kind, origin) {
|
match (kind, origin) {
|
||||||
(OriginKind::Native, MultiLocation::X1(Junction::AccountKey20 { key, network }))
|
(
|
||||||
if matches!(network, NetworkId::Any) || network == Network::get() =>
|
OriginKind::Native,
|
||||||
|
MultiLocation { parents: 0, interior: X1(Junction::AccountKey20 { key, network }) },
|
||||||
|
) if (matches!(network, NetworkId::Any) || network == Network::get()) =>
|
||||||
Ok(Origin::signed(key.into())),
|
Ok(Origin::signed(key.into())),
|
||||||
(_, origin) => Err(origin),
|
(_, origin) => Err(origin),
|
||||||
}
|
}
|
||||||
@@ -170,7 +181,7 @@ where
|
|||||||
// We institute a root fallback so root can always represent the context. This
|
// We institute a root fallback so root can always represent the context. This
|
||||||
// guarantees that `successful_origin` will work.
|
// guarantees that `successful_origin` will work.
|
||||||
if o.caller() == Origin::root().caller() {
|
if o.caller() == Origin::root().caller() {
|
||||||
Ok(MultiLocation::Here)
|
Ok(Here.into())
|
||||||
} else {
|
} else {
|
||||||
Err(o)
|
Err(o)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,35 +20,41 @@ use xcm_executor::{traits::*, Config, XcmExecutor};
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic_setup_works() {
|
fn basic_setup_works() {
|
||||||
add_reserve(X1(Parent), Wild((X1(Parent), WildFungible).into()));
|
add_reserve(Parent.into(), Wild((Parent, WildFungible).into()));
|
||||||
assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
|
assert!(<TestConfig as Config>::IsReserve::filter_asset_location(
|
||||||
&(X1(Parent), 100).into(),
|
&(Parent, 100).into(),
|
||||||
&X1(Parent),
|
&Parent.into(),
|
||||||
));
|
));
|
||||||
|
|
||||||
assert_eq!(to_account(X1(Parachain(1))), Ok(1001));
|
assert_eq!(to_account(X1(Parachain(1)).into()), Ok(1001));
|
||||||
assert_eq!(to_account(X1(Parachain(50))), Ok(1050));
|
assert_eq!(to_account(X1(Parachain(50)).into()), Ok(1050));
|
||||||
assert_eq!(to_account(X2(Parent, Parachain(1))), Ok(2001));
|
assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(1)))), Ok(2001));
|
||||||
assert_eq!(to_account(X2(Parent, Parachain(50))), Ok(2050));
|
assert_eq!(to_account(MultiLocation::new(1, X1(Parachain(50)))), Ok(2050));
|
||||||
assert_eq!(to_account(X1(AccountIndex64 { index: 1, network: Any })), Ok(1));
|
assert_eq!(
|
||||||
assert_eq!(to_account(X1(AccountIndex64 { index: 42, network: Any })), Ok(42));
|
to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 1, network: Any }))),
|
||||||
assert_eq!(to_account(Here), Ok(3000));
|
Ok(1),
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
to_account(MultiLocation::new(0, X1(AccountIndex64 { index: 42, network: Any }))),
|
||||||
|
Ok(42),
|
||||||
|
);
|
||||||
|
assert_eq!(to_account(Here.into()), Ok(3000));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn weigher_should_work() {
|
fn weigher_should_work() {
|
||||||
let mut message = opaque::Xcm::ReserveAssetDeposited {
|
let mut message = opaque::Xcm::ReserveAssetDeposited {
|
||||||
assets: (X1(Parent), 100).into(),
|
assets: (Parent, 100).into(),
|
||||||
effects: vec![
|
effects: vec![
|
||||||
Order::BuyExecution {
|
Order::BuyExecution {
|
||||||
fees: (X1(Parent), 1).into(),
|
fees: (Parent, 1).into(),
|
||||||
weight: 0,
|
weight: 0,
|
||||||
debt: 30,
|
debt: 30,
|
||||||
halt_on_error: true,
|
halt_on_error: true,
|
||||||
orders: vec![],
|
orders: vec![],
|
||||||
instructions: vec![],
|
instructions: vec![],
|
||||||
},
|
},
|
||||||
Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
|
Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here.into() },
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
.into();
|
.into();
|
||||||
@@ -58,16 +64,26 @@ fn weigher_should_work() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn take_weight_credit_barrier_should_work() {
|
fn take_weight_credit_barrier_should_work() {
|
||||||
let mut message =
|
let mut message =
|
||||||
opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
|
opaque::Xcm::TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() };
|
||||||
|
|
||||||
let mut weight_credit = 10;
|
let mut weight_credit = 10;
|
||||||
let r =
|
let r = TakeWeightCredit::should_execute(
|
||||||
TakeWeightCredit::should_execute(&X1(Parent), true, &mut message, 10, &mut weight_credit);
|
&Parent.into(),
|
||||||
|
true,
|
||||||
|
&mut message,
|
||||||
|
10,
|
||||||
|
&mut weight_credit,
|
||||||
|
);
|
||||||
assert_eq!(r, Ok(()));
|
assert_eq!(r, Ok(()));
|
||||||
assert_eq!(weight_credit, 0);
|
assert_eq!(weight_credit, 0);
|
||||||
|
|
||||||
let r =
|
let r = TakeWeightCredit::should_execute(
|
||||||
TakeWeightCredit::should_execute(&X1(Parent), true, &mut message, 10, &mut weight_credit);
|
&Parent.into(),
|
||||||
|
true,
|
||||||
|
&mut message,
|
||||||
|
10,
|
||||||
|
&mut weight_credit,
|
||||||
|
);
|
||||||
assert_eq!(r, Err(()));
|
assert_eq!(r, Err(()));
|
||||||
assert_eq!(weight_credit, 0);
|
assert_eq!(weight_credit, 0);
|
||||||
}
|
}
|
||||||
@@ -75,12 +91,12 @@ fn take_weight_credit_barrier_should_work() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn allow_unpaid_should_work() {
|
fn allow_unpaid_should_work() {
|
||||||
let mut message =
|
let mut message =
|
||||||
opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
|
opaque::Xcm::TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() };
|
||||||
|
|
||||||
AllowUnpaidFrom::set(vec![X1(Parent)]);
|
AllowUnpaidFrom::set(vec![Parent.into()]);
|
||||||
|
|
||||||
let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
|
let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
|
||||||
&X1(Parachain(1)),
|
&Parachain(1).into(),
|
||||||
true,
|
true,
|
||||||
&mut message,
|
&mut message,
|
||||||
10,
|
10,
|
||||||
@@ -89,7 +105,7 @@ fn allow_unpaid_should_work() {
|
|||||||
assert_eq!(r, Err(()));
|
assert_eq!(r, Err(()));
|
||||||
|
|
||||||
let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
|
let r = AllowUnpaidExecutionFrom::<IsInVec<AllowUnpaidFrom>>::should_execute(
|
||||||
&X1(Parent),
|
&Parent.into(),
|
||||||
true,
|
true,
|
||||||
&mut message,
|
&mut message,
|
||||||
10,
|
10,
|
||||||
@@ -100,13 +116,13 @@ fn allow_unpaid_should_work() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn allow_paid_should_work() {
|
fn allow_paid_should_work() {
|
||||||
AllowPaidFrom::set(vec![X1(Parent)]);
|
AllowPaidFrom::set(vec![Parent.into()]);
|
||||||
|
|
||||||
let mut message =
|
let mut message =
|
||||||
opaque::Xcm::TransferAsset { assets: (X1(Parent), 100).into(), beneficiary: Here };
|
opaque::Xcm::TransferAsset { assets: (Parent, 100).into(), beneficiary: Here.into() };
|
||||||
|
|
||||||
let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
|
let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
|
||||||
&X1(Parachain(1)),
|
&Parachain(1).into(),
|
||||||
true,
|
true,
|
||||||
&mut message,
|
&mut message,
|
||||||
10,
|
10,
|
||||||
@@ -114,9 +130,9 @@ fn allow_paid_should_work() {
|
|||||||
);
|
);
|
||||||
assert_eq!(r, Err(()));
|
assert_eq!(r, Err(()));
|
||||||
|
|
||||||
let fees = (X1(Parent), 1).into();
|
let fees = (Parent, 1).into();
|
||||||
let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
|
let mut underpaying_message = opaque::Xcm::ReserveAssetDeposited {
|
||||||
assets: (X1(Parent), 100).into(),
|
assets: (Parent, 100).into(),
|
||||||
effects: vec![
|
effects: vec![
|
||||||
Order::BuyExecution {
|
Order::BuyExecution {
|
||||||
fees,
|
fees,
|
||||||
@@ -126,12 +142,12 @@ fn allow_paid_should_work() {
|
|||||||
orders: vec![],
|
orders: vec![],
|
||||||
instructions: vec![],
|
instructions: vec![],
|
||||||
},
|
},
|
||||||
Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
|
Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here.into() },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
|
let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
|
||||||
&X1(Parent),
|
&Parent.into(),
|
||||||
true,
|
true,
|
||||||
&mut underpaying_message,
|
&mut underpaying_message,
|
||||||
30,
|
30,
|
||||||
@@ -139,9 +155,9 @@ fn allow_paid_should_work() {
|
|||||||
);
|
);
|
||||||
assert_eq!(r, Err(()));
|
assert_eq!(r, Err(()));
|
||||||
|
|
||||||
let fees = (X1(Parent), 1).into();
|
let fees = (Parent, 1).into();
|
||||||
let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
|
let mut paying_message = opaque::Xcm::ReserveAssetDeposited {
|
||||||
assets: (X1(Parent), 100).into(),
|
assets: (Parent, 100).into(),
|
||||||
effects: vec![
|
effects: vec![
|
||||||
Order::BuyExecution {
|
Order::BuyExecution {
|
||||||
fees,
|
fees,
|
||||||
@@ -151,12 +167,12 @@ fn allow_paid_should_work() {
|
|||||||
orders: vec![],
|
orders: vec![],
|
||||||
instructions: vec![],
|
instructions: vec![],
|
||||||
},
|
},
|
||||||
Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here },
|
Order::DepositAsset { assets: All.into(), max_assets: 1, beneficiary: Here.into() },
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
|
let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
|
||||||
&X1(Parachain(1)),
|
&Parachain(1).into(),
|
||||||
true,
|
true,
|
||||||
&mut paying_message,
|
&mut paying_message,
|
||||||
30,
|
30,
|
||||||
@@ -165,7 +181,7 @@ fn allow_paid_should_work() {
|
|||||||
assert_eq!(r, Err(()));
|
assert_eq!(r, Err(()));
|
||||||
|
|
||||||
let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
|
let r = AllowTopLevelPaidExecutionFrom::<IsInVec<AllowPaidFrom>>::should_execute(
|
||||||
&X1(Parent),
|
&Parent.into(),
|
||||||
true,
|
true,
|
||||||
&mut paying_message,
|
&mut paying_message,
|
||||||
30,
|
30,
|
||||||
@@ -176,14 +192,14 @@ fn allow_paid_should_work() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn paying_reserve_deposit_should_work() {
|
fn paying_reserve_deposit_should_work() {
|
||||||
AllowPaidFrom::set(vec![X1(Parent)]);
|
AllowPaidFrom::set(vec![Parent.into()]);
|
||||||
add_reserve(X1(Parent), (Parent, WildFungible).into());
|
add_reserve(Parent.into(), (Parent, WildFungible).into());
|
||||||
WeightPrice::set((Parent.into(), 1_000_000_000_000));
|
WeightPrice::set((Parent.into(), 1_000_000_000_000));
|
||||||
|
|
||||||
let origin = X1(Parent);
|
let origin = Parent.into();
|
||||||
let fees = (X1(Parent), 30).into();
|
let fees = (Parent, 30).into();
|
||||||
let message = Xcm::<TestCall>::ReserveAssetDeposited {
|
let message = Xcm::<TestCall>::ReserveAssetDeposited {
|
||||||
assets: (X1(Parent), 100).into(),
|
assets: (Parent, 100).into(),
|
||||||
effects: vec![
|
effects: vec![
|
||||||
Order::<TestCall>::BuyExecution {
|
Order::<TestCall>::BuyExecution {
|
||||||
fees,
|
fees,
|
||||||
@@ -196,28 +212,28 @@ fn paying_reserve_deposit_should_work() {
|
|||||||
Order::<TestCall>::DepositAsset {
|
Order::<TestCall>::DepositAsset {
|
||||||
assets: All.into(),
|
assets: All.into(),
|
||||||
max_assets: 1,
|
max_assets: 1,
|
||||||
beneficiary: Here,
|
beneficiary: Here.into(),
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
let weight_limit = 50;
|
let weight_limit = 50;
|
||||||
let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
|
let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
|
||||||
assert_eq!(r, Outcome::Complete(30));
|
assert_eq!(r, Outcome::Complete(30));
|
||||||
assert_eq!(assets(3000), vec![(X1(Parent), 70).into()]);
|
assert_eq!(assets(3000), vec![(Parent, 70).into()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn transfer_should_work() {
|
fn transfer_should_work() {
|
||||||
// we'll let them have message execution for free.
|
// 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.
|
// Child parachain #1 owns 1000 tokens held by us in reserve.
|
||||||
add_asset(1001, (Here, 1000).into());
|
add_asset(1001, (Here, 1000).into());
|
||||||
// They want to transfer 100 of them to their sibling parachain #2
|
// They want to transfer 100 of them to their sibling parachain #2
|
||||||
let r = XcmExecutor::<TestConfig>::execute_xcm(
|
let r = XcmExecutor::<TestConfig>::execute_xcm(
|
||||||
X1(Parachain(1)),
|
Parachain(1).into(),
|
||||||
Xcm::TransferAsset {
|
Xcm::TransferAsset {
|
||||||
assets: (Here, 100).into(),
|
assets: (Here, 100).into(),
|
||||||
beneficiary: X1(AccountIndex64 { index: 3, network: Any }),
|
beneficiary: X1(AccountIndex64 { index: 3, network: Any }).into(),
|
||||||
},
|
},
|
||||||
50,
|
50,
|
||||||
);
|
);
|
||||||
@@ -229,19 +245,19 @@ fn transfer_should_work() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn reserve_transfer_should_work() {
|
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.
|
// Child parachain #1 owns 1000 tokens held by us in reserve.
|
||||||
add_asset(1001, (Here, 1000).into());
|
add_asset(1001, (Here, 1000).into());
|
||||||
// The remote account owned by gav.
|
// 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
|
// 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.
|
// and let them know to hand it to account #3.
|
||||||
let r = XcmExecutor::<TestConfig>::execute_xcm(
|
let r = XcmExecutor::<TestConfig>::execute_xcm(
|
||||||
X1(Parachain(1)),
|
Parachain(1).into(),
|
||||||
Xcm::TransferReserveAsset {
|
Xcm::TransferReserveAsset {
|
||||||
assets: (Here, 100).into(),
|
assets: (Here, 100).into(),
|
||||||
dest: X1(Parachain(2)),
|
dest: Parachain(2).into(),
|
||||||
effects: vec![Order::DepositAsset {
|
effects: vec![Order::DepositAsset {
|
||||||
assets: All.into(),
|
assets: All.into(),
|
||||||
max_assets: 1,
|
max_assets: 1,
|
||||||
@@ -256,9 +272,9 @@ fn reserve_transfer_should_work() {
|
|||||||
assert_eq!(
|
assert_eq!(
|
||||||
sent_xcm(),
|
sent_xcm(),
|
||||||
vec![(
|
vec![(
|
||||||
X1(Parachain(2)),
|
Parachain(2).into(),
|
||||||
Xcm::ReserveAssetDeposited {
|
Xcm::ReserveAssetDeposited {
|
||||||
assets: (X1(Parent), 100).into(),
|
assets: (Parent, 100).into(),
|
||||||
effects: vec![Order::DepositAsset {
|
effects: vec![Order::DepositAsset {
|
||||||
assets: All.into(),
|
assets: All.into(),
|
||||||
max_assets: 1,
|
max_assets: 1,
|
||||||
@@ -271,9 +287,9 @@ fn reserve_transfer_should_work() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn transacting_should_work() {
|
fn transacting_should_work() {
|
||||||
AllowUnpaidFrom::set(vec![X1(Parent)]);
|
AllowUnpaidFrom::set(vec![Parent.into()]);
|
||||||
|
|
||||||
let origin = X1(Parent);
|
let origin = Parent.into();
|
||||||
let message = Xcm::<TestCall>::Transact {
|
let message = Xcm::<TestCall>::Transact {
|
||||||
origin_type: OriginKind::Native,
|
origin_type: OriginKind::Native,
|
||||||
require_weight_at_most: 50,
|
require_weight_at_most: 50,
|
||||||
@@ -286,9 +302,9 @@ fn transacting_should_work() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn transacting_should_respect_max_weight_requirement() {
|
fn transacting_should_respect_max_weight_requirement() {
|
||||||
AllowUnpaidFrom::set(vec![X1(Parent)]);
|
AllowUnpaidFrom::set(vec![Parent.into()]);
|
||||||
|
|
||||||
let origin = X1(Parent);
|
let origin = Parent.into();
|
||||||
let message = Xcm::<TestCall>::Transact {
|
let message = Xcm::<TestCall>::Transact {
|
||||||
origin_type: OriginKind::Native,
|
origin_type: OriginKind::Native,
|
||||||
require_weight_at_most: 40,
|
require_weight_at_most: 40,
|
||||||
@@ -301,9 +317,9 @@ fn transacting_should_respect_max_weight_requirement() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn transacting_should_refund_weight() {
|
fn transacting_should_refund_weight() {
|
||||||
AllowUnpaidFrom::set(vec![X1(Parent)]);
|
AllowUnpaidFrom::set(vec![Parent.into()]);
|
||||||
|
|
||||||
let origin = X1(Parent);
|
let origin = Parent.into();
|
||||||
let message = Xcm::<TestCall>::Transact {
|
let message = Xcm::<TestCall>::Transact {
|
||||||
origin_type: OriginKind::Native,
|
origin_type: OriginKind::Native,
|
||||||
require_weight_at_most: 50,
|
require_weight_at_most: 50,
|
||||||
@@ -316,15 +332,15 @@ fn transacting_should_refund_weight() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn paid_transacting_should_refund_payment_for_unused_weight() {
|
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()]);
|
AllowPaidFrom::set(vec![one.clone()]);
|
||||||
add_asset(1, (Parent, 100).into());
|
add_asset(1, (Parent, 100).into());
|
||||||
WeightPrice::set((Parent.into(), 1_000_000_000_000));
|
WeightPrice::set((Parent.into(), 1_000_000_000_000));
|
||||||
|
|
||||||
let origin = one.clone();
|
let origin = one.clone();
|
||||||
let fees = (X1(Parent), 100).into();
|
let fees = (Parent, 100).into();
|
||||||
let message = Xcm::<TestCall>::WithdrawAsset {
|
let message = Xcm::<TestCall>::WithdrawAsset {
|
||||||
assets: (X1(Parent), 100).into(), // enough for 100 units of weight.
|
assets: (Parent, 100).into(), // enough for 100 units of weight.
|
||||||
effects: vec![
|
effects: vec![
|
||||||
Order::<TestCall>::BuyExecution {
|
Order::<TestCall>::BuyExecution {
|
||||||
fees,
|
fees,
|
||||||
@@ -349,17 +365,17 @@ fn paid_transacting_should_refund_payment_for_unused_weight() {
|
|||||||
let weight_limit = 100;
|
let weight_limit = 100;
|
||||||
let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
|
let r = XcmExecutor::<TestConfig>::execute_xcm(origin, message, weight_limit);
|
||||||
assert_eq!(r, Outcome::Complete(50));
|
assert_eq!(r, Outcome::Complete(50));
|
||||||
assert_eq!(assets(1), vec![(X1(Parent), 50).into()]);
|
assert_eq!(assets(1), vec![(Parent, 50).into()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn prepaid_result_of_query_should_get_free_execution() {
|
fn prepaid_result_of_query_should_get_free_execution() {
|
||||||
let query_id = 33;
|
let query_id = 33;
|
||||||
let origin = X1(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.
|
// 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());
|
expect_response(query_id, origin.clone());
|
||||||
|
|
||||||
let the_response = Response::Assets((X1(Parent), 100).into());
|
let the_response = Response::Assets((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;
|
let weight_limit = 10;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ use polkadot_test_client::{
|
|||||||
use polkadot_test_service::construct_extrinsic;
|
use polkadot_test_service::construct_extrinsic;
|
||||||
use sp_runtime::{generic::BlockId, traits::Block};
|
use sp_runtime::{generic::BlockId, traits::Block};
|
||||||
use sp_state_machine::InspectState;
|
use sp_state_machine::InspectState;
|
||||||
use xcm::latest::{Error as XcmError, Junction::*, MultiLocation::*, Order, Outcome, Xcm::*};
|
use xcm::latest::prelude::*;
|
||||||
use xcm_executor::MAX_RECURSION_LIMIT;
|
use xcm_executor::MAX_RECURSION_LIMIT;
|
||||||
|
|
||||||
// This is the inflection point where the test should either fail or pass.
|
// 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)
|
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut msg = WithdrawAsset { assets: (X1(Parent), 100).into(), effects: vec![] };
|
let mut msg = WithdrawAsset { assets: (Parent, 100).into(), effects: vec![] };
|
||||||
for _ in 0..MAX_RECURSION_CHECK {
|
for _ in 0..MAX_RECURSION_CHECK {
|
||||||
msg = WithdrawAsset {
|
msg = WithdrawAsset {
|
||||||
assets: (X1(Parent), 100).into(),
|
assets: (Parent, 100).into(),
|
||||||
effects: vec![Order::BuyExecution {
|
effects: vec![Order::BuyExecution {
|
||||||
fees: (X1(Parent), 1).into(),
|
fees: (Parent, 1).into(),
|
||||||
weight: 0,
|
weight: 0,
|
||||||
debt: 0,
|
debt: 0,
|
||||||
halt_on_error: true,
|
halt_on_error: true,
|
||||||
@@ -92,12 +92,12 @@ fn exceed_recursion_limit() {
|
|||||||
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
.set_execution_strategy(ExecutionStrategy::AlwaysWasm)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
let mut msg = WithdrawAsset { assets: (X1(Parent), 100).into(), effects: vec![] };
|
let mut msg = WithdrawAsset { assets: (Parent, 100).into(), effects: vec![] };
|
||||||
for _ in 0..(MAX_RECURSION_CHECK + 1) {
|
for _ in 0..(MAX_RECURSION_CHECK + 1) {
|
||||||
msg = WithdrawAsset {
|
msg = WithdrawAsset {
|
||||||
assets: (X1(Parent), 100).into(),
|
assets: (Parent, 100).into(),
|
||||||
effects: vec![Order::BuyExecution {
|
effects: vec![Order::BuyExecution {
|
||||||
fees: (X1(Parent), 1).into(),
|
fees: (Parent, 1).into(),
|
||||||
weight: 0,
|
weight: 0,
|
||||||
debt: 0,
|
debt: 0,
|
||||||
halt_on_error: true,
|
halt_on_error: true,
|
||||||
|
|||||||
@@ -430,7 +430,6 @@ impl Assets {
|
|||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use xcm::latest::prelude::*;
|
use xcm::latest::prelude::*;
|
||||||
use MultiLocation::Here;
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
/// Abstract fungible constructor
|
/// Abstract fungible constructor
|
||||||
fn AF(id: u8, amount: u128) -> MultiAsset {
|
fn AF(id: u8, amount: u128) -> MultiAsset {
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ impl<Config: config::Config> XcmExecutor<Config> {
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
(origin, Xcm::RelayedFrom { who, message }) => {
|
(origin, Xcm::RelayedFrom { who, message }) => {
|
||||||
ensure!(who.is_interior(), XcmError::EscalationOfPrivilege);
|
ensure!(who.parent_count() == 0, XcmError::EscalationOfPrivilege);
|
||||||
let mut origin = origin;
|
let mut origin = origin;
|
||||||
origin.append_with(who).map_err(|_| XcmError::MultiLocationFull)?;
|
origin.append_with(who).map_err(|_| XcmError::MultiLocationFull)?;
|
||||||
let surplus = Self::do_execute_xcm(
|
let surplus = Self::do_execute_xcm(
|
||||||
|
|||||||
@@ -139,15 +139,15 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
|
|||||||
/// which is passed to the next convert item.
|
/// which is passed to the next convert item.
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use xcm::latest::{MultiLocation, Junction, OriginKind};
|
/// # use xcm::latest::{MultiLocation, Junctions, Junction, OriginKind};
|
||||||
/// # use xcm_executor::traits::ConvertOrigin;
|
/// # use xcm_executor::traits::ConvertOrigin;
|
||||||
/// // A convertor that will bump the para id and pass it to the next one.
|
/// // A convertor that will bump the para id and pass it to the next one.
|
||||||
/// struct BumpParaId;
|
/// struct BumpParaId;
|
||||||
/// impl ConvertOrigin<u32> for BumpParaId {
|
/// impl ConvertOrigin<u32> for BumpParaId {
|
||||||
/// fn convert_origin(origin: MultiLocation, _: OriginKind) -> Result<u32, MultiLocation> {
|
/// fn convert_origin(origin: MultiLocation, _: OriginKind) -> Result<u32, MultiLocation> {
|
||||||
/// match origin {
|
/// match origin.interior() {
|
||||||
/// MultiLocation::X1(Junction::Parachain(id)) => {
|
/// Junctions::X1(Junction::Parachain(id)) if origin.parent_count() == 0 => {
|
||||||
/// Err(MultiLocation::X1(Junction::Parachain(id + 1)))
|
/// Err(Junctions::X1(Junction::Parachain(id + 1)).into())
|
||||||
/// }
|
/// }
|
||||||
/// _ => unreachable!()
|
/// _ => unreachable!()
|
||||||
/// }
|
/// }
|
||||||
@@ -157,8 +157,8 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
|
|||||||
/// struct AcceptPara7;
|
/// struct AcceptPara7;
|
||||||
/// impl ConvertOrigin<u32> for AcceptPara7 {
|
/// impl ConvertOrigin<u32> for AcceptPara7 {
|
||||||
/// fn convert_origin(origin: MultiLocation, _: OriginKind) -> Result<u32, MultiLocation> {
|
/// fn convert_origin(origin: MultiLocation, _: OriginKind) -> Result<u32, MultiLocation> {
|
||||||
/// match origin {
|
/// match origin.interior() {
|
||||||
/// MultiLocation::X1(Junction::Parachain(id)) if id == 7 => {
|
/// Junctions::X1(Junction::Parachain(id)) if id == &7 && origin.parent_count() == 0 => {
|
||||||
/// Ok(7)
|
/// Ok(7)
|
||||||
/// }
|
/// }
|
||||||
/// _ => Err(origin)
|
/// _ => Err(origin)
|
||||||
@@ -166,7 +166,7 @@ impl<T: Clone + Encode + Decode> Convert<Vec<u8>, T> for Decoded {
|
|||||||
/// }
|
/// }
|
||||||
/// }
|
/// }
|
||||||
/// # fn main() {
|
/// # fn main() {
|
||||||
/// let origin = MultiLocation::X1(Junction::Parachain(6));
|
/// let origin: MultiLocation = Junctions::X1(Junction::Parachain(6)).into();
|
||||||
/// assert!(
|
/// assert!(
|
||||||
/// <(BumpParaId, AcceptPara7) as ConvertOrigin<u32>>::convert_origin(origin, OriginKind::Native)
|
/// <(BumpParaId, AcceptPara7) as ConvertOrigin<u32>>::convert_origin(origin, OriginKind::Native)
|
||||||
/// .is_ok()
|
/// .is_ok()
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ impl TransactAsset for Tuple {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use MultiLocation::Here;
|
use xcm::latest::Junctions::Here;
|
||||||
|
|
||||||
pub struct UnimplementedTransactor;
|
pub struct UnimplementedTransactor;
|
||||||
impl TransactAsset for UnimplementedTransactor {}
|
impl TransactAsset for UnimplementedTransactor {}
|
||||||
@@ -273,7 +273,7 @@ mod tests {
|
|||||||
(UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
|
(UnimplementedTransactor, NotFoundTransactor, UnimplementedTransactor);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MultiTransactor::deposit_asset(&(Here, 1).into(), &Here),
|
MultiTransactor::deposit_asset(&(Here, 1).into(), &Here.into()),
|
||||||
Err(XcmError::AssetNotFound)
|
Err(XcmError::AssetNotFound)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -282,7 +282,7 @@ mod tests {
|
|||||||
fn unimplemented_and_not_found_continue_iteration() {
|
fn unimplemented_and_not_found_continue_iteration() {
|
||||||
type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, SuccessfulTransactor);
|
type MultiTransactor = (UnimplementedTransactor, NotFoundTransactor, SuccessfulTransactor);
|
||||||
|
|
||||||
assert_eq!(MultiTransactor::deposit_asset(&(Here, 1).into(), &Here), Ok(()));
|
assert_eq!(MultiTransactor::deposit_asset(&(Here, 1).into(), &Here.into()), Ok(()),);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -290,7 +290,7 @@ mod tests {
|
|||||||
type MultiTransactor = (OverflowTransactor, SuccessfulTransactor);
|
type MultiTransactor = (OverflowTransactor, SuccessfulTransactor);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
MultiTransactor::deposit_asset(&(Here, 1).into(), &Here),
|
MultiTransactor::deposit_asset(&(Here, 1).into(), &Here.into()),
|
||||||
Err(XcmError::Overflow)
|
Err(XcmError::Overflow)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -299,6 +299,6 @@ mod tests {
|
|||||||
fn success_stops_iteration() {
|
fn success_stops_iteration() {
|
||||||
type MultiTransactor = (SuccessfulTransactor, OverflowTransactor);
|
type MultiTransactor = (SuccessfulTransactor, OverflowTransactor);
|
||||||
|
|
||||||
assert_eq!(MultiTransactor::deposit_asset(&(Here, 1).into(), &Here), Ok(()));
|
assert_eq!(MultiTransactor::deposit_asset(&(Here, 1).into(), &Here.into()), Ok(()),);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,8 +111,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
Relay::execute_with(|| {
|
Relay::execute_with(|| {
|
||||||
assert_ok!(RelayChainPalletXcm::send_xcm(
|
assert_ok!(RelayChainPalletXcm::send_xcm(
|
||||||
Here,
|
Here.into(),
|
||||||
X1(Parachain(1)),
|
Parachain(1).into(),
|
||||||
Transact {
|
Transact {
|
||||||
origin_type: OriginKind::SovereignAccount,
|
origin_type: OriginKind::SovereignAccount,
|
||||||
require_weight_at_most: INITIAL_BALANCE as u64,
|
require_weight_at_most: INITIAL_BALANCE as u64,
|
||||||
@@ -138,8 +138,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
ParaA::execute_with(|| {
|
ParaA::execute_with(|| {
|
||||||
assert_ok!(ParachainPalletXcm::send_xcm(
|
assert_ok!(ParachainPalletXcm::send_xcm(
|
||||||
Here,
|
Here.into(),
|
||||||
X1(Parent),
|
Parent.into(),
|
||||||
Transact {
|
Transact {
|
||||||
origin_type: OriginKind::SovereignAccount,
|
origin_type: OriginKind::SovereignAccount,
|
||||||
require_weight_at_most: INITIAL_BALANCE as u64,
|
require_weight_at_most: INITIAL_BALANCE as u64,
|
||||||
@@ -165,8 +165,8 @@ mod tests {
|
|||||||
);
|
);
|
||||||
ParaA::execute_with(|| {
|
ParaA::execute_with(|| {
|
||||||
assert_ok!(ParachainPalletXcm::send_xcm(
|
assert_ok!(ParachainPalletXcm::send_xcm(
|
||||||
Here,
|
Here.into(),
|
||||||
X2(Parent, Parachain(2)),
|
MultiLocation::new(1, X1(Parachain(2))),
|
||||||
Transact {
|
Transact {
|
||||||
origin_type: OriginKind::SovereignAccount,
|
origin_type: OriginKind::SovereignAccount,
|
||||||
require_weight_at_most: INITIAL_BALANCE as u64,
|
require_weight_at_most: INITIAL_BALANCE as u64,
|
||||||
@@ -190,8 +190,8 @@ mod tests {
|
|||||||
Relay::execute_with(|| {
|
Relay::execute_with(|| {
|
||||||
assert_ok!(RelayChainPalletXcm::reserve_transfer_assets(
|
assert_ok!(RelayChainPalletXcm::reserve_transfer_assets(
|
||||||
relay_chain::Origin::signed(ALICE),
|
relay_chain::Origin::signed(ALICE),
|
||||||
Box::new(X1(Parachain(1))),
|
Box::new(X1(Parachain(1)).into()),
|
||||||
Box::new(X1(AccountId32 { network: Any, id: ALICE.into() })),
|
Box::new(X1(AccountId32 { network: Any, id: ALICE.into() }).into()),
|
||||||
(Here, 123).into(),
|
(Here, 123).into(),
|
||||||
0,
|
0,
|
||||||
3,
|
3,
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ parameter_types! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const KsmLocation: MultiLocation = MultiLocation::X1(Parent);
|
pub const KsmLocation: MultiLocation = MultiLocation::parent();
|
||||||
pub const RelayNetwork: NetworkId = NetworkId::Kusama;
|
pub const RelayNetwork: NetworkId = NetworkId::Kusama;
|
||||||
pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
|
pub Ancestry: MultiLocation = Parachain(MsgQueue::parachain_id().into()).into();
|
||||||
}
|
}
|
||||||
@@ -120,7 +120,7 @@ pub type XcmOriginToCallOrigin = (
|
|||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const UnitWeightCost: Weight = 1;
|
pub const UnitWeightCost: Weight = 1;
|
||||||
pub KsmPerSecond: (AssetId, u128) = (Concrete(X1(Parent)), 1);
|
pub KsmPerSecond: (AssetId, u128) = (Concrete(Parent.into()), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type LocalAssetTransactor =
|
pub type LocalAssetTransactor =
|
||||||
@@ -210,8 +210,8 @@ pub mod mock_msg_queue {
|
|||||||
let hash = Encode::using_encoded(&xcm, T::Hashing::hash);
|
let hash = Encode::using_encoded(&xcm, T::Hashing::hash);
|
||||||
let (result, event) = match Xcm::<T::Call>::try_from(xcm) {
|
let (result, event) = match Xcm::<T::Call>::try_from(xcm) {
|
||||||
Ok(xcm) => {
|
Ok(xcm) => {
|
||||||
let location = (Parent, Parachain(sender.into()));
|
let location = MultiLocation::new(1, X1(Parachain(sender.into())));
|
||||||
match T::XcmExecutor::execute_xcm(location.into(), xcm, max_weight) {
|
match T::XcmExecutor::execute_xcm(location, xcm, max_weight) {
|
||||||
Outcome::Error(e) => (Err(e.clone()), Event::Fail(Some(hash), e)),
|
Outcome::Error(e) => (Err(e.clone()), Event::Fail(Some(hash), e)),
|
||||||
Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))),
|
Outcome::Complete(w) => (Ok(w), Event::Success(Some(hash))),
|
||||||
// As far as the caller is concerned, this was dispatched without error, so
|
// As far as the caller is concerned, this was dispatched without error, so
|
||||||
|
|||||||
@@ -87,10 +87,10 @@ impl shared::Config for Runtime {}
|
|||||||
impl configuration::Config for Runtime {}
|
impl configuration::Config for Runtime {}
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
pub const KsmLocation: MultiLocation = MultiLocation::Here;
|
pub const KsmLocation: MultiLocation = Here.into();
|
||||||
pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
|
pub const KusamaNetwork: NetworkId = NetworkId::Kusama;
|
||||||
pub const AnyNetwork: NetworkId = NetworkId::Any;
|
pub const AnyNetwork: NetworkId = NetworkId::Any;
|
||||||
pub Ancestry: MultiLocation = MultiLocation::Here;
|
pub Ancestry: MultiLocation = Here.into();
|
||||||
pub UnitWeightCost: Weight = 1_000;
|
pub UnitWeightCost: Weight = 1_000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -195,8 +195,8 @@ macro_rules! decl_test_network {
|
|||||||
fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::XcmResult {
|
fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::XcmResult {
|
||||||
use $crate::{UmpSink, XcmpMessageHandlerT};
|
use $crate::{UmpSink, XcmpMessageHandlerT};
|
||||||
|
|
||||||
match destination {
|
match destination.interior() {
|
||||||
$crate::X1($crate::Parent) => {
|
$crate::Junctions::Here if destination.parent_count() == 1 => {
|
||||||
let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump);
|
let encoded = $crate::encode_xcm(message, $crate::MessageKind::Ump);
|
||||||
let _ = <$relay_chain>::process_upward_message(
|
let _ = <$relay_chain>::process_upward_message(
|
||||||
T::get(), &encoded[..],
|
T::get(), &encoded[..],
|
||||||
@@ -205,7 +205,7 @@ macro_rules! decl_test_network {
|
|||||||
Ok(())
|
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 encoded = $crate::encode_xcm(message, $crate::MessageKind::Xcmp);
|
||||||
let messages = vec![(T::get(), 1, &encoded[..])];
|
let messages = vec![(T::get(), 1, &encoded[..])];
|
||||||
let _ = <$parachain>::handle_xcmp_messages(
|
let _ = <$parachain>::handle_xcmp_messages(
|
||||||
@@ -226,9 +226,9 @@ macro_rules! decl_test_network {
|
|||||||
fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::XcmResult {
|
fn send_xcm(destination: $crate::MultiLocation, message: $crate::Xcm<()>) -> $crate::XcmResult {
|
||||||
use $crate::DmpMessageHandlerT;
|
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 encoded = $crate::encode_xcm(message, $crate::MessageKind::Dmp);
|
||||||
let messages = vec![(1, encoded)];
|
let messages = vec![(1, encoded)];
|
||||||
let _ = <$parachain>::handle_dmp_messages(
|
let _ = <$parachain>::handle_dmp_messages(
|
||||||
|
|||||||
Reference in New Issue
Block a user