git.delta.rocks / unique-network / refs/commits / 5a619a936664

difftreelog

fix(xcm) improve denythentry, deny transact xcm

Daniel Shiposha2022-08-30parent: #247c0b0.patch.diff
in: master

8 files changed

modifiedCargo.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",
modifiedruntime/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)
 	}
 }
modifiedruntime/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`
modifiedruntime/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]
modifiedruntime/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]
modifiedruntime/quartz/src/xcm_config.rsdiffbeforeafterboth
--- a/runtime/quartz/src/xcm_config.rs
+++ b/runtime/quartz/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::{
@@ -93,12 +93,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
@@ -126,9 +124,11 @@
 }
 
 pub type Barrier = DenyThenTry<
-    DenyExchangeWithUnknownLocation,
     (
         DenyTransact,
+        DenyExchangeWithUnknownLocation,
+    ),
+    (
         TakeWeightCredit,
         AllowTopLevelPaidExecutionFrom<Everything>,
         // Parent and its exec plurality get free execution
modifiedruntime/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]
modifiedruntime/unique/src/xcm_config.rsdiffbeforeafterboth
before · runtime/unique/src/xcm_config.rs
1// 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;676869pub type Barrier = DenyThenTry<70    DenyExchangeWithUnknownLocation,71    (72        DenyTransact,73        TakeWeightCredit,74        AllowTopLevelPaidExecutionFrom<Everything>,75        // Parent and its exec plurality get free execution76        AllowUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,77        // Expected responses are OK.78        AllowKnownQueryResponses<PolkadotXcm>,79        // Subscriptions for version tracking are OK.80        AllowSubscriptionsFrom<ParentOrSiblings>,81    ),82>;8384pub fn get_allowed_locations() -> Vec<MultiLocation> {85    vec![86        // Self location87        MultiLocation { parents: 0, interior: Here },88        // Parent location89        MultiLocation { parents: 1, interior: Here },90        // Karura/Acala location91        MultiLocation { parents: 1, interior: X1(Parachain(2000)) },92        // Moonbeam location93        MultiLocation { parents: 1, interior: X1(Parachain(2004)) },94        // Self parachain address95        MultiLocation { parents: 1, interior: X1(Parachain(ParachainInfo::get().into())) },96    ]97}9899// Allow xcm exchange only with locations in list100pub struct DenyExchangeWithUnknownLocation;101impl ShouldExecute for DenyExchangeWithUnknownLocation {102    fn should_execute<Call>(103        origin: &MultiLocation,104        message: &mut Xcm<Call>,105        _max_weight: Weight,106        _weight_credit: &mut Weight,107    ) -> Result<(), ()> {108109        // Check if deposit or transfer belongs to allowed parachains110        let mut allowed = get_allowed_locations().contains(origin);111112        message.0.iter().for_each(|inst| {113            match inst {114                DepositReserveAsset { dest: dst, .. } => { allowed |= get_allowed_locations().contains(dst); }115                TransferReserveAsset { dest: dst, .. } => { allowed |= get_allowed_locations().contains(dst); }116                _ => {}117            }118        });119120        if allowed {121            return Ok(());122        }123124        log::warn!(125			target: "xcm::barrier",126			"Unexpected deposit or transfer location"127		);128        // Deny129        Err(())130    }131}132133134match_types! {135	pub type ParentOrParentsExecutivePlurality: impl Contains<MultiLocation> = {136		MultiLocation { parents: 1, interior: Here } |137		MultiLocation { parents: 1, interior: X1(Plurality { id: BodyId::Executive, .. }) }138	};139	pub type ParentOrSiblings: impl Contains<MultiLocation> = {140		MultiLocation { parents: 1, interior: Here } |141		MultiLocation { parents: 1, interior: X1(_) }142	};143}144145pub fn get_all_module_accounts() -> Vec<AccountId> {146    vec![TreasuryModuleId::get().into_account_truncating()]147}148149pub struct DustRemovalWhitelist;150impl Contains<AccountId> for DustRemovalWhitelist {151    fn contains(a: &AccountId) -> bool {152        get_all_module_accounts().contains(a)153    }154}155156parameter_type_with_key! {157	pub ExistentialDeposits: |currency_id: CurrencyId| -> Balance {158		match currency_id {159			CurrencyId::NativeAssetId(symbol) => match symbol {160				NativeCurrency::Here => 0,161				NativeCurrency::Parent=> 0,162			},163			_ => 100_000164		}165	};166}167168impl orml_tokens::Config for Runtime {169    type Event = Event;170    type Balance = Balance;171    type Amount = Amount;172    type CurrencyId = CurrencyId;173    type WeightInfo = ();174    type ExistentialDeposits = ExistentialDeposits;175    type OnDust = orml_tokens::TransferDust<Runtime, TreasuryAccountId>;176    type MaxLocks = MaxLocks;177    type MaxReserves = MaxReserves;178    // TODO: Add all module accounts179    type DustRemovalWhitelist = DustRemovalWhitelist;180    /// The id type for named reserves.181    type ReserveIdentifier = ();182    type OnNewTokenAccount = ();183    type OnKilledTokenAccount = ();184}185186impl orml_xtokens::Config for Runtime {187    type Event = Event;188    type Balance = Balance;189    type CurrencyId = CurrencyId;190    type CurrencyIdConvert = CurrencyIdConvert;191    type AccountIdToMultiLocation = AccountIdToMultiLocation;192    type SelfLocation = SelfLocation;193    type XcmExecutor = XcmExecutor<XcmConfig<Self>>;194    type Weigher = FixedWeightBounds<UnitWeightCost, Call, MaxInstructions>;195    type BaseXcmWeight = BaseXcmWeight;196    type LocationInverter = LocationInverter<Ancestry>;197    type MaxAssetsForTransfer = MaxAssetsForTransfer;198    type MinXcmFee = ParachainMinFee;199    type MultiLocationsFilter = Everything;200    type ReserveProvider = AbsoluteReserveProvider;201}202203pub struct CurrencyIdConvert;204impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {205    fn convert(id: AssetIds) -> Option<MultiLocation> {206        match id {207            AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(208                1,209                X1(Parachain(ParachainInfo::get().into())),210            )),211            _ => None,212        }213    }214}215216parameter_types! {217	pub const BaseXcmWeight: Weight = 100_000_000; // TODO: recheck this218	pub const MaxAssetsForTransfer: usize = 2;219220    pub Ancestry: MultiLocation = Parachain(ParachainInfo::parachain_id().into()).into();221    pub SelfLocation: MultiLocation = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));222}223224parameter_type_with_key! {225	pub ParachainMinFee: |_location: MultiLocation| -> Option<u128> {226		Some(100_000_000)227	};228}229230231pub struct AccountIdToMultiLocation;232impl Convert<AccountId, MultiLocation> for AccountIdToMultiLocation {233    fn convert(account: AccountId) -> MultiLocation {234        X1(AccountId32 {235            network: NetworkId::Any,236            id: account.into(),237        })238            .into()239    }240}