Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[xcm] Small enhancements for NetworkExportTable and xcm-builder #1848

Merged
merged 14 commits into from
Oct 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions bridges/modules/xcm-bridge-hub-router/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use sp_runtime::{
BuildStorage,
};
use xcm::prelude::*;
use xcm_builder::NetworkExportTable;
use xcm_builder::{NetworkExportTable, NetworkExportTableItem};

pub type AccountId = u64;
type Block = frame_system::mocking::MockBlock<TestRuntime>;
Expand All @@ -53,8 +53,15 @@ parameter_types! {
pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(ThisNetworkId::get()), Parachain(1000));
pub SiblingBridgeHubLocation: MultiLocation = ParentThen(X1(Parachain(1002))).into();
pub BridgeFeeAsset: AssetId = MultiLocation::parent().into();
pub BridgeTable: Vec<(NetworkId, MultiLocation, Option<MultiAsset>)>
= vec![(BridgedNetworkId::get(), SiblingBridgeHubLocation::get(), Some((BridgeFeeAsset::get(), BASE_FEE).into()))];
pub BridgeTable: Vec<NetworkExportTableItem>
= vec![
NetworkExportTableItem::new(
BridgedNetworkId::get(),
None,
SiblingBridgeHubLocation::get(),
Some((BridgeFeeAsset::get(), BASE_FEE).into())
)
];
}

impl frame_system::Config for TestRuntime {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ use super::{
use crate::ForeignAssets;
use assets_common::{
local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation,
matching::{
FromSiblingParachain, IsForeignConcreteAsset, StartsWith, StartsWithExplicitGlobalConsensus,
},
matching::{FromSiblingParachain, IsForeignConcreteAsset},
};
use frame_support::{
match_types, parameter_types,
Expand All @@ -45,8 +43,8 @@ use xcm_builder::{
EnsureXcmOrigin, FungiblesAdapter, HashedDescription, IsConcrete, LocalMint, NoChecking,
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
};
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ use super::{
ParachainInfo, ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
};
use assets_common::matching::{
FromSiblingParachain, IsForeignConcreteAsset, StartsWith, StartsWithExplicitGlobalConsensus,
};
use assets_common::matching::{FromSiblingParachain, IsForeignConcreteAsset};
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, Everything, Nothing, PalletInfoAccess},
Expand All @@ -41,8 +39,8 @@ use xcm_builder::{
EnsureXcmOrigin, FungiblesAdapter, HashedDescription, IsConcrete, LocalMint, NoChecking,
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
};
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ use super::{
use crate::ForeignAssets;
use assets_common::{
local_and_foreign_assets::MatchesLocalAndForeignAssetsMultiLocation,
matching::{
FromSiblingParachain, IsForeignConcreteAsset, StartsWith, StartsWithExplicitGlobalConsensus,
},
matching::{FromSiblingParachain, IsForeignConcreteAsset},
};
use frame_support::{
match_types, parameter_types,
Expand All @@ -45,8 +43,8 @@ use xcm_builder::{
EnsureXcmOrigin, FungiblesAdapter, HashedDescription, IsConcrete, LocalMint, NoChecking,
ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32,
SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents,
WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
SovereignSignedViaLocation, StartsWith, StartsWithExplicitGlobalConsensus, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WeightInfoBounds, WithComputedOrigin, WithUniqueTopic,
};
use xcm_executor::{traits::WithOriginFilter, XcmExecutor};

Expand Down
8 changes: 4 additions & 4 deletions cumulus/parachains/runtimes/assets/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ pub mod local_and_foreign_assets;
pub mod matching;
pub mod runtime_api;

use crate::matching::{Equals, LocalMultiLocationPattern, ParentLocation, StartsWith};
use frame_support::traits::EverythingBut;
use crate::matching::{LocalMultiLocationPattern, ParentLocation};
use frame_support::traits::{Equals, EverythingBut};
use parachains_common::AssetIdForTrustBackedAssets;
use xcm::prelude::MultiLocation;
use xcm_builder::{AsPrefixedGeneralIndex, MatchedConvertedConcreteId};
use xcm_builder::{AsPrefixedGeneralIndex, MatchedConvertedConcreteId, StartsWith};
use xcm_executor::traits::{Identity, JustTry};

/// `MultiLocation` vs `AssetIdForTrustBackedAssets` converter for `TrustBackedAssets`
Expand Down Expand Up @@ -96,9 +96,9 @@ pub type PoolAssetsConvertedConcreteId<PoolAssetsPalletLocation, Balance> =
#[cfg(test)]
mod tests {
use super::*;
use crate::matching::StartsWithExplicitGlobalConsensus;
use sp_runtime::traits::MaybeEquivalence;
use xcm::latest::prelude::*;
use xcm_builder::StartsWithExplicitGlobalConsensus;
use xcm_executor::traits::{Error as MatchError, MatchesFungibles};

#[test]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -407,13 +407,14 @@ where
#[cfg(test)]
mod tests {
use crate::{
local_and_foreign_assets::MultiLocationConverter, matching::StartsWith,
AssetIdForPoolAssetsConvert, AssetIdForTrustBackedAssetsConvert,
local_and_foreign_assets::MultiLocationConverter, AssetIdForPoolAssetsConvert,
AssetIdForTrustBackedAssetsConvert,
};
use frame_support::traits::EverythingBut;
use pallet_asset_conversion::{MultiAssetIdConversionResult, MultiAssetIdConverter};
use sp_runtime::traits::MaybeEquivalence;
use xcm::latest::prelude::*;
use xcm_builder::StartsWith;

#[test]
fn test_multi_location_converter_works() {
Expand Down
28 changes: 1 addition & 27 deletions cumulus/parachains/runtimes/assets/common/src/matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,38 +14,12 @@
// limitations under the License.

use cumulus_primitives_core::ParaId;
use frame_support::{
pallet_prelude::Get,
traits::{Contains, ContainsPair},
};
use frame_support::{pallet_prelude::Get, traits::ContainsPair};
use xcm::{
latest::prelude::{MultiAsset, MultiLocation},
prelude::*,
};

pub struct StartsWith<T>(sp_std::marker::PhantomData<T>);
impl<Location: Get<MultiLocation>> Contains<MultiLocation> for StartsWith<Location> {
fn contains(t: &MultiLocation) -> bool {
t.starts_with(&Location::get())
}
}

pub struct Equals<T>(sp_std::marker::PhantomData<T>);
impl<Location: Get<MultiLocation>> Contains<MultiLocation> for Equals<Location> {
fn contains(t: &MultiLocation) -> bool {
t == &Location::get()
}
}

pub struct StartsWithExplicitGlobalConsensus<T>(sp_std::marker::PhantomData<T>);
impl<Network: Get<NetworkId>> Contains<MultiLocation>
for StartsWithExplicitGlobalConsensus<Network>
{
fn contains(t: &MultiLocation) -> bool {
matches!(t.interior.global_consensus(), Ok(requested_network) if requested_network.eq(&Network::get()))
}
}

frame_support::parameter_types! {
pub LocalMultiLocationPattern: MultiLocation = MultiLocation::new(0, Here);
pub ParentLocation: MultiLocation = MultiLocation::parent();
Expand Down
177 changes: 173 additions & 4 deletions polkadot/xcm/xcm-builder/src/filter_asset_location.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! Various implementations of `ContainsPair<MultiAsset, MultiLocation>`.
//! Various implementations of `ContainsPair<MultiAsset, MultiLocation>` or
//! `Contains<(MultiLocation, Vec<MultiAsset>)>`.

use frame_support::traits::{ContainsPair, Get};
use sp_std::marker::PhantomData;
use xcm::latest::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation};
use frame_support::traits::{Contains, ContainsPair, Get};
use sp_std::{marker::PhantomData, vec::Vec};
use xcm::latest::{AssetId::Concrete, MultiAsset, MultiAssetFilter, MultiLocation, WildMultiAsset};

/// Accepts an asset iff it is a native asset.
pub struct NativeAsset;
Expand All @@ -40,3 +41,171 @@ impl<T: Get<(MultiAssetFilter, MultiLocation)>> ContainsPair<MultiAsset, MultiLo
a.matches(asset) && &o == origin
}
}

/// Accepts a tuple `(location, assets)` if the `location` is contained in the `Contains`
/// implementation of the given `Location` and if every asset from `assets` matches at least one of
/// the `MultiAssetFilter` instances provided by the `Get` implementation of `AssetFilters`.
pub struct LocationWithAssetFilters<Location, AssetFilters>(
sp_std::marker::PhantomData<(Location, AssetFilters)>,
);
impl<Location: Contains<MultiLocation>, AssetFilters: Get<Vec<MultiAssetFilter>>>
Contains<(MultiLocation, Vec<MultiAsset>)> for LocationWithAssetFilters<Location, AssetFilters>
{
fn contains((location, assets): &(MultiLocation, Vec<MultiAsset>)) -> bool {
log::trace!(target: "xcm::contains", "LocationWithAssetFilters location: {:?}, assets: {:?}", location, assets);

// `location` must match the `Location` filter.
if !Location::contains(location) {
return false
}

// All `assets` must match at least one of the `AssetFilters`.
let filters = AssetFilters::get();
assets.iter().all(|asset| {
for filter in &filters {
if filter.matches(asset) {
return true
}
}
false
})
}
}

/// Implementation of `Get<Vec<MultiAssetFilter>>` which accepts every asset.
/// (For example, it can be used with `LocationWithAssetFilters`).
pub struct AllAssets;
impl Get<Vec<MultiAssetFilter>> for AllAssets {
fn get() -> Vec<MultiAssetFilter> {
sp_std::vec![MultiAssetFilter::Wild(WildMultiAsset::All)]
}
}

#[cfg(test)]
mod tests {
use super::*;
use frame_support::traits::Equals;
use xcm::latest::prelude::*;

#[test]
fn location_with_asset_filters_works() {
frame_support::parameter_types! {
pub ParaA: MultiLocation = MultiLocation::new(1, X1(Parachain(1001)));
pub ParaB: MultiLocation = MultiLocation::new(1, X1(Parachain(1002)));
pub ParaC: MultiLocation = MultiLocation::new(1, X1(Parachain(1003)));

pub AssetXLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(1111)));
pub AssetYLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(2222)));
pub AssetZLocation: MultiLocation = MultiLocation::new(1, X1(GeneralIndex(3333)));

pub OnlyAssetXOrAssetY: sp_std::vec::Vec<MultiAssetFilter> = sp_std::vec![
Wild(AllOf { fun: WildFungible, id: Concrete(AssetXLocation::get()) }),
Wild(AllOf { fun: WildFungible, id: Concrete(AssetYLocation::get()) }),
];
pub OnlyAssetZ: sp_std::vec::Vec<MultiAssetFilter> = sp_std::vec![
Wild(AllOf { fun: WildFungible, id: Concrete(AssetZLocation::get()) })
];
}

let test_data: Vec<(MultiLocation, Vec<MultiAsset>, bool)> = vec![
(ParaA::get(), vec![(AssetXLocation::get(), 1).into()], true),
(ParaA::get(), vec![(AssetYLocation::get(), 1).into()], true),
(ParaA::get(), vec![(AssetZLocation::get(), 1).into()], false),
(
ParaA::get(),
vec![(AssetXLocation::get(), 1).into(), (AssetYLocation::get(), 1).into()],
true,
),
(
ParaA::get(),
vec![(AssetXLocation::get(), 1).into(), (AssetZLocation::get(), 1).into()],
false,
),
(
ParaA::get(),
vec![(AssetYLocation::get(), 1).into(), (AssetZLocation::get(), 1).into()],
false,
),
(
ParaA::get(),
vec![
(AssetXLocation::get(), 1).into(),
(AssetYLocation::get(), 1).into(),
(AssetZLocation::get(), 1).into(),
],
false,
),
(ParaB::get(), vec![(AssetXLocation::get(), 1).into()], false),
(ParaB::get(), vec![(AssetYLocation::get(), 1).into()], false),
(ParaB::get(), vec![(AssetZLocation::get(), 1).into()], true),
(
ParaB::get(),
vec![(AssetXLocation::get(), 1).into(), (AssetYLocation::get(), 1).into()],
false,
),
(
ParaB::get(),
vec![(AssetXLocation::get(), 1).into(), (AssetZLocation::get(), 1).into()],
false,
),
(
ParaB::get(),
vec![(AssetYLocation::get(), 1).into(), (AssetZLocation::get(), 1).into()],
false,
),
(
ParaB::get(),
vec![
(AssetXLocation::get(), 1).into(),
(AssetYLocation::get(), 1).into(),
(AssetZLocation::get(), 1).into(),
],
false,
),
(ParaC::get(), vec![(AssetXLocation::get(), 1).into()], true),
(ParaC::get(), vec![(AssetYLocation::get(), 1).into()], true),
(ParaC::get(), vec![(AssetZLocation::get(), 1).into()], true),
(
ParaC::get(),
vec![(AssetXLocation::get(), 1).into(), (AssetYLocation::get(), 1).into()],
true,
),
(
ParaC::get(),
vec![(AssetXLocation::get(), 1).into(), (AssetZLocation::get(), 1).into()],
true,
),
(
ParaC::get(),
vec![(AssetYLocation::get(), 1).into(), (AssetZLocation::get(), 1).into()],
true,
),
(
ParaC::get(),
vec![
(AssetXLocation::get(), 1).into(),
(AssetYLocation::get(), 1).into(),
(AssetZLocation::get(), 1).into(),
],
true,
),
];

type Filter = (
// For ParaA accept only asset X and Y.
LocationWithAssetFilters<Equals<ParaA>, OnlyAssetXOrAssetY>,
// For ParaB accept only asset Z.
LocationWithAssetFilters<Equals<ParaB>, OnlyAssetZ>,
// For ParaC accept all assets.
LocationWithAssetFilters<Equals<ParaC>, AllAssets>,
);

for (location, assets, expected_result) in test_data {
assert_eq!(
Filter::contains(&(location, assets.clone())),
expected_result,
"expected_result: {expected_result} not matched for (location, assets): ({:?}, {:?})!", location, assets,
)
}
}
}
7 changes: 5 additions & 2 deletions polkadot/xcm/xcm-builder/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,14 +83,17 @@ pub use weight::{
FixedRateOfFungible, FixedWeightBounds, TakeRevenue, UsingComponents, WeightInfoBounds,
};

mod matches_location;
pub use matches_location::{StartsWith, StartsWithExplicitGlobalConsensus};

mod matches_token;
pub use matches_token::{IsAbstract, IsConcrete};

mod matcher;
pub use matcher::{CreateMatcher, MatchXcm, Matcher};

mod filter_asset_location;
pub use filter_asset_location::{Case, NativeAsset};
pub use filter_asset_location::{AllAssets, Case, LocationWithAssetFilters, NativeAsset};

mod routing;
pub use routing::{WithTopicSource, WithUniqueTopic};
Expand All @@ -99,7 +102,7 @@ mod universal_exports;
pub use universal_exports::{
ensure_is_remote, BridgeBlobDispatcher, BridgeMessage, DispatchBlob, DispatchBlobError,
ExporterFor, HaulBlob, HaulBlobError, HaulBlobExporter, NetworkExportTable,
SovereignPaidRemoteExporter, UnpaidLocalExporter, UnpaidRemoteExporter,
NetworkExportTableItem, SovereignPaidRemoteExporter, UnpaidLocalExporter, UnpaidRemoteExporter,
};

mod origin_aliases;
Expand Down
Loading
Loading