diff --git a/syllabus/6-Polkadot-SDK/XCM/1-Core_Concepts_of_XCM/Core_Concepts_of_XCM-slides.md b/syllabus/6-Polkadot-SDK/XCM/1-Core_Concepts_of_XCM/Core_Concepts_of_XCM-slides.md index 50542679b..66559fae2 100644 --- a/syllabus/6-Polkadot-SDK/XCM/1-Core_Concepts_of_XCM/Core_Concepts_of_XCM-slides.md +++ b/syllabus/6-Polkadot-SDK/XCM/1-Core_Concepts_of_XCM/Core_Concepts_of_XCM-slides.md @@ -6,774 +6,8 @@ duration: 1 hour # Introduction to Cross-Consensus Messaging (XCM) -## _Core Concepts, Terms, and Logic_ - -Notes: - -**Pre-requisites** - -- FRAME (Storage Items, Dispatchables, Event, Errors, etc.) -- Polkadot & parachains conceptually -- Assets (NFTs and fungibles) - ----v - -## _At the end of this lecture, you will be able to:_ - - - -- Define the concepts, syntax, and terms of XCM -- Navigate existing resources that relate to XCM -- Differentiate between XCM and message-passing protocols like XCMP - ---- - -# Cross-chain use cases - -Why would we want to perform operations on different blockchains? - -Notes: - -EXERCISE: ask the class to raise hands and postulate on generally what one might do. -We are expecting them to say transfers, but there are so many other things you could do, so many more problems worth solving with cross-chain: - -- One contract calling another contract -- Credential checking -- Voting - ----v - -## ๐ŸŽฌ Some Concrete Use-cases - - - -- Cross-consensus asset transfers -- Execute platform-specific actions such as governance voting -- Enables single use-case chains - - [Collectives](https://github.com/paritytech/cumulus/tree/master/parachains/runtimes/collectives) - - Identity chains - -Notes: - -While the goal of XCM is to be general, flexible and future-proof, there are of course practical needs which it must address, not least the transfer of tokens between chains. -We need a way to reason about, and pay for, any required fees on the receiving CS. -Platform-specific action; for example, within a Substrate chain, it can be desirable to dispatch a remote call into one of its pallets to access a niche feature. -XCM enables a single chain to direct the actions of many other chains, which hides the complexity of multi-chain messaging behind an understandable and declarative API. - ---- - -> XCM is a **language** for communicating **intentions** between **consensus systems**. - ----v - -### Consensus systems - -A chain, contract or other global, encapsulated, state machine singleton. - - - -It does not even have to be a _distributed_ system, only that it can form _some_ kind of consensus. - -Notes: - -A consensus system does not necessarily have to be a blockchain or a smart contract. -It can be something that already exists in the Web 2.0 world, such as an EC2 instance in an AWS server. -XCM is Cross-Consensus since it's much more than cross chain. - ----v - -### โœ‰๏ธ A Format, not a Protocol - -XCM is a **_messaging format_**. - -It is akin to the post card from the post office. - -It is _not_ a messaging protocol! - -A post card doesn't send itself! - -Notes: - -It cannot be used to actually "send" any message between systems; its utility is only in expressing what should be done by the receiver. -Like many aspects core to Substrate, this separation of concerns empowers us to be far more generic and enable much more. -A post card relies on the postal service to get itself sent towards its receivers, and that is what a messaging protocol does. - -The transport layer concerns itself with sending arbitrary blobs, it doesn't care about the format. -A common format has its benefits though, as we'll see next. - ----v - -### Versioning - -XCM is a **versioned** language. - -It's currently in version 4. - -What goes in each version is defined via an RFC process. - ----v - -### Terminology: XCMs - -**XCM**, Cross-Consensus Messaging, is the format. - -**An XCM** is a Cross-Consensus Message. - -It's not called an XCM message, - -the same way it's not called an ATM machine. - -We can also call them XCM programs, since they are executable. - ---- - -## ๐Ÿ˜ฌ Why not _native_ messages? - -Drawbacks of relying on native messaging or transaction format: - - - -- Native message format changes from system to system, it also could change within the _same_ system, e.g. when upgrading it -- Common cross-consensus use-cases do not map one-to-one to a single transaction -- Different consensus systems have different assumptions e.g. fee payment - -Notes: - -- A system which intends to send messages to more than one destination would need to understand how to author a message for each. - On that note, even a single destination may alter its native transaction/message format over time. - Smart contracts might get upgrades, blockchains might introduce new features or alter existing ones and in doing so change their transaction format. -- Special tricks may be required to withdraw funds, exchange them and then deposit the result all inside a single transaction. - Onward notifications of transfers, needed for a coherent reserve-asset framework, do not exist in chains unaware of others. - Some use-cases don't require accounts. -- Some systems assume that fee payment had already been negotiated, while some do not. - -TODO: Why not just send EVM programs. Why XCVM instead of EVM? -Add Shawn's picture. -It's up to the interpreter to interpret the intention how it makes sense. - ----v - -### Message format changes - - - ----v - -### Message format changes - - - ----v - -### Message format changes - - - -Notes: - -XCM abstracts away the actual on-chain operation that will be called, which lets the recipient redirect calls to always make them valid. - ----v - -### No one-to-one mapping - - -graph TD - subgraph Message - WithdrawAsset(WithdrawAsset)-->DepositAlice("DepositAsset(Alice)") - DepositAlice-->DepositBob("DepositAsset(Bob)") - end - - -Notes: - -You might want to withdraw some assets and deposit some amount to one account and another to another. -Using transactions, you'd have to send many messages to achieve this. - ----v - -### Different assumptions - - -graph LR - A(Chain A)--"Pays for fees"-->B(Chain B) - A--"Doesn't pay for fees"-->C(Chain C) - - -Notes: - -Different systems have different assumptions. -Using native messages, you'd have to tailor your messages to all systems you want to message. - ---- - -## Four 'A's - -XCM assumes the following things from the underlying environment. - - - -- **Agnostic** -- **Absolute** -- **Asynchronous** -- **Asymmetric** - -Notes: - -The 4 'A's are assumptions XCM makes over the transport protocol and overall the environment where these messages are sent and processed. -This doesn't mean that the transport protocol used has to have these guarantees, it simply means the language constructs are built around them. - ----v - -## Agnostic - -XCM makes no assumptions about the nature of the Consensus System between which messages are being passed. - -Notes: - -XCM is not restricted to Polkadot, it's a language that can be used for communication between any systems. -For example, EVM-chains or Cosmos hubs. - ----v - -## Absolute - -XCM assumes that the environment guarantees delivery, interpretation, and ordering of messages. - -Notes: - -The message format does not do much about the message possibly not being delivered. -In IBC, for example, you factor in fallibility of the transport protocol into your messages. - ----v - -## Asynchronous - -XCMs crossing the barrier between a single consensus system cannot generally be synchronous. - -XCM in no way assume that the sender will be blocking on messages. - -Notes: - -You can't just block execution in the middle of a block, it has to be asynchronous. -Different systems have different ways of tracking time. -No assumption of blocking for sender/receiver. - -Generally, consensus systems are not designed to operate in sync with external systems. -They intrinsically need to have a uniform state to reason about and do not, by default, have the means to verify states of other consensus systems. -Thus, each consensus system cannot make any guarantees on the expected time required to deliver results; doing so haphazardly would cause the recipient to be blocked waiting for responses that are either late or would never be delivered, and one of the possible reasons for that would be an impending runtime upgrade that caused a change in how responses are delivered. - ----v - -## Asymmetric - -XCM doesn't assume there'll be messages flowing in the other direction. - -If you want to send responses, you have to make it explicitly. - -Notes: - -There are no results or callbacks. -Any results must be separately communicated to the sender with an additional message. -The receiver side can and does handle errors, but the sender will not be notified, unless the error handler specifically tries to send back an XCM that makes some sort of XCM that notifies status back to the origin, but such an action should be considered as constructing a separate XCM for the sole purpose of reporting information, rather than an intrinsic functionality built into XCM. -XCM is a bit like REST. -XCMP is a bit like TCP/IP but not quite. -Analogies can often hurt more than they help. - ---- - -## ๐Ÿ“ Locations in XCM - - - -Before sending a message to another system, we need a way to address it. - - -graph LR - Message(Message) - Alice(Alice)--"?"-->Bob(Bob) - Alice--"?"-->AssetHub(Asset Hub) - Alice--"?"-->Pallet(Pallet) - Alice--"?"-->SmartContract(Smart Contract) - - -Notes: - -XCM defines a `Location` type that acts as a URL for consensus systems. - -The `Location` type identifies any single _location_ that exists within the world of consensus. -Representing a scalable multi-shard blockchain such as Polkadot, an ERC-20 asset account on a parachain, a smart contract on some chain, etc. -It is usually represented as a location _relative_ to the current consensus system. -Relative locations are easier to handle due to the fact that the network structure can change. - -Locations don't define the actual path to get there, just a way of addressing. - ----v - -## Interior locations - -> Given two consensus systems, A and B. A is **interior** to B if a state change in A implies a state change in B. - -Notes: - -An example, a smart contract in Ethereum would be interior to Ethereum itself. - ----v - -## Location hierarchy - - -graph TD; - Relay(Relay)-->A(Parachain A) - Relay-->B(Parachain B) - B-->Alice(Account A) - B-->Bob(Account B) - A-->Pallet(Pallet Contracts) - Pallet-->SCA(Smart Contract A) - Pallet-->SCB(Smart Contract B) - - -Notes: - -Locations form a hierarchy using the interior relation. - ----v - -## Location Representation - - - -```rust -struct Location { - parents: u8, - junctions: Junctions, -} -``` - -
- -```rust -enum Junction { - Parachain(u32), - AccountId32 { id: [u8; 32], network: Option }, - PalletInstance(u8), - GeneralIndex(u128), - GlobalConsensus(NetworkId), - ... -} -``` - -Notes: - -Right now Junctions are limited to 8 because of stack space. -We also don't expect Junctions being more than 8 levels deep. - -It's perfectly possible to create locations that don't point anywhere. - ----v - -### Network Id - - - -```rust -enum NetworkId { - ByGenesis([u8; 32]), - ByFork { block_number: u64, block_hash: [u8; 32] }, - Polkadot, - Kusama, - Westend, - Rococo, - Wococo, - Ethereum { chain_id: u64 }, - BitcoinCore, - BitcoinCash, -} -``` - - - - - -Notes: - -Junctions are ways to descend the location hierarchy - ----v - -## Text notation - - - - - - - -```rust -Location { - parents: 1, - interior: Parachain(50) -} -``` - - - - ---> - - - - -`../Parachain(50)` - - - -Notes: - -This notation comes from an analogy to a file system. - ----v - -## Universal Location - -> The Universal Location is a **theoretical** location. It's the parent of all locations which generate their own consensus. It itself has no parents. - ----v - -## Universal Location - - -graph TD; - UniversalLocation(Universal Location)-->Polkadot(Polkadot) - UniversalLocation-->Kusama(Kusama) - UniversalLocation-->Ethereum(Ethereum) - UniversalLocation-->Bitcoin(Bitcoin) - - -Notes: - -We can imagine a hypothetical location that contains all top-level consensus systems. - ----v - -## Absolute locations - - - -```rust -pub type InteriorLocation = Junctions; -``` - -Sometimes, absolute locations are necessary, e.g. for bridges. - -They don't have parents. - -The first junction has to be a `GlobalConsensus`. - -Notes: - -To write an absolute location, we need to know our location relative to the Universal Location. - ----v - -## What are `Location`s used for? - - - -- Addressing -- Origins -- Assets -- Fees -- Bridging - ----v - -## Cross-Chain Origins - -When a receiver gets an XCM, a `Location` specifies the sender. - -This `Location` is _relative_ to the receiver. - -Can be converted into a pallet origin in a FRAME runtime - -Used for determining privileges during XCM execution. - -Notes: - -Reanchoring: - -Since `Location`s are relative, when an XCM gets sent over to another chain, the origin location needs to be rewritten from the perspective of the receiver, before the XCM is sent to it. - ---- - -## Location Examples - ----v - -### Sibling parachain - -`../Parachain(1001)` - - -graph TD - Polkadot(Polkadot)-->AssetHub("๐Ÿ“ AssetHub (1000)") - Polkadot-->Collectives("Collectives (1001)") - - -Notes: - -What does the location resolve to if evaluated on Parachain(1000)? - ----v - -### Sibling parachain - -`../Parachain(1001)` - - -graph TD - Polkadot(Polkadot)-->AssetHub("๐Ÿ“ AssetHub (1000)") - Polkadot-->Collectives("Collectives (1001)") - AssetHub-->Polkadot - linkStyle 0 opacity:0.3 - linkStyle 2 stroke-dasharray:5 - - ----v - -### Parachain account - -`Parachain(1000)/AccountId32(0x1234...cdef)` - - -graph TD - Polkadot("๐Ÿ“ Polkadot")-->AssetHub("AssetHub (1000)") - Polkadot-->Collectives("Collectives (1001)") - AssetHub-->Account("AccountId32 (0x1234...cdef)") - - -Notes: - -What does the location resolve to if evaluated on the relay chain? - ----v - -### Parachain account - -`Parachain(1000)/AccountId32(0x1234...cdef)` - - -graph TD - Polkadot("๐Ÿ“ Polkadot")-->AssetHub("AssetHub (1000)") - Polkadot-->Collectives("Collectives (1001)"):::disabled - AssetHub-->Account("AccountId32 (0x1234...cdef)") - linkStyle 1 opacity:0.3 - classDef disabled opacity:0.3 - - ----v - -### Bridge - -`../../GlobalConsensus(Kusama)/Parachain(1000)` - - -graph TD - Universe(Universal Location)-->Polkadot(Polkadot) - Universe-->Kusama(Kusama) - Polkadot-->PolkaA("๐Ÿ“ Asset Hub (1000)") - Polkadot-->PolkaB(Bridge Hub) - PolkaA-->Alice(Alice) - PolkaA-->AssetsPallet(Pallet Assets) - AssetsPallet-->Asset(USDT) - Kusama-->KusamaA("Asset Hub (1000)") - Kusama-->KusamaB(Bridge Hub) - - -Notes: - -Speak to an example of non-parachain multi-location that would use a bridge -XCM reasons about addressing (as in a postal address) that must include understanding where you are, not just where you are going! -This will be very powerful later on (Origins) - ----v - -### Bridge - -`../../GlobalConsensus(Kusama)/Parachain(1000)` - - -graph TD - Universe(Universal Location)-->Polkadot(Polkadot) - Universe-->Kusama(Kusama) - Polkadot-->PolkaA("๐Ÿ“ Asset Hub (1000)") - Polkadot-->PolkaB(Bridge Hub):::disabled - PolkaA-->Alice(Alice):::disabled - PolkaA-->AssetsPallet(Pallet Assets):::disabled - AssetsPallet-->Asset(USDT):::disabled - Kusama-->KusamA("Asset Hub (1000)") - Kusama-->KusamB(Bridge Hub):::disabled - PolkaA-->Polkadot - Polkadot-->Universe - linkStyle 0 opacity:0.3 - linkStyle 2 opacity:0.3 - linkStyle 3 opacity:0.3 - linkStyle 4 opacity:0.3 - linkStyle 5 opacity:0.3 - linkStyle 6 opacity:0.3 - linkStyle 8 opacity:0.3 - linkStyle 9 stroke-dasharray:5 - linkStyle 10 stroke-dasharray:5 - classDef disabled opacity:0.3 - - -Notes: - -Even with Bridge Hubs, the relative location is what you'd expect. -Bridge Hubs are just a way for routing messages. -They are an implementation detail of the transport layer. - ----v - -### Bridge (actual routing) - - -graph TD - Universe(Universal Location):::disabled-->Polkadot(Polkadot):::disabled - Universe-->Kusama(Kusama) - Polkadot-->PolkaA("๐Ÿ“ Asset Hub (1000)") - Polkadot-->PolkaB(Bridge Hub) - PolkaA-->Alice(Alice):::disabled - PolkaA-->AssetsPallet(Pallet Assets):::disabled - AssetsPallet-->Asset(USDT):::disabled - Kusama-->KusamB(Bridge Hub) - Kusama-->KusamA("Asset Hub (1000)") - PolkaA-->PolkaB - PolkaB--"Bridge"-->KusamB - KusamB-->Kusama - linkStyle 0 opacity:0.3 - linkStyle 1 opacity:0.3 - linkStyle 2 opacity:0.3 - linkStyle 3 opacity:0.3 - linkStyle 4 opacity:0.3 - linkStyle 5 opacity:0.3 - linkStyle 6 opacity:0.3 - linkStyle 7 opacity:0.3 - linkStyle 11 stroke-dasharray:5 - classDef disabled opacity:0.3 - - -Notes: - -The actual message is routed through Bridge Hub. - ---- - -## Sovereign Accounts - -Locations external to the local system can be represented by a local account. - -We call this the **sovereign account** of that location. - -They are a mapping from a `Location` to an account id. - ----v - - -graph TD - Polkadot(Polkadot)-->A(A) & B(B) - A-->Alice(Alice) - B-->AliceSA("Alice's sovereign account") - - -Notes: - -A sovereign account is an account on one system that is controlled by another on a different system. -A single account on a system can have multiple sovereign accounts on many other systems. -In this example, Alice is an account on AssetHub, and it controls a sovereign account on Collectives. - -When transferring between consensus systems, the sovereign account is the one that gets the funds on the destination system. - ----v - - -graph TD - Polkadot(Polkadot)-->A(A) & B(B) - A-->Alice(Alice) - B-->AliceSA("Alice's sovereign account") - B-->ASA("Asset Hub's sovereign account") - A-->BSA("Collective's sovereign account") - - ---- - - - ## ๐Ÿ’ฐ Assets in XCM -Most messages will deal with assets in some way. - -How do we address these assets? - ----v - -### Asset Representation - -```rust -struct Asset { - pub id: AssetId, - pub fun: Fungibility, -} - -struct AssetId(Location); // <- We reuse the location! - -enum Fungibility { - Fungible(u128), - NonFungible(AssetInstance), -} -``` - -Notes: - -We use locations, which we've already discussed, to refer to assets. - -A Asset is composed of an asset ID and an enum representing the fungibility of the asset. -Asset IDs are the location that leads to the system that issues it, this can be just an index in an assets pallet, for example. - -Assets can also either be fungible or non-fungible: -Fungible - each token of this asset has the same value as any other -NonFungible - each token of this asset is unique and cannot be seen as having the same value as any other token under this asset - ----v - -### Asset filtering and wildcards - -```rust -enum AssetFilter { - Definite(Assets), - Wild(WildAsset), -} - -enum WildAsset { - All, - AllOf { id: AssetId, fun: WildFungibility }, - // Counted variants -} - -enum WildFungibility { - Fungible, - NonFungible, -} -``` - -Notes: - -Sometimes we don't want to specify an asset, but rather filter a collection of them. -In this case, we can either list all the assets we want or use a wildcard to select all of them. -In reality, it's better to use the counted variant of the wildcards, for benchmarking. - ---- - ## Summary diff --git a/syllabus/6-Polkadot-SDK/XCM/1-Presentation-slides.md b/syllabus/6-Polkadot-SDK/XCM/1-Presentation-slides.md new file mode 100644 index 000000000..d4560f523 --- /dev/null +++ b/syllabus/6-Polkadot-SDK/XCM/1-Presentation-slides.md @@ -0,0 +1,237 @@ +--- +title: Introduction to Cross-Consensus Messaging (XCM) +description: What it is, why it's necessary, what we'll cover +duration: 45 minutes +--- + +# XCM module + +--- + +## On this module, we'll see + +- What is XCM? +- What primitives make up XCMs +- How XCMs are executed +- The XCM Pallet +- How to configure systems to work with XCM +- How to simulate messages on a network + +--- + +# The problem + +Substrate and FRAME encourage an ecosystem of many blockchains. + +We don't want them to be general. + +E.g. assets, swaps, governance, staking, identity, multisigs, etc. + +---v + +## Specialization + +We want them to specialize. + +--- + +# The solution + +We can pass messages from one chain to another. + +What type of messages? + +---v + +## Native messages + +The messages could just be the native transactions of each chain. + +---v + +## Native messages downsides + +- Format changes from system to system, it could also change within the same system, e.g. on a runtime upgrade. +- Common cross-consensus use-cases don't map one-to-one to a single transaction. +- Different consensus systems have different assumptions e.g. fee payment. + +Notes: + +- A system which intends to send messages to more than one destination would need to understand how to author a message for each. + On that note, even a single destination may alter its native transaction/message format over time. + Smart contracts might get upgrades, blockchains might introduce new features or alter existing ones and in doing so change their transaction format. +- Special tricks may be required to withdraw funds, exchange them and then deposit the result all inside a single transaction. + Onward notifications of transfers, needed for a coherent reserve-asset framework, do not exist in chains unaware of others. + Some use-cases don't require accounts. +- Some systems assume that fee payment had already been negotiated, while some do not. + +---v + +### Message format changes + + + +---v + +### Message format changes + + + +---v + +### Message format changes + + + +Notes: + +XCM abstracts away the actual on-chain operation that will be called, which lets the recipient redirect calls to always make them valid. + +---v + +### No one-to-one mapping + + +graph TD + subgraph Message + WithdrawAsset(WithdrawAsset)-->DepositAlice("DepositAsset(Alice)") + DepositAlice-->DepositBob("DepositAsset(Bob)") + end + + +Notes: + +You might want to withdraw some assets and deposit some amount to one account and another to another. +Using transactions, you'd have to send many messages to achieve this. + +---v + + +### Different assumptions + + +graph LR + A(Chain A)--"Pays for fees"-->B(Chain B) + A--"Doesn't pay for fees"-->C(Chain C) + + +Notes: + +Different systems have different assumptions. +Using native messages, you'd have to tailor your messages to all systems you want to message. + +---v + +## A better solution + +A domain-specific language that is agnostic to the underlying chain implementing it. + +Able to express multiple actions in a single message. + +Flexible enough to accomodate multiple different paradigms. + +--- + +# XCM + +> XCM is a **language** for communicating **intentions** between **consensus systems**. + +---v + +## Language + +Cross-chain DSL. Each message is a script that allows expressing multiple actions. + +---v + +## Intentions + +Because blockchains are sovereign entities, the language only expresses what we _want_ +the receiver to do, it doesn't enforce it. + +Verification can be done on another layer, e.g. checking the expected result with a light client. + +Notes: + +It's up to the receiver to interpret the message and execute the corresponding actions. + +Not every chain might implement every intention, for example swaps. + +---v + +## Consensus systems + +We extend the actors to be consensus systems, not only chains. + +This includes smart contracts and any system that achieves consensus in some way. + +Notes: + +Proof-of-authority web2 systems can also be considered consensus systems. + +---v + +## Versioned + +XCM is a **versioned** language. + +Each system declares what version they support. + +It's currently in version 4. + +What goes in each version is defined via an RFC process. + +Notes: + +This protects against runtime upgrades breaking everything. + +--- + +# โœ‰๏ธ A Format, not a Protocol + +XCM is a **_messaging format_**. + +It is akin to the post card from the post office. + +It is _not_ a messaging protocol! + +A post card doesn't send itself! + +Notes: + +It cannot be used to actually "send" any message between systems; its utility is only in expressing what should be done by the receiver. +Like many aspects core to Substrate, this separation of concerns empowers us to be far more generic and enable much more. +A post card relies on the postal service to get itself sent towards its receivers, and that is what a messaging protocol does. + +The transport layer concerns itself with sending arbitrary blobs, it doesn't care about the format. +A common format has its benefits though, as we'll see next. + +--- + +### Terminology: XCMs + +**XCM**, Cross-Consensus Messaging, is the format. + +**An XCM** is a Cross-Consensus Message. + +It's not called an XCM message, + +the same way it's not called an ATM machine. + +We can also call them XCM programs, since they are executable. + +Notes: + +More about their executable nature later. + +--- + +# Summary + +We learned what XCM is and why it's useful. + +--- + +# Next steps + +We'll learn about the primitives that make up any XCMs. diff --git a/syllabus/6-Polkadot-SDK/XCM/2-Primitives-slides.md b/syllabus/6-Polkadot-SDK/XCM/2-Primitives-slides.md new file mode 100644 index 000000000..3a6f16411 --- /dev/null +++ b/syllabus/6-Polkadot-SDK/XCM/2-Primitives-slides.md @@ -0,0 +1,597 @@ +--- +title: XCM primitives +description: Locations, assets and instructions +duration: 2 hours +--- + +# XCM Primitives + +---v + +## What you'll learn + + + +- Locations +- Assets +- Instructions + +Notes: + +Locations: how an XCM references various entities in the network. +Assets: how an XCM can specify fungible and non-fungible assets. +Instructions: how an XCM expresses what actions it wants the receiver to perform. + +--- + +# Locations + +Way of referencing any entity in the network, for example, the recipient of the message. + + +graph LR + Message(Message) + Alice(Alice)--"?"-->Bob(Bob) + Alice--"?"-->AssetHub(Asset Hub) + Alice--"?"-->Pallet(Pallet) + Alice--"?"-->SmartContract(Smart Contract) + + +Notes: + +The `Location` is sort of the URL for consensus systems. +A Location can be a scalable multi-shard blockchain such as Polkadot, an ERC-20 asset account on a parachain, a smart contract, etc. +They can be relative or absolute. +They don't need to correspond with the actual path the message will take, that's the job of the transport protocol. + +---v + +## Interior Locations + +> Given two consensus systems, A and B. A is **interior** to B if a state change in A implies a state change in B. + +Notes: + +An example, a smart contract in Ethereum would be interior to Ethereum itself. + +---v + +## Location hierarchy + + +graph TD; + Relay(Relay)-->A(Parachain A) + Relay-->B(Parachain B) + B-->Alice(Account A) + B-->Bob(Account B) + A-->Pallet(Pallet Contracts) + Pallet-->SCA(Smart Contract A) + Pallet-->SCB(Smart Contract B) + + +Notes: + +Locations form a hierarchy using the interior relation. + +---v + +## Location Representation + + + +```rust +struct Location { + parents: u8, + junctions: Junctions, +} +``` + +
+ +```rust +enum Junction { + Parachain(u32), + AccountId32 { id: [u8; 32], network: Option }, + PalletInstance(u8), + GeneralIndex(u128), + GlobalConsensus(NetworkId), + ... +} +``` + +Notes: + +Right now Junctions are limited to 8 because of stack space. +We also don't expect Junctions being more than 8 levels deep. + +It's perfectly possible to create locations that don't point anywhere. + +---v + +### Network Id + + + +```rust +enum NetworkId { + ByGenesis([u8; 32]), + ByFork { block_number: u64, block_hash: [u8; 32] }, + Polkadot, + Kusama, + Westend, + Rococo, + Wococo, + Ethereum { chain_id: u64 }, + BitcoinCore, + BitcoinCash, +} +``` + +
+ +
+ +Notes: + +Junctions are ways to descend the location hierarchy + +---v + +## Text notation + + + + + + + +```rust +Location { + parents: 1, + interior: Parachain(50) +} +``` + + + + +--> + + + + +`../Parachain(50)` + + + +Notes: + +This notation comes from an analogy to a file system. + +---v + +## Universal Location + +> The Universal Location is a **theoretical** location. It's the parent of all locations which generate their own consensus. It itself has no parents. + +---v + +## Universal Location + + +graph TD; + UniversalLocation(Universal Location)-->Polkadot(Polkadot) + UniversalLocation-->Kusama(Kusama) + UniversalLocation-->Ethereum(Ethereum) + UniversalLocation-->Bitcoin(Bitcoin) + + +Notes: + +We can imagine a hypothetical location that contains all top-level consensus systems. + +---v + +## Absolute locations + + + +```rust +pub type InteriorLocation = Junctions; +``` + +Sometimes, absolute locations are necessary, e.g. for bridges. + +They don't have parents. + +The first junction has to be a `GlobalConsensus`. + +Notes: + +To write an absolute location, we need to know our location relative to the Universal Location. + +---v + +## What are `Location`s used for? + + + +- Addressing +- Origins +- Assets +- Fees +- Bridging + +---v + +## Cross-Chain Origins + +When a receiver gets an XCM, a `Location` specifies the sender. + +This `Location` is _relative_ to the receiver. + +Can be converted into a pallet origin in a FRAME runtime + +Used for determining privileges during XCM execution. + +Notes: + +Reanchoring: + +Since `Location`s are relative, when an XCM gets sent over to another chain, the origin location needs to be rewritten from the perspective of the receiver, before the XCM is sent to it. + +--- + +## Location Examples + +---v + +### Sibling parachain + +`../Parachain(1001)` + + +graph TD + Polkadot(Polkadot)-->AssetHub("๐Ÿ“ AssetHub (1000)") + Polkadot-->Collectives("Collectives (1001)") + + +Notes: + +What does the location resolve to if evaluated on Parachain(1000)? + +---v + +### Sibling parachain + +`../Parachain(1001)` + + +graph TD + Polkadot(Polkadot)-->AssetHub("๐Ÿ“ AssetHub (1000)") + Polkadot-->Collectives("Collectives (1001)") + AssetHub-->Polkadot + linkStyle 0 opacity:0.3 + linkStyle 2 stroke-dasharray:5 + + +---v + +### Parachain account + +`Parachain(1000)/AccountId32(0x1234...cdef)` + + +graph TD + Polkadot("๐Ÿ“ Polkadot")-->AssetHub("AssetHub (1000)") + Polkadot-->Collectives("Collectives (1001)") + AssetHub-->Account("AccountId32 (0x1234...cdef)") + + +Notes: + +What does the location resolve to if evaluated on the relay chain? + +---v + +### Parachain account + +`Parachain(1000)/AccountId32(0x1234...cdef)` + + +graph TD + Polkadot("๐Ÿ“ Polkadot")-->AssetHub("AssetHub (1000)") + Polkadot-->Collectives("Collectives (1001)"):::disabled + AssetHub-->Account("AccountId32 (0x1234...cdef)") + linkStyle 1 opacity:0.3 + classDef disabled opacity:0.3 + + +---v + +### Bridge + +`../../GlobalConsensus(Kusama)/Parachain(1000)` + + +graph TD + Universe(Universal Location)-->Polkadot(Polkadot) + Universe-->Kusama(Kusama) + Polkadot-->PolkaA("๐Ÿ“ Asset Hub (1000)") + Polkadot-->PolkaB(Bridge Hub) + PolkaA-->Alice(Alice) + PolkaA-->AssetsPallet(Pallet Assets) + AssetsPallet-->Asset(USDT) + Kusama-->KusamaA("Asset Hub (1000)") + Kusama-->KusamaB(Bridge Hub) + + +Notes: + +Speak to an example of non-parachain multi-location that would use a bridge +XCM reasons about addressing (as in a postal address) that must include understanding where you are, not just where you are going! +This will be very powerful later on (Origins) + +---v + +### Bridge + +`../../GlobalConsensus(Kusama)/Parachain(1000)` + + +graph TD + Universe(Universal Location)-->Polkadot(Polkadot) + Universe-->Kusama(Kusama) + Polkadot-->PolkaA("๐Ÿ“ Asset Hub (1000)") + Polkadot-->PolkaB(Bridge Hub):::disabled + PolkaA-->Alice(Alice):::disabled + PolkaA-->AssetsPallet(Pallet Assets):::disabled + AssetsPallet-->Asset(USDT):::disabled + Kusama-->KusamA("Asset Hub (1000)") + Kusama-->KusamB(Bridge Hub):::disabled + PolkaA-->Polkadot + Polkadot-->Universe + linkStyle 0 opacity:0.3 + linkStyle 2 opacity:0.3 + linkStyle 3 opacity:0.3 + linkStyle 4 opacity:0.3 + linkStyle 5 opacity:0.3 + linkStyle 6 opacity:0.3 + linkStyle 8 opacity:0.3 + linkStyle 9 stroke-dasharray:5 + linkStyle 10 stroke-dasharray:5 + classDef disabled opacity:0.3 + + +Notes: + +Even with Bridge Hubs, the relative location is what you'd expect. +Bridge Hubs are just a way for routing messages. +They are an implementation detail of the transport layer. + +---v + +### Bridge (actual routing) + + +graph TD + Universe(Universal Location):::disabled-->Polkadot(Polkadot):::disabled + Universe-->Kusama(Kusama) + Polkadot-->PolkaA("๐Ÿ“ Asset Hub (1000)") + Polkadot-->PolkaB(Bridge Hub) + PolkaA-->Alice(Alice):::disabled + PolkaA-->AssetsPallet(Pallet Assets):::disabled + AssetsPallet-->Asset(USDT):::disabled + Kusama-->KusamB(Bridge Hub) + Kusama-->KusamA("Asset Hub (1000)") + PolkaA-->PolkaB + PolkaB--"Bridge"-->KusamB + KusamB-->Kusama + linkStyle 0 opacity:0.3 + linkStyle 1 opacity:0.3 + linkStyle 2 opacity:0.3 + linkStyle 3 opacity:0.3 + linkStyle 4 opacity:0.3 + linkStyle 5 opacity:0.3 + linkStyle 6 opacity:0.3 + linkStyle 7 opacity:0.3 + linkStyle 11 stroke-dasharray:5 + classDef disabled opacity:0.3 + + +Notes: + +The actual message is routed through Bridge Hub. + +---v + +## Sovereign Accounts + +Locations external to the local system can be represented by a local account. + +We call this the **sovereign account** of that location. + +They are a mapping from a `Location` to an account id. + +---v + + +graph TD + Polkadot(Polkadot)-->A(A) & B(B) + A-->Alice(Alice) + B-->AliceSA("Alice's sovereign account") + + +Notes: + +A sovereign account is an account on one system that is controlled by another on a different system. +A single account on a system can have multiple sovereign accounts on many other systems. +In this example, Alice is an account on AssetHub, and it controls a sovereign account on Collectives. + +When transferring between consensus systems, the sovereign account is the one that gets the funds on the destination system. + +---v + + +graph TD + Polkadot(Polkadot)-->A(A) & B(B) + A-->Alice(Alice) + B-->AliceSA("Alice's sovereign account") + B-->ASA("Asset Hub's sovereign account") + A-->BSA("Collective's sovereign account") + + +--- + +# Assets + +Most messages will deal with assets in some way. + +How do we reference these assets? + +---v + +### Asset Representation + +```rust +struct Asset { + pub id: AssetId, + pub fun: Fungibility, +} + +struct AssetId(Location); // <- We reuse the location! + +enum Fungibility { + Fungible(u128), + NonFungible(AssetInstance), +} +``` + +Notes: + +We use locations, which we've already discussed, to refer to assets. + +A Asset is composed of an asset ID and an enum representing the fungibility of the asset. +Asset IDs are the location that leads to the system that issues it, this can be just an index in an assets pallet, for example. + +Assets can also either be fungible or non-fungible: +Fungible - each token of this asset has the same value as any other +NonFungible - each token of this asset is unique and cannot be seen as having the same value as any other token under this asset + +---v + +### Asset filtering and wildcards + +```rust +enum AssetFilter { + Definite(Assets), + Wild(WildAsset), +} + +enum WildAsset { + All, + AllOf { id: AssetId, fun: WildFungibility }, + // Counted variants +} + +enum WildFungibility { + Fungible, + NonFungible, +} +``` + +Notes: + +Sometimes we don't want to specify an asset, but rather filter a collection of them. +In this case, we can either list all the assets we want or use a wildcard to select all of them. +In reality, it's better to use the counted variant of the wildcards, for benchmarking. + +--- + +# Instructions + +Every XCM is a sequence of instructions. + +---v + +## Kinds of instructions + + + +- Command +- Trusted Indication +- Information +- System Notification + +---v + +## Example: WithdrawAsset + +An instruction used to get assets from an account and put them into the holding register. + + + +```rust +WithdrawAsset(Assets) +``` + +Notes: + +This instruction is a command. +It takes the assets from the account specified in the origin register and puts them in the holding register. + +---v + +## Example: ReceiveTeleportedAsset + + + +Used for teleporting assets between two systems. + +```rust +ReceiveTeleportedAsset(Assets) +``` + +Notes: + +This instruction is a trusted indication. +It tells the receiver that the sender has burnt some assets and they should be minted here. +This is used for teleports, which we'll look into in the next lecture. +A lot of trust is needed between both systems. + +---v + +## Example: QueryResponse + +Used for reporting information back to another system. + + + +```rust +QueryResponse { + #[codec(compact)] + query_id: QueryId, + response: Response, + max_weight: Weight, + querier: Option, +} +``` + +Notes: + +This instruction is reporting back information. +Different things can be reported, like a certain pallet, the result of an operation, etc. + +--- + +# Summary + +- Locations +- Assets +- Instructions + +--- + +# Next steps + +How do these primitives get together to perform cross-chain execution? diff --git a/syllabus/6-Polkadot-SDK/XCM/2-XCVM/XCVM-slides.md b/syllabus/6-Polkadot-SDK/XCM/2-XCVM/XCVM-slides.md index e8edef38f..b17fdad35 100644 --- a/syllabus/6-Polkadot-SDK/XCM/2-XCVM/XCVM-slides.md +++ b/syllabus/6-Polkadot-SDK/XCM/2-XCVM/XCVM-slides.md @@ -4,334 +4,6 @@ description: Learning about the XCVM state machine duration: 1 hour --- -# XCVM - ---- - -# ๐Ÿซ€ The XCVM - -At the core of XCM lies the **Cross-Consensus Virtual Machine (XCVM)**. - -A โ€œmessageโ€ in XCM is an XCVM program, which is a sequence of instructions. - -The XCVM is a state machine, state is kept track in **registers**. - -Notes: - -Itโ€™s an ultra-high level non-Turing-complete computer. -Messages are one or more XCM instructions. -The program executes until it either runs to the end or hits an error, at which point it finishes up and halts. -An XCM executor following the XCVM specification is provided by Parity, and it can be extended or customized, or even ignored altogether and users can create their own construct that follows the XCVM spec. - ---- - -# XCVM Registers - - -graph LR - subgraph Registers[ ] - Holding(Holding) - Origin(Origin) - More(...) - end - - -Notes: - -Registers _are_ the state of XCVM. -Note that they are temporary/transient. -We'll talk about are the `holding` and `origin` registers, but there are more. - ----v - -## ๐Ÿ“ The Origin Register - -Contains an `Option` of the cross-consensus origin where the message originated from. - -Notes: - -This `Location` can change over the course of program execution. - -It might be `None` because some instructions clear the origin register. - ----v - -### ๐Ÿ’ธ The Holding Register - -Expresses a number of assets in control of the xcm execution that have no on-chain representation. - -They don't belong to any account. - -It can be seen as the register holding "unspent assets". - ---- - -# ๐Ÿ“œ XCVM Instructions - -XCVM Instructions might change a register, they might change the state of the consensus system or both. - ----v - -## Kinds of instructions - - - -- Command -- Trusted Indication -- Information -- System Notification - ----v - -## Example: WithdrawAsset - -An instruction used to get assets from an account and put them into the holding register. - - - -```rust -WithdrawAsset(Assets) -``` - -Notes: - -This instruction is a command. -It takes the assets from the account specified in the origin register and puts them in the holding register. - ----v - -## Example: ReceiveTeleportedAsset - - - -Used for teleporting assets between two systems. - -```rust -ReceiveTeleportedAsset(Assets) -``` - -Notes: - -This instruction is a trusted indication. -It tells the receiver that the sender has burnt some assets and they should be minted here. -This is used for teleports, which we'll look into in the next lecture. -A lot of trust is needed between both systems. - ----v - -## Example: QueryResponse - -Used for reporting information back to another system. - - - -```rust -QueryResponse { - #[codec(compact)] - query_id: QueryId, - response: Response, - max_weight: Weight, - querier: Option, -} -``` - -Notes: - -This instruction is reporting back information. -Different things can be reported, like a certain pallet, the result of an operation, etc. - ---- - -# Basic XCVM Operation - - -graph LR - subgraph Program - direction LR - WithdrawAsset-->BuyExecution - BuyExecution-->DepositAsset - end - - -Notes: - -Here we have a very simple program, which if executed locally would result in a regular asset transfer within a single consensus system. - ----v - -## XCVM Operation - - -graph LR - subgraph Program - WithdrawAsset-->BuyExecution:::disabled - BuyExecution-->DepositAsset:::disabled - end - Executor(Executor)--"Fetch"-->WithdrawAsset - subgraph Registers - Origin(Origin) - Holding(Holding) - end - Registers-.-Executor - linkStyle 0 opacity:0.3 - linkStyle 1 opacity:0.3 - classDef disabled opacity:0.3 - - -Notes: - -The XCVM, or executor, fetches instruction from the program and executes them one by one. -It starts with the `WithdrawAsset` instruction, which loads the holding register using assets from the location specified in the origin register. - ----v - -## XCVM Operation - - -graph LR - subgraph Program - WithdrawAsset-->BuyExecution:::disabled - BuyExecution-->DepositAsset:::disabled - end - Executor(Executor)--"Fetch"-->WithdrawAsset - Executor--"Get assets"-->Origin - subgraph Registers - Origin(Origin) - Holding(Holding) - end - Registers-.-Executor - linkStyle 0 opacity:0.3 - linkStyle 1 opacity:0.3 - classDef disabled opacity:0.3 - - ----v - -## XCVM Operation - - -graph LR - subgraph Program - WithdrawAsset-->BuyExecution:::disabled - BuyExecution-->DepositAsset:::disabled - end - Executor(Executor)--"Fetch"-->WithdrawAsset - Executor--"Put assets"-->Holding - subgraph Registers - Origin(Origin) - Holding(Holding) - end - Registers-.-Executor - linkStyle 0 opacity:0.3 - linkStyle 1 opacity:0.3 - classDef disabled opacity:0.3 - - ----v - -## XCVM Operation - - -graph LR - subgraph Program - WithdrawAsset:::disabled-->BuyExecution - BuyExecution-->DepositAsset:::disabled - DepositAsset - end - Executor(Executor)--"Fetch"-->BuyExecution - linkStyle 0 opacity:0.3 - linkStyle 1 opacity:0.3 - classDef disabled opacity:0.3 - - ----v - -## XCVM Operation - - -graph LR -subgraph Program -WithdrawAsset:::disabled-->BuyExecution:::disabled -BuyExecution-->DepositAsset -DepositAsset -end -Executor(Executor)--"Fetch"-->DepositAsset -subgraph Registers -Holding(Holding) -Origin(Origin) -end -Registers-.-Executor -linkStyle 0 opacity:0.3 -linkStyle 1 opacity:0.3 -classDef disabled opacity:0.3 - - ----v - -## XCVM Operation - - -graph LR -subgraph Program -WithdrawAsset:::disabled-->BuyExecution:::disabled -BuyExecution-->DepositAsset -DepositAsset -end -Executor(Executor)--"Fetch"-->DepositAsset -subgraph Registers -Holding(Holding) -Origin(Origin) -end -Registers-.-Executor -Executor--"Get assets"-->Holding -linkStyle 0 opacity:0.3 -linkStyle 1 opacity:0.3 -classDef disabled opacity:0.3 - - ----v - -## XCVM Operation - - -graph LR -subgraph Program -WithdrawAsset:::disabled-->BuyExecution:::disabled -BuyExecution-->DepositAsset -DepositAsset -end -Executor(Executor)--"Fetch"-->DepositAsset -subgraph Registers -Holding(Holding) -Origin(Origin) -end -Registers-.-Executor -DepositAsset-.-Beneficiary(Beneficiary) -Executor--"Put assets"-->Beneficiary -linkStyle 0 opacity:0.3 -linkStyle 1 opacity:0.3 -classDef disabled opacity:0.3 - - - ----v - -## XCVM vs. Standard State Machine - - - -1. Error _handler_ register -2. Appendix register - -Notes: - -1. Code that is run in the case where the XCM program fails or errors. - Regardless of the result, when the program completes, the error handler register is cleared. - This ensures that error handling logic from a previous program does not affect any appended code (i.e. the code in the error handler register does not loop infinitely, the code in the Appendix register cannot access the result of the code execution in the error handler). -2. Code that is run regardless of the execution result of the XCM program. - ---- - ## Reanchoring How do different locations reference the same asset? @@ -407,6 +79,8 @@ graph LR --- + + ## ๐Ÿคน Cross-consensus transfers Notes: diff --git a/syllabus/6-Polkadot-SDK/XCM/3-Executor-slides.md b/syllabus/6-Polkadot-SDK/XCM/3-Executor-slides.md new file mode 100644 index 000000000..6c6e83d9f --- /dev/null +++ b/syllabus/6-Polkadot-SDK/XCM/3-Executor-slides.md @@ -0,0 +1,141 @@ +--- +title: XCM Executor +description: How XCMs are executed +duration: 1 hour +--- + +# XCM Executor + +---v + +## What you'll learn + +- The XCVM +- XCM Executor + +--- + +# The XCVM + +At the core of XCM lies the **Cross-Consensus Virtual Machine (XCVM)**. + +The XCVM is a state machine, state is kept track in **registers**. + +How the virtual machine should act is written in the XCM [specification](https://github.com/paritytech/xcm-format). + +Notes: + +Itโ€™s an ultra-high level non-Turing-complete computer. +Messages are one or more XCM instructions. +The program executes until it either runs to the end or hits an error, at which point it finishes up and halts. + +---v + +## XCVM Registers + +- Holding +- Origin +- ErrorHandler +- Appendix +- etc + +Notes: + +Registers are the state of the XCVM. +They are transient, temporary. + +---v + +## The Origin Register + +Contains an `Option` of the cross-consensus origin where the message originated from. + +Notes: + +This `Location` can change over the course of program execution. + +It might be `None` because some instructions clear the origin register. + +---v + +## The Holding Register + +Expresses a number of assets in control of the xcm execution that have no on-chain representation. + +They don't belong to any account. + +It can be seen as the register holding "unspent assets". + +---v + +## Instructions + +Instructions might change a register, the state of the consensus system, or both. + +--- + +# XCVM Operation + +---v + +## Fetch/execute loop + +The XCVM operates in a typical fetch/execute loop. + +Each instruction is fetched and executed in order. + +---v + +## Error handler and appendix + +Two interesting additions by the XCVM are the error handler and appendix. + +They contain more instructions that are executed if there's an error or unconditionally +at the end of execution, accordingly. + +--- + +# XCM Executor + +Parity provides an implementation of the XCVM spec, the `XcmExecutor`. + +It's the entrypoint for executing XCMs. + +---v + + + +```rust +XcmExecutor::prepare_and_execute( + origin, + xcm, + &mut hash, + weight_limit, + weight_credit, +); +``` + +---v + +## Configuration + +The `XcmExecutor` is highly configurable, so it can be implemented by many different chains +just adjusting some configuration items. + +These items provide the executor access to the chain's runtime. + +This is, for example, how different chains can route different asset instructions to different +pallets (pallet-balances vs pallet-assets). + +--- + +# Summary + +- XCVM +- XCM Executor + +--- + +# Workshop + +We'll implement our own very simple implementation of the XCVM. diff --git a/syllabus/6-Polkadot-SDK/XCM/3-Pallet_XCM/Pallet_XCM-slides.md b/syllabus/6-Polkadot-SDK/XCM/3-Pallet_XCM/Pallet_XCM-slides.md index d11ba3e20..c3d6f6633 100644 --- a/syllabus/6-Polkadot-SDK/XCM/3-Pallet_XCM/Pallet_XCM-slides.md +++ b/syllabus/6-Polkadot-SDK/XCM/3-Pallet_XCM/Pallet_XCM-slides.md @@ -6,340 +6,6 @@ duration: 1 hour # XCM Pallet ----v - -#### Lesson goals: - - - -- Understand what the interface of the XCM pallet is. -- How versioning discovery works. -- How receiving responses work. -- Understand how to craft XCM in FRAME pallets. - ---- - -## The XCM pallet - -We have now learnt about the XCVM and FRAME. - -The XCM pallet is the bridge between the XCVM subsystem and the FRAME subsystem. - -**It allows us to send/execute XCMs and interact with the XCM executor**. - ----v - -## How XCM is expected to be used - -XCM is not intended to be written by end-users. - -Instead, _developers_ write XCVM programs, and package them up into FRAME extrinsics. - -Notes: - -How do wallets wallet providers use XCM ? - -We will see examples of XCM being built in the runtime when exploring `teleport_assets` and `reserve_transfer_assets` extrinsics. - ---- - -### Key roles of `pallet-xcm` - - - -1. Allows local execution of XCMs -2. Allows sending XCMs to other chains -3. Provides an easier interface to do cross-consensus asset transfers -4. Handles state based XCVM duties, e.g. version negotiation, claiming trapped assets - - - -Notes: - -- Execution and sending can only be done by certain origins -- Even when the XCM pallet allows any FRAME origin to send XCMs, it distinguishes root calls vs any other origin calls. - In the case of the latter, it appends the `DescendOrigin` instruction to make sure non-root origins cannot act on behalf of the parachain. - ---- - -## Execute - -Direct access to the XCM executor. -Executed on behalf of FRAME's signed origin. - - - -flowchart TD -subgraph paraA[Parachain Aโ€€โ€€โ€€โ€€โ€€โ€€โ€€โ€€โ€€โ€€โ€€โ€€โ€€โ€€.] - executor --"success?"--> palletxcm - palletxcm("pallet-xcm") --"execute"--> executor("xcm-executor") -end -execute("execute(xcm)") --> palletxcm - - - -Notes: - -It checks the origin to ensure that the configured `SendXcmOrigin` filter is not blocking the execution. -It executes the message **locally** and returns the outcome as an event. - ----v - -## Send - -Sends a message to the provided destination. - - - -flowchart LR -subgraph paraA[Parachain A] -palletxcma("pallet-xcm") --"deliver"--> routera("xcm-router") -routera --> mqueuea("message queue") -end - -subgraph paraB[Parachain B] -mqueueb("message queue") --> executorb("xcm-executor") -end - -send("send(xcm)") --> palletxcma -mqueuea --> mqueueb - - - - -Notes: - -This extrinsic is a function to send a message to a destination. -It checks the origin, the destination and the message. -Then it lets the `XcmRouter` handle the forwarding of the message. - ---- - -## Cross-consensus asset transfers - - - - - - - - - - - -Notes: - -We have already seen what teleports and reserve transfers mean in lesson 7.1; A quick reminder. - ----v - -## Teleports - -`limited_teleport_assets` - -This extrinsic allows the user to perform an asset teleport. - - - -flowchart LR -subgraph paraA[Parachain A] - palletxcma("pallet-xcm") --"1. execute"--> executora("xcm-executor") - executora --"send"--> sendera("xcm-sender") -end - -subgraph tdestination[Trusted Destination] -end -lteleport("limited_teleport_assets(\nโ€€โ€€dest,\nโ€€โ€€beneficiary,\nโ€€โ€€assets,\nโ€€โ€€fee_asset_item,\nโ€€โ€€weight_limit\n)"):::left --> palletxcma - -sendera --"2."--> tdestination - -classDef left text-align:left - - - - ----v - -## Reserve asset transfers - -`limited_reserve_transfer_assets` - -Allow the user to perform a reserve-backed transfer from the reserve chain to the destination. - - - -flowchart LR -subgraph reserve[Reserve Chain] - palletxcma("pallet-xcm") --"1. execute"--> executora("xcm-executor") - executora --"send"--> sendera("xcm-sender") -end - -subgraph destination[Destination] -end -lteleport("limited_reserve_transfer_assets(\nโ€€โ€€dest,\nโ€€โ€€beneficiary,\nโ€€โ€€assets,\nโ€€โ€€fee_asset_item,\nโ€€โ€€weight_limit\n)"):::left --> palletxcma - -sendera --"2."--> destination - -classDef left text-align:left - - - - ----v - -## Cross-consensus asset transfers - -`transfer_assets` - -Simple interface for either reserve asset transfers or teleports. -Figures out which one is needed according to the trusted reserves and teleporters, configured on the executor. - ---- - -## ๐Ÿ—ฃ๏ธ Version negotiation - -XCM is **versioned**. - -One version may contain more or different instructions than another, so for parties to communicate via XCM, it is important to know which version the other party is using. - -The version subscription mechanism allows parties to subscribe to version updates from others. - - - -```rust -pub enum VersionedXcm { - V3(v3::Xcm), - V4(v4::Xcm), -} -``` - -Notes: - -- V0 and V1 were removed with the addition of XCM v3. -- V2 will soon be removed since v4 was recently added. - ----v - -## ๐Ÿ—ฃ๏ธ Version negotiation - -Chains need to be aware of the version supported by each other. -`SubscribeVersion` and `QueryResponse` play a key role here: - - - -```rust -enum Instruction { - // --snip-- - SubscribeVersion { - query_id: QueryId, - max_response_weight: u64, - }, - QueryResponse { - query_id: QueryId, - response: Response, - max_weight: u64, - }, - // --snip-- -} -``` - -Notes: - -- `query_id` would be identical in the `SubscribeVersion` and `QueryResponse` instructions. -- Likewise, `max_response_weight` should also match `max_weight` in the response - ----v - -## ๐Ÿ—ฃ๏ธ Version negotiation - -- `ResponseHandler`: The component in charge of handling response messages from other chains. -- `SubscriptionService`: The component in charge of handling version subscription notifications to other chains. - - - -```rust - impl Config for XcmConfig { - // --snip-- - type ResponseHandler = PalletXcm; - type SubscriptionService = PalletXcm; - } -``` - -Notes: - -- `PalletXcm` keeps track of the versions of each chain when it receives a response. -- It also keeps track of which chains it needs to notify whenever we change our version - ----v - -## Subscription Service - -Any system can be notified of when another system changes its latest supported XCM version. -This is done via the `SubscribeVersion` and `UnsubscribeVersion` instructions. - -The `SubscriptionService` type defines what action to take when processing a `SubscribeVersion` instruction. - -Notes: - -`pallet-xcm` provides a default implementation of this trait. -When receiving a `SubscribeVersion`, the chain sends back an XCM with the `QueryResponse` instruction containing its current version. - ----v - -## Version Negotiation - -The subscription service leverages any kind of exchange of XCMs between two systems to begin the process of version negotiation. - -Each time a system needs to send a message to a destination with an unknown supported XCM version, its location will be stored in the `VersionDiscoveryQueue`. -This queue will then be checked in the next block and `SubscribeVersion` instructions will be sent out to those locations present in the queue. - -Notes: - -SubscribeVersion - instructs the local system to notify the sender whenever the former has its XCM version upgraded or downgraded. -UnsubscribeVersion - if the sender was previously subscribed to XCM version change notifications for the local system, then this instruction tells the local system to stop notifying the sender on version changes. - ----v - -## ๐Ÿ—ฃ๏ธ XCM Version Negotiation - -XCM version negotiation: - - -1. Chain A sends `SubscribeVersion` to chain B. -1. Chain B responds `QueryResponse` to chain A with the same query_id and max_weight params, and puts the XCM version in the response -1. Chain A stores chain B's supported version on storage. -1. The same procedure happens from chain B to chain A. -1. Communication is established using the highest mutually supported version. - ----v - -## ๐Ÿ—ฃ๏ธ XCM Version Negotiation - -In the following scenario Chain A is using XCM v4 - - - -flowchart BT -subgraph registryA[Chain A's Registry] - chainB("Chain B \n\n v3") - chainC("Chain C \n\n v4") - chainD("Chain D \n\n v4") - chainE("Chain E \n\n v3") -end - - - - - -flowchart LR - -chainARequest("Chain A") --"Chain E ? \n\n v3"--> chainERequest("Chain E") - - - - ---- - ## Response Handler Version negotiation is just one example among many kinds of queries one chain can make to another. @@ -395,45 +61,3 @@ Notes: The above instruction is the one used for offering some requested information that the local system is expecting. `querier` parameter should be checked to ensure that the system that requested the information matches with what is expected. - ---- - -## Asset Trap/Claims - -What happens when there are still funds in the holding register after the execution of every instruction is done? - -Any situation in which the holding register contains assets after the execution of the XCM message would lead to asset trapping. - -These assets need to be **stored** to allow for their owner to claim them in the future, the xcm pallet stores them. - -Notes: - -- This is handled in the `post_execute` function of the xcm-executor. - ----v - -## Asset Trap/Claims - -- **Asset trapper**: Trapped assets are stored in a storage item, indexed by origin and assets - -- **Asset claimer**: The pallet also allows for claiming trapped assets, providing that: - - the origin claiming the assets is identical to the one that trapped them. - - the `Asset` being claimed is identical to the one that was trapped - -Notes: - -- Each map element on `AssetTraps` holds a counter of how many times such origin has trapped such `Asset`. -- Every time such `Asset` gets reclaimed, the counter decrements by one. - ---- - -## Summary - -In this lecture, we learnt: - -- What the XCM pallet is and what it's used for. -- How XCM is intended to be used, both by wallet and runtime developers. -- The useful extrinsics in the XCM pallet. -- How XCM versioning works. -- How the XCM pallet is used to receive responses. -- How assets might be trapped and how to use the XCM pallet to claim them. diff --git a/syllabus/6-Polkadot-SDK/XCM/4-Pallet-Xcm-slides.md b/syllabus/6-Polkadot-SDK/XCM/4-Pallet-Xcm-slides.md new file mode 100644 index 000000000..fa3e5424e --- /dev/null +++ b/syllabus/6-Polkadot-SDK/XCM/4-Pallet-Xcm-slides.md @@ -0,0 +1,57 @@ +--- +title: XCM Pallet +description: The XCM Pallet - The link between XCM and FRAME +duration: 1 hour +--- + +# XCM Pallet + +---v + +## What you'll learn + +- The link between XCM and FRAME + +--- + +# How XCM can be used + +- Interacting directly with the executor by writing XCMs + +or + +- Packaging up all XCM-logic on extrinsics + +--- + +# The XCM Pallet + +We have now learnt about the XCVM and FRAME. + +The XCM pallet is the bridge between the XCVM subsystem and the FRAME subsystem. + +**It allows us both to interact with the executor directly and provides useful extrinsics**. + +---v + +## Some functionalities of the pallet + +- Executing xcms locally. +- Sending xcms to a different location. +- Transferring assets to a different consensus system +- Version negotiation +- Handling responses +- Claiming trapped assets + +--- + +# Summary + +- Learnt how to link XCM and FRAME. +- Learnt what the XCM pallet does. + +--- + +# Workshop + +We're going to write our own version of some extrinsics from the XCM pallet. diff --git a/syllabus/6-Polkadot-SDK/XCM/5-Xcm-config-and-simulator-slides.md b/syllabus/6-Polkadot-SDK/XCM/5-Xcm-config-and-simulator-slides.md new file mode 100644 index 000000000..32427afec --- /dev/null +++ b/syllabus/6-Polkadot-SDK/XCM/5-Xcm-config-and-simulator-slides.md @@ -0,0 +1,25 @@ +--- +title: XCM Config and XCM simulator +description: How to configure and simulate XCM +duration: 2 hours +--- + +# XCM Config and XCM Simulator + +--- + +# XCM Config + +TODO: List some of the most relevant config items. + +--- + +# XCM Simulator + +TODO: Talk about it, show some code, demo. + +--- + +# Workshop + +Next, we'll play around with all we've learnt with XCM. diff --git a/syllabus/6-Polkadot-SDK/XCM/README.md b/syllabus/6-Polkadot-SDK/XCM/README.md index 6e6860a01..9d155779d 100644 --- a/syllabus/6-Polkadot-SDK/XCM/README.md +++ b/syllabus/6-Polkadot-SDK/XCM/README.md @@ -1,43 +1,41 @@ # Cross Consensus Messaging (XCM) -## Lessons Overview +## Learning outcomes -### Exercises +- Students will understand the what and why of XCM. +- Students will get familiar with writing XCM programs. +- Students will understand how XCM programs are executed. +- Students will get familiar with configuring chains for XCM execution. -All referenced below are stored in a [master copy](https://github.com/Polkadot-Blockchain-Academy/pba-xcm-activities--master) monorepo. -Each cohort should have a new template derived from that repo, and the new one shared to the cohort specific github team to them using this master copy. +## Hands-on activities -### Day 1 +The whole module will revolve around a workshop, with each lecture introducing the relevant +concepts needed to get hacking. -**Morning** (Founder Friendly) +## Schedule -Lecture - 1-Core_Concepts_of_XCM (2.5 hr) @gav -Coffee break (30 min) -Lecture - 2-XCVM (1 hr) @gav +### Day 1 -**Afternoon** (Engineers Only) +#### Morning -Exercise - Usage of XCM locations (1.5 hr) @keith & @cisco -Exercise - Using XCM simulator (1.5 hr) @keith & @cisco +Lecture 1 - Presentation (45 minutes) +Lecture 2 - Primitives (2 hours) +Workshop - Fundamentals 1, 2 and 3 (1 hour) -### Day 2 +#### Afternoon -**Morning** (Engineers Only) +Lecture 3 - XCM Executor (1 hour) +Workshop - Fundamentals 4 (1 hour) +Lecture 4 - Pallet XCM (1 hour) +Workshop - Fundamentals 5 (1 hour) -Lecture - 3-XCM Pallet XCM (2.5 hr) @gav -Coffee break (20 min) -Lecture - 4-Chain_Config_in_XCM (1.5 hr) @gav - -**Afternoon** (Engineers Only) +### Day 2 -Exercise - More XCM simulator (1.5 hr) @keith -Coffee break (15 min) -Exercise - Configuring XCM (1.5 hr) @keith +#### Morning -### Additional content +Lecture 5 - XCM configuration and XCM simulator (2 hours) +Lecture 6 - ??? (2 hours) -Things that did not fit into this sequence but can be used to extend: +#### Afternoon -Lecture - XCM 5, Beyond Asset Transfers (1.5 hr) @arrudagates (Beyond Asset Transfers) -Lecture and Workshop - XCM in Use (2 hr) @chrisli30 (XCM in Use) -Exercise - Writing an RFC (1.5 hr) @keith & @cisco (_not yet created_) +Workshop - Simulator (4 hours)