From 5046c6c3ec98897ecfbbe9ab3127b4f78948ce3b Mon Sep 17 00:00:00 2001 From: Shaun Wang Date: Wed, 16 Aug 2023 16:19:45 +1200 Subject: [PATCH] orml-xtokens Astar integration. (#1000) --- Cargo.lock | 5 +-- primitives/Cargo.toml | 4 +++ primitives/src/xcm/mod.rs | 40 +++++++++++++++++++--- runtime/astar/Cargo.toml | 8 +++++ runtime/astar/src/lib.rs | 1 + runtime/astar/src/xcm_config.rs | 57 ++++++++++++++++++++++++++++--- runtime/shibuya/Cargo.toml | 2 -- runtime/shibuya/src/xcm_config.rs | 38 +++------------------ runtime/shiden/Cargo.toml | 2 -- runtime/shiden/src/xcm_config.rs | 38 +++------------------ 10 files changed, 113 insertions(+), 82 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 94e894bc5..49ee57f0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -515,6 +515,7 @@ dependencies = [ "frame-support", "impl-trait-for-tuples", "log", + "orml-traits", "pallet-assets", "pallet-evm", "pallet-evm-precompile-assets-erc20", @@ -558,6 +559,8 @@ dependencies = [ "moonbeam-evm-tracer", "moonbeam-rpc-primitives-debug", "moonbeam-rpc-primitives-txpool", + "orml-xcm-support", + "orml-xtokens", "pallet-assets", "pallet-aura", "pallet-authorship", @@ -12373,7 +12376,6 @@ dependencies = [ "moonbeam-evm-tracer", "moonbeam-rpc-primitives-debug", "moonbeam-rpc-primitives-txpool", - "orml-traits", "orml-xcm-support", "orml-xtokens", "pallet-assets", @@ -12482,7 +12484,6 @@ dependencies = [ "moonbeam-evm-tracer", "moonbeam-rpc-primitives-debug", "moonbeam-rpc-primitives-txpool", - "orml-traits", "orml-xcm-support", "orml-xtokens", "pallet-assets", diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 6a4306fe0..8f0effb94 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -31,6 +31,9 @@ xcm = { workspace = true } xcm-builder = { workspace = true } xcm-executor = { workspace = true } +# ORML dependencies +orml-traits = { workspace = true } + # Frontier dependencies pallet-evm = { workspace = true } @@ -55,6 +58,7 @@ std = [ "xcm/std", "xcm-builder/std", "xcm-executor/std", + "orml-traits/std", "pallet-xc-asset-config/std", "fp-evm/std", "pallet-assets/std", diff --git a/primitives/src/xcm/mod.rs b/primitives/src/xcm/mod.rs index 66210bf95..e59e01283 100644 --- a/primitives/src/xcm/mod.rs +++ b/primitives/src/xcm/mod.rs @@ -32,11 +32,13 @@ #![cfg_attr(not(feature = "std"), no_std)] +use crate::AccountId; + use frame_support::{ traits::{tokens::fungibles, ContainsPair, Get}, weights::constants::WEIGHT_REF_TIME_PER_SECOND, }; -use sp_runtime::traits::{Bounded, Zero}; +use sp_runtime::traits::{Bounded, Convert, Zero}; use sp_std::{borrow::Borrow, marker::PhantomData, vec::Vec}; // Polkadot imports @@ -44,6 +46,9 @@ use xcm::latest::{prelude::*, Weight}; use xcm_builder::TakeRevenue; use xcm_executor::traits::{MatchesFungibles, WeightTrader}; +// ORML imports +use orml_traits::location::{RelativeReserveProvider, Reserve}; + use pallet_xc_asset_config::{ExecutionPaymentRate, XcAssetLocation}; #[cfg(test)] @@ -53,9 +58,7 @@ mod tests; /// /// This implementation relies on `XcAssetConfig` pallet to handle mapping. /// In case asset location hasn't been mapped, it means the asset isn't supported (yet). -pub struct AssetLocationIdConverter( - sp_std::marker::PhantomData<(AssetId, AssetMapper)>, -); +pub struct AssetLocationIdConverter(PhantomData<(AssetId, AssetMapper)>); impl xcm_executor::traits::Convert for AssetLocationIdConverter where @@ -384,3 +387,32 @@ impl + Clone, Describe: DescribeLocation> } } } + +/// Convert `AccountId` to `MultiLocation`. +pub struct AccountIdToMultiLocation; +impl Convert for AccountIdToMultiLocation { + fn convert(account: AccountId) -> MultiLocation { + X1(AccountId32 { + network: None, + id: account.into(), + }) + .into() + } +} + +/// `MultiAsset` reserve location provider. It's based on `RelativeReserveProvider` and in +/// addition will convert self absolute location to relative location. +pub struct AbsoluteAndRelativeReserveProvider(PhantomData); +impl> Reserve + for AbsoluteAndRelativeReserveProvider +{ + fn reserve(asset: &MultiAsset) -> Option { + RelativeReserveProvider::reserve(asset).map(|reserve_location| { + if reserve_location == AbsoluteLocation::get() { + MultiLocation::here() + } else { + reserve_location + } + }) + } +} diff --git a/runtime/astar/Cargo.toml b/runtime/astar/Cargo.toml index beff8e5c6..41d71de41 100644 --- a/runtime/astar/Cargo.toml +++ b/runtime/astar/Cargo.toml @@ -83,6 +83,10 @@ xcm = { workspace = true } xcm-builder = { workspace = true } xcm-executor = { workspace = true } +# orml dependencies +orml-xcm-support = { workspace = true } +orml-xtokens = { workspace = true } + # benchmarking array-bytes = { workspace = true } frame-benchmarking = { workspace = true, optional = true } @@ -198,6 +202,8 @@ std = [ "xcm-executor/std", "pallet-xc-asset-config/std", "substrate-wasm-builder", + "orml-xtokens/std", + "orml-xcm-support/std", "astar-primitives/std", ] runtime-benchmarks = [ @@ -218,6 +224,7 @@ runtime-benchmarks = [ "pallet-xc-asset-config/runtime-benchmarks", "pallet-collator-selection/runtime-benchmarks", "polkadot-runtime/runtime-benchmarks", + "orml-xtokens/runtime-benchmarks", "astar-primitives/runtime-benchmarks", "pallet-assets/runtime-benchmarks", ] @@ -258,6 +265,7 @@ try-runtime = [ "pallet-base-fee/try-runtime", "pallet-contracts/try-runtime", "pallet-evm/try-runtime", + "orml-xtokens/try-runtime", ] evm-tracing = [ "moonbeam-evm-tracer", diff --git a/runtime/astar/src/lib.rs b/runtime/astar/src/lib.rs index d832a98a2..4205963c2 100644 --- a/runtime/astar/src/lib.rs +++ b/runtime/astar/src/lib.rs @@ -1021,6 +1021,7 @@ construct_runtime!( CumulusXcm: cumulus_pallet_xcm = 52, DmpQueue: cumulus_pallet_dmp_queue = 53, XcAssetConfig: pallet_xc_asset_config = 54, + Xtokens: orml_xtokens = 55, EVM: pallet_evm = 60, Ethereum: pallet_ethereum = 61, diff --git a/runtime/astar/src/xcm_config.rs b/runtime/astar/src/xcm_config.rs index a44ed82aa..5c86c9e93 100644 --- a/runtime/astar/src/xcm_config.rs +++ b/runtime/astar/src/xcm_config.rs @@ -28,6 +28,7 @@ use frame_support::{ weights::Weight, }; use frame_system::EnsureRoot; +use sp_runtime::traits::Convert; // Polkadot imports use xcm::latest::prelude::*; @@ -40,12 +41,18 @@ use xcm_builder::{ SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, }; use xcm_executor::{ - traits::{JustTry, WithOriginFilter}, + traits::{Convert as XcmConvert, JustTry, WithOriginFilter}, XcmExecutor, }; +// ORML imports +use orml_xcm_support::DisabledParachainFee; + // Astar imports -use astar_primitives::xcm::{FixedRateOfForeignAsset, ReserveAssetFilter, XcmFungibleFeeHandler}; +use astar_primitives::xcm::{ + AbsoluteAndRelativeReserveProvider, AccountIdToMultiLocation, FixedRateOfForeignAsset, + ReserveAssetFilter, XcmFungibleFeeHandler, +}; parameter_types! { pub RelayNetwork: Option = Some(NetworkId::Polkadot); @@ -242,7 +249,7 @@ impl xcm_executor::Config for XcmConfig { type IsTeleporter = (); type UniversalLocation = UniversalLocation; type Barrier = XcmBarrier; - type Weigher = FixedWeightBounds; + type Weigher = Weigher; type Trader = ( UsingComponents, FixedRateOfForeignAsset, @@ -284,6 +291,8 @@ parameter_types! { pub ReachableDest: Option = Some(Parent.into()); } +pub type Weigher = FixedWeightBounds; + impl pallet_xcm::Config for Runtime { const VERSION_DISCOVERY_QUEUE_SIZE: u32 = 100; @@ -295,7 +304,7 @@ impl pallet_xcm::Config for Runtime { type XcmExecutor = XcmExecutor; type XcmTeleportFilter = Nothing; type XcmReserveTransferFilter = Everything; - type Weigher = FixedWeightBounds; + type Weigher = Weigher; type UniversalLocation = UniversalLocation; type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; @@ -334,3 +343,43 @@ impl cumulus_pallet_dmp_queue::Config for Runtime { type XcmExecutor = XcmExecutor; type ExecuteOverweightOrigin = EnsureRoot; } + +parameter_types! { + /// The absolute location in perspective of the whole network. + pub AstarLocationAbsolute: MultiLocation = MultiLocation { + parents: 1, + interior: X1( + Parachain(ParachainInfo::parachain_id().into()) + ) + }; + /// Max asset types for one cross-chain transfer. `2` covers all current use cases. + /// Can be updated with extra test cases in the future if needed. + pub const MaxAssetsForTransfer: usize = 2; +} + +/// Convert `AssetId` to optional `MultiLocation`. The impl is a wrapper +/// on `ShidenAssetLocationIdConverter`. +pub struct AssetIdConvert; +impl Convert> for AssetIdConvert { + fn convert(asset_id: AssetId) -> Option { + AstarAssetLocationIdConverter::reverse_ref(&asset_id).ok() + } +} + +impl orml_xtokens::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type CurrencyId = AssetId; + type CurrencyIdConvert = AssetIdConvert; + type AccountIdToMultiLocation = AccountIdToMultiLocation; + type SelfLocation = AstarLocation; + type XcmExecutor = XcmExecutor; + type Weigher = Weigher; + type BaseXcmWeight = UnitWeightCost; + type UniversalLocation = UniversalLocation; + type MaxAssetsForTransfer = MaxAssetsForTransfer; + // Default impl. Refer to `orml-xtokens` docs for more details. + type MinXcmFee = DisabledParachainFee; + type MultiLocationsFilter = Everything; + type ReserveProvider = AbsoluteAndRelativeReserveProvider; +} diff --git a/runtime/shibuya/Cargo.toml b/runtime/shibuya/Cargo.toml index 29e5cb658..a62e03006 100644 --- a/runtime/shibuya/Cargo.toml +++ b/runtime/shibuya/Cargo.toml @@ -91,7 +91,6 @@ xcm-builder = { workspace = true } xcm-executor = { workspace = true } # orml dependencies -orml-traits = { workspace = true } orml-xcm-support = { workspace = true } orml-xtokens = { workspace = true } @@ -233,7 +232,6 @@ std = [ "substrate-wasm-builder", "pallet-chain-extension-assets/std", "orml-xtokens/std", - "orml-traits/std", "orml-xcm-support/std", "astar-primitives/std", ] diff --git a/runtime/shibuya/src/xcm_config.rs b/runtime/shibuya/src/xcm_config.rs index a7e7fb291..3848b0bd1 100644 --- a/runtime/shibuya/src/xcm_config.rs +++ b/runtime/shibuya/src/xcm_config.rs @@ -28,8 +28,7 @@ use frame_support::{ weights::Weight, }; use frame_system::EnsureRoot; -use sp_runtime::traits::{Convert, Get}; -use sp_std::marker::PhantomData; +use sp_runtime::traits::Convert; // Polkadot imports use xcm::latest::prelude::*; @@ -47,13 +46,13 @@ use xcm_executor::{ }; // ORML imports -use orml_traits::location::{RelativeReserveProvider, Reserve}; use orml_xcm_support::DisabledParachainFee; // Astar imports use astar_primitives::xcm::{ - DescribeAllTerminal, DescribeFamily, FixedRateOfForeignAsset, HashedDescription, - ReserveAssetFilter, XcmFungibleFeeHandler, + AbsoluteAndRelativeReserveProvider, AccountIdToMultiLocation, DescribeAllTerminal, + DescribeFamily, FixedRateOfForeignAsset, HashedDescription, ReserveAssetFilter, + XcmFungibleFeeHandler, }; parameter_types! { @@ -276,18 +275,6 @@ impl cumulus_pallet_dmp_queue::Config for Runtime { type ExecuteOverweightOrigin = EnsureRoot; } -/// Convert `AccountId` to `MultiLocation`. -pub struct AccountIdToMultiLocation; -impl Convert for AccountIdToMultiLocation { - fn convert(account: AccountId) -> MultiLocation { - X1(AccountId32 { - network: None, - id: account.into(), - }) - .into() - } -} - parameter_types! { /// The absolute location in perspective of the whole network. pub ShibuyaLocationAbsolute: MultiLocation = MultiLocation { @@ -310,23 +297,6 @@ impl Convert> for AssetIdConvert { } } -/// `MultiAsset` reserve location provider. It's based on `RelativeReserveProvider` and in -/// addition will convert self absolute location to relative location. -pub struct AbsoluteAndRelativeReserveProvider(PhantomData); -impl> Reserve - for AbsoluteAndRelativeReserveProvider -{ - fn reserve(asset: &MultiAsset) -> Option { - RelativeReserveProvider::reserve(asset).map(|reserve_location| { - if reserve_location == AbsoluteLocation::get() { - MultiLocation::here() - } else { - reserve_location - } - }) - } -} - impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance; diff --git a/runtime/shiden/Cargo.toml b/runtime/shiden/Cargo.toml index d02064223..d112937e5 100644 --- a/runtime/shiden/Cargo.toml +++ b/runtime/shiden/Cargo.toml @@ -86,7 +86,6 @@ xcm-builder = { workspace = true } xcm-executor = { workspace = true } # orml dependencies -orml-traits = { workspace = true } orml-xcm-support = { workspace = true } orml-xtokens = { workspace = true } @@ -207,7 +206,6 @@ std = [ "pallet-xc-asset-config/std", "substrate-wasm-builder", "orml-xtokens/std", - "orml-traits/std", "orml-xcm-support/std", "astar-primitives/std", ] diff --git a/runtime/shiden/src/xcm_config.rs b/runtime/shiden/src/xcm_config.rs index ab2d7d2b9..981c906c5 100644 --- a/runtime/shiden/src/xcm_config.rs +++ b/runtime/shiden/src/xcm_config.rs @@ -28,8 +28,7 @@ use frame_support::{ weights::Weight, }; use frame_system::EnsureRoot; -use sp_runtime::traits::{Convert, Get}; -use sp_std::marker::PhantomData; +use sp_runtime::traits::Convert; // Polkadot imports use xcm::latest::prelude::*; @@ -47,13 +46,13 @@ use xcm_executor::{ }; // ORML imports -use orml_traits::location::{RelativeReserveProvider, Reserve}; use orml_xcm_support::DisabledParachainFee; // Astar imports use astar_primitives::xcm::{ - DescribeAllTerminal, DescribeFamily, FixedRateOfForeignAsset, HashedDescription, - ReserveAssetFilter, XcmFungibleFeeHandler, + AbsoluteAndRelativeReserveProvider, AccountIdToMultiLocation, DescribeAllTerminal, + DescribeFamily, FixedRateOfForeignAsset, HashedDescription, ReserveAssetFilter, + XcmFungibleFeeHandler, }; parameter_types! { @@ -349,18 +348,6 @@ impl cumulus_pallet_dmp_queue::Config for Runtime { type ExecuteOverweightOrigin = EnsureRoot; } -/// Convert `AccountId` to `MultiLocation`. -pub struct AccountIdToMultiLocation; -impl Convert for AccountIdToMultiLocation { - fn convert(account: AccountId) -> MultiLocation { - X1(AccountId32 { - network: None, - id: account.into(), - }) - .into() - } -} - parameter_types! { /// The absolute location in perspective of the whole network. pub ShidenLocationAbsolute: MultiLocation = MultiLocation { @@ -383,23 +370,6 @@ impl Convert> for AssetIdConvert { } } -/// `MultiAsset` reserve location provider. It's based on `RelativeReserveProvider` and in -/// addition will convert self absolute location to relative location. -pub struct AbsoluteAndRelativeReserveProvider(PhantomData); -impl> Reserve - for AbsoluteAndRelativeReserveProvider -{ - fn reserve(asset: &MultiAsset) -> Option { - RelativeReserveProvider::reserve(asset).map(|reserve_location| { - if reserve_location == AbsoluteLocation::get() { - MultiLocation::here() - } else { - reserve_location - } - }) - } -} - impl orml_xtokens::Config for Runtime { type RuntimeEvent = RuntimeEvent; type Balance = Balance;