diff --git a/README.md b/README.md index 5be902c..f70d4b9 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ -# Polkadot Cross-Consensus Message (XCM) Format +# Cross-Consensus Message (XCM) Format **Version 3, in-progress.** **Authors: Gavin Wood.** -This document details the message format for Polkadot-based message passing between chains. It describes the formal data format, any environmental data which may be additionally required and the corresponding meaning of the datagrams. +This document details the message format for message passing between differing chains and consensus systems. It describes the formal data format, any environmental data which may be required and the corresponding meaning of the datagrams. ## **1** Background @@ -22,6 +22,8 @@ Polkadot has three main transport systems for passing messages between chains al - **UMP** *Upward Message Passing* message passing from a parachain to the Relay-chain. - **DMP** *Downward Message Passing* message passing from the Relay-chain to a parachain. +While XCM was created with an acute need from within the Polkadot ecosystem, it is never the less designed to be of utility beyond wht might be termed the purely Polkadot ecosystem and rather more broadly in the general consensus, crypto and blockchain industry. + ### **1.1** XCM Communication Model XCM is designed around four 'A's: @@ -104,6 +106,7 @@ The registers are named: - *Holding* - *Surplus Weight* - *Refunded Weight* +- *Transact Status* ### **3.1** Programme @@ -159,6 +162,12 @@ Of type `u64`, initialized to `0`. Expresses the portion of Surplus Weight which has been refunded. Not used on XCM platforms which do not require payment for execution. +### **3.10** Transact Status + +Of type `Option>`, initialized to `None`. + +Expresses the outcome of the most recent dispatch made by the `Transact` operation. + ## **4** Basic XCVM Operation The XCVM operates as a fetch-dispatch loop common in state machines. The steps of the loop are: @@ -218,6 +227,8 @@ The instructions, in order, are: - `Trap` - `SubscribeVersion` - `UnsubscribeVersion` +- `QueryPallet` +- `Dispatch` ### Notes on terminology @@ -235,9 +246,9 @@ Operands: - `assets: MultiAssets`: The asset(s) to be removed; must be owned by Origin. -Kind: *Instruction*. +Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `ReserveAssetDeposited` @@ -251,7 +262,7 @@ Kind: *Trusted Indication*. Trust: Origin must be trusted to act as a reserve for `assets`. -Errors: *Fallible*. +Errors: *Fallible* ### `ReceiveTeleportedAsset` @@ -265,7 +276,7 @@ Kind: *Trusted Indication*. Trust: Origin must be trusted to have removed the `assets` as a consequence of sending this message. -Errors: *Fallible*. +Errors: *Fallible* ### `QueryResponse` @@ -279,7 +290,7 @@ Operands: Kind: *Information*. -Errors: *Fallible*. +Errors: *Fallible* Weight: Weight estimation may utilise `max_weight` which may lead to an increase in Surplus Weight Register at run-time. @@ -291,6 +302,8 @@ The `Response` type is used to express information content in the `QueryResponse - `Assets { assets: MultiAssets } = 1`: Some assets. - `ExecutionResult { result: Result<(), (u32, Error)> } = 2`: An error (or not), equivalent to the type of value contained in the Error Register. - `Version { version: Compact } = 3`: An XCM version. +- `PalletsInfo { info: Vec } = 4`: The information relating to a number of pallets. +- `DispatchResult { maybe_error: Option } = 5`: The error of a dispatch attempt, or `None` if the dispatch executed without error. ### `TransferAsset` @@ -301,9 +314,9 @@ Operands: - `assets: MultiAssetFilter`: The asset(s) to be withdrawn. - `beneficiary`: The new owner for the assets. -Kind: *Instruction*. +Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `TransferReserveAsset` @@ -317,9 +330,9 @@ Operands: - `destination: MultiLocation`: The location whose sovereign account will own the assets and thus the effective beneficiary for the assets and the notification target for the reserve asset deposit message. - `xcm: Xcm`: The instructions that should follow the `ReserveAssetDeposited` instruction, which is sent onwards to `destination`. -Kind: *Instruction*. +Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `Transact` @@ -328,15 +341,16 @@ by the kind of origin `origin_type`. Operands: -- `origin_type: OriginKind`: The means of expressing the message origin as a dispatch origin. -- `max_weight: Weight`: The maximum amount of weight to expend while dispatching `call`. If dispatch requires more weight then an error will be thrown. If dispatch requires less weight, then Surplus Weight Register may increase. +- `origin_kind: OriginKind`: The means of expressing the message origin as a dispatch origin. +- `require_weight_at_most: Weight`: The maximum amount of weight to expend while dispatching `call`. If dispatch requires more weight then an error will be thrown. If dispatch requires less weight, then Surplus Weight Register may increase. - `call: Vec`: The encoded transaction to be applied. +- `query_id: Option`: If present, then a `QueryResponse` constructed according to the provided `QueryResponseInfo` should be sent with a `DispatchResult` response corresponding to the error status of the "inner" dispatch. This only happens if the dispatch was actually made - if an error happened prior to dispatch, then the Error Register is set and the operation aborted as usual. -Kind: *Instruction*. +Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* -Weight: Weight estimation may utilise `max_weight` which may lead to an increase in Surplus Weight Register at run-time. +Weight: Weight estimation may utilise `require_weight_at_most` which may lead to an increase in Surplus Weight Register at run-time. ### `HrmpNewChannelOpenRequest` @@ -365,7 +379,7 @@ Safety: The message should originate directly from the Relay-chain. Kind: *System Notification* -Errors: *Fallible*. +Errors: *Fallible* ### `HrmpChannelClosing` @@ -381,7 +395,7 @@ Safety: The message should originate directly from the Relay-chain. Kind: *System Notification* -Errors: *Fallible*. +Errors: *Fallible* ### `ClearOrigin` @@ -389,9 +403,9 @@ Clear the Origin Register. This may be used by the XCM author to ensure that later instructions cannot command the authority of the Original Origin (e.g. if they are being relayed from an untrusted source, as often the case with `ReserveAssetDeposited`). -Kind: *Instruction*. +Kind: *Instruction* -Errors: *Infallible*. +Errors: *Infallible* ### `DescendOrigin` @@ -403,7 +417,7 @@ Operands: Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `ReportError` @@ -420,7 +434,7 @@ Operands: Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `DepositAsset` @@ -429,12 +443,11 @@ Subtract the asset(s) (`assets`) from Holding and deposit on-chain equivalent as Operands: - `assets: MultiAssetFilter`: The asset(s) to remove from the Holding Register. -- `max_assets: Compact`: The maximum number of unique assets/asset instances to remove from the Holding Register. Only the first `max_assets` assets/instances of those matched by `assets` will be removed, prioritized under standard asset ordering. Any others will remain in holding. - `beneficiary: MultiLocation`: The new owner for the assets. Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `DepositReserveAsset` @@ -445,13 +458,12 @@ Send an onward XCM message to `destination` of `ReserveAssetDeposited` with the Operands: - `assets: MultiAssetFilter`: The asset(s) to remove from the Holding Register. -- `max_assets: Compact`: The maximum number of unique assets/asset instances to remove from the Holding Register. Only the first `max_assets` assets/instances of those matched by `assets` will be removed, prioritized under standard asset ordering. Any others will remain in holding. - `destination: MultiLocation`: The location whose sovereign account will own the assets and thus the effective beneficiary for the assets and the notification target for the reserve asset deposit message. - `xcm: Xcm`: The orders that should follow the `ReserveAssetDeposited` instruction which is sent onwards to `destination`. Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `ExchangeAsset` @@ -464,7 +476,7 @@ Operands: Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `InitiateReserveWithdraw` @@ -478,7 +490,7 @@ Operands: Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `InitiateTeleport` @@ -494,7 +506,7 @@ Operands: Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `ReportHolding` @@ -509,7 +521,7 @@ Operands: Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `BuyExecution` @@ -522,7 +534,7 @@ Operands: Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `RefundSurplus` @@ -530,7 +542,7 @@ Increase Refunded Weight Register to the value of Surplus Weight Register. Attem Kind: *Instruction* -Errors: *Infallible*. +Errors: *Fallible* ### `SetErrorHandler` @@ -542,7 +554,7 @@ Operands: Kind: *Instruction* -Errors: *Infallible*. +Errors: *Infallible* Weight: The estimated weight of this instruction must include the estimated weight of `error_handler`. At run-time, Surplus Weight Register should be increased by the estimated weight of the Error Handler prior to being changed. @@ -556,7 +568,7 @@ Operands: Kind: *Instruction* -Errors: *Infallible*. +Errors: *Infallible* Weight: The estimated weight of this instruction must include the estimated weight of `appendix`. At run-time, Surplus Weight Register should be increased by the estimated weight of the Appendix prior to being changed. @@ -566,7 +578,7 @@ Clear the Error Register. Kind: *Instruction* -Errors: *Infallible*. +Errors: *Infallible* ### `ClaimAsset` @@ -579,7 +591,7 @@ Operands: Kind: *Instruction* -Errors: *Fallible*. +Errors: *Fallible* ### `Trap` @@ -591,7 +603,7 @@ Operands: Kind: *Instruction* -Errors: *Always*. +Errors: *Always* ### `SubscribeVersion` @@ -606,12 +618,16 @@ Operands: Kind: *Instruction* +Errors: *Fallible* + ### `UnsubscribeVersion` Cancel the effect of a previous `SubscribeVersion` instruction from Origin. Kind: *Instruction* +Errors: *Fallible* + ### `BurnAsset(MultiAssets)` Reduce Holding by up to the given assets. @@ -668,6 +684,96 @@ Errors: - `ExpectationFalse`: If the value of the Error Register is not equal to the parameter. +### `QueryPallet` + +Query the existence of a particular pallet type. + +- `name: Vec`: The name of the pallet to query. +- `query_id: QueryId`: The value to make the returned message identifiable with this query. +- `max_response_weight: Weight`: The value to be used for the `max_weight` field of the `QueryResponse` message. + +Sends a `QueryResponse` to Origin whose data field `PalletsInfo` containing the information of all pallets on the local chain whose name is equal to `name`. This is empty in the case that the local chain is not based on Substrate Frame. + +Safety: No concerns. + +Kind: *Instruction* + +Errors: *Fallible* + +### `ExpectPallet` + +Ensure that a particular pallet with a particular version exists. + +- `index: Compact`: The index which identifies the pallet. An error if no pallet exists at this index. +- `name: Vec`: Name which must be equal to the name of the pallet. +- `module_name: Vec`: Module name which must be equal to the name of the module in which the pallet exists. +- `crate_major: Compact`: Version number which must be equal to the major version of the crate which implements the pallet. +- `min_crate_minor: Compact`: Version number which must be at most the minor version of the crate which implements the pallet. + +Safety: No concerns. + +Kind: *Instruction* + +Errors: + +- `ExpectationFalse`: In case any of the expectations are broken. + +### `ReportTransactStatus` + +Send a `QueryResponse` message containing the value of the Transact Status Register to some +destination. + +- `query_response_info: QueryResponseInfo`: The information needed for constructing and sending the + `QueryResponse` message. + +Safety: No concerns. + +Kind: *Instruction* + +Errors: *Fallible* + +### `ClearTransactStatus` + +Set the Transact Status Register to its default, cleared, value. + +Safety: No concerns. + +Kind: *Instruction* + +Errors: *Infallible* + +### Auxiliary Data-types + +#### `PalletInfo` + +Information regarding an instance of a pallet within a chain. Encoded as the tuple of fields: + +- `index: Compact`: The index of the pallet instance. +- `name: Vec`: The name given to the pallet instance. +- `module_name: Vec`: The module name in which the pallet exists. If it exists at the top-level of a crate then this will be the crate's name. +- `crate_major: Compact`: The major version of the crate which implements the pallet. +- `crate_minor: Compact`: The minor version of the crate which implements the pallet. +- `crate_patch: Compact`: The patch version of the crate which implements the pallet. + +#### `OriginKind` + +An identifier for a type of calling origin. + +Encoded as the tagged union of: + +- `Native = 0`: Origin should be the native dispatch origin representation for the sender in the local runtime framework. For Cumulus/Frame chains this is the `Parachain` or `Relay` origin if coming from a chain, though there may be others if the `MultiLocation` XCM origin has a primary/native dispatch origin form. +- `SovereignAccount = 1`: Origin should be the standard account-based origin with the sovereign account of the sender. For Cumulus/Frame chains, this is the `Signed` origin. +- `Superuser = 2`: Origin should be the super-user. For Cumulus/Frame chains, this is the `Root` origin. This will not usually be an available option. +- `Xcm = 3`: Origin should be interpreted as an XCM native origin and the `MultiLocation` should be encoded directly in the dispatch origin unchanged. For Cumulus/Frame chains, this will be the `pallet_xcm::Origin::Xcm` type. + +#### `QueryResponseInfo` + +Information needed to determine how a `QueryResponse` message should be constructed and sent. Encoded as the tuple of fields: + +- `destination: MultiLocation`: The destination to which the query response message should be send. +- `query_id: QueryId`: The `query_id` field of the `QueryResponse` message. +- `max_weight: Weight`: The `max_weight` field of the `QueryResponse` message. + ## **6** Universal Asset Identifiers *Note on versioning:* This describes the `MultiAsset` (and associates) as used in XCM version of this document, and its version is strictly implied by the XCM it is used within. If it is necessary to form a `MultiAsset` value is used _outside_ of an XCM (where its version cannot be inferred) then the version-aware `VersionedMultiAsset` should be used instead, exactly analogous to how `Xcm` relates to `VersionedXcm`. @@ -732,6 +838,8 @@ A `WildMultiAsset` value is represented by the SCALE-encoded tagged union with t - `All = 0`: Matches for all assets. - `AllOf = 1 { class: AssetId, fun: WildFungibility }`: Matches for any assets which match the given `class` and fungibility (`fun`). +- `AllCounted = 2 { count: Compact }`: Matches for the first `count` assets, when placed under standard asset ordering. +- `AllOfCounted = 3 { class: AssetId, fun: WildFungibility, count: Compact }`: Matches for the first `count` (under standard asset ordering) of any assets which match the given `class` and fungibility (`fun`). A `MultiAssetFilter` value is represented by the SCALE-encoded tagged union with two variants: @@ -867,3 +975,4 @@ Within XCM it is necessary to communicate some problem encountered while executi - `TooExpensive = 20`: Used by `BuyExecution` when the fees declared to purchase weight are insufficient. - `Trap(u64) = 21`: Used by the `Trap` instruction to force an error intentionally. Its code is included. - `ExpectationFalse = 22`: Used by `ExpectAsset`, `ExpectError` and `ExpectOrigin` when the expectation was not true. +- `IncorrectVersion = 23`: Used by the `Dispatch` instruction when pallet of the correct version is not found.