pallet_xcm

Branch/Release: release-polkadot-v1.10.0

Source Code

Purpose

pallet-xcm is responsible for filtering, routing, and executing incoming XCM.

Config

  • Pallet-specific origins:

    • AdminOrigin — The origin that is allowed to call privileged operations on the XCM pallet. Type must implement trait EnsureOrigin.

    • ExecuteXcmOrigin — Required origin for executing XCM messages, including the teleport functionality. If successful, it returns a MultiLocation which exists as an interior location within this chain’s XCM context. Type must implement trait EnsureOrigin.

    • SendXcmOrigin — Required origin for sending XCM messages. If successful, it resolves to MultiLocation. Type must implement trait EnsureOrigin.

  • Pallet-specific ID types:

    • RemoteLockConsumerIdentifier — The ID type for local consumers of remote locks. The type must implement Copy.

  • Pallet-specific handlers:

    • Currency — Lockable currency used in the pallet. Type must implement the trait LockableCurrency.

    • Weigher — Measures weight consumed by XCM local execution. Type must implement the trait WeightBounds.

    • XcmExecutor — Means of executing XCM. Type must implement the trait ExecuteXcm.

    • XcmRouter —  The type used to dispatch an XCM to its destination. Type must implement the trait SendXcm.

  • Pallet-specific filters:

    • XcmExecuteFilter — XCM filter for which messages to be executed using XcmExecutor must pass. Type must implement trait Contains<(MultiLocation, Xcm<<Self as Config>::RuntimeCall>)>.

    • XcmReserveTransferFilter — XCM filter for which messages to be reserve-transferred using the dedicated extrinsic must pass.Type must implement the trait Contains<(MultiLocation, Vec<MultiAsset>)>.

    • XcmTeleportFilter — XCM filter for which messages to be teleported using the dedicated extrinsic must pass. Type must implement the trait Contains<(MultiLocation, Vec<MultiAsset>)>.

    • TrustedLockers — Returns whether or not the origin can be trusted for a specific asset. Type must implement ContainsPair where each pair is an asset and an origin thereby entrusting origin for operations relating to asset.

  • Pallet-specific converters:

    • CurrencyMatcher — The MultiAsset matcher for Currency. Type must implement the trait MatchesFungible.

    • SovereignAccountOf — How to get an AccountId value from a MultiLocation, useful for handling asset locks. Type must implement ConvertLocation.

  • Pallet-specific constants:

    • VERSION_DISCOVERY_QUEUE_SIZE — u32 measures the size of the version discovery queue. Typically set to 100.

    • AdvertisedXcmVersion — The latest supported XCM version that this chain accepts. Type must implement the trait Get<XcmVersion>. Commonly set to pallet_xcm::CurrentXcmVersion.

    • MaxLockers —  The maximum number of local XCM locks that a single account may have. Type must implement the trait Get<u32>.

    • MaxRemoteLockConsumers — The maximum number of consumers a single remote lock may have. Type must implement the trait Get<u32>.

    • UniversalLocation — This chain’s Universal Location. Type must implement the trait Get<InteriorMultiLocation>.

  • Common configs:

    • RuntimeEvent

    • RuntimeCall

    • RuntimeOrigin

    • WeightInfo

Dispatchables

send

pub fn send(
    origin: OriginFor<T>,
    dest: Box<VersionedMultiLocation>,
    message: Box<VersionedXcm<()>>,
)
DEPRECATED. send will be removed after June 2024. Use send_blob instead.
  • Deprecation explanation:

    • pallet-xcm has a new pair of extrinsics, execute_blob and send_blob. These are meant to be used instead of execute and send, which are now deprecated and will be removed eventually. These new extrinsics just require you to input the encoded XCM.

    • There’s a new utility in PolkadotJS Apps for encoding XCMs you can use: https://polkadot.js.org/apps/#/utilities/xcm Just pass in the encoded XCM to the new extrinsics and you’re done.

    • The migration from the old extrinsic to the new is very simple. If you have your message xcm: VersionedXcm<Call>, then instead of passing in Box::new(xcm) to both execute and send, you would pass in xcm.encode().try_into() and handle the potential error of its encoded length being bigger than MAX_XCM_ENCODED_SIZE.

    • pallet-contracts takes the XCM encoded now as well. It follows the same API as execute_blob and send_blob.

Send a versioned XCM message to the destination dest.

The origin must be SendXcmOrigin for this call.

Params:

  • dest: Box<VersionedMultiLocation> — destination for the XCM

  • message: Box<VersionedXcm<()>> — versioned XCM to be sent to the multilocation dest

Errors:

  • InvalidOrigin — origin did not match SendXcmOrigin

  • BadVersion — version for XCM not valid

Events:

  • Sent(origin, destination, message, message_id) — The versioned XCM message was sent from the origin to the destination.

execute

pub fn execute(
    origin: OriginFor<T>,
    message: Box<VersionedXcm<<T as Config>::RuntimeCall>>,
    max_weight: Weight,
)
DEPRECATED. execute will be removed after June 2024. Use execute_blob instead.
  • Deprecation explanation:

    • pallet-xcm has a new pair of extrinsics, execute_blob and send_blob. These are meant to be used instead of execute and send, which are now deprecated and will be removed eventually. These new extrinsics just require you to input the encoded XCM.

    • There’s a new utility in PolkadotJS Apps for encoding XCMs you can use: https://polkadot.js.org/apps/#/utilities/xcm Just pass in the encoded XCM to the new extrinsics and you’re done.

    • The migration from the old extrinsic to the new is very simple. If you have your message xcm: VersionedXcm<Call>, then instead of passing in Box::new(xcm) to both execute and send, you would pass in xcm.encode().try_into() and handle the potential error of its encoded length being bigger than MAX_XCM_ENCODED_SIZE.

    • pallet-contracts takes the XCM encoded now as well. It follows the same API as execute_blob and send_blob.

Execute an XCM message from a local, signed, origin.

The origin must be ExecuteXcmOrigin for this call.

A successful return to this does NOT imply that the msg was executed successfully to completion; only that SOME of it was executed.

Params:

  • message: Box<VersionedXcm<T as Config::RuntimeCall>> — versioned XCM to be executed

  • max_weight: Weight — No more than this amount of Weight will be consumed during this execution attempt.

Errors:

  • BadOrigin —- origin did not match ExecuteXcmOrigin

  • BadVersion —- version for XCM not valid

Events:

  • Attempted(outcome) — Indicates whether the msg was executed completely or only partially.

force_xcm_version

pub fn force_xcm_version(
    origin: OriginFor<T>,
    location: Box<MultiLocation>,
    version: XcmVersion,
)

Set that a particular destination can be communicated with through a particular version of XCM.

The origin must be AdminOrigin for this call.

Params:

  • location: Box<MultiLocation> —- The destination that is being described.

  • version: XcmVersion — The latest version of XCM that location supports.

Errors:

  • BadOrigin — origin did not match AdminOrigin

Events:

  • Event::SupportedVersionChanged { location, version } — location was updated to support the latest version of XCM version

force_default_xcm_version

pub fn force_default_xcm_version(
    origin: OriginFor<T>,
	maybe_xcm_version: Option<XcmVersion>,
)

Set a safe XCM version (the version that XCM should be encoded with if the most recent version a destination can accept is unknown).

The origin must be AdminOrigin for this call.

Params:

  • maybe_xcm_version: Option<XcmVersion> —- The default XCM encoding version, or None to disable.

Errors:

  • BadOrigin — origin did not match AdminOrigin

Events:

None

force_subscribe_version_notify

pub fn force_subscribe_version_notify(
    origin: OriginFor<T>,
	location: Box<VersionedMultiLocation>,
)

Ask a location to notify us regarding their XCM version and any changes to it.

The origin must be AdminOrigin for this call.

Params:

  • location: Box<VersionedMultiLocation>: The location to which we should subscribe for XCM version notifications.

Errors:

  • BadOrigin — origin did not match AdminOrigin

Events:

None

force_unsubscribe_version_notify

pub fn force_unsubscribe_version_notify(
    origin: OriginFor<T>,
	location: Box<VersionedMultiLocation>,
)

Require that a particular destination should no longer notify us regarding any XCM version changes.

The origin must be AdminOrigin for this call.

Params:

  • location: Box<VersionedMultiLocation>: The location from which we are but no longer wish to subscribe to XCM version notifications.

Errors:

  • BadOrigin —- origin did not match AdminOrigin

  • NoSubscription — subscription not found to location

  • BadLocation — location not found

Events:

None

limited_reserve_transfer_assets

pub fn limited_reserve_transfer_assets(
    origin: OriginFor<T>,
    dest: Box<VersionedMultiLocation>,
    beneficiary: Box<VersionedMultiLocation>,
    assets: Box<VersionedMultiAssets>,
    fee_asset_item: u32,
    weight_limit: WeightLimit,
)

Transfer some assets from the local chain to the sovereign account of a destination chain and forward a notification XCM.

The origin must be ExecuteXcmOrigin for this call.

Params:

  • dest: Box<VersionedMultiLocation> — Destination context for the assets. Will typically be X2(Parent, Parachain(..)) to send from parachain to parachain, or X1(Parachain(..)) to send from relay to parachain.

  • beneficiary: Box<VersionedMultiLocation> — A beneficiary location for the assets in the context of dest. Willgenerally be an AccountId32 value.

  • assets: Box<VersionedMultiAssets> — The assets to be withdrawn. This should include the assets used to pay the fee on the dest side.

  • fee_asset_item: u32 — The index into assets of the item which should be used to pay fees.

  • weight_limit: WeightLimit — The remote-side weight limit, if any, for the XCM fee purchase.

Errors:

  • BadOrigin —- origin did not match ExecuteXcm

  • BadVersion — beneficiary or assets have incorrect versioning

  • TooManyAssets — assets length exceeds MAX_ASSETS_FOR_TRANSFER which equals 2 in this code

Events:

  • Event::Attempted { outcome } — Attempted the reserve transfer with returned status outcome

limited_teleport_assets

pub fn limited_teleport_assets(
    origin: OriginFor<T>,
    dest: Box<VersionedMultiLocation>,
    beneficiary: Box<VersionedMultiLocation>,
    assets: Box<VersionedMultiAssets>,
    fee_asset_item: u32,
    weight_limit: WeightLimit,
)

Teleport some assets from the local chain to some destination chain.

Fee payment on the destination side is made from the asset in the assets vector of index fee_asset_item, up to enough to pay for weight_limit of weight. If more weight is needed than weight_limit, then the operation will fail and the assets send may be at risk.

The origin must be ExecuteXcmOrigin for this call.

Params:

  • dest: Box<VersionedMultiLocation> — Destination context for the assets. Will typically be X2(Parent, Parachain(..)) to teleport from parachain to parachain, or X1(Parachain(..)) to teleport from relay to parachain.

  • beneficiary: Box<VersionedMultiLocation> — A beneficiary location for the assets in the context of dest. Will generally be an AccountId32 value.

  • assets: Box<VersionedMultiAssets> — The assets to be withdrawn. This should include the assets used to pay the fee on the dest side.

  • fee_asset_item: u32 — The index into assets of the item which should be used to pay fees.

  • weight_limit: WeightLimit — The remote-side weight limit, if any, for the XCM fee purchase.

Errors:

  • BadOrigin —- origin did not match ExecuteXcm

  • BadVersion — beneficiary or assets have incorrect versioning

  • TooManyAssets — assets length exceeds MAX_ASSETS_FOR_TRANSFER which equals 2 in this code

Events:

  • Event::Attempted { outcome } — Attempted the teleport status with returned status outcome

force_suspension

pub fn force_suspension(
    origin: OriginFor<T>,
    suspended: bool,
)

Set or unset the global suspension state of the XCM executor.

The origin must be AdminOrigin for this call.

Params:

  • suspended: bool — true to suspend, false to resume.

Errors:

None

Events:

None

transfer_assets

pub fn transfer_assets(
	origin: OriginFor<T>,
	dest: Box<VersionedLocation>,
	beneficiary: Box<VersionedLocation>,
	assets: Box<VersionedAssets>,
	fee_asset_item: u32,
	weight_limit: WeightLimit,
)

Transfer some assets from the local chain to the destination chain through their local, destination or remote reserve, or through teleports.

Params:

  • dest: Box<VersionedLocation> — Destination context for the assets. Will typically be X2(Parent, Parachain(..)) to send from parachain to parachain, or X1(Parachain(..)) to send from relay to parachain.

  • beneficiary: Box<VersionedLocation> — A beneficiary location for the assets in the context of dest. Will generally be an AccountId32 value.

  • assets: The assets to be withdrawn. This should include the assets used to pay the fee on the dest (and possibly reserve) chains.

  • fee_asset_item: u32 — The index into assets of the item which should be used to pay fees.

  • weight_limit: WeightLimit — The remote-side weight limit, if any, for the XCM fee purchase.

Errors:

  • BadOrigin —- origin did not match ExecuteXcmOrigin.

  • BadVersion — v2/v3 conversion to v4 failed for assets, dest, or beneficiary.

  • TooManyAssets — assets contain more than MAX_ASSETS_FOR_TRANSFER = 2 to transfer.

  • Empty — can be a number of different errors:

    • fee_asset_item is not present in assets.

    • some fungible asset in assets has a value of 0.

    • fees or asset transfer type was not determined.

  • TooManyReserves — there are more than one transfer type for an asset.

  • InvalidAssetUnknownReserve — transfer type can not be determined for a given asset.

  • InvalidAssetUnsupportedReserve — asset or fees transfer type is remote reserve and asset and fees asset are different.

  • Filtered — can be a number of different errors:

    • XcmReserveTransferFilter filtered the asset.

    • XcmTeleportFilter filtered the asset

  • CannotReanchor — asset can’t be reanchored.

  • CannotCheckOutTeleport — asset can’t be teleported

  • UnweighableMessage — prepared XCM message had issues with weighing (i.e. more instructions than the limit).

  • LocalExecutionIncomplete — local execution of XCM message have failed.

  • FeesNotMet — unable to charge fees. See the error log of any node to see the details.

Events:

  • Sent(origin, destination, message, message_id)

Deprecated Extrinsics: - teleport_assets — Use limited_teleport_assets instead. - reserve_transfer_assets — Use limited_reserve_transfer_assets instead.

claim_assets

pub fn claim_assets(
    origin: OriginFor<T>,
    assets: Box<VersionedAssets>,
    beneficiary: Box<VersionedLocation>,
) -> DispatchResult

Params:

  • origin: OriginFor<T> — Must be signed.

  • assets: Box<VersionedAssets> — The exact assets that were trapped. Use the version to specify what version was the latest when they were trapped.

  • beneficiary: Box<VersionedLocation> — A beneficiary location for the assets in the context of dest. Will generally be an AccountId32 value.

Errors:

  • BadOrigin —- origin did not match ExecuteXcmOrigin.

  • BadVersion — v2/v3 conversion to v4 failed for assets, dest, or beneficiary.

  • UnweighableMessage — prepared XCM message had issues with weighing (i.e. more instructions than the limit).

  • LocalExecutionIncomplete — local execution of XCM message have failed.

Events:

None

execute_blob

pub fn execute_blob(
    origin: OriginFor<T>,
    encoded_message: BoundedVec<u8, MaxXcmEncodedSize>,
    max_weight: Weight,
) -> DispatchResultWithPostInfo

Execute an XCM from a local, signed, origin.

Params:

  • origin: OriginFor<T> — Must be signed.

  • encoded_message: BoundedVec<u8, MaxXcmEncodedSize> — The message is passed in encoded. It needs to be decodable as a [VersionedXcm].

  • max_weight: Weight — No more than max_weight will be used in its attempted execution. If this is less than the maximum amount of weight that the message could take to be executed, then no execution attempt will be made.

Errors:

  • BadOrigin —- origin did not match ExecuteXcmOrigin.

  • BadVersion — v2/v3 conversion to v4 failed for assets, dest, or beneficiary.

  • Filtered — can be a number of different errors:

  • LocalExecutionIncomplete — local execution of XCM message have failed.

  • UnableToDecode — unable to decode the XCM.

  • XcmTooLarge — XCM encoded length is larger than MaxXcmEncodedSize.

Events:

  • Attempted(outcome) — Indicates whether the msg was executed completely or only partially.

send_blob

pub fn send_blob(
    origin: OriginFor<T>,
    dest: Box<VersionedLocation>,
    encoded_message: BoundedVec<u8, MaxXcmEncodedSize>,
) -> DispatchResult

Send an XCM from a local, signed, origin.

Params:

  • origin: OriginFor<T> — Must be signed.

  • dest: Box<VersionedLocation> — The destination, dest, will receive this message with a DescendOrigin instruction that makes the origin of the message be the origin on this system.

  • encoded_message: BoundedVec<u8, MaxXcmEncodedSize> — The message is passed in encoded. It needs to be decodable as a [VersionedXcm].

Errors:

  • InvalidOrigin — origin did not match SendXcmOrigin

  • BadVersion — v2/v3 conversion to v4 failed for assets, dest, or beneficiary.

  • UnableToDecode — unable to decode the XCM.

  • FeesNotMet — unable to charge fees. See the error log of any node to see the details.

  • Unreachable — The desired destination was unreachable, generally because there is a no way of routing to it.

  • SendFailure — There was some other issue (i.e. not to do with routing) in sending the message. Perhaps a lack of space for buffering the message.

Events:

  • Sent(origin, destination, message, message_id) — The versioned XCM message was sent from the origin to the destination.