Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update the pallet guide in sdk-docs #4735

Merged
merged 7 commits into from
Jun 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo.lock

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

15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ forks](https://img.shields.io/github/forks/paritytech/polkadot-sdk)
## 📚 Documentation

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

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

You can use [`psvm`](https://github.com/paritytech/psvm) to manage your Polkadot-SDK dependency
versions in downstream projects.

### 😌 Stable

`stable` releases have a support duration of **three months**. In this period, the release will not
Expand Down Expand Up @@ -81,7 +88,3 @@ fellowship, this separation, the RFC process
This repository is the amalgamation of 3 separate repositories that used to make up Polkadot SDK,
namely Substrate, Polkadot and Cumulus. Read more about the merge and its history
[here](https://polkadot-public.notion.site/Polkadot-SDK-FAQ-fbc4cecc2c46443fb37b9eeec2f0d85f).

## Other useful resources and tooling

* A simple tool to manage and update the Polkadot SDK dependencies (https://github.com/paritytech/psvm)
4 changes: 2 additions & 2 deletions docs/mermaid/IA.mmd
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
flowchart
parity[paritytech.github.io] --> devhub[polkadot_sdk_docs]
polkadot[polkadot.network] --> devhub[polkadot_sdk_docs]
polkadot_network[polkadot.network] --> devhub[polkadot_sdk_docs]

devhub --> polkadot_sdk
devhub --> reference_docs
Expand All @@ -9,5 +9,5 @@ flowchart
polkadot_sdk --> substrate
polkadot_sdk --> frame
polkadot_sdk --> cumulus
polkadot_sdk --> polkadot
polkadot_sdk --> polkadot[polkadot node]
polkadot_sdk --> xcm
16 changes: 10 additions & 6 deletions docs/sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,27 +83,31 @@ pallet-democracy = { path = "../../substrate/frame/democracy" }
pallet-uniques = { path = "../../substrate/frame/uniques" }
pallet-nfts = { path = "../../substrate/frame/nfts" }
pallet-scheduler = { path = "../../substrate/frame/scheduler" }
pallet-referenda = { path = "../../substrate/frame/referenda" }
pallet-broker = { path = "../../substrate/frame/broker" }
pallet-babe = { path = "../../substrate/frame/babe" }

# Primitives
sp-io = { path = "../../substrate/primitives/io" }
sp-runtime-interface = { path = "../../substrate/primitives/runtime-interface" }
sp-api = { path = "../../substrate/primitives/api" }
sp-core = { path = "../../substrate/primitives/core" }
sp-keyring = { path = "../../substrate/primitives/keyring" }
sp-runtime = { path = "../../substrate/primitives/runtime" }
sp-arithmetic = { path = "../../substrate/primitives/arithmetic" }
sp-genesis-builder = { path = "../../substrate/primitives/genesis-builder" }

# Misc pallet dependencies
pallet-referenda = { path = "../../substrate/frame/referenda" }
pallet-broker = { path = "../../substrate/frame/broker" }
pallet-babe = { path = "../../substrate/frame/babe" }

sp-offchain = { path = "../../substrate/primitives/offchain" }
sp-version = { path = "../../substrate/primitives/version" }


# XCM
xcm = { package = "staging-xcm", path = "../../polkadot/xcm" }
xcm-docs = { path = "../../polkadot/xcm/docs" }

# runtime guides
chain-spec-guide-runtime = { path = "./src/reference_docs/chain_spec_runtime" }

# Templates
minimal-template-runtime = { path = "../../templates/minimal/runtime" }
solochain-template-runtime = { path = "../../templates/solochain/runtime" }
parachain-template-runtime = { path = "../../templates/parachain/runtime" }
25 changes: 17 additions & 8 deletions docs/sdk/src/guides/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
//! # Polkadot SDK Docs Guides
//!
//! This crate contains a collection of guides that are foundational to the developers of
//! Polkadot SDK. They are common user-journeys that are traversed in the Polkadot ecosystem.
//! This crate contains a collection of guides that are foundational to the developers of Polkadot
//! SDK. They are common user-journeys that are traversed in the Polkadot ecosystem.
//!
//! 1. [`crate::guides::your_first_pallet`] is your starting point with Polkadot SDK. It contains
//! the basics of
//! building a simple crypto currency with FRAME.
//! 2. [`crate::guides::your_first_runtime`] is the next step in your journey. It contains the
//! basics of building a runtime that contains this pallet, plus a few common pallets from FRAME.
//!
//!
//! Other guides are related to other miscellaneous topics and are listed as modules below.

/// Write your first simple pallet, learning the most most basic features of FRAME along the way.
pub mod your_first_pallet;
Expand All @@ -11,18 +20,18 @@ pub mod your_first_pallet;
pub mod your_first_runtime;

/// Running the given runtime with a node. No specific consensus mechanism is used at this stage.
pub mod your_first_node;

/// How to change the consensus engine of both the node and the runtime.
pub mod changing_consensus;
// TODO
// pub mod your_first_node;

/// How to enhance a given runtime and node to be cumulus-enabled, run it as a parachain and connect
/// it to a relay-chain.
pub mod cumulus_enabled_parachain;
// TODO
// pub mod cumulus_enabled_parachain;

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

/// How to enable storage weight reclaiming in a parachain node and runtime.
pub mod enable_pov_reclaim;
Expand Down
109 changes: 70 additions & 39 deletions docs/sdk/src/guides/your_first_pallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,35 +14,43 @@
//! > FRAME-based runtimes use various techniques to re-use a currency pallet instead of writing
//! > one. Further advanced FRAME related topics are discussed in [`crate::reference_docs`].
//!
//! ## Topics Covered
//! ## Writing Your First Pallet
//!
//! The following FRAME topics are covered in this guide:
//! To get started, use one of the templates mentioned in [`crate::polkadot_sdk::templates`]. We
//! recommend using the `polkadot-sdk-minimal-template`. You might need to change small parts of
//! this guide, namely the crate/package names, based on which tutorial you use.
//!
//! - [Storage](frame::pallet_macros::storage)
//! - [Call](frame::pallet_macros::call)
//! - [Event](frame::pallet_macros::event)
//! - [Error](frame::pallet_macros::error)
//! - Basics of testing a pallet
//! - [Constructing a runtime](frame::runtime::prelude::construct_runtime)
//!
//! ## Writing Your First Pallet
//! > Be aware that you can read the entire source code backing this tutorial by clicking on the
//! > [`source`](./mod.rs.html) button at the top right of the page.
//!
//! You should have studied the following modules as a prelude to this guide:
//!
//! - [`crate::reference_docs::blockchain_state_machines`]
//! - [`crate::reference_docs::trait_based_programming`]
//! - [`crate::polkadot_sdk::frame_runtime`]
//!
//! ## Topics Covered
//!
//! The following FRAME topics are covered in this guide:
//!
//! - [`pallet::storage`]
//! - [`pallet::call`]
//! - [`pallet::event`]
//! - [`pallet::error`]
//! - Basics of testing a pallet
//! - [Constructing a runtime](frame::runtime::prelude::construct_runtime)
//!
//! ### Shell Pallet
//!
//! Consider the following as a "shell pallet". We continue building the rest of this pallet based
//! on this template.
//!
//! [`pallet::config`](frame::pallet_macros::config) and
//! [`pallet::pallet`](frame::pallet_macros::pallet) are both mandatory parts of any pallet. Refer
//! to the documentation of each to get an overview of what they do.
//! [`pallet::config`] and [`pallet::pallet`] are both mandatory parts of any pallet. Refer to the
//! documentation of each to get an overview of what they do.
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", shell_pallet)]
//!
//! All of the code that follows in this guide should live inside of the `mod pallet`.
//!
//! ### Storage
//!
//! First, we will need to create two onchain storage declarations.
Expand All @@ -55,15 +63,14 @@
//! > generic bounded type in the `Config` trait, and then specify it in the implementation.
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Balance)]
//!
//! The definition of these two storage items, based on [`frame::pallet_macros::storage`] details,
//! is as follows:
//! The definition of these two storage items, based on [`pallet::storage`] details, is as follows:
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", TotalIssuance)]
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Balances)]
//!
//! ### Dispatchables
//!
//! Next, we will define the dispatchable functions. As per [`frame::pallet_macros::call`], these
//! will be defined as normal `fn`s attached to `struct Pallet`.
//! Next, we will define the dispatchable functions. As per [`pallet::call`], these will be defined
//! as normal `fn`s attached to `struct Pallet`.
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", impl_pallet)]
//!
//! The logic of the functions is self-explanatory. Instead, we will focus on the FRAME-related
Expand All @@ -79,7 +86,6 @@
//! was signed by `who`.
#![doc = docify::embed!("../../substrate/frame/system/src/lib.rs", ensure_signed)]
//!
//!
//! - Where does `mutate`, `get` and `insert` and other storage APIs come from? All of them are
//! explained in the corresponding `type`, for example, for `Balances::<T>::insert`, you can look
//! into [`frame::prelude::StorageMap::insert`].
Expand All @@ -95,8 +101,7 @@
//!
//! - Why are all `get` and `mutate` functions returning an `Option`? This is the default behavior
//! of FRAME storage APIs. You can learn more about how to override this by looking into
//! [`frame::pallet_macros::storage`], and
//! [`frame::prelude::ValueQuery`]/[`frame::prelude::OptionQuery`]
//! [`pallet::storage`], and [`frame::prelude::ValueQuery`]/[`frame::prelude::OptionQuery`]
//!
//! ### Improving Errors
//!
Expand All @@ -116,6 +121,25 @@
//!
//! ### Your First (Test) Runtime
//!
//! The typical testing code of a pallet lives in a module that imports some preludes useful for
//! testing, similar to:
//!
//! ```
//! pub mod pallet {
//! // snip -- actually pallet code.
//! }
//!
//! #[cfg(test)]
//! mod tests {
//! // bring in the testing prelude of frame
//! use frame::testing_prelude::*;
//! // bring in all pallet items
//! use super::pallet::*;
//!
//! // snip -- rest of the testing code.
//! }
//! ```
//!
//! Next, we create a "test runtime" in order to test our pallet. Recall from
//! [`crate::polkadot_sdk::frame_runtime`] that a runtime is a collection of pallets, expressed
//! through [`frame::runtime::prelude::construct_runtime`]. All runtimes also have to include
Expand Down Expand Up @@ -166,7 +190,6 @@
//! As noted above, the `T::AccountId` is now `u64`. Moreover, `Runtime` is replacing `<T: Config>`.
//! This is why for example you see `Balances::<Runtime>::get(..)`. Finally, notice that the
//! dispatchables are simply functions that can be called on top of the `Pallet` struct.
// TODO: hard to explain exactly `RuntimeOrigin::signed(ALICE)` at this point.
//!
//! Congratulations! You have written your first pallet and tested it! Next, we learn a few optional
//! steps to improve our pallet.
Expand Down Expand Up @@ -236,8 +259,7 @@
//! by one character. FRAME errors are exactly a solution to maintain readability, whilst fixing
//! the drawbacks mentioned. In short, we use an enum to represent different variants of our
//! error. These variants are then mapped in an efficient way (using only `u8` indices) to
//! [`sp_runtime::DispatchError::Module`]. Read more about this in
//! [`frame::pallet_macros::error`].
//! [`sp_runtime::DispatchError::Module`]. Read more about this in [`pallet::error`].
//!
//! - **Event**: Events are akin to the return type of dispatchables. They are mostly data blobs
//! emitted by the runtime to let outside world know what is happening inside the pallet. Since
Expand All @@ -246,20 +268,16 @@
//! use passive tense for event names (eg. `SomethingHappened`). This allows other sub-systems or
//! external parties (eg. a light-node, a DApp) to listen to particular events happening, without
//! needing to re-execute the whole state transition function.
// TODO: both need to be improved a lot at the pallet-macro rust-doc level. Also my explanation
// of event is probably not the best.
//!
//! With the explanation out of the way, let's see how these components can be added. Both follow a
//! fairly familiar syntax: normal Rust enums, with extra
//! [`#[frame::event]`](frame::pallet_macros::event) and
//! [`#[frame::error]`](frame::pallet_macros::error) attributes attached.
//! fairly familiar syntax: normal Rust enums, with extra [`pallet::event`] and [`pallet::error`]
//! attributes attached.
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Event)]
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", Error)]
//!
//! One slightly custom part of this is the [`#[pallet::generate_deposit(pub(super) fn
//! deposit_event)]`](frame::pallet_macros::generate_deposit) part. Without going into too
//! much detail, in order for a pallet to emit events to the rest of the system, it needs to do two
//! things:
//! One slightly custom part of this is the [`pallet::generate_deposit`] part. Without going into
//! too much detail, in order for a pallet to emit events to the rest of the system, it needs to do
//! two things:
//!
//! 1. Declare a type in its `Config` that refers to the overarching event type of the runtime. In
//! short, by doing this, the pallet is expressing an important bound: `type RuntimeEvent:
Expand All @@ -268,8 +286,8 @@
//! store it where needed.
//!
//! 2. But, doing this conversion and storing is too much to expect each pallet to define. FRAME
//! provides a default way of storing events, and this is what
//! [`pallet::generate_deposit`](frame::pallet_macros::generate_deposit) is doing.
//! provides a default way of storing events, and this is what [`pallet::generate_deposit`] is
//! doing.
#![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", config_v2)]
//!
//! > These `Runtime*` types are better explained in
Expand Down Expand Up @@ -297,10 +315,17 @@
//! - [`crate::reference_docs::defensive_programming`].
//! - [`crate::reference_docs::frame_origin`].
//! - [`crate::reference_docs::frame_runtime_types`].
//! - The pallet we wrote in this guide was using `dev_mode`, learn more in
//! [`frame::pallet_macros::config`].
//! - The pallet we wrote in this guide was using `dev_mode`, learn more in [`pallet::config`].
//! - Learn more about the individual pallet items/macros, such as event and errors and call, in
//! [`frame::pallet_macros`].
//!
//! [`pallet::storage`]: ../../../frame_support/pallet_macros/attr.config.html
//! [`pallet::call`]: ../../../frame_support/pallet_macros/attr.call.html
//! [`pallet::event`]: ../../../frame_support/pallet_macros/attr.event.html
//! [`pallet::error`]: ../../../frame_support/pallet_macros/attr.error.html
//! [`pallet::pallet`]: ../../../frame_support/pallet_macros/attr.pallet.html
//! [`pallet::config`]: ../../../frame_support/pallet_macros/attr.config.html
//! [`pallet::generate_deposit`]: ../../../frame_support/pallet_macros/attr.generate_deposit.html

#[docify::export]
#[frame::pallet(dev_mode)]
Expand Down Expand Up @@ -418,16 +443,22 @@ pub mod pallet {
#[cfg(any(test, doc))]
pub(crate) mod tests {
use crate::guides::your_first_pallet::pallet::*;

#[docify::export(testing_prelude)]
use frame::testing_prelude::*;
const ALICE: u64 = 1;
const BOB: u64 = 2;
const CHARLIE: u64 = 3;

pub(crate) const ALICE: u64 = 1;
pub(crate) const BOB: u64 = 2;
pub(crate) const CHARLIE: u64 = 3;

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

construct_runtime!(
gupnik marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
2 changes: 2 additions & 0 deletions docs/sdk/src/guides/your_first_runtime.rs
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
//! # Your first Runtime
//!
//! 🚧 <https://github.com/paritytech/polkadot-sdk/pull/3946>
Loading
Loading