Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Configure XCM messaging between Relay Chain and Parachain #31

Merged
merged 11 commits into from
May 27, 2024
56 changes: 45 additions & 11 deletions runtime/src/configs/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,13 @@ 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,
SignedAccountId32AsNative, SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit,
TrailingSetTopicAsId, UsingComponents, WithComputedOrigin, WithUniqueTopic,
FrameTransactionalProcessor, FungibleAdapter, IsConcrete, ParentIsPreset, RelayChainAsNative,
SiblingParachainAsNative, SiblingParachainConvertsVia, SignedAccountId32AsNative,
SignedToAccountId32, SovereignSignedViaLocation, TakeWeightCredit, TrailingSetTopicAsId,
UsingComponents, WithComputedOrigin, WithUniqueTopic, XcmFeeManagerFromComponents,
};
use xcm_executor::XcmExecutor;

Expand All @@ -23,6 +24,11 @@ use crate::{
Runtime, RuntimeCall, RuntimeEvent, RuntimeOrigin, WeightToFee, XcmpQueue,
};

use parachains_common::xcm_config::{
AllSiblingSystemParachains, ConcreteAssetFromSystem, ParentRelayOrSiblingParachains,
RelayOrOtherSystemParachains,
};

parameter_types! {
pub const RelayLocation: Location = Location::parent();
pub const RelayNetwork: Option<NetworkId> = None;
Expand Down Expand Up @@ -103,16 +109,28 @@ impl Contains<Location> 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<RelayLocation> trusts teleports of a native currency (assets from a location of a relay Chain).
th7nder marked this conversation as resolved.
Show resolved Hide resolved
pub type TrustedTeleporters = (ConcreteAssetFromSystem<RelayLocation>,);

pub type Barrier = TrailingSetTopicAsId<
DenyThenTry<
DenyReserveTransferToRelayChain,
(
TakeWeightCredit,
AllowKnownQueryResponses<PolkadotXcm>,
WithComputedOrigin<
(
AllowTopLevelPaidExecutionFrom<Everything>,
AllowExplicitUnpaidExecutionFrom<ParentOrParentsExecutivePlurality>,
// ^^^ Parent and its exec plurality get free execution
// SubscribeVersion is a query about the XCM version that is supported
// In the process of teleport those are send both ways.
AllowSubscriptionsFrom<ParentRelayOrSiblingParachains>,
// 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.
th7nder marked this conversation as resolved.
Show resolved Hide resolved
AllowHrmpNotificationsFromRelayChain,
),
UniversalLocation,
ConstU32<8>,
Expand All @@ -121,17 +139,27 @@ 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<AllSiblingSystemParachains, Runtime>,);

pub struct XcmConfig;
impl xcm_executor::Config for XcmConfig {
type RuntimeCall = RuntimeCall;
type XcmSender = XcmRouter;
// How to withdraw and deposit an asset.
type AssetTransactor = LocalAssetTransactor;
type OriginConverter = XcmOriginToTransactDispatchOrigin;
type IsReserve = NativeAsset;
type IsTeleporter = (); // Teleporting is disabled.
// 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.
th7nder marked this conversation as resolved.
Show resolved Hide resolved
// In our parachain we don't allow nor leverage reserve transfers, so it's disabled.
type IsReserve = ();
th7nder marked this conversation as resolved.
Show resolved Hide resolved
type IsTeleporter = TrustedTeleporters;
type UniversalLocation = UniversalLocation;
type Barrier = Barrier;
// TODO(@th7nder, #35, 2024-05-22): Set proper weight
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type Trader =
UsingComponents<WeightToFee, RelayLocation, AccountId, Balances, ToAuthor<Runtime>>;
Expand All @@ -143,7 +171,10 @@ impl xcm_executor::Config for XcmConfig {
type MaxAssetsIntoHolding = MaxAssetsIntoHolding;
type AssetLocker = ();
type AssetExchanger = ();
type FeeManager = ();
// 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<WaivedLocations, ()>;
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = RuntimeCall;
Expand Down Expand Up @@ -171,13 +202,15 @@ impl pallet_xcm::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type SendXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
type XcmRouter = XcmRouter;
// We support local origins dispatching XCM executions in principle...
type ExecuteXcmOrigin = EnsureXcmOrigin<RuntimeOrigin, LocalOriginToLocation>;
// ... but disallow generic XCM execution. As a result only teleports and reserve transfers are
// allowed.
type XcmExecuteFilter = Nothing;
// ^ Disable dispatchable execute on the XCM pallet.
// Needs to be `Everything` for local testing.
type XcmExecutor = XcmExecutor<XcmConfig>;
type XcmTeleportFilter = Everything;
type XcmReserveTransferFilter = Nothing;
// TODO(@th7nder, #35, 2024-05-22): Set proper weight.
type Weigher = FixedWeightBounds<UnitWeightCost, RuntimeCall, MaxInstructions>;
type UniversalLocation = UniversalLocation;
type RuntimeOrigin = RuntimeOrigin;
Expand All @@ -191,6 +224,7 @@ impl pallet_xcm::Config for Runtime {
type TrustedLockers = ();
type SovereignAccountOf = LocationToAccountId;
type MaxLockers = ConstU32<8>;
// TODO(@th7nder, #35, 2024-05-22): Set proper weight, TestWeightInfo is equal to ()
type WeightInfo = pallet_xcm::TestWeightInfo;
type AdminOrigin = EnsureRoot<AccountId>;
type MaxRemoteLockConsumers = ConstU32<0>;
Expand Down
8 changes: 7 additions & 1 deletion zombienet/local-testnet.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[relaychain]
chain = "rococo-local"
default_args = ["--detailed-log-output", "-lparachain=debug,xcm=trace,runtime=trace"]
default_command = "polkadot"

[[relaychain.nodes]]
Expand All @@ -12,10 +13,15 @@ validator = true

[[parachains]]
cumulus_based = true
id = 2000

# 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 1000 (which is AssetHub and trusted).
id = 1000

# run charlie as parachain collator
[[parachains.collators]]
args = ["--detailed-log-output", "-lparachain=debug,xcm=trace,runtime=trace"]
command = "target/release/polka-storage-node"
name = "charlie"
validator = true