Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

FeeManager that puts fees in a central account #2358

Closed
wants to merge 2 commits into from
Closed
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
8 changes: 7 additions & 1 deletion parachains/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,10 @@ mod types {
/// Common constants of parachains.
mod constants {
use super::types::BlockNumber;
use frame_support::weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight};
use frame_support::{
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight},
PalletId,
};
use sp_runtime::Perbill;
/// This determines the average expected block time that we are targeting. Blocks will be
/// produced at a minimum duration defined by `SLOT_DURATION`. `SLOT_DURATION` is picked up by
Expand Down Expand Up @@ -96,6 +99,9 @@ mod constants {
WEIGHT_REF_TIME_PER_SECOND.saturating_div(2),
polkadot_primitives::MAX_POV_SIZE as u64,
);

/// Relay Chain treasury pallet id, used to convert into AccountId
pub const RELAY_TREASURY_PALLET_ID: PalletId = PalletId(*b"py/trsry");
}

/// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
Expand Down
8 changes: 6 additions & 2 deletions parachains/runtimes/assets/statemine/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use super::{
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
};
use cumulus_primitives_utility::XcmFeeManagerToAccount;
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, Everything, Nothing, PalletInfoAccess},
Expand All @@ -28,9 +29,10 @@ use parachains_common::{
xcm_config::{
AssetFeeAsExistentialDepositMultiplier, DenyReserveTransferToRelayChain, DenyThenTry,
},
RELAY_TREASURY_PALLET_ID,
};
use polkadot_parachain::primitives::Sibling;
use sp_runtime::traits::ConvertInto;
use sp_runtime::traits::{AccountIdConversion, ConvertInto};
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
Expand Down Expand Up @@ -133,6 +135,7 @@ parameter_types! {
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub XcmAssetFeesReceiver: Option<AccountId> = Authorship::author();
pub XcmAssetFeesReceiverToTreasury: Option<AccountId> = Some(RELAY_TREASURY_PALLET_ID.into_account_truncating());
}

match_types! {
Expand Down Expand Up @@ -351,7 +354,8 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type FeeManager =
XcmFeeManagerToAccount<AssetTransactors, AccountId, XcmAssetFeesReceiverToTreasury>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
Expand Down
8 changes: 6 additions & 2 deletions parachains/runtimes/assets/statemint/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use super::{
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
};
use cumulus_primitives_utility::XcmFeeManagerToAccount;
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, Everything, Nothing, PalletInfoAccess},
Expand All @@ -28,9 +29,10 @@ use parachains_common::{
xcm_config::{
AssetFeeAsExistentialDepositMultiplier, DenyReserveTransferToRelayChain, DenyThenTry,
},
RELAY_TREASURY_PALLET_ID,
};
use polkadot_parachain::primitives::Sibling;
use sp_runtime::traits::ConvertInto;
use sp_runtime::traits::{AccountIdConversion, ConvertInto};
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
Expand Down Expand Up @@ -133,6 +135,7 @@ parameter_types! {
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub XcmAssetFeesReceiver: Option<AccountId> = Authorship::author();
pub XcmAssetFeesReceiverToTreasury: Option<AccountId> = Some(RELAY_TREASURY_PALLET_ID.into_account_truncating());
}

match_types! {
Expand Down Expand Up @@ -317,7 +320,8 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type FeeManager =
XcmFeeManagerToAccount<AssetTransactors, AccountId, XcmAssetFeesReceiverToTreasury>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
Expand Down
8 changes: 6 additions & 2 deletions parachains/runtimes/assets/westmint/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use super::{
ParachainSystem, PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin,
TrustBackedAssetsInstance, WeightToFee, XcmpQueue,
};
use cumulus_primitives_utility::XcmFeeManagerToAccount;
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, Everything, Nothing, PalletInfoAccess},
Expand All @@ -28,9 +29,10 @@ use parachains_common::{
xcm_config::{
AssetFeeAsExistentialDepositMultiplier, DenyReserveTransferToRelayChain, DenyThenTry,
},
RELAY_TREASURY_PALLET_ID,
};
use polkadot_parachain::primitives::Sibling;
use sp_runtime::traits::ConvertInto;
use sp_runtime::traits::{AccountIdConversion, ConvertInto};
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
Expand Down Expand Up @@ -131,6 +133,7 @@ parameter_types! {
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub XcmAssetFeesReceiver: Option<AccountId> = Authorship::author();
pub XcmAssetFeesReceiverToTreasury: Option<AccountId> = Some(RELAY_TREASURY_PALLET_ID.into_account_truncating());
}

match_types! {
Expand Down Expand Up @@ -344,7 +347,8 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type FeeManager =
XcmFeeManagerToAccount<AssetTransactors, AccountId, XcmAssetFeesReceiverToTreasury>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ use super::{
AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm,
Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue,
};
use cumulus_primitives_utility::XcmFeeManagerToAccount;
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, Everything, Nothing},
};
use pallet_xcm::XcmPassthrough;
use parachains_common::xcm_config::{
ConcreteNativeAssetFrom, DenyReserveTransferToRelayChain, DenyThenTry,
use parachains_common::{
xcm_config::{ConcreteNativeAssetFrom, DenyReserveTransferToRelayChain, DenyThenTry},
RELAY_TREASURY_PALLET_ID,
};
use polkadot_parachain::primitives::Sibling;
use polkadot_runtime_common::impls::ToAuthor;
use sp_runtime::traits::AccountIdConversion;
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
Expand All @@ -47,6 +50,7 @@ parameter_types! {
X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into()));
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub XcmAssetFeesReceiverToTreasury: Option<AccountId> = Some(RELAY_TREASURY_PALLET_ID.into_account_truncating());
pub const GovernanceLocation: MultiLocation = MultiLocation::parent();
pub const FellowshipLocation: MultiLocation = MultiLocation::parent();
}
Expand Down Expand Up @@ -205,7 +209,8 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type FeeManager =
XcmFeeManagerToAccount<CurrencyTransactor, AccountId, XcmAssetFeesReceiverToTreasury>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ use super::{
AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm,
Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue,
};
use cumulus_primitives_utility::XcmFeeManagerToAccount;
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, Everything, Nothing},
};
use pallet_xcm::XcmPassthrough;
use parachains_common::xcm_config::{
ConcreteNativeAssetFrom, DenyReserveTransferToRelayChain, DenyThenTry,
use parachains_common::{
xcm_config::{ConcreteNativeAssetFrom, DenyReserveTransferToRelayChain, DenyThenTry},
RELAY_TREASURY_PALLET_ID,
};
use polkadot_parachain::primitives::Sibling;
use polkadot_runtime_common::impls::ToAuthor;
use sp_runtime::traits::AccountIdConversion;
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
Expand All @@ -47,6 +50,7 @@ parameter_types! {
X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into()));
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub XcmAssetFeesReceiverToTreasury: Option<AccountId> = Some(RELAY_TREASURY_PALLET_ID.into_account_truncating());
pub FellowshipLocation: MultiLocation = MultiLocation::new(1, Parachain(1001));
pub const GovernanceLocation: MultiLocation = MultiLocation::parent();
}
Expand Down Expand Up @@ -205,7 +209,8 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type FeeManager =
XcmFeeManagerToAccount<CurrencyTransactor, AccountId, XcmAssetFeesReceiverToTreasury>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,19 @@ use super::{
AccountId, AllPalletsWithSystem, Balances, ParachainInfo, ParachainSystem, PolkadotXcm,
Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue,
};
use cumulus_primitives_utility::XcmFeeManagerToAccount;
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, Everything, Nothing},
};
use pallet_xcm::XcmPassthrough;
use parachains_common::xcm_config::{
ConcreteNativeAssetFrom, DenyReserveTransferToRelayChain, DenyThenTry,
use parachains_common::{
xcm_config::{ConcreteNativeAssetFrom, DenyReserveTransferToRelayChain, DenyThenTry},
RELAY_TREASURY_PALLET_ID,
};
use polkadot_parachain::primitives::Sibling;
use polkadot_runtime_common::impls::ToAuthor;
use sp_runtime::traits::AccountIdConversion;
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
Expand All @@ -47,6 +50,7 @@ parameter_types! {
X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(ParachainInfo::parachain_id().into()));
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub XcmAssetFeesReceiverToTreasury: Option<AccountId> = Some(RELAY_TREASURY_PALLET_ID.into_account_truncating());
}

/// Type for specifying how a `MultiLocation` can be converted into an `AccountId`. This is used
Expand Down Expand Up @@ -203,7 +207,8 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type FeeManager =
XcmFeeManagerToAccount<CurrencyTransactor, AccountId, XcmAssetFeesReceiverToTreasury>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ use super::{
AccountId, AllPalletsWithSystem, Balances, Fellows, ParachainInfo, ParachainSystem,
PolkadotXcm, Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue,
};
use cumulus_primitives_utility::XcmFeeManagerToAccount;
use frame_support::{
match_types, parameter_types,
traits::{ConstU32, Contains, Everything, Nothing},
Expand All @@ -26,8 +27,10 @@ use pallet_xcm::XcmPassthrough;
use parachains_common::{
impls::ToStakingPot,
xcm_config::{ConcreteNativeAssetFrom, DenyReserveTransferToRelayChain, DenyThenTry},
RELAY_TREASURY_PALLET_ID,
};
use polkadot_parachain::primitives::Sibling;
use sp_runtime::traits::AccountIdConversion;
use xcm::latest::prelude::*;
use xcm_builder::{
AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowKnownQueryResponses,
Expand Down Expand Up @@ -105,6 +108,7 @@ parameter_types! {
pub UnitWeightCost: Weight = Weight::from_parts(1_000_000_000, 64 * 1024);
pub const MaxInstructions: u32 = 100;
pub const MaxAssetsIntoHolding: u32 = 64;
pub XcmAssetFeesReceiverToTreasury: Option<AccountId> = Some(RELAY_TREASURY_PALLET_ID.into_account_truncating());
// Fellows pluralistic body.
pub const FellowsBodyId: BodyId = BodyId::Technical;
}
Expand Down Expand Up @@ -241,7 +245,8 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
type FeeManager =
XcmFeeManagerToAccount<CurrencyTransactor, AccountId, XcmAssetFeesReceiverToTreasury>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = WithOriginFilter<SafeCallFilter>;
Expand Down
41 changes: 39 additions & 2 deletions primitives/utility/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use sp_runtime::{traits::Saturating, SaturatedConversion};
use sp_std::{marker::PhantomData, prelude::*};
use xcm::{latest::prelude::*, WrapVersion};
use xcm_builder::TakeRevenue;
use xcm_executor::traits::{MatchesFungibles, TransactAsset, WeightTrader};
use xcm_executor::traits::{FeeManager, FeeReason, MatchesFungibles, TransactAsset, WeightTrader};

pub trait PriceForParentDelivery {
fn price_for_parent_delivery(message: &Xcm<()>) -> MultiAssets;
Expand Down Expand Up @@ -270,7 +270,7 @@ impl<
}

/// XCM fee depositor to which we implement the TakeRevenue trait
/// It receives a Transact implemented argument, a 32 byte convertible acocuntId, and the fee receiver account
/// It receives a Transact implemented argument, a 32 byte convertible accountId, and the fee receiver account
/// FungiblesMutateAdapter should be identical to that implemented by WithdrawAsset
pub struct XcmFeesTo32ByteAccount<FungiblesMutateAdapter, AccountId, ReceiverAccount>(
PhantomData<(FungiblesMutateAdapter, AccountId, ReceiverAccount)>,
Expand All @@ -297,6 +297,43 @@ impl<
}
}

pub struct XcmFeeManagerToAccount<FungiblesMutateAdapter, AccountId, ReceiverAccount>
where
FungiblesMutateAdapter: xcm_executor::traits::TransactAsset,
{
_phantom: PhantomData<(FungiblesMutateAdapter, AccountId, ReceiverAccount)>,
}

impl<FungiblesMutateAdapter, AccountId, ReceiverAccount> FeeManager
for XcmFeeManagerToAccount<FungiblesMutateAdapter, AccountId, ReceiverAccount>
where
FungiblesMutateAdapter: xcm_executor::traits::TransactAsset,
AccountId: Clone + Into<[u8; 32]>,
ReceiverAccount: frame_support::traits::Get<Option<AccountId>>,
gilescope marked this conversation as resolved.
Show resolved Hide resolved
{
fn is_waived(origin: Option<&MultiLocation>, _: FeeReason) -> bool {
matches!(origin, Some(MultiLocation { parents: 1, interior: Here }))
vstam1 marked this conversation as resolved.
Show resolved Hide resolved
}

fn handle_fee(fee: MultiAssets) {
if let Some(receiver) = ReceiverAccount::get() {
let dest = X1(AccountId32 { network: None, id: receiver.into() }).into();
for asset in fee.into_inner() {
let ok = FungiblesMutateAdapter::deposit_asset(
&asset,
&dest,
// We aren't able to track the XCM that initiated the fee deposit, so we create a
// fake message hash here
&XcmContext::with_message_hash([0; 32]),
gilescope marked this conversation as resolved.
Show resolved Hide resolved
)
.is_ok();

debug_assert!(ok, "`deposit_asset` cannot generally fail");
}
}
}
}

/// ChargeWeightInFungibles trait, which converts a given amount of weight
/// and an assetId, and it returns the balance amount that should be charged
/// in such assetId for that amount of weight
Expand Down