Skip to content

Commit eca1052

Browse files
authored
Update the pallet guide in sdk-docs (#4735)
After using this tutorial in PBA, there was a few areas to improve it. Moreover, I have: - Improve `your_first_pallet`, link it in README, improve the parent `guide` section. - Updated the templates page, in light of recent efforts related to in #3155 - Added small ref docs about metadata, completed the one about native runtime, added one about host functions. - Remove a lot of unfinished stuff from sdk-docs - update diagram for `Hooks`
1 parent c4aa2ab commit eca1052

23 files changed

+302
-160
lines changed

Cargo.lock

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

README.md

+9-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@ forks](https://img.shields.io/github/forks/paritytech/polkadot-sdk)
2424
## 📚 Documentation
2525

2626
* [🦀 rust-docs](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/index.html)
27-
* [Introduction](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/index.html)
28-
to each component of the Polkadot SDK: Substrate, FRAME, Cumulus, and XCM
27+
* [Introduction](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/index.html)
28+
to each component of the Polkadot SDK: Substrate, FRAME, Cumulus, and XCM
29+
* [Guides](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/guides/index.html),
30+
namely how to build your first FRAME pallet.
31+
* [Templates](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/templates/index.html)
32+
for starting a new project.
2933
* Other Resources:
3034
* [Polkadot Wiki -> Build](https://wiki.polkadot.network/docs/build-guide)
3135

@@ -39,6 +43,9 @@ The Polkadot-SDK has two release channels: `stable` and `nightly`. Production so
3943
only use `stable`. `nightly` is meant for tinkerers to try out the latest features. The detailed
4044
release process is described in [RELEASE.md](docs/RELEASE.md).
4145

46+
You can use [`psvm`](https://github.com/paritytech/psvm) to manage your Polkadot-SDK dependency
47+
versions in downstream projects.
48+
4249
### 😌 Stable
4350

4451
`stable` releases have a support duration of **three months**. In this period, the release will not

docs/mermaid/IA.mmd

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
flowchart
22
parity[paritytech.github.io] --> devhub[polkadot_sdk_docs]
3-
polkadot[polkadot.network] --> devhub[polkadot_sdk_docs]
3+
polkadot_network[polkadot.network] --> devhub[polkadot_sdk_docs]
44

55
devhub --> polkadot_sdk
66
devhub --> reference_docs
@@ -9,5 +9,5 @@ flowchart
99
polkadot_sdk --> substrate
1010
polkadot_sdk --> frame
1111
polkadot_sdk --> cumulus
12-
polkadot_sdk --> polkadot
12+
polkadot_sdk --> polkadot[polkadot node]
1313
polkadot_sdk --> xcm

docs/sdk/Cargo.toml

+10-6
Original file line numberDiff line numberDiff line change
@@ -83,27 +83,31 @@ pallet-democracy = { path = "../../substrate/frame/democracy" }
8383
pallet-uniques = { path = "../../substrate/frame/uniques" }
8484
pallet-nfts = { path = "../../substrate/frame/nfts" }
8585
pallet-scheduler = { path = "../../substrate/frame/scheduler" }
86+
pallet-referenda = { path = "../../substrate/frame/referenda" }
87+
pallet-broker = { path = "../../substrate/frame/broker" }
88+
pallet-babe = { path = "../../substrate/frame/babe" }
8689

8790
# Primitives
8891
sp-io = { path = "../../substrate/primitives/io" }
92+
sp-runtime-interface = { path = "../../substrate/primitives/runtime-interface" }
8993
sp-api = { path = "../../substrate/primitives/api" }
9094
sp-core = { path = "../../substrate/primitives/core" }
9195
sp-keyring = { path = "../../substrate/primitives/keyring" }
9296
sp-runtime = { path = "../../substrate/primitives/runtime" }
9397
sp-arithmetic = { path = "../../substrate/primitives/arithmetic" }
9498
sp-genesis-builder = { path = "../../substrate/primitives/genesis-builder" }
95-
96-
# Misc pallet dependencies
97-
pallet-referenda = { path = "../../substrate/frame/referenda" }
98-
pallet-broker = { path = "../../substrate/frame/broker" }
99-
pallet-babe = { path = "../../substrate/frame/babe" }
100-
10199
sp-offchain = { path = "../../substrate/primitives/offchain" }
102100
sp-version = { path = "../../substrate/primitives/version" }
103101

102+
104103
# XCM
105104
xcm = { package = "staging-xcm", path = "../../polkadot/xcm" }
106105
xcm-docs = { path = "../../polkadot/xcm/docs" }
107106

108107
# runtime guides
109108
chain-spec-guide-runtime = { path = "./src/reference_docs/chain_spec_runtime" }
109+
110+
# Templates
111+
minimal-template-runtime = { path = "../../templates/minimal/runtime" }
112+
solochain-template-runtime = { path = "../../templates/solochain/runtime" }
113+
parachain-template-runtime = { path = "../../templates/parachain/runtime" }

docs/sdk/src/guides/mod.rs

+17-8
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
//! # Polkadot SDK Docs Guides
22
//!
3-
//! This crate contains a collection of guides that are foundational to the developers of
4-
//! Polkadot SDK. They are common user-journeys that are traversed in the Polkadot ecosystem.
3+
//! This crate contains a collection of guides that are foundational to the developers of Polkadot
4+
//! SDK. They are common user-journeys that are traversed in the Polkadot ecosystem.
5+
//!
6+
//! 1. [`crate::guides::your_first_pallet`] is your starting point with Polkadot SDK. It contains
7+
//! the basics of
8+
//! building a simple crypto currency with FRAME.
9+
//! 2. [`crate::guides::your_first_runtime`] is the next step in your journey. It contains the
10+
//! basics of building a runtime that contains this pallet, plus a few common pallets from FRAME.
11+
//!
12+
//!
13+
//! Other guides are related to other miscellaneous topics and are listed as modules below.
514
615
/// Write your first simple pallet, learning the most most basic features of FRAME along the way.
716
pub mod your_first_pallet;
@@ -11,18 +20,18 @@ pub mod your_first_pallet;
1120
pub mod your_first_runtime;
1221

1322
/// Running the given runtime with a node. No specific consensus mechanism is used at this stage.
14-
pub mod your_first_node;
15-
16-
/// How to change the consensus engine of both the node and the runtime.
17-
pub mod changing_consensus;
23+
// TODO
24+
// pub mod your_first_node;
1825

1926
/// How to enhance a given runtime and node to be cumulus-enabled, run it as a parachain and connect
2027
/// it to a relay-chain.
21-
pub mod cumulus_enabled_parachain;
28+
// TODO
29+
// pub mod cumulus_enabled_parachain;
2230

2331
/// How to make a given runtime XCM-enabled, capable of sending messages (`Transact`) between itself
2432
/// and the relay chain to which it is connected.
25-
pub mod xcm_enabled_parachain;
33+
// TODO
34+
// pub mod xcm_enabled_parachain;
2635

2736
/// How to enable storage weight reclaiming in a parachain node and runtime.
2837
pub mod enable_pov_reclaim;

docs/sdk/src/guides/your_first_pallet/mod.rs

+70-39
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,43 @@
1414
//! > FRAME-based runtimes use various techniques to re-use a currency pallet instead of writing
1515
//! > one. Further advanced FRAME related topics are discussed in [`crate::reference_docs`].
1616
//!
17-
//! ## Topics Covered
17+
//! ## Writing Your First Pallet
1818
//!
19-
//! The following FRAME topics are covered in this guide:
19+
//! To get started, use one of the templates mentioned in [`crate::polkadot_sdk::templates`]. We
20+
//! recommend using the `polkadot-sdk-minimal-template`. You might need to change small parts of
21+
//! this guide, namely the crate/package names, based on which tutorial you use.
2022
//!
21-
//! - [Storage](frame::pallet_macros::storage)
22-
//! - [Call](frame::pallet_macros::call)
23-
//! - [Event](frame::pallet_macros::event)
24-
//! - [Error](frame::pallet_macros::error)
25-
//! - Basics of testing a pallet
26-
//! - [Constructing a runtime](frame::runtime::prelude::construct_runtime)
27-
//!
28-
//! ## Writing Your First Pallet
23+
//! > Be aware that you can read the entire source code backing this tutorial by clicking on the
24+
//! > [`source`](./mod.rs.html) button at the top right of the page.
2925
//!
3026
//! You should have studied the following modules as a prelude to this guide:
3127
//!
3228
//! - [`crate::reference_docs::blockchain_state_machines`]
3329
//! - [`crate::reference_docs::trait_based_programming`]
3430
//! - [`crate::polkadot_sdk::frame_runtime`]
3531
//!
32+
//! ## Topics Covered
33+
//!
34+
//! The following FRAME topics are covered in this guide:
35+
//!
36+
//! - [`pallet::storage`]
37+
//! - [`pallet::call`]
38+
//! - [`pallet::event`]
39+
//! - [`pallet::error`]
40+
//! - Basics of testing a pallet
41+
//! - [Constructing a runtime](frame::runtime::prelude::construct_runtime)
42+
//!
3643
//! ### Shell Pallet
3744
//!
3845
//! Consider the following as a "shell pallet". We continue building the rest of this pallet based
3946
//! on this template.
4047
//!
41-
//! [`pallet::config`](frame::pallet_macros::config) and
42-
//! [`pallet::pallet`](frame::pallet_macros::pallet) are both mandatory parts of any pallet. Refer
43-
//! to the documentation of each to get an overview of what they do.
48+
//! [`pallet::config`] and [`pallet::pallet`] are both mandatory parts of any pallet. Refer to the
49+
//! documentation of each to get an overview of what they do.
4450
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", shell_pallet)]
4551
//!
52+
//! All of the code that follows in this guide should live inside of the `mod pallet`.
53+
//!
4654
//! ### Storage
4755
//!
4856
//! First, we will need to create two onchain storage declarations.
@@ -55,15 +63,14 @@
5563
//! > generic bounded type in the `Config` trait, and then specify it in the implementation.
5664
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Balance)]
5765
//!
58-
//! The definition of these two storage items, based on [`frame::pallet_macros::storage`] details,
59-
//! is as follows:
66+
//! The definition of these two storage items, based on [`pallet::storage`] details, is as follows:
6067
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", TotalIssuance)]
6168
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Balances)]
6269
//!
6370
//! ### Dispatchables
6471
//!
65-
//! Next, we will define the dispatchable functions. As per [`frame::pallet_macros::call`], these
66-
//! will be defined as normal `fn`s attached to `struct Pallet`.
72+
//! Next, we will define the dispatchable functions. As per [`pallet::call`], these will be defined
73+
//! as normal `fn`s attached to `struct Pallet`.
6774
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", impl_pallet)]
6875
//!
6976
//! The logic of the functions is self-explanatory. Instead, we will focus on the FRAME-related
@@ -79,7 +86,6 @@
7986
//! was signed by `who`.
8087
#![doc = docify::embed!("../../substrate/frame/system/src/lib.rs", ensure_signed)]
8188
//!
82-
//!
8389
//! - Where does `mutate`, `get` and `insert` and other storage APIs come from? All of them are
8490
//! explained in the corresponding `type`, for example, for `Balances::<T>::insert`, you can look
8591
//! into [`frame::prelude::StorageMap::insert`].
@@ -95,8 +101,7 @@
95101
//!
96102
//! - Why are all `get` and `mutate` functions returning an `Option`? This is the default behavior
97103
//! of FRAME storage APIs. You can learn more about how to override this by looking into
98-
//! [`frame::pallet_macros::storage`], and
99-
//! [`frame::prelude::ValueQuery`]/[`frame::prelude::OptionQuery`]
104+
//! [`pallet::storage`], and [`frame::prelude::ValueQuery`]/[`frame::prelude::OptionQuery`]
100105
//!
101106
//! ### Improving Errors
102107
//!
@@ -116,6 +121,25 @@
116121
//!
117122
//! ### Your First (Test) Runtime
118123
//!
124+
//! The typical testing code of a pallet lives in a module that imports some preludes useful for
125+
//! testing, similar to:
126+
//!
127+
//! ```
128+
//! pub mod pallet {
129+
//! // snip -- actually pallet code.
130+
//! }
131+
//!
132+
//! #[cfg(test)]
133+
//! mod tests {
134+
//! // bring in the testing prelude of frame
135+
//! use frame::testing_prelude::*;
136+
//! // bring in all pallet items
137+
//! use super::pallet::*;
138+
//!
139+
//! // snip -- rest of the testing code.
140+
//! }
141+
//! ```
142+
//!
119143
//! Next, we create a "test runtime" in order to test our pallet. Recall from
120144
//! [`crate::polkadot_sdk::frame_runtime`] that a runtime is a collection of pallets, expressed
121145
//! through [`frame::runtime::prelude::construct_runtime`]. All runtimes also have to include
@@ -166,7 +190,6 @@
166190
//! As noted above, the `T::AccountId` is now `u64`. Moreover, `Runtime` is replacing `<T: Config>`.
167191
//! This is why for example you see `Balances::<Runtime>::get(..)`. Finally, notice that the
168192
//! dispatchables are simply functions that can be called on top of the `Pallet` struct.
169-
// TODO: hard to explain exactly `RuntimeOrigin::signed(ALICE)` at this point.
170193
//!
171194
//! Congratulations! You have written your first pallet and tested it! Next, we learn a few optional
172195
//! steps to improve our pallet.
@@ -236,8 +259,7 @@
236259
//! by one character. FRAME errors are exactly a solution to maintain readability, whilst fixing
237260
//! the drawbacks mentioned. In short, we use an enum to represent different variants of our
238261
//! error. These variants are then mapped in an efficient way (using only `u8` indices) to
239-
//! [`sp_runtime::DispatchError::Module`]. Read more about this in
240-
//! [`frame::pallet_macros::error`].
262+
//! [`sp_runtime::DispatchError::Module`]. Read more about this in [`pallet::error`].
241263
//!
242264
//! - **Event**: Events are akin to the return type of dispatchables. They are mostly data blobs
243265
//! emitted by the runtime to let outside world know what is happening inside the pallet. Since
@@ -246,20 +268,16 @@
246268
//! use passive tense for event names (eg. `SomethingHappened`). This allows other sub-systems or
247269
//! external parties (eg. a light-node, a DApp) to listen to particular events happening, without
248270
//! needing to re-execute the whole state transition function.
249-
// TODO: both need to be improved a lot at the pallet-macro rust-doc level. Also my explanation
250-
// of event is probably not the best.
251271
//!
252272
//! With the explanation out of the way, let's see how these components can be added. Both follow a
253-
//! fairly familiar syntax: normal Rust enums, with extra
254-
//! [`#[frame::event]`](frame::pallet_macros::event) and
255-
//! [`#[frame::error]`](frame::pallet_macros::error) attributes attached.
273+
//! fairly familiar syntax: normal Rust enums, with extra [`pallet::event`] and [`pallet::error`]
274+
//! attributes attached.
256275
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Event)]
257276
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Error)]
258277
//!
259-
//! One slightly custom part of this is the [`#[pallet::generate_deposit(pub(super) fn
260-
//! deposit_event)]`](frame::pallet_macros::generate_deposit) part. Without going into too
261-
//! much detail, in order for a pallet to emit events to the rest of the system, it needs to do two
262-
//! things:
278+
//! One slightly custom part of this is the [`pallet::generate_deposit`] part. Without going into
279+
//! too much detail, in order for a pallet to emit events to the rest of the system, it needs to do
280+
//! two things:
263281
//!
264282
//! 1. Declare a type in its `Config` that refers to the overarching event type of the runtime. In
265283
//! short, by doing this, the pallet is expressing an important bound: `type RuntimeEvent:
@@ -268,8 +286,8 @@
268286
//! store it where needed.
269287
//!
270288
//! 2. But, doing this conversion and storing is too much to expect each pallet to define. FRAME
271-
//! provides a default way of storing events, and this is what
272-
//! [`pallet::generate_deposit`](frame::pallet_macros::generate_deposit) is doing.
289+
//! provides a default way of storing events, and this is what [`pallet::generate_deposit`] is
290+
//! doing.
273291
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", config_v2)]
274292
//!
275293
//! > These `Runtime*` types are better explained in
@@ -297,10 +315,17 @@
297315
//! - [`crate::reference_docs::defensive_programming`].
298316
//! - [`crate::reference_docs::frame_origin`].
299317
//! - [`crate::reference_docs::frame_runtime_types`].
300-
//! - The pallet we wrote in this guide was using `dev_mode`, learn more in
301-
//! [`frame::pallet_macros::config`].
318+
//! - The pallet we wrote in this guide was using `dev_mode`, learn more in [`pallet::config`].
302319
//! - Learn more about the individual pallet items/macros, such as event and errors and call, in
303320
//! [`frame::pallet_macros`].
321+
//!
322+
//! [`pallet::storage`]: ../../../frame_support/pallet_macros/attr.config.html
323+
//! [`pallet::call`]: ../../../frame_support/pallet_macros/attr.call.html
324+
//! [`pallet::event`]: ../../../frame_support/pallet_macros/attr.event.html
325+
//! [`pallet::error`]: ../../../frame_support/pallet_macros/attr.error.html
326+
//! [`pallet::pallet`]: ../../../frame_support/pallet_macros/attr.pallet.html
327+
//! [`pallet::config`]: ../../../frame_support/pallet_macros/attr.config.html
328+
//! [`pallet::generate_deposit`]: ../../../frame_support/pallet_macros/attr.generate_deposit.html
304329
305330
#[docify::export]
306331
#[frame::pallet(dev_mode)]
@@ -418,16 +443,22 @@ pub mod pallet {
418443
#[cfg(any(test, doc))]
419444
pub(crate) mod tests {
420445
use crate::guides::your_first_pallet::pallet::*;
446+
447+
#[docify::export(testing_prelude)]
421448
use frame::testing_prelude::*;
422-
const ALICE: u64 = 1;
423-
const BOB: u64 = 2;
424-
const CHARLIE: u64 = 3;
449+
450+
pub(crate) const ALICE: u64 = 1;
451+
pub(crate) const BOB: u64 = 2;
452+
pub(crate) const CHARLIE: u64 = 3;
425453

426454
#[docify::export]
455+
// This runtime is only used for testing, so it should be somewhere like `#[cfg(test)] mod
456+
// tests { .. }`
427457
mod runtime {
428458
use super::*;
429459
// we need to reference our `mod pallet` as an identifier to pass to
430460
// `construct_runtime`.
461+
// YOU HAVE TO CHANGE THIS LINE BASED ON YOUR TEMPLATE
431462
use crate::guides::your_first_pallet::pallet as pallet_currency;
432463

433464
construct_runtime!(
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
//! # Your first Runtime
2+
//!
3+
//! 🚧 <https://github.com/paritytech/polkadot-sdk/pull/3946>

0 commit comments

Comments
 (0)