mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 03:31:05 +00:00
XCM: Land XCM Builder (#1793)
* Land XCM Builder * Clean up Cargo dependencies Co-authored-by: Gavin Wood <gavin@parity.io>
This commit is contained in:
Generated
+149
-134
File diff suppressed because it is too large
Load Diff
@@ -41,6 +41,7 @@ members = [
|
||||
"service",
|
||||
"validation",
|
||||
"xcm",
|
||||
"xcm/xcm-builder",
|
||||
"xcm/xcm-executor",
|
||||
"node/collation-generation",
|
||||
"node/core/av-store",
|
||||
|
||||
@@ -124,9 +124,21 @@ impl Id {
|
||||
}
|
||||
|
||||
/// Returns `true` if this parachain runs with system-level privileges.
|
||||
/// Use IsSystem instead.
|
||||
#[deprecated]
|
||||
pub fn is_system(&self) -> bool { self.0 < USER_INDEX_START }
|
||||
}
|
||||
|
||||
pub trait IsSystem {
|
||||
fn is_system(&self) -> bool;
|
||||
}
|
||||
|
||||
impl IsSystem for Id {
|
||||
fn is_system(&self) -> bool {
|
||||
self.0 < USER_INDEX_START
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_std::ops::Add<u32> for Id {
|
||||
type Output = Self;
|
||||
|
||||
|
||||
@@ -7,3 +7,10 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "1.3.5", default-features = false, features = [ "derive" ] }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
wasm-api = []
|
||||
std = [
|
||||
"codec/std",
|
||||
]
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
[package]
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
name = "xcm-builder"
|
||||
description = "Tools & types for building with XCM and its executor."
|
||||
version = "0.8.22"
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "1.3.0", default-features = false, features = ["derive"] }
|
||||
xcm = { path = "..", default-features = false }
|
||||
xcm-executor = { path = "../xcm-executor", default-features = false }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-arithmetic = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "master" }
|
||||
|
||||
# Polkadot dependencies
|
||||
polkadot-parachain = { path = "../../parachain", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = [
|
||||
"codec/std",
|
||||
"xcm/std",
|
||||
"xcm-executor/std",
|
||||
"sp-std/std",
|
||||
"sp-arithmetic/std",
|
||||
"sp-io/std",
|
||||
"sp-runtime/std",
|
||||
"frame-support/std",
|
||||
"polkadot-parachain/std",
|
||||
]
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot 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.
|
||||
|
||||
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use sp_std::{result, convert::TryInto, marker::PhantomData};
|
||||
use xcm::v0::{Error, Result, MultiAsset, MultiLocation};
|
||||
use sp_arithmetic::traits::SaturatedConversion;
|
||||
use frame_support::traits::{ExistenceRequirement::AllowDeath, WithdrawReason};
|
||||
use xcm_executor::traits::{MatchesFungible, LocationConversion, TransactAsset};
|
||||
|
||||
pub struct CurrencyAdapter<Currency, Matcher, AccountIdConverter, AccountId>(
|
||||
PhantomData<Currency>,
|
||||
PhantomData<Matcher>,
|
||||
PhantomData<AccountIdConverter>,
|
||||
PhantomData<AccountId>,
|
||||
);
|
||||
|
||||
impl<
|
||||
Matcher: MatchesFungible<Currency::Balance>,
|
||||
AccountIdConverter: LocationConversion<AccountId>,
|
||||
Currency: frame_support::traits::Currency<AccountId>,
|
||||
AccountId, // can't get away without it since Currency is generic over it.
|
||||
> TransactAsset for CurrencyAdapter<Currency, Matcher, AccountIdConverter, AccountId> {
|
||||
|
||||
fn deposit_asset(what: &MultiAsset, who: &MultiLocation) -> Result {
|
||||
// Check we handle this asset.
|
||||
let amount = Matcher::matches_fungible(&what).ok_or(())?.saturated_into();
|
||||
let who = AccountIdConverter::from_location(who).ok_or(())?;
|
||||
let balance_amount = amount.try_into().map_err(|_| ())?;
|
||||
let _imbalance = Currency::deposit_creating(&who, balance_amount);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn withdraw_asset(what: &MultiAsset, who: &MultiLocation) -> result::Result<MultiAsset, Error> {
|
||||
// Check we handle this asset.
|
||||
let amount = Matcher::matches_fungible(&what).ok_or(())?.saturated_into();
|
||||
let who = AccountIdConverter::from_location(who).ok_or(())?;
|
||||
let balance_amount = amount.try_into().map_err(|_| ())?;
|
||||
Currency::withdraw(&who, balance_amount, WithdrawReason::Transfer.into(), AllowDeath).map_err(|_| ())?;
|
||||
Ok(what.clone())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot 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.
|
||||
|
||||
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
mod location_conversion;
|
||||
pub use location_conversion::{
|
||||
Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases
|
||||
};
|
||||
|
||||
mod origin_conversion;
|
||||
pub use origin_conversion::{
|
||||
SovereignSignedViaLocation, ParentAsSuperuser, ChildSystemParachainAsSuperuser, SiblingSystemParachainAsSuperuser,
|
||||
ChildParachainAsNative, SiblingParachainAsNative, RelayChainAsNative, SignedAccountId32AsNative
|
||||
};
|
||||
|
||||
mod currency_adapter;
|
||||
pub use currency_adapter::CurrencyAdapter;
|
||||
|
||||
use sp_std::marker::PhantomData;
|
||||
use xcm_executor::traits::InvertLocation;
|
||||
use xcm::v0::{MultiLocation, Junction};
|
||||
use frame_support::traits::Get;
|
||||
|
||||
/// Simple location inverter; give it this location's ancestry and it'll
|
||||
pub struct LocationInverter<Ancestry>(PhantomData<Ancestry>);
|
||||
|
||||
impl<Ancestry: Get<MultiLocation>> InvertLocation for LocationInverter<Ancestry> {
|
||||
fn invert_location(location: &MultiLocation) -> MultiLocation {
|
||||
let mut ancestry = Ancestry::get();
|
||||
let mut result = location.clone();
|
||||
for (i, j) in location.iter_rev()
|
||||
.map(|j| match j {
|
||||
Junction::Parent => ancestry.take_first().unwrap_or(Junction::OnlyChild),
|
||||
_ => Junction::Parent,
|
||||
})
|
||||
.enumerate()
|
||||
{
|
||||
*result.at_mut(i).expect("location and result begin equal; same size; qed") = j;
|
||||
}
|
||||
result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot 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.
|
||||
|
||||
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use sp_std::marker::PhantomData;
|
||||
use sp_io::hashing::blake2_256;
|
||||
use sp_runtime::traits::AccountIdConversion;
|
||||
use frame_support::traits::Get;
|
||||
use codec::Encode;
|
||||
use xcm::v0::{MultiLocation, NetworkId, Junction};
|
||||
use xcm_executor::traits::LocationConversion;
|
||||
|
||||
pub struct Account32Hash<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
AccountId: From<[u8; 32]> + Into<[u8; 32]>,
|
||||
> LocationConversion<AccountId> for Account32Hash<Network, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
Some(("multiloc", location).using_encoded(blake2_256).into())
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
Err(who)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ParentIsDefault<AccountId>(PhantomData<AccountId>);
|
||||
|
||||
impl<
|
||||
AccountId: Default + Eq,
|
||||
> LocationConversion<AccountId> for ParentIsDefault<AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X1(Junction::Parent) = location {
|
||||
Some(AccountId::default())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
if who == AccountId::default() {
|
||||
Ok(Junction::Parent.into())
|
||||
} else {
|
||||
Err(who)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChildParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
|
||||
|
||||
impl<
|
||||
ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>,
|
||||
AccountId,
|
||||
> LocationConversion<AccountId> for ChildParachainConvertsVia<ParaId, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X1(Junction::Parachain { id }) = location {
|
||||
Some(ParaId::from(*id).into_account())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
if let Some(id) = ParaId::try_from_account(&who) {
|
||||
Ok(Junction::Parachain { id: id.into() }.into())
|
||||
} else {
|
||||
Err(who)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SiblingParachainConvertsVia<ParaId, AccountId>(PhantomData<(ParaId, AccountId)>);
|
||||
|
||||
impl<
|
||||
ParaId: From<u32> + Into<u32> + AccountIdConversion<AccountId>,
|
||||
AccountId,
|
||||
> LocationConversion<AccountId> for SiblingParachainConvertsVia<ParaId, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X2(Junction::Parent, Junction::Parachain { id }) = location {
|
||||
Some(ParaId::from(*id).into_account())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
if let Some(id) = ParaId::try_from_account(&who) {
|
||||
Ok([Junction::Parent, Junction::Parachain { id: id.into() }].into())
|
||||
} else {
|
||||
Err(who)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AccountId32Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
|
||||
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
AccountId: From<[u8; 32]> + Into<[u8; 32]>,
|
||||
> LocationConversion<AccountId> for AccountId32Aliases<Network, AccountId> {
|
||||
fn from_location(location: &MultiLocation) -> Option<AccountId> {
|
||||
if let MultiLocation::X1(Junction::AccountId32 { id, network }) = location {
|
||||
if matches!(network, NetworkId::Any) || network == &Network::get() {
|
||||
return Some((*id).into())
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
|
||||
Ok(Junction::AccountId32 { id: who.into(), network: Network::get() }.into())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
// Copyright 2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot 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.
|
||||
|
||||
// Polkadot 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 Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use sp_std::marker::PhantomData;
|
||||
use frame_support::traits::{Get, OriginTrait};
|
||||
use xcm::v0::{MultiLocation, OriginKind, NetworkId, Junction};
|
||||
use xcm_executor::traits::{LocationConversion, ConvertOrigin};
|
||||
use polkadot_parachain::primitives::IsSystem;
|
||||
|
||||
/// Sovereign accounts use the system's `Signed` origin with an account ID derived from the
|
||||
/// `LocationConverter`.
|
||||
pub struct SovereignSignedViaLocation<LocationConverter, Origin>(
|
||||
PhantomData<(LocationConverter, Origin)>
|
||||
);
|
||||
impl<
|
||||
LocationConverter: LocationConversion<Origin::AccountId>,
|
||||
Origin: OriginTrait,
|
||||
> ConvertOrigin<Origin> for SovereignSignedViaLocation<LocationConverter, Origin> {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
if let OriginKind::SovereignAccount = kind {
|
||||
let location = LocationConverter::from_location(&origin).ok_or(origin)?;
|
||||
Ok(Origin::signed(location).into())
|
||||
} else {
|
||||
Err(origin)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ParentAsSuperuser<Origin>(PhantomData<Origin>);
|
||||
impl<
|
||||
Origin: OriginTrait,
|
||||
> ConvertOrigin<Origin> for ParentAsSuperuser<Origin> {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Superuser, MultiLocation::X1(Junction::Parent)) =>
|
||||
Ok(Origin::root()),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChildSystemParachainAsSuperuser<ParaId, Origin>(PhantomData<(ParaId, Origin)>);
|
||||
impl<
|
||||
ParaId: IsSystem + From<u32>,
|
||||
Origin: OriginTrait,
|
||||
> ConvertOrigin<Origin> for ChildSystemParachainAsSuperuser<ParaId, Origin> {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Superuser, MultiLocation::X1(Junction::Parachain { id }))
|
||||
if ParaId::from(id).is_system() =>
|
||||
Ok(Origin::root()),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SiblingSystemParachainAsSuperuser<ParaId, Origin>(PhantomData<(ParaId, Origin)>);
|
||||
impl<
|
||||
ParaId: IsSystem + From<u32>,
|
||||
Origin: OriginTrait
|
||||
> ConvertOrigin<Origin> for SiblingSystemParachainAsSuperuser<ParaId, Origin> {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Superuser, MultiLocation::X2(Junction::Parent, Junction::Parachain { id }))
|
||||
if ParaId::from(id).is_system() =>
|
||||
Ok(Origin::root()),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ChildParachainAsNative<ParachainOrigin, Origin>(
|
||||
PhantomData<(ParachainOrigin, Origin)>
|
||||
);
|
||||
impl<
|
||||
ParachainOrigin: From<u32>,
|
||||
Origin: From<ParachainOrigin>,
|
||||
> ConvertOrigin<Origin> for ChildParachainAsNative<ParachainOrigin, Origin> {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X1(Junction::Parachain { id }))
|
||||
=> Ok(Origin::from(ParachainOrigin::from(id))),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SiblingParachainAsNative<ParachainOrigin, Origin>(
|
||||
PhantomData<(ParachainOrigin, Origin)>
|
||||
);
|
||||
impl<
|
||||
ParachainOrigin: From<u32>,
|
||||
Origin: From<ParachainOrigin>,
|
||||
> ConvertOrigin<Origin> for SiblingParachainAsNative<ParachainOrigin, Origin> {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X2(Junction::Parent, Junction::Parachain { id }))
|
||||
=> Ok(Origin::from(ParachainOrigin::from(id))),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Our Relay-chain has a native origin given by the `Get`ter.
|
||||
pub struct RelayChainAsNative<RelayOrigin, Origin>(
|
||||
PhantomData<(RelayOrigin, Origin)>
|
||||
);
|
||||
impl<
|
||||
RelayOrigin: Get<Origin>,
|
||||
Origin,
|
||||
> ConvertOrigin<Origin> for RelayChainAsNative<RelayOrigin, Origin> {
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X1(Junction::Parent)) => Ok(RelayOrigin::get()),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct SignedAccountId32AsNative<Network, Origin>(
|
||||
PhantomData<(Network, Origin)>
|
||||
);
|
||||
impl<
|
||||
Network: Get<NetworkId>,
|
||||
Origin: OriginTrait,
|
||||
> ConvertOrigin<Origin> for SignedAccountId32AsNative<Network, Origin> where
|
||||
Origin::AccountId: From<[u8; 32]>,
|
||||
{
|
||||
fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
|
||||
match (kind, origin) {
|
||||
(OriginKind::Native, MultiLocation::X1(Junction::AccountId32 { id, network }))
|
||||
if matches!(network, NetworkId::Any) || network == Network::get()
|
||||
=> Ok(Origin::signed(id.into())),
|
||||
(_, origin) => Err(origin),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user