mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-07 11:57:23 +00:00
cf4a6efbbd
* Companion for paritytech/polkadot#7098 * Fixes * Add missing benchmarked function * Fix typo * update lockfile for {"polkadot", "substrate"} --------- Co-authored-by: parity-processbot <>
140 lines
4.7 KiB
Rust
140 lines
4.7 KiB
Rust
use crate::impls::AccountIdOf;
|
|
use core::{marker::PhantomData, ops::ControlFlow};
|
|
use frame_support::{
|
|
log,
|
|
traits::{
|
|
fungibles::Inspect, tokens::ConversionToAssetBalance, ContainsPair, ProcessMessageError,
|
|
},
|
|
weights::Weight,
|
|
};
|
|
use sp_runtime::traits::Get;
|
|
use xcm::latest::prelude::*;
|
|
use xcm_builder::{CreateMatcher, MatchXcm};
|
|
use xcm_executor::traits::ShouldExecute;
|
|
|
|
//TODO: move DenyThenTry to polkadot's xcm module.
|
|
/// Deny executing the XCM if it matches any of the Deny filter regardless of anything else.
|
|
/// If it passes the Deny, and matches one of the Allow cases then it is let through.
|
|
pub struct DenyThenTry<Deny, Allow>(PhantomData<Deny>, PhantomData<Allow>)
|
|
where
|
|
Deny: ShouldExecute,
|
|
Allow: ShouldExecute;
|
|
|
|
impl<Deny, Allow> ShouldExecute for DenyThenTry<Deny, Allow>
|
|
where
|
|
Deny: ShouldExecute,
|
|
Allow: ShouldExecute,
|
|
{
|
|
fn should_execute<RuntimeCall>(
|
|
origin: &MultiLocation,
|
|
message: &mut [Instruction<RuntimeCall>],
|
|
max_weight: Weight,
|
|
weight_credit: &mut Weight,
|
|
) -> Result<(), ProcessMessageError> {
|
|
Deny::should_execute(origin, message, max_weight, weight_credit)?;
|
|
Allow::should_execute(origin, message, max_weight, weight_credit)
|
|
}
|
|
}
|
|
|
|
// See issue <https://github.com/paritytech/polkadot/issues/5233>
|
|
pub struct DenyReserveTransferToRelayChain;
|
|
impl ShouldExecute for DenyReserveTransferToRelayChain {
|
|
fn should_execute<RuntimeCall>(
|
|
origin: &MultiLocation,
|
|
message: &mut [Instruction<RuntimeCall>],
|
|
_max_weight: Weight,
|
|
_weight_credit: &mut Weight,
|
|
) -> Result<(), ProcessMessageError> {
|
|
message.matcher().match_next_inst_while(
|
|
|_| true,
|
|
|inst| match inst {
|
|
InitiateReserveWithdraw {
|
|
reserve: MultiLocation { parents: 1, interior: Here },
|
|
..
|
|
} |
|
|
DepositReserveAsset {
|
|
dest: MultiLocation { parents: 1, interior: Here }, ..
|
|
} |
|
|
TransferReserveAsset {
|
|
dest: MultiLocation { parents: 1, interior: Here }, ..
|
|
} => {
|
|
Err(ProcessMessageError::Unsupported) // Deny
|
|
},
|
|
|
|
// An unexpected reserve transfer has arrived from the Relay Chain. Generally,
|
|
// `IsReserve` should not allow this, but we just log it here.
|
|
ReserveAssetDeposited { .. }
|
|
if matches!(origin, MultiLocation { parents: 1, interior: Here }) =>
|
|
{
|
|
log::warn!(
|
|
target: "xcm::barrier",
|
|
"Unexpected ReserveAssetDeposited from the Relay Chain",
|
|
);
|
|
Ok(ControlFlow::Continue(()))
|
|
},
|
|
|
|
_ => Ok(ControlFlow::Continue(())),
|
|
},
|
|
)?;
|
|
|
|
// Permit everything else
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// A `ChargeFeeInFungibles` implementation that converts the output of
|
|
/// a given WeightToFee implementation an amount charged in
|
|
/// a particular assetId from pallet-assets
|
|
pub struct AssetFeeAsExistentialDepositMultiplier<
|
|
Runtime,
|
|
WeightToFee,
|
|
BalanceConverter,
|
|
AssetInstance: 'static,
|
|
>(PhantomData<(Runtime, WeightToFee, BalanceConverter, AssetInstance)>);
|
|
impl<CurrencyBalance, Runtime, WeightToFee, BalanceConverter, AssetInstance>
|
|
cumulus_primitives_utility::ChargeWeightInFungibles<
|
|
AccountIdOf<Runtime>,
|
|
pallet_assets::Pallet<Runtime, AssetInstance>,
|
|
> for AssetFeeAsExistentialDepositMultiplier<Runtime, WeightToFee, BalanceConverter, AssetInstance>
|
|
where
|
|
Runtime: pallet_assets::Config<AssetInstance>,
|
|
WeightToFee: frame_support::weights::WeightToFee<Balance = CurrencyBalance>,
|
|
BalanceConverter: ConversionToAssetBalance<
|
|
CurrencyBalance,
|
|
<Runtime as pallet_assets::Config<AssetInstance>>::AssetId,
|
|
<Runtime as pallet_assets::Config<AssetInstance>>::Balance,
|
|
>,
|
|
AccountIdOf<Runtime>:
|
|
From<polkadot_primitives::AccountId> + Into<polkadot_primitives::AccountId>,
|
|
{
|
|
fn charge_weight_in_fungibles(
|
|
asset_id: <pallet_assets::Pallet<Runtime, AssetInstance> as Inspect<
|
|
AccountIdOf<Runtime>,
|
|
>>::AssetId,
|
|
weight: Weight,
|
|
) -> Result<
|
|
<pallet_assets::Pallet<Runtime, AssetInstance> as Inspect<AccountIdOf<Runtime>>>::Balance,
|
|
XcmError,
|
|
> {
|
|
let amount = WeightToFee::weight_to_fee(&weight);
|
|
// If the amount gotten is not at least the ED, then make it be the ED of the asset
|
|
// This is to avoid burning assets and decreasing the supply
|
|
let asset_amount = BalanceConverter::to_asset_balance(amount, asset_id)
|
|
.map_err(|_| XcmError::TooExpensive)?;
|
|
Ok(asset_amount)
|
|
}
|
|
}
|
|
|
|
/// Accepts an asset if it is a native asset from a particular `MultiLocation`.
|
|
pub struct ConcreteNativeAssetFrom<Location>(PhantomData<Location>);
|
|
impl<Location: Get<MultiLocation>> ContainsPair<MultiAsset, MultiLocation>
|
|
for ConcreteNativeAssetFrom<Location>
|
|
{
|
|
fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool {
|
|
log::trace!(target: "xcm::filter_asset_location",
|
|
"ConcreteNativeAsset asset: {:?}, origin: {:?}, location: {:?}",
|
|
asset, origin, Location::get());
|
|
matches!(asset.id, Concrete(ref id) if id == origin && origin == &Location::get())
|
|
}
|
|
}
|