From a2a959818a788222bfd952b8c99e2243d05af9f9 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Mon, 20 May 2024 17:05:34 +0200 Subject: [PATCH 1/9] test: add proper zombienet configuration so we can use a trusted teleporter --- zombienet/local-testnet.toml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/zombienet/local-testnet.toml b/zombienet/local-testnet.toml index 8c0f821d4..f05fc1b0a 100644 --- a/zombienet/local-testnet.toml +++ b/zombienet/local-testnet.toml @@ -1,5 +1,6 @@ [relaychain] chain = "rococo-local" +default_args = ["--detailed-log-output", "-lxcm=trace"] default_command = "polkadot" [[relaychain.nodes]] @@ -12,10 +13,15 @@ validator = true [[parachains]] cumulus_based = true -id = 2000 +# 1000 and 1001 do not work for some reason. +# We need to use a Parachain of an existing System Chain (https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/runtime/rococo/src/xcm_config.rs). +# The reason: being able to get native DOTs from Relay Chain to Parachain via XCM Teleport. +# We'll have a proper Parachain ID in the *future*, but for now, let's stick to 1002. +id = 1002 # run charlie as parachain collator [[parachains.collators]] +args = ["--detailed-log-output", "-lxcm=trace"] command = "target/release/polka-storage-node" name = "charlie" validator = true From 1165702e4a732212c4b0af3b0f220732b17ff917 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Tue, 21 May 2024 15:48:31 +0200 Subject: [PATCH 2/9] feat: add proper xcm teleport handling from a native chain --- runtime/src/configs/xcm_config.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/runtime/src/configs/xcm_config.rs b/runtime/src/configs/xcm_config.rs index 16b087363..f639b951b 100644 --- a/runtime/src/configs/xcm_config.rs +++ b/runtime/src/configs/xcm_config.rs @@ -9,7 +9,8 @@ use polkadot_parachain_primitives::primitives::Sibling; use polkadot_runtime_common::impls::ToAuthor; use xcm::latest::prelude::*; use xcm_builder::{ - AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowTopLevelPaidExecutionFrom, + AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, + AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, FixedWeightBounds, FrameTransactionalProcessor, FungibleAdapter, IsConcrete, NativeAsset, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, @@ -23,6 +24,8 @@ use crate::{ Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }; +use parachains_common::xcm_config::{ConcreteAssetFromSystem, ParentRelayOrSiblingParachains}; + parameter_types! { pub const RelayLocation: Location = Location::parent(); pub const RelayNetwork: Option = None; @@ -103,16 +106,20 @@ impl Contains for ParentOrParentsExecutivePlurality { } } +pub type TrustedTeleporters = (ConcreteAssetFromSystem,); + pub type Barrier = TrailingSetTopicAsId< DenyThenTry< DenyReserveTransferToRelayChain, ( TakeWeightCredit, + AllowKnownQueryResponses, WithComputedOrigin< ( AllowTopLevelPaidExecutionFrom, AllowExplicitUnpaidExecutionFrom, - // ^^^ Parent and its exec plurality get free execution + AllowSubscriptionsFrom, + AllowHrmpNotificationsFromRelayChain, ), UniversalLocation, ConstU32<8>, @@ -129,7 +136,7 @@ impl xcm_executor::Config for XcmConfig { type AssetTransactor = LocalAssetTransactor; type OriginConverter = XcmOriginToTransactDispatchOrigin; type IsReserve = NativeAsset; - type IsTeleporter = (); // Teleporting is disabled. + type IsTeleporter = TrustedTeleporters; type UniversalLocation = UniversalLocation; type Barrier = Barrier; type Weigher = FixedWeightBounds; From b26afd95d611b6905dacba830a8adac7b6119e91 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Wed, 22 May 2024 14:49:48 +0200 Subject: [PATCH 3/9] feat: allow sending xcm from the relay chain --- runtime/src/configs/xcm_config.rs | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/runtime/src/configs/xcm_config.rs b/runtime/src/configs/xcm_config.rs index f639b951b..fc1e0cf3c 100644 --- a/runtime/src/configs/xcm_config.rs +++ b/runtime/src/configs/xcm_config.rs @@ -12,10 +12,11 @@ use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, FixedWeightBounds, - FrameTransactionalProcessor, FungibleAdapter, IsConcrete, NativeAsset, ParentIsPreset, + FrameTransactionalProcessor, FungibleAdapter, IsConcrete, ParentIsPreset, RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic, + XcmFeeManagerFromComponents, }; use xcm_executor::XcmExecutor; @@ -24,10 +25,14 @@ use crate::{ Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue, }; -use parachains_common::xcm_config::{ConcreteAssetFromSystem, ParentRelayOrSiblingParachains}; +use parachains_common::xcm_config::{ + AllSiblingSystemParachains, ConcreteAssetFromSystem, ParentRelayOrSiblingParachains, + RelayOrOtherSystemParachains, +}; parameter_types! { pub const RelayLocation: Location = Location::parent(); + pub const HereLocation: Location = Location::here(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); // For the real deployment, it is recommended to set `RelayNetwork` according to the relay chain @@ -52,7 +57,7 @@ pub type LocalAssetTransactor = FungibleAdapter< // Use this currency: Balances, // Use this currency when it is a fungible asset matching the given location or name: - IsConcrete, + (IsConcrete, IsConcrete), // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): @@ -106,7 +111,11 @@ impl Contains for ParentOrParentsExecutivePlurality { } } -pub type TrustedTeleporters = (ConcreteAssetFromSystem,); +pub type TrustedTeleporters = ( + ConcreteAssetFromSystem, + ConcreteAssetFromSystem, + ConcreteAssetFromSystem, +); pub type Barrier = TrailingSetTopicAsId< DenyThenTry< @@ -128,6 +137,8 @@ pub type Barrier = TrailingSetTopicAsId< >, >; +pub type WaivedLocations = (RelayOrOtherSystemParachains,); + pub struct XcmConfig; impl xcm_executor::Config for XcmConfig { type RuntimeCall = RuntimeCall; @@ -135,7 +146,7 @@ impl xcm_executor::Config for XcmConfig { // How to withdraw and deposit an asset. type AssetTransactor = LocalAssetTransactor; type OriginConverter = XcmOriginToTransactDispatchOrigin; - type IsReserve = NativeAsset; + type IsReserve = (); type IsTeleporter = TrustedTeleporters; type UniversalLocation = UniversalLocation; type Barrier = Barrier; @@ -150,7 +161,7 @@ impl xcm_executor::Config for XcmConfig { type MaxAssetsIntoHolding = MaxAssetsIntoHolding; type AssetLocker = (); type AssetExchanger = (); - type FeeManager = (); + type FeeManager = XcmFeeManagerFromComponents; type MessageExporter = (); type UniversalAliases = Nothing; type CallDispatcher = RuntimeCall; @@ -179,7 +190,7 @@ impl pallet_xcm::Config for Runtime { type SendXcmOrigin = EnsureXcmOrigin; type XcmRouter = XcmRouter; type ExecuteXcmOrigin = EnsureXcmOrigin; - type XcmExecuteFilter = Nothing; + type XcmExecuteFilter = Everything; // ^ Disable dispatchable execute on the XCM pallet. // Needs to be `Everything` for local testing. type XcmExecutor = XcmExecutor; @@ -198,6 +209,7 @@ impl pallet_xcm::Config for Runtime { type TrustedLockers = (); type SovereignAccountOf = LocationToAccountId; type MaxLockers = ConstU32<8>; + // TODO: type WeightInfo = pallet_xcm::TestWeightInfo; type AdminOrigin = EnsureRoot; type MaxRemoteLockConsumers = ConstU32<0>; From 1cad0f248c22ee8f525ae1140b57fb0f7ae099d3 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Wed, 22 May 2024 17:56:38 +0200 Subject: [PATCH 4/9] fix: simplify xcm config --- runtime/src/configs/xcm_config.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/runtime/src/configs/xcm_config.rs b/runtime/src/configs/xcm_config.rs index fc1e0cf3c..b8c2e66e3 100644 --- a/runtime/src/configs/xcm_config.rs +++ b/runtime/src/configs/xcm_config.rs @@ -32,7 +32,6 @@ use parachains_common::xcm_config::{ parameter_types! { pub const RelayLocation: Location = Location::parent(); - pub const HereLocation: Location = Location::here(); pub const RelayNetwork: Option = None; pub RelayChainOrigin: RuntimeOrigin = cumulus_pallet_xcm::Origin::Relay.into(); // For the real deployment, it is recommended to set `RelayNetwork` according to the relay chain @@ -57,7 +56,7 @@ pub type LocalAssetTransactor = FungibleAdapter< // Use this currency: Balances, // Use this currency when it is a fungible asset matching the given location or name: - (IsConcrete, IsConcrete), + IsConcrete, // Do a simple punn to convert an AccountId32 Location into a native chain account ID: LocationToAccountId, // Our chain's account ID type (we can't get away without mentioning it explicitly): @@ -113,8 +112,6 @@ impl Contains for ParentOrParentsExecutivePlurality { pub type TrustedTeleporters = ( ConcreteAssetFromSystem, - ConcreteAssetFromSystem, - ConcreteAssetFromSystem, ); pub type Barrier = TrailingSetTopicAsId< From 030b5165086e53d962ba681590399623b4a7fc38 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Wed, 22 May 2024 17:57:14 +0200 Subject: [PATCH 5/9] test: simplify zombienet configuration and add debugging --- zombienet/local-testnet.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/zombienet/local-testnet.toml b/zombienet/local-testnet.toml index f05fc1b0a..35151f15f 100644 --- a/zombienet/local-testnet.toml +++ b/zombienet/local-testnet.toml @@ -1,6 +1,6 @@ [relaychain] chain = "rococo-local" -default_args = ["--detailed-log-output", "-lxcm=trace"] +default_args = ["--detailed-log-output", "-lparachain=debug,xcm=trace,runtime=trace"] default_command = "polkadot" [[relaychain.nodes]] @@ -13,15 +13,15 @@ validator = true [[parachains]] cumulus_based = true -# 1000 and 1001 do not work for some reason. + # We need to use a Parachain of an existing System Chain (https://github.com/paritytech/polkadot-sdk/blob/master/polkadot/runtime/rococo/src/xcm_config.rs). # The reason: being able to get native DOTs from Relay Chain to Parachain via XCM Teleport. -# We'll have a proper Parachain ID in the *future*, but for now, let's stick to 1002. -id = 1002 +# We'll have a proper Parachain ID in the *future*, but for now, let's stick to 1000 (which is AssetHub and trusted). +id = 1000 # run charlie as parachain collator [[parachains.collators]] -args = ["--detailed-log-output", "-lxcm=trace"] +args = ["--detailed-log-output", "-lparachain=debug,xcm=trace,runtime=trace"] command = "target/release/polka-storage-node" name = "charlie" validator = true From ab90d6c34fd15e79ae9addb1e5a8260105876c25 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Wed, 22 May 2024 18:07:36 +0200 Subject: [PATCH 6/9] style: fix formatting --- runtime/src/configs/xcm_config.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/runtime/src/configs/xcm_config.rs b/runtime/src/configs/xcm_config.rs index b8c2e66e3..84f005a26 100644 --- a/runtime/src/configs/xcm_config.rs +++ b/runtime/src/configs/xcm_config.rs @@ -12,11 +12,10 @@ use xcm_builder::{ AccountId32Aliases, AllowExplicitUnpaidExecutionFrom, AllowHrmpNotificationsFromRelayChain, AllowKnownQueryResponses, AllowSubscriptionsFrom, AllowTopLevelPaidExecutionFrom, DenyReserveTransferToRelayChain, DenyThenTry, EnsureXcmOrigin, FixedWeightBounds, - FrameTransactionalProcessor, FungibleAdapter, IsConcrete, ParentIsPreset, - RelayChainAsNative, SiblingParachainAsNative, SiblingParachainConvertsVia, - SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, - TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic, - XcmFeeManagerFromComponents, + FrameTransactionalProcessor, FungibleAdapter, IsConcrete, ParentIsPreset, RelayChainAsNative, + SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative, + SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId, + UsingComponents, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents, }; use xcm_executor::XcmExecutor; @@ -110,9 +109,7 @@ impl Contains for ParentOrParentsExecutivePlurality { } } -pub type TrustedTeleporters = ( - ConcreteAssetFromSystem, -); +pub type TrustedTeleporters = (ConcreteAssetFromSystem,); pub type Barrier = TrailingSetTopicAsId< DenyThenTry< From ced46eb18e648efa26cb888a0c24c08ba9811cdc Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Wed, 22 May 2024 19:06:12 +0200 Subject: [PATCH 7/9] style: add proper todo link for weights --- runtime/src/configs/xcm_config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/configs/xcm_config.rs b/runtime/src/configs/xcm_config.rs index 84f005a26..664ff8550 100644 --- a/runtime/src/configs/xcm_config.rs +++ b/runtime/src/configs/xcm_config.rs @@ -203,7 +203,7 @@ impl pallet_xcm::Config for Runtime { type TrustedLockers = (); type SovereignAccountOf = LocationToAccountId; type MaxLockers = ConstU32<8>; - // TODO: + // TODO(@th7nder, #35, 2024-05-22): Set proper weight, TestWeightInfo is equal to () type WeightInfo = pallet_xcm::TestWeightInfo; type AdminOrigin = EnsureRoot; type MaxRemoteLockConsumers = ConstU32<0>; From 3555b8c57c22bd85365646b2ab904a240448db35 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Thu, 23 May 2024 10:40:03 +0200 Subject: [PATCH 8/9] docs: add reasoning behind XCM changes in comments --- runtime/src/configs/xcm_config.rs | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/runtime/src/configs/xcm_config.rs b/runtime/src/configs/xcm_config.rs index 664ff8550..f027fa56f 100644 --- a/runtime/src/configs/xcm_config.rs +++ b/runtime/src/configs/xcm_config.rs @@ -109,6 +109,9 @@ impl Contains for ParentOrParentsExecutivePlurality { } } +/// Teleporting assets between chains (relay<->parachain) requires both-way trust. +/// Relay Chain trusts its system parachains, by hardcoded parachain IDs. Currently we use 1000 (AssetHub) id, for this to work out of the box. +/// ConcreteAssetFromSystem trusts teleports of a native currency (assets from a location of a relay Chain). pub type TrustedTeleporters = (ConcreteAssetFromSystem,); pub type Barrier = TrailingSetTopicAsId< @@ -121,7 +124,12 @@ pub type Barrier = TrailingSetTopicAsId< ( AllowTopLevelPaidExecutionFrom, AllowExplicitUnpaidExecutionFrom, + // SubscribeVersion is a query about the XCM version that is supported + // In the process of teleport those are send both ways. AllowSubscriptionsFrom, + // HRMP is the current protocol for the communications between the chains, + // When teleporting assets, XCM instructions are exchanged via HRMP. + // It'll be someday replaced by XCMP, but it's not implemented yet. AllowHrmpNotificationsFromRelayChain, ), UniversalLocation, @@ -131,6 +139,9 @@ pub type Barrier = TrailingSetTopicAsId< >, >; +/// Locations that will not be charged fees in the executor, +/// either execution or delivery. +/// We only waive fees for system functions, which these locations represent pub type WaivedLocations = (RelayOrOtherSystemParachains,); pub struct XcmConfig; @@ -140,10 +151,15 @@ impl xcm_executor::Config for XcmConfig { // How to withdraw and deposit an asset. type AssetTransactor = LocalAssetTransactor; type OriginConverter = XcmOriginToTransactDispatchOrigin; + // Reserve is a different kind of transfering assets between chains. + // You can either teleport or reserve. Teleport is for trusted chains (polkadot<->system parachain). + // Reserve is for other kinds consensum system, like Ethereum. + // In our parachain we don't allow nor leverage reserve transfers, so it's disabled. type IsReserve = (); type IsTeleporter = TrustedTeleporters; type UniversalLocation = UniversalLocation; type Barrier = Barrier; + // TODO(@th7nder, #35, 2024-05-22): Set proper weight type Weigher = FixedWeightBounds; type Trader = UsingComponents>; @@ -155,6 +171,9 @@ impl xcm_executor::Config for XcmConfig { type MaxAssetsIntoHolding = MaxAssetsIntoHolding; type AssetLocker = (); type AssetExchanger = (); + // XcmFees are paid when executing XCM instructions (e.g. teleporting assets between chains). + // We don't want to take fees when doing those instructions between relay<->parachains, so it's waived. + // The () corresponds to what we do, when it's not system parachain or relay. Currently we don't support that, so it does nothing. type FeeManager = XcmFeeManagerFromComponents; type MessageExporter = (); type UniversalAliases = Nothing; @@ -183,13 +202,15 @@ impl pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type SendXcmOrigin = EnsureXcmOrigin; type XcmRouter = XcmRouter; + // We support local origins dispatching XCM executions in principle... type ExecuteXcmOrigin = EnsureXcmOrigin; - type XcmExecuteFilter = Everything; - // ^ Disable dispatchable execute on the XCM pallet. - // Needs to be `Everything` for local testing. + // ... but disallow generic XCM execution. As a result only teleports and reserve transfers are + // allowed. + type XcmExecuteFilter = Nothing; type XcmExecutor = XcmExecutor; type XcmTeleportFilter = Everything; type XcmReserveTransferFilter = Nothing; + // TODO(@th7nder, #35, 2024-05-22): Set proper weight. type Weigher = FixedWeightBounds; type UniversalLocation = UniversalLocation; type RuntimeOrigin = RuntimeOrigin; From 0c96ff849a423d687be0c624a0f1620146c46016 Mon Sep 17 00:00:00 2001 From: Konrad Stepniak Date: Thu, 23 May 2024 12:31:35 +0200 Subject: [PATCH 9/9] docs: add more docs to xcm_config --- runtime/src/configs/xcm_config.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/runtime/src/configs/xcm_config.rs b/runtime/src/configs/xcm_config.rs index f027fa56f..d71f7ba79 100644 --- a/runtime/src/configs/xcm_config.rs +++ b/runtime/src/configs/xcm_config.rs @@ -111,7 +111,7 @@ impl Contains for ParentOrParentsExecutivePlurality { /// Teleporting assets between chains (relay<->parachain) requires both-way trust. /// Relay Chain trusts its system parachains, by hardcoded parachain IDs. Currently we use 1000 (AssetHub) id, for this to work out of the box. -/// ConcreteAssetFromSystem trusts teleports of a native currency (assets from a location of a relay Chain). +/// [`ConcreteAssetFromSystem`](parachains_common::xcm_config::ConcreteAssetFromSystem) trusts teleports of a native currency (assets from a location of a relay Chain). pub type TrustedTeleporters = (ConcreteAssetFromSystem,); pub type Barrier = TrailingSetTopicAsId< @@ -130,6 +130,7 @@ pub type Barrier = TrailingSetTopicAsId< // HRMP is the current protocol for the communications between the chains, // When teleporting assets, XCM instructions are exchanged via HRMP. // It'll be someday replaced by XCMP, but it's not implemented yet. + // https://wiki.polkadot.network/docs/learn-xcm-transport#xcmp-cross-chain-message-passing AllowHrmpNotificationsFromRelayChain, ), UniversalLocation, @@ -153,7 +154,7 @@ impl xcm_executor::Config for XcmConfig { type OriginConverter = XcmOriginToTransactDispatchOrigin; // Reserve is a different kind of transfering assets between chains. // You can either teleport or reserve. Teleport is for trusted chains (polkadot<->system parachain). - // Reserve is for other kinds consensum system, like Ethereum. + // Reserve is for other kinds consensus system, like Ethereum. // In our parachain we don't allow nor leverage reserve transfers, so it's disabled. type IsReserve = (); type IsTeleporter = TrustedTeleporters;