Skip to content
Closed
Prev Previous commit
Next Next commit
Make a struct in xcm_primitives with the required bounds
  • Loading branch information
girazoki committed Nov 29, 2021
commit 6ac546a7cfb6ffd3a6e4818aaf9db3e59a763b05
23 changes: 20 additions & 3 deletions primitives/xcm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
#![cfg_attr(not(feature = "std"), no_std)]

use frame_support::{
traits::{Get, OriginTrait},
traits::{tokens::fungibles::Mutate, Get, OriginTrait},
weights::{constants::WEIGHT_PER_SECOND, Weight},
};
use xcm::latest::{
Expand All @@ -29,8 +29,7 @@ use xcm::latest::{
MultiAsset, MultiLocation, NetworkId,
};
use xcm_builder::TakeRevenue;
use xcm_executor::traits::FilterAssetLocation;
use xcm_executor::traits::WeightTrader;
use xcm_executor::traits::{FilterAssetLocation, MatchesFungibles, WeightTrader};

use sp_std::borrow::Borrow;
use sp_std::{convert::TryInto, marker::PhantomData};
Expand Down Expand Up @@ -310,3 +309,21 @@ pub trait AccountIdToCurrencyId<Account, CurrencyId> {
// Get assetId from account
fn account_to_currency_id(account: Account) -> Option<CurrencyId>;
}

pub struct XcmFeesToAccount<Assets, Matcher, AccountId, ReceiverAccount>(
PhantomData<(Assets, Matcher, AccountId, ReceiverAccount)>,
);
impl<
Assets: Mutate<AccountId>,
Matcher: MatchesFungibles<Assets::AssetId, Assets::Balance>,
AccountId: Clone, // can't get away without it since Currency is generic over it.
ReceiverAccount: Get<AccountId>,
> TakeRevenue for XcmFeesToAccount<Assets, Matcher, AccountId, ReceiverAccount>
{
fn take_revenue(revenue: MultiAsset) {
if let Ok((asset_id, amount)) = Matcher::matches_fungibles(&revenue) {
let ok = Assets::mint_into(asset_id, &ReceiverAccount::get(), amount).is_ok();
debug_assert!(ok, "`mint_into` cannot generally fail; qed");
}
}
}
52 changes: 24 additions & 28 deletions runtime/moonbase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ use fp_rpc::TransactionStatus;
use pallet_evm_precompile_assets_erc20::AccountIdAssetIdConversion;

use account::AccountId20;
use frame_support::traits::tokens::fungibles::Mutate;
use sp_runtime::traits::Hash as THash;

use frame_support::{
Expand All @@ -55,7 +54,7 @@ use xcm_builder::{
CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter,
IsConcrete, LocationInverter, ParentAsSuperuser, ParentIsDefault, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountKey20AsNative,
SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit, UsingComponents,
SovereignSignedViaLocation, TakeWeightCredit, UsingComponents,
};

use xcm_executor::traits::JustTry;
Expand Down Expand Up @@ -106,7 +105,8 @@ use precompiles::{MoonbasePrecompiles, ASSET_PRECOMPILE_ADDRESS_PREFIX};

use xcm_primitives::{
AccountIdToCurrencyId, AccountIdToMultiLocation, AsAssetType, FirstAssetTrader,
MultiNativeAsset, SignedToAccountId20, UtilityAvailableCalls, UtilityEncodeCall, XcmTransact,
MultiNativeAsset, SignedToAccountId20, UtilityAvailableCalls, UtilityEncodeCall,
XcmFeesToAccount, XcmTransact,
};

#[cfg(any(feature = "std", test))]
Expand Down Expand Up @@ -576,25 +576,6 @@ impl pallet_democracy::Config for Runtime {
type MaxProposals = MaxProposals;
}

pub struct ToTreasury<AssetXConverter>(sp_std::marker::PhantomData<AssetXConverter>);
impl<AssetXConverter> TakeRevenue for ToTreasury<AssetXConverter>
where
AssetXConverter: xcm_executor::traits::Convert<MultiLocation, AssetId>,
{
fn take_revenue(revenue: MultiAsset) {
if let MultiAsset {
id: Concrete(location),
fun: Fungible(amount),
} = revenue
{
if let Some(asset_id) = AssetXConverter::convert_ref(location).ok() {
// Mint fees in treasury
let _ = Assets::mint_into(asset_id, &Treasury::account_id(), amount);
}
}
}
}

parameter_types! {
pub const ProposalBond: Permill = Permill::from_percent(5);
pub const ProposalBondMinimum: Balance = 1 * currency::UNIT * currency::SUPPLY_FACTOR;
Expand Down Expand Up @@ -1070,6 +1051,26 @@ pub type XcmBarrier = (
AllowSubscriptionsFrom<Everything>,
);

parameter_types! {
/// Xcm fees will go to the treasury account
pub TreasuryAccount:AccountId = Treasury::account_id();
}

/// This is the struct that will handle the revenue from xcm fees
pub type XcmFeesToTreasury = XcmFeesToAccount<
Assets,
(
ConvertedConcreteAssetId<
AssetId,
Balance,
AsAssetType<AssetId, AssetType, AssetManager>,
JustTry,
>,
),
AccountId,
TreasuryAccount,
>;

pub struct XcmExecutorConfig;
impl xcm_executor::Config for XcmExecutorConfig {
type Call = Call;
Expand All @@ -1095,12 +1096,7 @@ impl xcm_executor::Config for XcmExecutorConfig {
Balances,
DealWithFees<Runtime>,
>,
FirstAssetTrader<
AssetId,
AssetType,
AssetManager,
ToTreasury<AsAssetType<AssetId, AssetType, AssetManager>>,
>,
FirstAssetTrader<AssetId, AssetType, AssetManager, XcmFeesToTreasury>,
);
type ResponseHandler = PolkadotXcm;
type SubscriptionService = PolkadotXcm;
Expand Down
46 changes: 21 additions & 25 deletions runtime/moonbase/tests/xcm_mock/parachain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

use frame_support::{
construct_runtime, parameter_types,
traits::{tokens::fungibles::Mutate, Everything, Get, Nothing, PalletInfo as PalletInfoTrait},
traits::{Everything, Get, Nothing, PalletInfo as PalletInfoTrait},
weights::Weight,
PalletId,
};
Expand Down Expand Up @@ -47,7 +47,7 @@ use xcm_builder::{
CurrencyAdapter as XcmCurrencyAdapter, EnsureXcmOrigin, FixedRateOfFungible, FixedWeightBounds,
FungiblesAdapter, IsConcrete, LocationInverter, ParentAsSuperuser, ParentIsDefault,
RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,
SignedAccountKey20AsNative, SovereignSignedViaLocation, TakeRevenue, TakeWeightCredit,
SignedAccountKey20AsNative, SovereignSignedViaLocation, TakeWeightCredit,
};
use xcm_executor::{traits::JustTry, Config, XcmExecutor};

Expand Down Expand Up @@ -222,25 +222,26 @@ pub type Barrier = (
AllowSubscriptionsFrom<Everything>,
);

pub struct ToTreasury<AssetXConverter>(sp_std::marker::PhantomData<AssetXConverter>);
impl<AssetXConverter> TakeRevenue for ToTreasury<AssetXConverter>
where
AssetXConverter: xcm_executor::traits::Convert<MultiLocation, AssetId>,
{
fn take_revenue(revenue: MultiAsset) {
if let MultiAsset {
id: Concrete(location),
fun: Fungible(amount),
} = revenue
{
if let Some(asset_id) = AssetXConverter::convert_ref(location).ok() {
// Mint fees in treasury
let _ = Assets::mint_into(asset_id, &Treasury::account_id(), amount);
}
}
}
parameter_types! {
/// Xcm fees will go to the treasury account
pub TreasuryAccount:AccountId = Treasury::account_id();
}

/// This is the struct that will handle the revenue from xcm fees
pub type XcmFeesToTreasury = xcm_primitives::XcmFeesToAccount<
Assets,
(
ConvertedConcreteAssetId<
AssetId,
Balance,
xcm_primitives::AsAssetType<AssetId, AssetType, AssetManager>,
JustTry,
>,
),
AccountId,
TreasuryAccount,
>;

parameter_types! {
// We cannot skip the native trader for some specific tests, so we will have to work with
// a native trader that charges same number of units as weight
Expand Down Expand Up @@ -272,12 +273,7 @@ impl Config for XcmConfig {
type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;
type Trader = (
FixedRateOfFungible<ParaTokensPerSecond, ()>,
xcm_primitives::FirstAssetTrader<
AssetId,
AssetType,
AssetManager,
ToTreasury<xcm_primitives::AsAssetType<AssetId, AssetType, AssetManager>>,
>,
xcm_primitives::FirstAssetTrader<AssetId, AssetType, AssetManager, XcmFeesToTreasury>,
);

type ResponseHandler = PolkadotXcm;
Expand Down