Deny using relay chain for reserve transfers (#1169)

* Deny using relay chain for reserve transfers

* match on junction as well.

* Update polkadot-parachains/parachains-common/src/xcm_config.rs

* Use Err to signal deny

* Deny depisiting reserved assets + fmt

* Allow DepositReserveAssets from relay chain

Deny InitiateReserveWithdrawal

* Rather than allow DepositReserveAsset,

it was ReservAssetDeposited that should be allowed but logged.

* don't reference common parachains.

* Update parachain-template/runtime/src/xcm_config.rs

* Warn if reserve asset deposited msg detected.

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
Co-authored-by: joe petrowski <25483142+joepetrowski@users.noreply.github.com>
This commit is contained in:
Squirrel
2022-04-20 10:14:08 +01:00
committed by GitHub
parent bf51fd1513
commit 563ce7cb93
7 changed files with 209 additions and 51 deletions
+75 -8
View File
@@ -2,8 +2,9 @@ use super::{
AccountId, Balances, Call, Event, Origin, ParachainInfo, ParachainSystem, PolkadotXcm, Runtime,
WeightToFee, XcmpQueue,
};
use core::marker::PhantomData;
use frame_support::{
match_types, parameter_types,
log, match_types, parameter_types,
traits::{Everything, Nothing},
weights::Weight,
};
@@ -18,7 +19,7 @@ use xcm_builder::{
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
UsingComponents,
};
use xcm_executor::XcmExecutor;
use xcm_executor::{traits::ShouldExecute, XcmExecutor};
parameter_types! {
pub const RelayLocation: MultiLocation = MultiLocation::parent();
@@ -87,12 +88,78 @@ match_types! {
};
}
pub type Barrier = (
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<Everything>,
AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
// ^^^ Parent and its exec plurality get free execution
);
//TODO: move DenyThenTry to polkadot's xcm module.
/// Deny executing the xcm message 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<Call>(
origin: &MultiLocation,
message: &mut Xcm<Call>,
max_weight: Weight,
weight_credit: &mut Weight,
) -> Result<(), ()> {
Deny::should_execute(origin, message, max_weight, weight_credit)?;
Allow::should_execute(origin, message, max_weight, weight_credit)
}
}
// See issue #5233
pub struct DenyReserveTransferToRelayChain;
impl ShouldExecute for DenyReserveTransferToRelayChain {
fn should_execute<Call>(
origin: &MultiLocation,
message: &mut Xcm<Call>,
_max_weight: Weight,
_weight_credit: &mut Weight,
) -> Result<(), ()> {
if message.0.iter().any(|inst| {
matches!(
inst,
InitiateReserveWithdraw {
reserve: MultiLocation { parents: 1, interior: Here },
..
} | DepositReserveAsset { dest: MultiLocation { parents: 1, interior: Here }, .. } |
TransferReserveAsset {
dest: MultiLocation { parents: 1, interior: Here },
..
}
)
}) {
return Err(()) // Deny
}
// allow reserve transfers to arrive from relay chain
if matches!(origin, MultiLocation { parents: 1, interior: Here }) &&
message.0.iter().any(|inst| matches!(inst, ReserveAssetDeposited { .. }))
{
log::warn!(
target: "xcm::barriers",
"Unexpected ReserveAssetDeposited from the relay chain",
);
}
// Permit everything else
Ok(())
}
}
pub type Barrier = DenyThenTry<
DenyReserveTransferToRelayChain,
(
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<Everything>,
AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
// ^^^ Parent and its exec plurality get free execution
),
>;
pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {