diff --git a/parachains/runtimes/assets/test-utils/src/lib.rs b/parachains/runtimes/assets/test-utils/src/lib.rs index fb4750bae9..ee7b71131f 100644 --- a/parachains/runtimes/assets/test-utils/src/lib.rs +++ b/parachains/runtimes/assets/test-utils/src/lib.rs @@ -56,6 +56,11 @@ impl Self { + frame_support::sp_tracing::try_init_simple(); + self + } + pub fn build(self) -> sp_io::TestExternalities where Runtime: diff --git a/parachains/runtimes/assets/westmint/src/weights/xcm/mod.rs b/parachains/runtimes/assets/westmint/src/weights/xcm/mod.rs index 8429b74f2e..7aed2094c5 100644 --- a/parachains/runtimes/assets/westmint/src/weights/xcm/mod.rs +++ b/parachains/runtimes/assets/westmint/src/weights/xcm/mod.rs @@ -211,7 +211,8 @@ impl XcmWeightInfo for WestmintXcmWeight { XcmGeneric::::clear_transact_status().ref_time() } fn universal_origin(_: &Junction) -> XCMWeight { - Weight::MAX.ref_time() + // TODO:check-parameter - temporary fix - replace with correct weight for benchmark (set UniversalAliases) + XcmGeneric::::unpaid_execution().ref_time() } fn export_message(_: &NetworkId, _: &Junctions, _: &Xcm<()>) -> XCMWeight { Weight::MAX.ref_time() diff --git a/parachains/runtimes/assets/westmint/src/xcm_config.rs b/parachains/runtimes/assets/westmint/src/xcm_config.rs index fee07a1643..f117230db1 100644 --- a/parachains/runtimes/assets/westmint/src/xcm_config.rs +++ b/parachains/runtimes/assets/westmint/src/xcm_config.rs @@ -20,7 +20,7 @@ use super::{ }; use frame_support::{ match_types, parameter_types, - traits::{ConstU32, EnsureOrigin, EnsureOriginWithArg, Everything, Nothing, PalletInfoAccess}, + traits::{ConstU32, Contains, EnsureOrigin, EnsureOriginWithArg, Everything, PalletInfoAccess}, }; use pallet_xcm::{EnsureXcm, XcmPassthrough}; use parachains_common::{ @@ -39,9 +39,10 @@ use xcm_builder::{ NativeAsset, ParentAsSuperuser, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, UsingComponents, WeightInfoBounds, + WithComputedOrigin, }; use xcm_executor::{ - traits::{Convert, JustTry}, + traits::{Convert, JustTry, ShouldExecute}, XcmExecutor, }; @@ -49,7 +50,7 @@ parameter_types! { pub const WestendLocation: MultiLocation = MultiLocation::parent(); pub RelayNetwork: NetworkId = NetworkId::Westend; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); - pub UniversalLocation: InteriorMultiLocation = Parachain(ParachainInfo::parachain_id().into()).into(); + pub UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(ParachainInfo::parachain_id().into())); pub const Local: MultiLocation = Here.into_location(); // todo: accept all instances, perhaps need a type for each instance? pub TrustBackedAssetsPalletLocation: MultiLocation = @@ -152,6 +153,12 @@ match_types! { MultiLocation { parents: 1, interior: Here } | MultiLocation { parents: 1, interior: X1(Plurality { .. }) } }; + + // TODO:check-parameter - add new pallet and persist/manage this via governance? + // Means, that we accept some `GlobalConsensus` from some `MultiLocation` (which is supposed to be our bridge-hub) + pub type TrustedBridgedNetworks: impl Contains<(MultiLocation, Junction)> = { + (MultiLocation { parents: 1, interior: X1(Parachain(1014)) }, GlobalConsensus(NetworkId::Rococo)) + }; } pub type Barrier = DenyThenTry< @@ -165,6 +172,8 @@ pub type Barrier = DenyThenTry< AllowKnownQueryResponses, // Subscriptions for version tracking are OK. AllowSubscriptionsFrom, + // Specific barrier for bridged calls from different globalConsensus/network + WithComputedOrigin>, ), >; @@ -225,7 +234,7 @@ impl xcm_executor::Config for XcmConfig { type AssetExchanger = (); type FeeManager = (); type MessageExporter = (); - type UniversalAliases = Nothing; + type UniversalAliases = TrustedBridgedNetworks; type CallDispatcher = RuntimeCall; } @@ -302,3 +311,33 @@ impl EnsureOriginWithArg for ForeignCreators { pallet_xcm::Origin::Xcm(a.clone()).into() } } + +pub type BridgedCallsBarrier = ( + // TODO:check-parameter - verify, if we need for production (usefull at least for testing connection in production) + AllowExecutionForTrapFrom, + // Expected responses are OK. + AllowKnownQueryResponses, + // Subscriptions for version tracking are OK. + AllowSubscriptionsFrom, +); + +pub struct AllowExecutionForTrapFrom(sp_std::marker::PhantomData); +impl> ShouldExecute for AllowExecutionForTrapFrom { + fn should_execute( + origin: &MultiLocation, + instructions: &mut [Instruction], + max_weight: xcm::latest::Weight, + _weight_credit: &mut xcm::latest::Weight, + ) -> Result<(), ()> { + log::warn!( + target: "xcm::barriers", + "(TODO:remove-in-production) AllowExecutionForTrapFrom origin: {:?}, instructions: {:?}, max_weight: {:?}, weight_credit: {:?}", + origin, instructions, max_weight, _weight_credit, + ); + + match instructions.first() { + Some(Trap { .. }) => Ok(()), + _ => Err(()), + } + } +} diff --git a/parachains/runtimes/assets/westmint/tests/tests.rs b/parachains/runtimes/assets/westmint/tests/tests.rs index 482a60d3b5..a8461b7f5d 100644 --- a/parachains/runtimes/assets/westmint/tests/tests.rs +++ b/parachains/runtimes/assets/westmint/tests/tests.rs @@ -1,16 +1,17 @@ use asset_test_utils::{ExtBuilder, RuntimeHelper}; +use codec::Encode; use frame_support::{ - assert_noop, assert_ok, + assert_noop, assert_ok, sp_io, traits::PalletInfo, weights::{Weight, WeightToFee as WeightToFeeT}, }; use parachains_common::{AccountId, AuraId}; pub use westmint_runtime::{ constants::fee::WeightToFee, xcm_config::XcmConfig, Balances, ExistentialDeposit, Runtime, - SessionKeys, System, TrustBackedAssets, + RuntimeCall, RuntimeEvent, SessionKeys, System, TrustBackedAssets, }; use xcm::latest::prelude::*; -use xcm_executor::traits::WeightTrader; +use xcm_executor::{traits::WeightTrader, XcmExecutor}; pub const ALICE: [u8; 32] = [1u8; 32]; @@ -303,3 +304,39 @@ fn test_that_buying_ed_refund_does_not_refund() { assert_eq!(Assets::total_supply(1), ExistentialDeposit::get()); }); } + +#[test] +fn test_bridged_xcm_trap_works() { + ExtBuilder::::default() + .with_collators(vec![AccountId::from(ALICE)]) + .with_session_keys(vec![( + AccountId::from(ALICE), + AccountId::from(ALICE), + SessionKeys { aura: AuraId::from(sp_core::sr25519::Public::from_raw(ALICE)) }, + )]) + .with_tracing() + .build() + .execute_with(|| { + // simulate received message: + // 2022-12-21 14:38:54.047 DEBUG tokio-runtime-worker xcm::execute_xcm: [Parachain] origin: MultiLocation { parents: 1, interior: X1(Parachain(1014)) }, message: Xcm([UniversalOrigin(GlobalConsensus(Rococo)), DescendOrigin(X1(AccountId32 { network: Some(Rococo), id: [28, 189, 45, 67, 83, 10, 68, 112, 90, 208, 136, 175, 49, 62, 24, 248, 11, 83, 239, 22, 179, 97, 119, 205, 75, 119, 184, 70, 242, 165, 240, 124] })), Transact { origin_kind: SovereignAccount, require_weight_at_most: 1000000000, call: [0, 8, 20, 104, 101, 108, 108, 111] }]), weight_limit: 41666666666 + // origin as BridgeHub + let origin = MultiLocation { parents: 1, interior: X1(Parachain(1014)) }; + let xcm = Xcm(vec![ + UniversalOrigin(GlobalConsensus(Rococo)), + DescendOrigin(X1(AccountId32 { + network: Some(Rococo), + id: [ + 28, 189, 45, 67, 83, 10, 68, 112, 90, 208, 136, 175, 49, 62, 24, 248, 11, + 83, 239, 22, 179, 97, 119, 205, 75, 119, 184, 70, 242, 165, 240, 124, + ], + })), + Trap(1234), + ]); + let hash = xcm.using_encoded(sp_io::hashing::blake2_256); + let weight_limit = 41666666666; + + let outcome = XcmExecutor::::execute_xcm(origin, xcm, hash, weight_limit); + log::trace!(target: "xcm::execute", "outcome: {:?}", outcome); + assert_eq!(outcome.ensure_complete(), Err(xcm::latest::Error::Trap(1234))); + }); +}