1c0e57d984
This commit systematically rebrands various references from Parity Technologies' Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk. Key changes include: - Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks. - Modified internal documentation and code comments to reflect PezkuwiChain naming and structure. - Replaced direct references to with or specific paths within the for XCM, Pezkuwi, and other modules. - Cleaned up deprecated issue and PR references in various and files, particularly in and modules. - Adjusted image and logo URLs in documentation to point to PezkuwiChain assets. - Removed or rephrased comments related to external Polkadot/Substrate PRs and issues. This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
299 lines
10 KiB
Rust
299 lines
10 KiB
Rust
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use crate::local_and_foreign_assets::ForeignAssetReserveData;
|
|
use core::fmt::Debug;
|
|
use cumulus_primitives_core::ParaId;
|
|
use pezframe_support::{
|
|
pezpallet_prelude::Get,
|
|
traits::{tokens::ProvideAssetReserves, Contains, ContainsPair},
|
|
};
|
|
use xcm::prelude::*;
|
|
use xcm_builder::ensure_is_remote;
|
|
|
|
pezframe_support::parameter_types! {
|
|
pub LocalLocationPattern: Location = Location::new(0, Here);
|
|
pub ParentLocation: Location = Location::parent();
|
|
}
|
|
|
|
/// Accepts an asset if it is from the origin.
|
|
pub struct IsForeignConcreteAsset<IsForeign>(core::marker::PhantomData<IsForeign>);
|
|
impl<IsForeign: ContainsPair<Location, Location>> ContainsPair<Asset, Location>
|
|
for IsForeignConcreteAsset<IsForeign>
|
|
{
|
|
fn contains(asset: &Asset, origin: &Location) -> bool {
|
|
let result = matches!(asset.id, AssetId(ref id) if IsForeign::contains(id, origin));
|
|
tracing::trace!(target: "xcm::contains", ?asset, ?origin, ?result, "IsForeignConcreteAsset");
|
|
result
|
|
}
|
|
}
|
|
|
|
/// Checks if `a` is from sibling location `b`. Checks that `Location-a` starts with
|
|
/// `Location-b`, and that the `ParaId` of `b` is not equal to `a`.
|
|
pub struct FromSiblingTeyrchain<SelfParaId, L = Location>(
|
|
core::marker::PhantomData<(SelfParaId, L)>,
|
|
);
|
|
impl<SelfParaId: Get<ParaId>, L: TryFrom<Location> + TryInto<Location> + Clone + Debug>
|
|
ContainsPair<L, L> for FromSiblingTeyrchain<SelfParaId, L>
|
|
{
|
|
fn contains(a: &L, b: &L) -> bool {
|
|
tracing::trace!(target: "xcm:contains", ?a, ?b, "FromSiblingTeyrchain");
|
|
// We convert locations to latest
|
|
let a = match ((*a).clone().try_into(), (*b).clone().try_into()) {
|
|
(Ok(a), Ok(b)) if a.starts_with(&b) => a, // `a` needs to be from `b` at least
|
|
_ => return false,
|
|
};
|
|
|
|
// here we check if sibling
|
|
match a.unpack() {
|
|
(1, interior) => {
|
|
matches!(interior.first(), Some(Teyrchain(sibling_para_id)) if sibling_para_id.ne(&u32::from(SelfParaId::get())))
|
|
},
|
|
_ => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Checks if asset `a` is coming from a trusted Reserve location `b`, then checks whether the local
|
|
/// chain is also a reserve of `a`. Assets can be teleported between their reserve locations.
|
|
pub struct TeleportableAssetWithTrustedReserve<SelfParaId, ReserveProvider, L = Location>(
|
|
core::marker::PhantomData<(SelfParaId, ReserveProvider, L)>,
|
|
);
|
|
impl<
|
|
SelfParaId: Get<ParaId>,
|
|
L: TryFrom<Location> + TryInto<Location> + Clone + Debug,
|
|
ReserveProvider: ProvideAssetReserves<Location, ForeignAssetReserveData>,
|
|
> ContainsPair<L, L> for TeleportableAssetWithTrustedReserve<SelfParaId, ReserveProvider, L>
|
|
{
|
|
fn contains(a: &L, b: &L) -> bool {
|
|
tracing::trace!(target: "xcm::contains", ?a, ?b, "TeleportableAssetWithTrustedReserve");
|
|
// We convert locations to latest
|
|
let (a, b) = match ((*a).clone().try_into(), (*b).clone().try_into()) {
|
|
(Ok(a), Ok(b)) => (a, b),
|
|
_ => return false,
|
|
};
|
|
let reserves = ReserveProvider::reserves(&a);
|
|
tracing::trace!(target: "xcm::contains", ?reserves, "TeleportableAssetWithTrustedReserve");
|
|
// check if `b` is reserve for `a` and teleportable flag is set
|
|
let filter = (b, true).into();
|
|
reserves.contains(&filter)
|
|
}
|
|
}
|
|
|
|
/// Checks if asset `a` is coming from a trusted Reserve location `b`.
|
|
/// Then checks that the local chain is NOT itself also reserve of `a`, otherwise a teleport is in
|
|
/// order.
|
|
pub struct NonTeleportableAssetFromTrustedReserve<SelfParaId, ReserveProvider, L = Location>(
|
|
core::marker::PhantomData<(SelfParaId, ReserveProvider, L)>,
|
|
);
|
|
impl<
|
|
SelfParaId: Get<ParaId>,
|
|
L: TryFrom<Location> + TryInto<Location> + Clone + Debug,
|
|
ReserveProvider: ProvideAssetReserves<Location, ForeignAssetReserveData>,
|
|
> ContainsPair<L, L> for NonTeleportableAssetFromTrustedReserve<SelfParaId, ReserveProvider, L>
|
|
{
|
|
fn contains(a: &L, b: &L) -> bool {
|
|
tracing::trace!(target: "xcm::contains", ?a, ?b, "NonTeleportableAssetFromTrustedReserve");
|
|
// We convert locations to latest
|
|
let (a, b) = match ((*a).clone().try_into(), (*b).clone().try_into()) {
|
|
(Ok(a), Ok(b)) => (a, b),
|
|
_ => return false,
|
|
};
|
|
let reserves = ReserveProvider::reserves(&a);
|
|
tracing::trace!(target: "xcm::contains", ?reserves, "NonTeleportableAssetFromTrustedReserve");
|
|
// check if `b` is reserve for `a` and teleportable flag is NOT set
|
|
let filter = (b, false).into();
|
|
reserves.contains(&filter)
|
|
}
|
|
}
|
|
|
|
/// Checks if `a` is from the expected global consensus network. Checks that `Location-a`
|
|
/// starts with `Location-b`, and that network is a foreign consensus system.
|
|
pub struct FromNetwork<UniversalLocation, ExpectedNetworkId, L = Location>(
|
|
core::marker::PhantomData<(UniversalLocation, ExpectedNetworkId, L)>,
|
|
);
|
|
impl<
|
|
UniversalLocation: Get<InteriorLocation>,
|
|
ExpectedNetworkId: Get<NetworkId>,
|
|
L: TryFrom<Location> + TryInto<Location> + Clone + Debug,
|
|
> ContainsPair<L, L> for FromNetwork<UniversalLocation, ExpectedNetworkId, L>
|
|
{
|
|
fn contains(a: &L, b: &L) -> bool {
|
|
tracing::trace!(target: "xcm:contains", ?a, ?b, "FromNetwork");
|
|
// We convert locations to latest
|
|
let a = match ((*a).clone().try_into(), (*b).clone().try_into()) {
|
|
(Ok(a), Ok(b)) if a.starts_with(&b) => a, // `a` needs to be from `b` at least
|
|
_ => return false,
|
|
};
|
|
|
|
let universal_source = UniversalLocation::get();
|
|
|
|
// ensure that `a` is remote and from the expected network
|
|
match ensure_is_remote(universal_source.clone(), a.clone()) {
|
|
Ok((network_id, _)) => network_id == ExpectedNetworkId::get(),
|
|
Err(e) => {
|
|
tracing::debug!(target: "xcm::contains", origin = ?a, ?universal_source, error = ?e, "FromNetwork origin is not remote to the universal_source");
|
|
false
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Accept an asset if it is native to `AssetsAllowedNetworks` and it is coming from
|
|
/// `OriginLocation`.
|
|
pub struct RemoteAssetFromLocation<AssetsAllowedNetworks, OriginLocation>(
|
|
core::marker::PhantomData<(AssetsAllowedNetworks, OriginLocation)>,
|
|
);
|
|
impl<
|
|
L: TryInto<Location> + Clone,
|
|
AssetsAllowedNetworks: Contains<Location>,
|
|
OriginLocation: Get<Location>,
|
|
> ContainsPair<L, L> for RemoteAssetFromLocation<AssetsAllowedNetworks, OriginLocation>
|
|
{
|
|
fn contains(asset: &L, origin: &L) -> bool {
|
|
let Ok(asset) = asset.clone().try_into() else {
|
|
return false;
|
|
};
|
|
let Ok(origin) = origin.clone().try_into() else {
|
|
return false;
|
|
};
|
|
let expected_origin = OriginLocation::get();
|
|
// ensure `origin` is expected `OriginLocation`
|
|
if !expected_origin.eq(&origin) {
|
|
tracing::trace!(
|
|
target: "xcm::contains",
|
|
?asset,
|
|
?origin,
|
|
?expected_origin,
|
|
"RemoteAssetFromLocation: Asset is not from expected origin"
|
|
);
|
|
return false;
|
|
} else {
|
|
tracing::trace!(
|
|
target: "xcm::contains",
|
|
?asset,
|
|
?origin,
|
|
"RemoteAssetFromLocation",
|
|
);
|
|
}
|
|
|
|
// ensure `asset` is from remote consensus listed in `AssetsAllowedNetworks`
|
|
AssetsAllowedNetworks::contains(&asset)
|
|
}
|
|
}
|
|
impl<AssetsAllowedNetworks: Contains<Location>, OriginLocation: Get<Location>>
|
|
ContainsPair<Asset, Location> for RemoteAssetFromLocation<AssetsAllowedNetworks, OriginLocation>
|
|
{
|
|
fn contains(asset: &Asset, origin: &Location) -> bool {
|
|
tracing::trace!(target: "xcm:contains", ?asset, ?origin, "RemoteAssetFromLocation");
|
|
<Self as ContainsPair<Location, Location>>::contains(&asset.id.0, origin)
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use pezframe_support::parameter_types;
|
|
use xcm::latest::{PEZKUWICHAIN_GENESIS_HASH, ZAGROS_GENESIS_HASH};
|
|
|
|
parameter_types! {
|
|
pub UniversalLocation: InteriorLocation = [GlobalConsensus(ByGenesis(PEZKUWICHAIN_GENESIS_HASH)), Teyrchain(1000)].into();
|
|
pub ExpectedNetworkId: NetworkId = ByGenesis(ZAGROS_GENESIS_HASH);
|
|
}
|
|
|
|
#[test]
|
|
fn from_network_contains_works() {
|
|
// asset and origin from foreign consensus works
|
|
let asset: Location = (
|
|
Parent,
|
|
Parent,
|
|
GlobalConsensus(ByGenesis(ZAGROS_GENESIS_HASH)),
|
|
Teyrchain(1000),
|
|
PalletInstance(1),
|
|
GeneralIndex(1),
|
|
)
|
|
.into();
|
|
let origin: Location =
|
|
(Parent, Parent, GlobalConsensus(ByGenesis(ZAGROS_GENESIS_HASH)), Teyrchain(1000))
|
|
.into();
|
|
assert!(FromNetwork::<UniversalLocation, ExpectedNetworkId>::contains(&asset, &origin));
|
|
|
|
// asset and origin from local consensus fails
|
|
let asset: Location = (
|
|
Parent,
|
|
Parent,
|
|
GlobalConsensus(ByGenesis(PEZKUWICHAIN_GENESIS_HASH)),
|
|
Teyrchain(1000),
|
|
PalletInstance(1),
|
|
GeneralIndex(1),
|
|
)
|
|
.into();
|
|
let origin: Location = (
|
|
Parent,
|
|
Parent,
|
|
GlobalConsensus(ByGenesis(PEZKUWICHAIN_GENESIS_HASH)),
|
|
Teyrchain(1000),
|
|
)
|
|
.into();
|
|
assert!(!FromNetwork::<UniversalLocation, ExpectedNetworkId>::contains(&asset, &origin));
|
|
|
|
// asset and origin from here fails
|
|
let asset: Location = (PalletInstance(1), GeneralIndex(1)).into();
|
|
let origin: Location = Here.into();
|
|
assert!(!FromNetwork::<UniversalLocation, ExpectedNetworkId>::contains(&asset, &origin));
|
|
|
|
// asset from different consensus fails
|
|
let asset: Location = (
|
|
Parent,
|
|
Parent,
|
|
GlobalConsensus(Pezkuwi),
|
|
Teyrchain(1000),
|
|
PalletInstance(1),
|
|
GeneralIndex(1),
|
|
)
|
|
.into();
|
|
let origin: Location =
|
|
(Parent, Parent, GlobalConsensus(ByGenesis(ZAGROS_GENESIS_HASH)), Teyrchain(1000))
|
|
.into();
|
|
assert!(!FromNetwork::<UniversalLocation, ExpectedNetworkId>::contains(&asset, &origin));
|
|
|
|
// origin from different consensus fails
|
|
let asset: Location = (
|
|
Parent,
|
|
Parent,
|
|
GlobalConsensus(ByGenesis(ZAGROS_GENESIS_HASH)),
|
|
Teyrchain(1000),
|
|
PalletInstance(1),
|
|
GeneralIndex(1),
|
|
)
|
|
.into();
|
|
let origin: Location = (Parent, Parent, GlobalConsensus(Pezkuwi), Teyrchain(1000)).into();
|
|
assert!(!FromNetwork::<UniversalLocation, ExpectedNetworkId>::contains(&asset, &origin));
|
|
|
|
// asset and origin from unexpected consensus fails
|
|
let asset: Location = (
|
|
Parent,
|
|
Parent,
|
|
GlobalConsensus(Pezkuwi),
|
|
Teyrchain(1000),
|
|
PalletInstance(1),
|
|
GeneralIndex(1),
|
|
)
|
|
.into();
|
|
let origin: Location = (Parent, Parent, GlobalConsensus(Pezkuwi), Teyrchain(1000)).into();
|
|
assert!(!FromNetwork::<UniversalLocation, ExpectedNetworkId>::contains(&asset, &origin));
|
|
}
|
|
}
|