Skip to content

Commit

Permalink
XCM Cookbook (paritytech#2633)
Browse files Browse the repository at this point in the history
# Context

XCM docs are currently an md book hosted with github pages:
https://paritytech.github.io/xcm-docs/.
While that's fine, it's not in line with the work being done in the
polkadot-sdk docs.

# Main addition

This PR aims to fix that by bringing the docs back to this repo.
This does not have all the information currently present in the mdbook
xcm-docs but aims to be a good chunk of it and fully replace it over
time.

I also added the sections `guides` and `cookbook` which will be very
useful for users wanting to get into XCM.
For now I only added one example to the cookbook, but have ideas for
guides and more examples.
Having this docs be in rust docs is very useful for the cookbook.

# TODO

- [x] Use `FungibleAdapter`
- [x] Improve and relocate mock message queue
- [x] Fix license issue. Why does docs/sdk/ not have this problem? (Just
added the licenses)

# Next steps

- More examples in the cookbook
- End-to-end XCM guide with zombienet testing

---------

Co-authored-by: command-bot <>
Co-authored-by: joe petrowski <[email protected]>
  • Loading branch information
2 people authored and liuchengxu committed Jun 19, 2024
1 parent ac39b97 commit 73482bf
Show file tree
Hide file tree
Showing 26 changed files with 1,381 additions and 48 deletions.
62 changes: 59 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ members = [
"polkadot/utils/generate-bags",
"polkadot/utils/remote-ext-tests/bags-list",
"polkadot/xcm",
"polkadot/xcm/docs",
"polkadot/xcm/pallet-xcm",
"polkadot/xcm/pallet-xcm-benchmarks",
"polkadot/xcm/procedural",
Expand Down
39 changes: 39 additions & 0 deletions polkadot/xcm/docs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
[package]
name = "xcm-docs"
description = "Documentation and guides for XCM"
version = "0.1.0"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
repository.workspace = true
authors.workspace = true
edition.workspace = true
publish = false

[dependencies]
# For XCM stuff
xcm = { path = "../../xcm", package = "staging-xcm" }
xcm-executor = { path = "../../xcm/xcm-executor", package = "staging-xcm-executor" }
xcm-builder = { path = "../../xcm/xcm-builder", package = "staging-xcm-builder" }
xcm-simulator = { path = "../../xcm/xcm-simulator" }
pallet-xcm = { path = "../../xcm/pallet-xcm" }

# For building FRAME runtimes
frame = { package = "polkadot-sdk-frame", path = "../../../substrate/frame", features = ["experimental", "runtime"] }
codec = { package = "parity-scale-codec", version = "3.6.9" }
scale-info = { version = "2.6.0", default-features = false }
polkadot-parachain-primitives = { path = "../../../polkadot/parachain" }
polkadot-runtime-parachains = { path = "../../../polkadot/runtime/parachains" }
polkadot-primitives = { path = "../../../polkadot/primitives" }
sp-runtime = { path = "../../../substrate/primitives/runtime" }
sp-std = { path = "../../../substrate/primitives/std" }
sp-io = { path = "../../../substrate/primitives/io" }

# Some pallets
pallet-message-queue = { path = "../../../substrate/frame/message-queue" }
pallet-balances = { path = "../../../substrate/frame/balances" }

# For building docs
simple-mermaid = { git = "https://github.com/kianenigma/simple-mermaid.git", branch = "main" }
docify = "0.2.6"

[dev-dependencies]
test-log = "0.2.14"
9 changes: 9 additions & 0 deletions polkadot/xcm/docs/mermaid/location_hierarchy.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
flowchart
relay[Relaychain] --> paraA["Parachain(1000)"]
relay --> paraB["Parachain(2000)"]

paraA --> pallet[Pallet]
pallet --> indexA[Index 1]
pallet --> indexB[Index 2]

paraA --> account[Account]
4 changes: 4 additions & 0 deletions polkadot/xcm/docs/mermaid/structure.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
flowchart
docs[xcm_docs] --> fundamentals
docs --> guides
docs --> cookbook
6 changes: 6 additions & 0 deletions polkadot/xcm/docs/mermaid/transport_protocols.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
flowchart
relay[Relaychain] --"DMP"--> paraA["Parachain(2000)"]
relay --"DMP"--> paraB["Parachain(2001)"]

paraA --"UMP"--> relay
paraB --"UMP"--> relay
3 changes: 3 additions & 0 deletions polkadot/xcm/docs/mermaid/universal_location.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
flowchart
universe[Universal Location] --> polkadot[Polkadot]
universe --> ethereum[Ethereum]
6 changes: 6 additions & 0 deletions polkadot/xcm/docs/mermaid/usdt_location.mmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
flowchart
relay[Polkadot] --> assetHub["Asset Hub"]
relay --> anotherPara["Another parachain"]

assetHub --> assetsPallet["Assets Pallet"]
assetsPallet --> usdt[1984]
27 changes: 27 additions & 0 deletions polkadot/xcm/docs/src/cookbook/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Copyright Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! # XCM Cookbook
//!
//! A collection of XCM recipes.
//!
//! Each recipe is tested and explains all the code necessary to run it -- they're not just snippets
//! to copy and paste.
/// Configuring a parachain that only uses the Relay Chain native token.
/// In the case of Polkadot, this recipe will show you how to launch a parachain with no native
/// token -- dealing only on DOT.
pub mod relay_token_transactor;
51 changes: 51 additions & 0 deletions polkadot/xcm/docs/src/cookbook/relay_token_transactor/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! # Relay Asset Transactor
//!
//! This example shows how to configure a parachain to only deal with the Relay Chain token.
//!
//! The first step is using the [`xcm_builder::FungibleAdapter`] to create an `AssetTransactor` that
//! can handle the relay chain token.
#![doc = docify::embed!("src/cookbook/relay_token_transactor/parachain/xcm_config.rs", asset_transactor)]
//!
//! The second step is to configure `IsReserve` to recognize the relay chain as a reserve for its
//! own asset.
//! With this, you'll be able to easily mint a derivative asset, backed one-to-one from the Relay
//! Chain, by using the xcm pallet's `transfer_assets` extrinsic.
//!
//! The `IsReserve` type takes a type that implements `ContainsPair<MultiAsset, MultiLocation>`.
//! In this case, we want a type that contains the pair `(relay_chain_native_token, relay_chain)`.
#![doc = docify::embed!("src/cookbook/relay_token_transactor/parachain/xcm_config.rs", is_reserve)]
//!
//! With this setup, we are able to do a reserve asset transfer to and from the parachain and relay
//! chain.
#![doc = docify::embed!("src/cookbook/relay_token_transactor/tests.rs", reserve_asset_transfers_work)]
//!
//! For the rest of the code, be sure to check the contents of this module.
/// The parachain runtime for this example
pub mod parachain;

/// The relay chain runtime for this example.
pub mod relay_chain;

/// The network for this example.
pub mod network;

/// Tests for this example.
#[cfg(test)]
pub mod tests;
90 changes: 90 additions & 0 deletions polkadot/xcm/docs/src/cookbook/relay_token_transactor/network.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright Parity Technologies (UK) Ltd.
// This file is part of Polkadot.

// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.

//! Mock network
use frame::deps::{
frame_system,
sp_io::TestExternalities,
sp_runtime::{AccountId32, BuildStorage},
};
use xcm_simulator::{decl_test_network, decl_test_parachain, decl_test_relay_chain, TestExt};

use super::{parachain, relay_chain};

pub const ALICE: AccountId32 = AccountId32::new([0u8; 32]);
pub const BOB: AccountId32 = AccountId32::new([1u8; 32]);
pub const UNITS: u64 = 10_000_000_000;
pub const CENTS: u64 = 100_000_000;
pub const INITIAL_BALANCE: u64 = UNITS;

decl_test_parachain! {
pub struct ParaA {
Runtime = parachain::Runtime,
XcmpMessageHandler = parachain::MessageQueue,
DmpMessageHandler = parachain::MessageQueue,
new_ext = para_ext(),
}
}

decl_test_relay_chain! {
pub struct Relay {
Runtime = relay_chain::Runtime,
RuntimeCall = relay_chain::RuntimeCall,
RuntimeEvent = relay_chain::RuntimeEvent,
XcmConfig = relay_chain::XcmConfig,
MessageQueue = relay_chain::MessageQueue,
System = relay_chain::System,
new_ext = relay_ext(),
}
}

decl_test_network! {
pub struct MockNet {
relay_chain = Relay,
parachains = vec![
(2222, ParaA),
],
}
}

pub fn para_ext() -> TestExternalities {
use parachain::{MessageQueue, Runtime, System};

let t = frame_system::GenesisConfig::<Runtime>::default().build_storage().unwrap();
let mut ext = frame::deps::sp_io::TestExternalities::new(t);
ext.execute_with(|| {
System::set_block_number(1);
MessageQueue::set_para_id(2222.into());
});
ext
}

pub fn relay_ext() -> TestExternalities {
use relay_chain::{Runtime, System};

let mut t = frame_system::GenesisConfig::<Runtime>::default().build_storage().unwrap();

pallet_balances::GenesisConfig::<Runtime> { balances: vec![(ALICE, INITIAL_BALANCE)] }
.assimilate_storage(&mut t)
.unwrap();

let mut ext = TestExternalities::new(t);
ext.execute_with(|| {
System::set_block_number(1);
});
ext
}
Loading

0 comments on commit 73482bf

Please sign in to comment.