Skip to content

Commit

Permalink
Allow bridged assets from Asset Hub (#2844)
Browse files Browse the repository at this point in the history
* add reserves

* Fix compile error to use xcm v4

* add to moonbeam runtime

* add moonriver

* Update runtime/moonbase/src/xcm_config.rs

Co-authored-by: Rodrigo Quelhas <22591718+RomarQ@users.noreply.github.com>

* name change

* cargo fmt

* make multiline

* spaces to tabs

---------

Co-authored-by: ron <yrong1997@gmail.com>
Co-authored-by: Rodrigo Quelhas <22591718+RomarQ@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 23, 2024
1 parent 54a2cc2 commit 00ae602
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 17 deletions.
24 changes: 22 additions & 2 deletions primitives/xcm/src/origin_conversion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
// You should have received a copy of the GNU General Public License
// along with Moonbeam. If not, see <http://www.gnu.org/licenses/>.

use frame_support::traits::{Get, OriginTrait};
use frame_support::traits::{ContainsPair, Get, OriginTrait};
use orml_traits::location::{RelativeReserveProvider, Reserve};
use sp_runtime::traits::TryConvert;
use sp_std::{convert::TryInto, marker::PhantomData};
use xcm::latest::{Asset, Junction::AccountKey20, Location, NetworkId};
use xcm::latest::{Asset, AssetId, Fungibility, Junction::AccountKey20, Location, NetworkId};

/// Instructs how to convert a 20 byte accountId into a Location
pub struct AccountIdToLocation<AccountId>(sp_std::marker::PhantomData<AccountId>);
Expand Down Expand Up @@ -82,3 +82,23 @@ where
})
}
}

/// Matches foreign assets from a given origin.
/// Foreign assets are assets bridged from other consensus systems. i.e parents > 1.
pub struct IsBridgedConcreteAssetFrom<Origin>(PhantomData<Origin>);
impl<Origin> ContainsPair<Asset, Location> for IsBridgedConcreteAssetFrom<Origin>
where
Origin: Get<Location>,
{
fn contains(asset: &Asset, origin: &Location) -> bool {
let loc = Origin::get();
&loc == origin
&& matches!(
asset,
Asset {
id: AssetId(Location { parents: 2, .. }),
fun: Fungibility::Fungible(_)
},
)
}
}
32 changes: 27 additions & 5 deletions runtime/moonbase/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use sp_core::{ConstU32, H160, H256};
use sp_weights::Weight;
use xcm_builder::{
AccountKey20Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
AllowTopLevelPaidExecutionFrom, ConvertedConcreteId, DescribeAllTerminal, DescribeFamily,
AllowTopLevelPaidExecutionFrom, Case, ConvertedConcreteId, DescribeAllTerminal, DescribeFamily,
EnsureXcmOrigin, FungibleAdapter as XcmCurrencyAdapter, FungiblesAdapter, HashedDescription,
NoChecking, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountKey20AsNative, SovereignSignedViaLocation,
Expand All @@ -51,16 +51,18 @@ use xcm_builder::{
use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling};

use xcm::latest::prelude::{
Asset, GlobalConsensus, InteriorLocation, Junction, Location, NetworkId, PalletInstance,
Parachain,
AllOf, Asset, AssetFilter, GlobalConsensus, InteriorLocation, Junction, Location, NetworkId,
PalletInstance, Parachain, Wild, WildFungible,
};

use xcm_executor::traits::{CallDispatcher, ConvertLocation, JustTry};

use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
use orml_xcm_support::MultiNativeAsset;
use xcm_primitives::{
AbsoluteAndRelativeReserve, AccountIdToCurrencyId, AccountIdToLocation, AsAssetType,
FirstAssetTrader, SignedToAccountId20, UtilityAvailableCalls, UtilityEncodeCall, XcmTransact,
FirstAssetTrader, IsBridgedConcreteAssetFrom, SignedToAccountId20, UtilityAvailableCalls,
UtilityEncodeCall, XcmTransact,
};

use parity_scale_codec::{Decode, Encode};
Expand Down Expand Up @@ -265,9 +267,29 @@ impl frame_support::traits::Contains<RuntimeCall> for SafeCallFilter {
}

parameter_types! {
/// Location of Asset Hub
pub AssetHubLocation: Location = Location::new(1, [Parachain(1001)]);
pub const RelayLocation: Location = Location::parent();
pub RelayLocationFilter: AssetFilter = Wild(AllOf {
fun: WildFungible,
id: xcm::prelude::AssetId(RelayLocation::get()),
});
pub RelayChainNativeAssetFromAssetHub: (AssetFilter, Location) = (
RelayLocationFilter::get(),
AssetHubLocation::get()
);
pub const MaxAssetsIntoHolding: u32 = xcm_primitives::MAX_ASSETS;
}

type Reserves = (
// Assets bridged from different consensus systems held in reserve on Asset Hub.
IsBridgedConcreteAssetFrom<AssetHubLocation>,
// Relaychain (DOT) from Asset Hub
Case<RelayChainNativeAssetFromAssetHub>,
// Assets which the reserve is the same as the origin.
MultiNativeAsset<AbsoluteAndRelativeReserve<SelfLocationAbsolute>>,
);

pub struct XcmExecutorConfig;
impl xcm_executor::Config for XcmExecutorConfig {
type RuntimeCall = RuntimeCall;
Expand All @@ -278,7 +300,7 @@ impl xcm_executor::Config for XcmExecutorConfig {
// Filter to the reserve withdraw operations
// Whenever the reserve matches the relative or absolute value
// of our chain, we always return the relative reserve
type IsReserve = MultiNativeAsset<AbsoluteAndRelativeReserve<SelfLocationAbsolute>>;
type IsReserve = Reserves;
type IsTeleporter = (); // No teleport
type UniversalLocation = UniversalLocation;
type Barrier = XcmBarrier;
Expand Down
32 changes: 27 additions & 5 deletions runtime/moonbeam/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use sp_core::{ConstU32, H160, H256};

use xcm_builder::{
AccountKey20Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
AllowTopLevelPaidExecutionFrom, ConvertedConcreteId, DescribeAllTerminal, DescribeFamily,
AllowTopLevelPaidExecutionFrom, Case, ConvertedConcreteId, DescribeAllTerminal, DescribeFamily,
EnsureXcmOrigin, FungibleAdapter as XcmCurrencyAdapter, FungiblesAdapter, HashedDescription,
NoChecking, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountKey20AsNative, SovereignSignedViaLocation,
Expand All @@ -49,16 +49,18 @@ use xcm_builder::{

use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling};
use xcm::latest::prelude::{
Asset, GlobalConsensus, InteriorLocation, Junction, Location, NetworkId, PalletInstance,
Parachain,
AllOf, Asset, AssetFilter, GlobalConsensus, InteriorLocation, Junction, Location, NetworkId,
PalletInstance, Parachain, Wild, WildFungible,
};

use xcm_executor::traits::{CallDispatcher, ConvertLocation, JustTry};

use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
use orml_xcm_support::MultiNativeAsset;
use xcm_primitives::{
AbsoluteAndRelativeReserve, AccountIdToCurrencyId, AccountIdToLocation, AsAssetType,
FirstAssetTrader, SignedToAccountId20, UtilityAvailableCalls, UtilityEncodeCall, XcmTransact,
FirstAssetTrader, IsBridgedConcreteAssetFrom, SignedToAccountId20, UtilityAvailableCalls,
UtilityEncodeCall, XcmTransact,
};

use parity_scale_codec::{Decode, Encode};
Expand Down Expand Up @@ -247,9 +249,29 @@ impl frame_support::traits::Contains<RuntimeCall> for SafeCallFilter {
}

parameter_types! {
/// Location of Asset Hub
pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]);
pub const RelayLocation: Location = Location::parent();
pub RelayLocationFilter: AssetFilter = Wild(AllOf {
fun: WildFungible,
id: xcm::prelude::AssetId(RelayLocation::get()),
});
pub RelayChainNativeAssetFromAssetHub: (AssetFilter, Location) = (
RelayLocationFilter::get(),
AssetHubLocation::get()
);
pub const MaxAssetsIntoHolding: u32 = xcm_primitives::MAX_ASSETS;
}

type Reserves = (
// Assets bridged from different consensus systems held in reserve on Asset Hub.
IsBridgedConcreteAssetFrom<AssetHubLocation>,
// Relaychain (DOT) from Asset Hub
Case<RelayChainNativeAssetFromAssetHub>,
// Assets which the reserve is the same as the origin.
MultiNativeAsset<AbsoluteAndRelativeReserve<SelfLocationAbsolute>>,
);

// Our implementation of the Moonbeam Call
// Attachs the right origin in case the call is made to pallet-ethereum-xcm
#[cfg(not(feature = "evm-tracing"))]
Expand All @@ -269,7 +291,7 @@ impl xcm_executor::Config for XcmExecutorConfig {
// Filter to the reserve withdraw operations
// Whenever the reserve matches the relative or absolute value
// of our chain, we always return the relative reserve
type IsReserve = MultiNativeAsset<AbsoluteAndRelativeReserve<SelfLocationAbsolute>>;
type IsReserve = Reserves;
type IsTeleporter = (); // No teleport
type UniversalLocation = UniversalLocation;
type Barrier = XcmBarrier;
Expand Down
32 changes: 27 additions & 5 deletions runtime/moonriver/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ use sp_core::{ConstU32, H160, H256};

use xcm_builder::{
AccountKey20Aliases, AllowKnownQueryResponses, AllowSubscriptionsFrom,
AllowTopLevelPaidExecutionFrom, ConvertedConcreteId, DescribeAllTerminal, DescribeFamily,
AllowTopLevelPaidExecutionFrom, Case, ConvertedConcreteId, DescribeAllTerminal, DescribeFamily,
EnsureXcmOrigin, FungibleAdapter as XcmCurrencyAdapter, FungiblesAdapter, HashedDescription,
NoChecking, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative,
SiblingParachainConvertsVia, SignedAccountKey20AsNative, SovereignSignedViaLocation,
Expand All @@ -49,16 +49,18 @@ use xcm_builder::{

use parachains_common::message_queue::{NarrowOriginToSibling, ParaIdToSibling};
use xcm::latest::prelude::{
Asset, GlobalConsensus, InteriorLocation, Junction, Location, NetworkId, PalletInstance,
Parachain,
AllOf, Asset, AssetFilter, GlobalConsensus, InteriorLocation, Junction, Location, NetworkId,
PalletInstance, Parachain, Wild, WildFungible,
};

use xcm_executor::traits::{CallDispatcher, ConvertLocation, JustTry};

use cumulus_primitives_core::{AggregateMessageOrigin, ParaId};
use orml_xcm_support::MultiNativeAsset;
use xcm_primitives::{
AbsoluteAndRelativeReserve, AccountIdToCurrencyId, AccountIdToLocation, AsAssetType,
FirstAssetTrader, SignedToAccountId20, UtilityAvailableCalls, UtilityEncodeCall, XcmTransact,
FirstAssetTrader, IsBridgedConcreteAssetFrom, SignedToAccountId20, UtilityAvailableCalls,
UtilityEncodeCall, XcmTransact,
};

use parity_scale_codec::{Decode, Encode};
Expand Down Expand Up @@ -255,9 +257,29 @@ impl frame_support::traits::Contains<RuntimeCall> for SafeCallFilter {
}

parameter_types! {
/// Location of Asset Hub
pub AssetHubLocation: Location = Location::new(1, [Parachain(1000)]);
pub const RelayLocation: Location = Location::parent();
pub RelayLocationFilter: AssetFilter = Wild(AllOf {
fun: WildFungible,
id: xcm::prelude::AssetId(RelayLocation::get()),
});
pub RelayChainNativeAssetFromAssetHub: (AssetFilter, Location) = (
RelayLocationFilter::get(),
AssetHubLocation::get()
);
pub const MaxAssetsIntoHolding: u32 = xcm_primitives::MAX_ASSETS;
}

type Reserves = (
// Assets bridged from different consensus systems held in reserve on Asset Hub.
IsBridgedConcreteAssetFrom<AssetHubLocation>,
// Relaychain (DOT) from Asset Hub
Case<RelayChainNativeAssetFromAssetHub>,
// Assets which the reserve is the same as the origin.
MultiNativeAsset<AbsoluteAndRelativeReserve<SelfLocationAbsolute>>,
);

// Our implementation of the Moonbeam Call
// Attachs the right origin in case the call is made to pallet-ethereum-xcm
#[cfg(not(feature = "evm-tracing"))]
Expand All @@ -277,7 +299,7 @@ impl xcm_executor::Config for XcmExecutorConfig {
// Filter to the reserve withdraw operations
// Whenever the reserve matches the relative or absolute value
// of our chain, we always return the relative reserve
type IsReserve = MultiNativeAsset<AbsoluteAndRelativeReserve<SelfLocationAbsolute>>;
type IsReserve = Reserves;
type IsTeleporter = (); // No teleport
type UniversalLocation = UniversalLocation;
type Barrier = XcmBarrier;
Expand Down

0 comments on commit 00ae602

Please sign in to comment.