difftreelog
fix(xcm) improve denythentry, deny transact xcm
in: master
8 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4572,6 +4572,16 @@
]
[[package]]
+name = "logtest"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eb3e43a8657c1d64516dcc9db8ca03826a4aceaf89d5ce1b37b59f6ff0e43026"
+dependencies = [
+ "lazy_static",
+ "log",
+]
+
+[[package]]
name = "lru"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5148,7 +5158,9 @@
"frame-system-rpc-runtime-api",
"frame-try-runtime",
"hex-literal",
+ "impl-trait-for-tuples",
"log",
+ "logtest",
"orml-tokens",
"orml-traits",
"orml-vesting",
@@ -8466,7 +8478,9 @@
"frame-system-rpc-runtime-api",
"frame-try-runtime",
"hex-literal",
+ "impl-trait-for-tuples",
"log",
+ "logtest",
"orml-tokens",
"orml-traits",
"orml-vesting",
@@ -12206,7 +12220,7 @@
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
"digest 0.10.3",
"rand 0.8.5",
"static_assertions",
@@ -12459,7 +12473,9 @@
"frame-system-rpc-runtime-api",
"frame-try-runtime",
"hex-literal",
+ "impl-trait-for-tuples",
"log",
+ "logtest",
"orml-tokens",
"orml-traits",
"orml-vesting",
runtime/common/config/xcm.rsdiffbeforeafterboth--- a/runtime/common/config/xcm.rs
+++ b/runtime/common/config/xcm.rs
@@ -172,13 +172,32 @@
};
}
+pub trait TryPass {
+ fn try_pass<Call>(
+ origin: &MultiLocation,
+ message: &mut Xcm<Call>,
+ ) -> Result<(), ()>;
+}
+
+#[impl_trait_for_tuples::impl_for_tuples(30)]
+impl TryPass for Tuple {
+ fn try_pass<Call>(
+ origin: &MultiLocation,
+ message: &mut Xcm<Call>,
+ ) -> Result<(), ()> {
+ for_tuples!( #(
+ Tuple::try_pass(origin, message)?;
+ )* );
+
+ Ok(())
+ }
+}
+
pub struct DenyTransact;
-impl ShouldExecute for DenyTransact {
- fn should_execute<Call>(
+impl TryPass for DenyTransact {
+ fn try_pass<Call>(
_origin: &MultiLocation,
message: &mut Xcm<Call>,
- _max_weight: Weight,
- _weight_credit: &mut Weight,
) -> Result<(), ()> {
let transact_inst = message
.0
@@ -203,12 +222,12 @@
/// 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,
+ Deny: TryPass,
Allow: ShouldExecute;
impl<Deny, Allow> ShouldExecute for DenyThenTry<Deny, Allow>
where
- Deny: ShouldExecute,
+ Deny: TryPass,
Allow: ShouldExecute,
{
fn should_execute<Call>(
@@ -217,7 +236,7 @@
max_weight: Weight,
weight_credit: &mut Weight,
) -> Result<(), ()> {
- Deny::should_execute(origin, message, max_weight, weight_credit)?;
+ Deny::try_pass(origin, message)?;
Allow::should_execute(origin, message, max_weight, weight_credit)
}
}
runtime/common/tests/xcm.rsdiffbeforeafterboth--- a/runtime/common/tests/xcm.rs
+++ b/runtime/common/tests/xcm.rs
@@ -34,7 +34,7 @@
}
#[test]
-fn xcm_barrier_does_not_allow_transact() {
+fn xcm_barrier_denies_transact() {
// We have a `AllowTopLevelPaidExecutionFrom` barrier,
// so an XCM program should start from one of the following commands:
// * `WithdrawAsset`
runtime/opal/Cargo.tomldiffbeforeafterboth--- a/runtime/opal/Cargo.toml
+++ b/runtime/opal/Cargo.toml
@@ -463,6 +463,11 @@
pallet-foreing-assets = { default-features = false, path = "../../pallets/foreing-assets" }
################################################################################
+# Other Dependencies
+
+impl-trait-for-tuples = "0.2.2"
+
+################################################################################
# Dev Dependencies
[dev-dependencies.logtest]
runtime/quartz/Cargo.tomldiffbeforeafterboth--- a/runtime/quartz/Cargo.toml
+++ b/runtime/quartz/Cargo.toml
@@ -471,6 +471,11 @@
pallet-foreing-assets = { default-features = false, path = "../../pallets/foreing-assets" }
################################################################################
+# Other Dependencies
+
+impl-trait-for-tuples = "0.2.2"
+
+################################################################################
# Dev Dependencies
[dev-dependencies.logtest]
runtime/quartz/src/xcm_config.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617use cumulus_pallet_xcm;18use frame_support::{19 {match_types, parameter_types, weights::Weight},20 pallet_prelude::Get,21 traits::{Contains, Everything, fungibles},22};23use frame_system::EnsureRoot;24use orml_traits::{location::AbsoluteReserveProvider, parameter_type_with_key};25use pallet_xcm::XcmPassthrough;26use polkadot_parachain::primitives::Sibling;27use sp_runtime::traits::{AccountIdConversion, CheckedConversion, Convert, Zero};28use sp_std::{borrow::Borrow, marker::PhantomData, vec, vec::Vec};29use xcm::{30 latest::{MultiAsset, Xcm},31 prelude::{Concrete, Fungible as XcmFungible},32 v1::{BodyId, Junction::*, Junctions::*, MultiLocation, NetworkId},33};34use xcm_builder::{35 AllowKnownQueryResponses, AllowSubscriptionsFrom,36 AccountId32Aliases, AllowTopLevelPaidExecutionFrom, AllowUnpaidExecutionFrom,37 EnsureXcmOrigin, FixedWeightBounds, FungiblesAdapter, LocationInverter, ParentAsSuperuser,38 ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia,39 SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,40 ConvertedConcreteAssetId,41};42use xcm_executor::{43 {Config, XcmExecutor},44 traits::{Convert as ConvertXcm, FilterAssetLocation, JustTry, MatchesFungible, ShouldExecute},45};4647use up_common::{48 constants::{MAXIMUM_BLOCK_WEIGHT, UNIQUE},49 types::{AccountId, Balance},50};51use pallet_foreing_assets::{52 AssetIds, AssetIdMapping, XcmForeignAssetIdMapping, CurrencyId, NativeCurrency,53 FreeForAll, TryAsForeing, ForeignAssetId,54};55use crate::{56 Balances, Call, DmpQueue, Event, Origin, ParachainInfo,57 ParachainSystem, PolkadotXcm, Runtime, XcmpQueue,58};59use crate::runtime_common::config::substrate::{TreasuryModuleId, MaxLocks, MaxReserves};60use crate::runtime_common::config::pallets::TreasuryAccountId;61use crate::runtime_common::config::xcm::*;62use crate::*;63use xcm::opaque::latest::prelude::{ DepositReserveAsset, DepositAsset, TransferAsset, TransferReserveAsset };6465// Signed version of balance66pub type Amount = i128;6768match_types! {69 pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {70 MultiLocation { parents: 1, interior: Here } |71 MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) }72 };73 pub type ParentOrSiblings: impl Contains<MultiLocation> = {74 MultiLocation { parents: 1, interior: Here } |75 MultiLocation { parents: 1, interior: X1(_) }76 };77}7879pub fn get_allowed_locations() -> Vec<MultiLocation> {80 vec![81 // Self location82 MultiLocation { parents: 0, interior: Here },83 // Parent location84 MultiLocation { parents: 1, interior: Here },85 // Karura/Acala location86 MultiLocation { parents: 1, interior: X1(Parachain(2000)) },87 // Moonriver location88 MultiLocation { parents: 1, interior: X1(Parachain(2023)) },89 // Self parachain address90 MultiLocation { parents: 1, interior: X1(Parachain(ParachainInfo::get().into())) },91 ]92}9394// Allow xcm exchange only with locations in list95pub struct DenyExchangeWithUnknownLocation;96impl ShouldExecute for DenyExchangeWithUnknownLocation {97 fn should_execute<Call>(98 origin: &MultiLocation,99 message: &mut Xcm<Call>,100 _max_weight: Weight,101 _weight_credit: &mut Weight,102 ) -> Result<(), ()> {103104 // Check if deposit or transfer belongs to allowed parachains105 let mut allowed = get_allowed_locations().contains(origin);106107 message.0.iter().for_each(|inst| {108 match inst {109 DepositReserveAsset { dest: dst, .. } => { allowed |= get_allowed_locations().contains(dst); }110 TransferReserveAsset { dest: dst, .. } => { allowed |= get_allowed_locations().contains(dst); }111 _ => {}112 }113 });114115 if allowed {116 return Ok(());117 }118119 log::warn!(120 target: "xcm::barrier",121 "Unexpected deposit or transfer location"122 );123 // Deny124 Err(())125 }126}127128pub type Barrier = DenyThenTry<129 DenyExchangeWithUnknownLocation,130 (131 DenyTransact,132 TakeWeightCredit,133 AllowTopLevelPaidExecutionFrom<Everything>,134 // Parent and its exec plurality get free execution135 AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,136 // Expected responses are OK.137 AllowKnownQueryResponses<PolkadotXcm>,138 // Subscriptions for version tracking are OK.139 AllowSubscriptionsFrom<ParentOrSiblings>,140 ),141>;142143impl orml_tokens::Config for Runtime {144 type Event = Event;145 type Balance = Balance;146 type Amount = Amount;147 type CurrencyId = CurrencyId;148 type WeightInfo = ();149 type ExistentialDeposits = ExistentialDeposits;150 type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;151 type MaxLocks = MaxLocks;152 type MaxReserves = MaxReserves;153 // TODO: Add all module accounts154 type DustRemovalWhitelist = DustRemovalWhitelist;155 /// The id type for named reserves.156 type ReserveIdentifier = ();157 type OnNewTokenAccount = ();158 type OnKilledTokenAccount = ();159}160161impl orml_xtokens::Config for Runtime {162 type Event = Event;163 type Balance = Balance;164 type CurrencyId = CurrencyId;165 type CurrencyIdConvert = CurrencyIdConvert;166 type AccountIdToMultiLocation = AccountIdToMultiLocation;167 type SelfLocation = SelfLocation;168 type XcmExecutor = XcmExecutor<XcmConfig<Self>>;169 type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;170 type BaseXcmWeight = BaseXcmWeight;171 type LocationInverter = LocationInverter<Ancestry>;172 type MaxAssetsForTransfer = MaxAssetsForTransfer;173 type MinXcmFee = ParachainMinFee;174 type MultiLocationsFilter = Everything;175 type ReserveProvider = AbsoluteReserveProvider;176}177178179parameter_type_with_key! {180 pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {181 match currency_id {182 CurrencyId::NativeAssetId(symbol) => match symbol {183 NativeCurrency::Here => 0,184 NativeCurrency::Parent=> 0,185 },186 _ => 100_000187 }188 };189}190191pub struct DustRemovalWhitelist;192impl Contains<AccountId> for DustRemovalWhitelist {193 fn contains(a: &AccountId) -> bool {194 get_all_module_accounts().contains(a)195 }196}197198199pub struct CurrencyIdConvert;200impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {201 fn convert(id: AssetIds) -> Option<MultiLocation> {202 match id {203 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(204 1,205 X1(Parachain(ParachainInfo::get().into())),206 )),207 AssetIds::NativeAssetId(NativeCurrency::Parent) => Some(MultiLocation::parent()),208 AssetIds::ForeignAssetId(_) => None,209 }210 }211}212/*213impl Convert<MultiLocation, Option<CurrencyId>> for CurrencyIdConvert {214 fn convert(location: MultiLocation) -> Option<CurrencyId> {215 if location == MultiLocation::here()216 || location == MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())))217 {218 return Some(AssetIds::NativeAssetId(NativeCurrency::Here));219 }220221 if location == MultiLocation::parent() {222 return Some(AssetIds::NativeAssetId(NativeCurrency::Parent));223 }224225 if let Some(currency_id) =226 XcmForeignAssetIdMapping::<Runtime>::get_currency_id(location.clone())227 {228 return Some(currency_id);229 }230231 None232 }233}234235 */236237238parameter_types! {239 pub const BaseXcmWeight: Weight = 100_000_000; // TODO: recheck this240 pub const MaxAssetsForTransfer: usize = 2;241}242243parameter_types! {244 pub const RelayLocation: MultiLocation = MultiLocation::parent();245 pub const RelayNetwork: NetworkId = NetworkId::Polkadot;246 pub RelayOrigin: Origin = cumulus_pallet_xcm::Origin::Relay.into();247 pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();248 pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));249}250251parameter_type_with_key! {252 pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {253 Some(100_000_000)254 };255}256257pub fn get_all_module_accounts() -> Vec<AccountId> {258 vec![TreasuryModuleId::get().into_account_truncating()]259}260261pub struct AccountIdToMultiLocation;262impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {263 fn convert(account: AccountId) -> MultiLocation {264 X1(AccountId32 {265 network: NetworkId::Any,266 id: account.into(),267 })268 .into()269 }270}runtime/unique/Cargo.tomldiffbeforeafterboth--- a/runtime/unique/Cargo.toml
+++ b/runtime/unique/Cargo.toml
@@ -463,6 +463,11 @@
pallet-foreing-assets = { default-features = false, path = "../../pallets/foreing-assets" }
################################################################################
+# Other Dependencies
+
+impl-trait-for-tuples = "0.2.2"
+
+################################################################################
# Dev Dependencies
[dev-dependencies.logtest]
runtime/unique/src/xcm_config.rsdiffbeforeafterboth--- a/runtime/unique/src/xcm_config.rs
+++ b/runtime/unique/src/xcm_config.rs
@@ -41,7 +41,7 @@
};
use xcm_executor::{
{Config, XcmExecutor},
- traits::{Convert as ConvertXcm, FilterAssetLocation, JustTry, MatchesFungible, ShouldExecute},
+ traits::{Convert as ConvertXcm, FilterAssetLocation, JustTry, MatchesFungible},
};
use up_common::{
@@ -67,9 +67,11 @@
pub type Barrier = DenyThenTry<
- DenyExchangeWithUnknownLocation,
(
DenyTransact,
+ DenyExchangeWithUnknownLocation,
+ ),
+ (
TakeWeightCredit,
AllowTopLevelPaidExecutionFrom<Everything>,
// Parent and its exec plurality get free execution
@@ -98,12 +100,10 @@
// Allow xcm exchange only with locations in list
pub struct DenyExchangeWithUnknownLocation;
-impl ShouldExecute for DenyExchangeWithUnknownLocation {
- fn should_execute<Call>(
+impl TryPass for DenyExchangeWithUnknownLocation {
+ fn try_pass<Call>(
origin: &MultiLocation,
message: &mut Xcm<Call>,
- _max_weight: Weight,
- _weight_credit: &mut Weight,
) -> Result<(), ()> {
// Check if deposit or transfer belongs to allowed parachains