From 1ffe06c806cbc7a6153a5c126ccd32c0e16b6acd Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 15 Feb 2024 21:31:37 +0000 Subject: [PATCH 01/20] add origin related articles --- Cargo.lock | 19 ++ Cargo.toml | 1 + docs/sdk/Cargo.toml | 20 +- docs/sdk/src/guides/your_first_pallet/mod.rs | 9 +- docs/sdk/src/lib.rs | 2 +- docs/sdk/src/meta_contributing.rs | 2 +- .../src/reference_docs/extrinsic_encoding.rs | 2 +- .../reference_docs/frame_composite_enums.rs | 1 - docs/sdk/src/reference_docs/frame_origin.rs | 275 +++++++++++++++- .../src/reference_docs/frame_runtime_types.rs | 307 ++++++++++++++++++ docs/sdk/src/reference_docs/mod.rs | 8 +- substrate/frame/src/lib.rs | 6 + .../src/construct_runtime/expand/origin.rs | 2 +- substrate/frame/system/src/lib.rs | 1 + 14 files changed, 625 insertions(+), 30 deletions(-) delete mode 100644 docs/sdk/src/reference_docs/frame_composite_enums.rs create mode 100644 docs/sdk/src/reference_docs/frame_runtime_types.rs diff --git a/Cargo.lock b/Cargo.lock index db9a2ca35643..aaadee36a122 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13262,11 +13262,20 @@ dependencies = [ "cumulus-pallet-parachain-system", "docify", "frame", + "frame-system", "kitchensink-runtime", "pallet-aura", + "pallet-authorship", + "pallet-balances", + "pallet-collective", "pallet-default-config-example", + "pallet-democracy", "pallet-examples", + "pallet-multisig", + "pallet-proxy", "pallet-timestamp", + "pallet-transaction-payment", + "pallet-utility", "parity-scale-codec", "sc-cli", "sc-client-db", @@ -13293,6 +13302,16 @@ dependencies = [ "substrate-wasm-builder", ] +[[package]] +name = "polkadot-sdk-docs-runtimes" +version = "0.0.1" +dependencies = [ + "frame", + "parity-scale-codec", + "polkadot-sdk-docs", + "scale-info", +] + [[package]] name = "polkadot-service" version = "7.0.0" diff --git a/Cargo.toml b/Cargo.toml index 8cbfc7a23fed..7395a90f133a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,6 +135,7 @@ members = [ "cumulus/test/service", "cumulus/xcm/xcm-emulator", "docs/sdk", + "docs/sdk/runtimes", "polkadot", "polkadot/cli", "polkadot/core-primitives", diff --git a/docs/sdk/Cargo.toml b/docs/sdk/Cargo.toml index c998a601486a..61e58bc741d2 100644 --- a/docs/sdk/Cargo.toml +++ b/docs/sdk/Cargo.toml @@ -17,7 +17,10 @@ workspace = true # Needed for all FRAME-based code parity-scale-codec = { version = "3.0.0", default-features = false } scale-info = { version = "2.6.0", default-features = false } -frame = { path = "../../substrate/frame", features = ["experimental", "runtime"] } +frame = { path = "../../substrate/frame", features = [ + "experimental", + "runtime", +] } pallet-examples = { path = "../../substrate/frame/examples" } pallet-default-config-example = { path = "../../substrate/frame/examples/default-config" } @@ -52,7 +55,18 @@ cumulus-pallet-parachain-system = { path = "../../cumulus/pallets/parachain-syst ] } parachain-info = { package = "staging-parachain-info", path = "../../cumulus/parachains/pallets/parachain-info" } pallet-aura = { path = "../../substrate/frame/aura", default-features = false } + +# Pallets and FRAME internals pallet-timestamp = { path = "../../substrate/frame/timestamp" } +pallet-balances = { path = "../../substrate/frame/balances" } +pallet-transaction-payment = { path = "../../substrate/frame/transaction-payment" } +pallet-utility = { path = "../../substrate/frame/utility" } +pallet-multisig = { path = "../../substrate/frame/multisig" } +pallet-proxy = { path = "../../substrate/frame/proxy" } +pallet-authorship = { path = "../../substrate/frame/authorship" } +pallet-collective = { path = "../../substrate/frame/collective" } +pallet-democracy = { path = "../../substrate/frame/democracy" } +frame-system = { path = "../../substrate/frame/system" } # Primitives sp-io = { path = "../../substrate/primitives/io" } @@ -61,9 +75,5 @@ sp-core = { path = "../../substrate/primitives/core" } sp-keyring = { path = "../../substrate/primitives/keyring" } sp-runtime = { path = "../../substrate/primitives/runtime" } -[dev-dependencies] -parity-scale-codec = "3.6.5" -scale-info = "2.9.0" - [features] experimental = ["pallet-aura/experimental"] diff --git a/docs/sdk/src/guides/your_first_pallet/mod.rs b/docs/sdk/src/guides/your_first_pallet/mod.rs index 29cdda36ed15..20a8639b2700 100644 --- a/docs/sdk/src/guides/your_first_pallet/mod.rs +++ b/docs/sdk/src/guides/your_first_pallet/mod.rs @@ -128,8 +128,8 @@ //! //! Recall that within our pallet, (almost) all blocks of code are generic over ``. And, //! because `trait Config: frame_system::Config`, we can get access to all items in `Config` (or -//! `frame_system::Config`) using `T::NameOfItem`. This is all within the boundaries of how Rust -//! traits and generics work. If unfamiliar with this pattern, read +//! `frame_system::Config`) using `T::NameOfItem`. This is all within the boundaries of how +//! Rust traits and generics work. If unfamiliar with this pattern, read //! [`crate::reference_docs::trait_based_programming`] before going further. //! //! Crucially, a typical FRAME runtime contains a `struct Runtime`. The main role of this `struct` @@ -270,7 +270,7 @@ #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", config_v2)] //! //! > These `Runtime*` types are better explained in -//! > [`crate::reference_docs::frame_composite_enums`]. +//! > [`crate::reference_docs::frame_runtime_types`]. //! //! Then, we can rewrite the `transfer` dispatchable as such: #![doc = docify::embed!("./src/guides/your_first_pallet/mod.rs", transfer_v2)] @@ -285,7 +285,6 @@ //! [`crate::guides::your_first_pallet::pallet_v2::tests::runtime_v2::RuntimeEvent`]. //! //! -//! //! ## What Next? //! //! The following topics where used in this guide, but not covered in depth. It is suggested to @@ -293,7 +292,7 @@ //! //! - [`crate::reference_docs::safe_defensive_programming`]. //! - [`crate::reference_docs::frame_origin`]. -//! - [`crate::reference_docs::frame_composite_enums`]. +//! - [`crate::reference_docs::frame_runtime_types`]. //! - The pallet we wrote in this guide was using `dev_mode`, learn more in //! [`frame::pallet_macros::config`]. //! - Learn more about the individual pallet items/macros, such as event and errors and call, in diff --git a/docs/sdk/src/lib.rs b/docs/sdk/src/lib.rs index 075d9ddaffe5..9d805bb3f81a 100644 --- a/docs/sdk/src/lib.rs +++ b/docs/sdk/src/lib.rs @@ -15,7 +15,7 @@ //! - Start by learning about the the [`polkadot_sdk`], its structure and context. //! - Then, head over the [`guides`]. This modules contains in-depth guides about the most important //! user-journeys of the Polkadot SDK. -//! - Whilst reading the guides, you might find back-links to [`crate::reference_docs`]. +//! - Whilst reading the guides, you might find back-links to [`reference_docs`]. //! - Finally, is the parent website of this crate that contains the //! list of further tools related to the Polkadot SDK. //! diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index 7ecf8b0adfd3..9592307e9feb 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -101,7 +101,7 @@ //! * Before even getting started, what is with all of this ``? We link to //! [`crate::reference_docs::trait_based_programming`]. //! * First, the name. Why is this called `pallet::call`? This goes back to `enum Call`, which is -//! explained in [`crate::reference_docs::frame_composite_enums`]. Build on top of this! +//! explained in [`crate::reference_docs::frame_runtime_types`]. Build on top of this! //! * Then, what is `origin`? Just an account id? [`crate::reference_docs::frame_origin`]. //! * Then, what is `DispatchResult`? Why is this called *dispatch*? Probably something that can be //! explained in the documentation of [`frame::prelude::DispatchResult`]. diff --git a/docs/sdk/src/reference_docs/extrinsic_encoding.rs b/docs/sdk/src/reference_docs/extrinsic_encoding.rs index 9008f8f835f5..8c8568a228fa 100644 --- a/docs/sdk/src/reference_docs/extrinsic_encoding.rs +++ b/docs/sdk/src/reference_docs/extrinsic_encoding.rs @@ -127,7 +127,7 @@ //! runtimes, a call is represented as an enum of enums, where the outer enum represents the FRAME //! pallet being called, and the inner enum represents the call being made within that pallet, and //! any arguments to it. Read more about the call enum -//! [here][crate::reference_docs::frame_composite_enums]. +//! [here][crate::reference_docs::frame_runtime_types]. //! //! FRAME `Call` enums are automatically generated, and end up looking something like this: #![doc = docify::embed!("./src/reference_docs/extrinsic_encoding.rs", call_data)] diff --git a/docs/sdk/src/reference_docs/frame_composite_enums.rs b/docs/sdk/src/reference_docs/frame_composite_enums.rs deleted file mode 100644 index 6051cd534467..000000000000 --- a/docs/sdk/src/reference_docs/frame_composite_enums.rs +++ /dev/null @@ -1 +0,0 @@ -//! # FRAME Composite Enums diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index a4078377cd77..092878d37e81 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -1,14 +1,265 @@ //! # FRAME Origin //! -//! Notes: -//! -//! - Def talk about account abstraction and how it is a solved issue in frame. See Gav's talk in -//! Protocol Berg 2023 -//! - system's raw origin, how it is amalgamated with other origins into one type -//! [`frame_composite_enums`] -//! - signed origin -//! - unsigned origin, link to [`fee_less_runtime`] -//! - Root origin, how no one can obtain it. -//! - Abstract origin: how FRAME allows you to express "origin is 2/3 of the this body or 1/2 of -//! that body or half of the token holders". -//! - `type CustomOrigin: EnsureOrigin<_>` in pallets. +//! let's start by eliminating a wrong assumption that is a common mistake: +//! +//! **ORIGIN IS NOT AN ACCOUNT ID**. +//! +//! FRAME's origin abstractions allow you to convey meanings far beyond just an account-id being the +//! caller of an extrinsic. Nonetheless, an account-id having signed an extrinsic is one of the +//! meanings that an origin can convey. This is the commonly used [`frame_system::ensure_signed`], +//! where the return value happens to be an account-id. +//! +//! Instead, let's establish the following as the correct definition of an origin: +//! +//! > The origin type represent the privilege level of the caller of an extrinsic. +//! +//! That is, an extrinsic, through checking the origin, can *express what privilege level it wishes +//! to impose on the caller of the extrinsic*. One of those checks can be as simple as "*any account +//! that has signed a statement can pass*". +//! +//! But the origin system can also express more abstract and complicated privilege levels. For +//! example: +//! +//! * If the majority of token holders agreed upon this. This is more or less what the +//! [`pallet_democracy`] does under the hood[^1]. +//! * If a specific ratio of an instance of [`pallet_collective`]/DAO agrees upon this. +//! * If another consensus system, for example a bridged network or a parachain, agrees upon this. +//! * If the majority of validator/authority set agrees upon this[^2]. +//! * If caller holds a particular NFT. +//! +//! and many more. +//! +//! ## Context +//! +//! First, let's look at where the `origin` type is encountered in a typical pallet. The `origin: +//! OriginFor` has to be the first argument of any given callable extrinsic in FRAME: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", call_simple)] +//! +//! Typically, the code of an extrinsic starts with an origin check, such as +//! [`frame_system::ensure_signed`]. +//! +//! Note that [`OriginFor`](frame_system::pallet_prelude::OriginFor) is merely a shorthand for +//! [`frame_system::Config::RuntimeOrigin`]. Given the name prefix `Runtime`, we can learn that +//! `RuntimeOrigin` is similar to `RuntimeCall` and others, a runtime composite that is amalgamated +//! at the runtime level. Read [`crate::reference_docs::frame_runtime_types`] to familiarize +//! yourself with these types. +//! +//! To understand this better, we will next create a pallet with a custom origin, which will add a +//! new variant to `RuntimeOrigin`. +//! +//! ## Adding Custom Pallet Origin to the Runtime +//! +//! For example, given a pallet that defines the following custom origin: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin)] +//! +//! And a runtime with the following pallets: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", runtime_exp)] +//! +//! The type [`crate::reference_docs::frame_origin::runtime_for_origin::RuntimeOrigin`] is expanded. +//! This `RuntimeOrigin` contains a variant for the [`frame_system::RawOrigin`] and the custom +//! origin of the pallet. +//! +//! > Notice how the [`frame_system::ensure_signed`] is nothing more than a `match` statement. If +//! > you want to know where the actual origin of an extrinsic is set (and the signature +//! > verification happens, if any), see +//! > [`sp_runtime::generic::CheckedExtrinsic#trait-implementations`], specifically +//! > [`sp_runtime::traits::Applyable`]'s implementation. +//! +//! ## Asserting on a Custom Internal Origin +//! +//! In order to assert on a custom origin that is defined within your pallet, we need a way to first +//! convert the `::RuntimeOrigin` into the local `enum Origin` of the +//! current pallet. This is a common process that is explained in +//! [`crate::reference_docs::frame_runtime_types# +//! adding-further-constraints-to-runtime-composite-enums`]. +//! +//! We use the same process here to express that `RuntimeOrigin` has a number of additional bounds, +//! as follows. +//! +//! 1. Defining a custom `RuntimeOrigin` with further bounds in the pallet. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin_bound)] +//! +//! 2. Using it in the pallet. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", custom_origin_usage)] +//! +//! ## Asserting on a Custom External Origin +//! +//! Very often, a pallet wants to have a parameterized origin that is **NOT** defined within the +//! pallet. In other words, a pallet wants to delegate an origin check to something that is +//! specified later at the runtime level. Like many other parameterizations in FRAME, this implies +//! adding a new associated type to `trait Config`. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_def)] +//! +//! Then, within the pallet, we can simply use this "unknown" origin check type: +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_usage)] +//! +//! Finally, at the runtime, any implementation of [`frame::traits::EnsureOrigin`] can be passed. +#![doc = docify::embed!("./src/reference_docs/frame_origin.rs", external_origin_provide)] +//! +//! Indeed, some of these implementations of [`frame::traits::EnsureOrigin`] are similar to the ones +//! that we know about: [`frame::runtime::prelude::EnsureSigned`], +//! [`frame::runtime::prelude::EnsureSignedBy`], [`frame::runtime::prelude::EnsureRoot`], +//! [`frame::runtime::prelude::EnsureNone`], etc. But, there are also many more that are not known +//! to us, and are defined in other pallets. +//! +//! For example, [`pallet_collective`] defines [`pallet_collective::EnsureMember`] and +//! [`pallet_collective::EnsureProportionMoreThan`] and many more, which is exactly what we alluded +//! to earlier in this document. +//! +//! Make sure to check the full list of [implementors of +//! `EnsureOrigin`](frame::traits::EnsureOrigin#implementors) for more inspiration. +//! +//! ## Obtaining Abstract Origins +//! +//! So far we have learned that FRAME pallet's can assert on custom and abstract origin types, +//! whether they are defined within the pallet or not. But how can we obtain these abstract origins? +//! +//! > All extrinsics that come from outer world can generally only obtained either `signed` or +//! > `none` origin +//! +//! Generally, these abstract origins asd only obtained within the runtime, when a call is +//! dispatched within the runtime. +//! +//! ## Further References +//! +//! - [Gavin Wood's speech about FRAME features at Protocol Berg 2023.](https://youtu.be/j7b8Upipmeg?si=83_XUgYuJxMwWX4g&t=195) +//! - [A related StackExchange question.](https://substrate.stackexchange.com/questions/10992/how-do-you-find-the-public-key-for-the-medium-spender-track-origin) +//! +//! [^1]: [Reference](https://github.com/paritytech/polkadot-sdk/blob/edd95b3749754d2ed0c5738588e872c87be91624/substrate/frame/democracy/src/lib.rs#L1603-L1633). +//! [^2]: Inherents are essentially unsigned extrinsics that need an [`frame_system::ensure_none`] +//! origin check, and through the virtue of being an inherent, are agreed upon by all +//! validators. + +use frame::prelude::*; + +#[frame::pallet(dev_mode)] +pub mod pallet_for_origin { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(call_simple)] + #[pallet::call] + impl Pallet { + pub fn do_something(_origin: OriginFor) -> DispatchResult { + // ^^^^^^^^^^^^^^^^^^^^^ + todo!(); + } + } +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_custom_origin { + use super::*; + + #[docify::export(custom_origin_bound)] + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeOrigin: From<::RuntimeOrigin> + + Into::RuntimeOrigin>>; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(custom_origin)] + /// A dummy custom origin. + #[pallet::origin] + #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub enum Origin { + /// If all holders of a particular NFT have agreed upon this. + AllNftHolders, + /// If all validators have agreed upon this. + ValidatorSet, + } + + #[docify::export(custom_origin_usage)] + #[pallet::call] + impl Pallet { + pub fn only_validators( + // we use the full syntax of `OriginFor` here, but it's not necessary. + origin: OriginFor, + ) -> DispatchResult { + // first, we convert from `::RuntimeOrigin` to `::RuntimeOrigin` + let local_runtime_origin = <::RuntimeOrigin as From< + ::RuntimeOrigin, + >>::from(origin); + // then we convert to `origin`, if possible + let local_origin = + local_runtime_origin.into().map_err(|_| "invalid origin type provided")?; + ensure!(matches!(local_origin, Origin::ValidatorSet), "Not authorized"); + todo!(); + } + } +} + +pub mod runtime_for_origin { + use super::pallet_with_custom_origin; + use frame::{runtime::prelude::*, testing_prelude::*}; + + #[docify::export(runtime_exp)] + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithCustomOrigin: pallet_with_custom_origin, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + impl pallet_with_custom_origin::Config for Runtime { + type RuntimeOrigin = RuntimeOrigin; + } +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_external_origin { + use super::*; + #[docify::export(external_origin_def)] + #[pallet::config] + pub trait Config: frame_system::Config { + type ExternalOrigin: EnsureOrigin; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[docify::export(external_origin_usage)] + #[pallet::call] + impl Pallet { + pub fn externally_checked_ext(origin: OriginFor) -> DispatchResult { + let _ = T::ExternalOrigin::ensure_origin(origin)?; + todo!(); + } + } +} + +pub mod runtime_for_external_origin { + use super::*; + use frame::{runtime::prelude::*, testing_prelude::*}; + + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithExternalOrigin: pallet_with_external_origin, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + #[docify::export(external_origin_provide)] + impl pallet_with_external_origin::Config for Runtime { + type ExternalOrigin = EnsureSigned<::AccountId>; + } +} diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs new file mode 100644 index 000000000000..ab3025144d21 --- /dev/null +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -0,0 +1,307 @@ +//! # FRAME Runtime Types +//! +//! This reference document briefly explores the idea around types generated at the runtime level by +//! the FRAME macros. +//! +//! > As of now, many of these important types are generated within the internals of +//! > [`construct_runtime`], and there is no easy way for you to visually know they exist. +//! > [#polkadot-sdk#1378](https://github.com/paritytech/polkadot-sdk/pull/1378) is meant to +//! > significantly improve this. Exploring the rust-docs of a runtime, such as [`runtime`] which is +//! > defined in this module is as of now the best way to learn about these types. +//! +//! ## Composite Enums +//! +//! Many types within a FRAME runtime follow the following structure: +//! +//! * Each individual pallet defines a type, for example `Foo`. +//! * At thr runtime level, these types are amalgamated into a single type, for example +//! `RuntimeFoo`. +//! +//! As the names suggest, all composite enums in a FRAME runtime start their name with `Runtime`. +//! For example, `RuntimeCall` is a representation of the most high level `Call`-able type in the +//! runtime. +//! +//! Composite enums are generally convertible to their individual parts as such: +//! +//! +//! In that one can always convert from the inner type into the outer type, but not visa versa. This +//! is usually expressed by implementing `From`, `TryFrom`, `From>` and similar traits. +//! +//! ### Example +//! +//! We provide the following two pallets: [`pallet_foo`] and [`pallet_bar`]. Each define a +//! dispatchable, and `Foo` also defines a custom origin. Lastly, `Bar` defines an additional +//! `GenesisConfig`. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_foo)] +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_bar)] +//! +//! Let's explore how each of these affect the [`RuntimeCall`], [`RuntimeOrigin`] and +//! [`RuntimeGenesisConfig`] generated in [`runtime`] by respectively. +//! +//! As observed, [`RuntimeCall`] has 3 variants, one for each pallet and one for `frame_system`. If +//! you explore further, you will soon realize that each variant is merely a pointer to the `Call` +//! type in each pallet, for example [`pallet_foo::Call`]. +//! +//! [`RuntimeOrigin`]'s [`OriginCaller`] has two variants, one for system, and one for `pallet_foo` +//! which utilized [`frame::pallet_macros::origin`]. +//! +//! Finally, [`RuntimeGenesisConfig`] is composed of `frame_system` and a variant for `pallet_bar`'s +//! [`pallet_bar::GenesisConfig`]. +//! +//! You can find other composite enums by scanning [`runtime`] for other types who's name starts +//! with `Runtime`. Some of the more noteworthy ones are: +//! +//! - [`RuntimeEvent`] +//! - [`RuntimeError`] +//! - [`RuntimeHoldReason`] +//! +//! ### Adding Further Constraints to Runtime Composite Enums +//! +//! This section explores a common scenario where a pallet has access to one of these runtime +//! composite enums, but it wishes to further specify it by adding more trait bounds to it. +//! +//! Let's take the example of `RuntimeCall`. This is an associated type in +//! [`frame_system::Config::RuntimeCall`], and all pallets have access to this type, because they +//! have access to [`frame_system::Config`]. Finally, this type is meant to be set to outer call of +//! the entire runtime. +//! +//! But, let's not forget that this is information that *we know*, and the Rust compiler does not. +//! All that the rust compiler knows about this type is *ONLY* what the trait bounds of +//! [`frame_system::Config::RuntimeCall`] are specifying: +#![doc = docify::embed!("../../substrate/frame/system/src/lib.rs", system_runtime_call)] +//! +//! So, when at a given pallet, one accesses `::RuntimeCall`, the type is +//! extremely opaque from the perspective of the Rust compiler. +//! +//! How can a pallet access the `RuntimeCall` type with further constraints? For example, each +//! pallet has its own `enum Call`, and knows that its local `Call` is a part of `RuntimeCall`, +//! therefore there should be a `impl From> for RuntimeCall`. +//! +//! The only way to express this using Rust's associated types is for the pallet to **define its own +//! associated type `RuntimeCall`, and further specify what it thinks `RuntimeCall` should be**. +//! +//! In this case, we will want to assert the existence of [`frame::traits::IsSubType`], which is +//! very similar to [`TryFrom`]. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", custom_runtime_call)] +//! +//! And indeed, at the runtime level, this associated type would be the same `RuntimeCall` that is +//! passed to `frame_system`. +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", pallet_with_specific_runtime_call_impl)] +//! +//! > In other words, the degree of specificity that [`frame_system::Config::RuntimeCall`] has is +//! > not enough for the pallet to work with. Therefore, the pallet has to define its own associated +//! > type. +//! +//! Another way to look at this is: +//! +//! `pallet_with_specific_runtime_call::Config::RuntimeCall` are two different representations of +//! the same concrete type that is only know at when the runtime is being constructed. +//! +//! Now, within this pallet, this new `RuntimeCall` can be used, and it can use its new trait +//! bounds, such as being [`frame::traits::IsSubType`]: +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", custom_runtime_call_usages)] +//! +//! ### Asserting Equality of Multiple Runtime Composite Enums +//! +//! Recall that in the above example, `::RuntimeCall` and `::RuntimeCall` are expected to be equal types, but at the compile-time we +//! have to represent them with two different associated types with different bounds. Would it not +//! be cool if we had a test to make sure they actually resolve to the same concrete type once the +//! runtime is constructed? The following snippet exactly does that: +#![doc = docify::embed!("./src/reference_docs/frame_runtime_types.rs", assert_equality)] +//! +//! We leave it to the reader to further explore what [`frame::traits::Hooks::integrity_test`] is, +//! and what [`core::any::TypeId`] is. Another way to assert this is using +//! [`frame::traits::IsType`]. +//! +//! ## Type Aliases +//! +//! A number of type aliases are generated by the `construct_runtime` which are also noteworthy: +//! +//! * [`runtime::PalletFoo`] is an alias to [`pallet_foo::Pallet`]. Same for `PalletBar`, and +//! `System` +//! * [`runtime::AllPalletsWithSystem`] is an alias for a tuple of all of the above. This type is +//! important to FRAME internals such as `executive`, as it implements traits such as +//! [`frame::traits::Hooks`]. +//! +//! ## Further Details +//! +//! * [`crate::reference_docs::frame_origin`] explores further details about the usage of +//! `RuntimeOrigin`. +//! * [`RuntimeCall`] is a particularly interesting composite enum as it dictates the encoding of an +//! extrinsic. See [`crate::reference_docs::signed_extensions`] for more information. +//! * See the documentation of [`construct_runtime`]. +//! * See the corresponding lecture in the [pba-book](https://polkadot-blockchain-academy.github.io/pba-book/frame/outer-enum/page.html). +//! +//! +//! [`construct_runtime`]: frame::runtime::prelude::construct_runtime +//! [`runtime::PalletFoo`]: crate::reference_docs::frame_runtime_types::runtime::PalletFoo +//! [`runtime::AllPalletsWithSystem`]: crate::reference_docs::frame_runtime_types::runtime::AllPalletsWithSystem +//! [`runtime`]: crate::reference_docs::frame_runtime_types::runtime +//! [`pallet_foo`]: crate::reference_docs::frame_runtime_types::pallet_foo +//! [`pallet_foo::Call`]: crate::reference_docs::frame_runtime_types::pallet_foo::Call +//! [`pallet_foo::Pallet`]: crate::reference_docs::frame_runtime_types::pallet_foo::Pallet +//! [`pallet_bar`]: crate::reference_docs::frame_runtime_types::pallet_bar +//! [`pallet_bar::GenesisConfig`]: crate::reference_docs::frame_runtime_types::pallet_bar::GenesisConfig +//! [`RuntimeEvent`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeEvent +//! [`RuntimeGenesisConfig`]: +//! crate::reference_docs::frame_runtime_types::runtime::RuntimeGenesisConfig +//! [`RuntimeOrigin`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeOrigin +//! [`OriginCaller`]: crate::reference_docs::frame_runtime_types::runtime::OriginCaller +//! [`RuntimeError`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeError +//! [`RuntimeCall`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeCall +//! [`RuntimeHoldReason`]: crate::reference_docs::frame_runtime_types::runtime::RuntimeHoldReason + +use frame::prelude::*; + +#[docify::export] +#[frame::pallet(dev_mode)] +pub mod pallet_foo { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::origin] + #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + pub enum Origin { + A, + B, + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::call] + impl Pallet { + pub fn foo(_origin: OriginFor) -> DispatchResult { + todo!(); + } + + pub fn other(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } +} + +#[docify::export] +#[frame::pallet(dev_mode)] +pub mod pallet_bar { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config {} + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::genesis_config] + #[derive(DefaultNoBound)] + pub struct GenesisConfig { + pub initial_account: Option, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + todo!(); + } + } + + #[pallet::call] + impl Pallet { + pub fn bar(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } +} + +pub mod runtime { + use super::{pallet_bar, pallet_foo}; + use frame::{runtime::prelude::*, testing_prelude::*}; + + #[docify::export(runtime_exp)] + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletFoo: pallet_foo, + PalletBar: pallet_bar, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + impl pallet_foo::Config for Runtime {} + impl pallet_bar::Config for Runtime {} +} + +#[frame::pallet(dev_mode)] +pub mod pallet_with_specific_runtime_call { + use super::*; + use frame::traits::IsSubType; + + #[docify::export(custom_runtime_call)] + /// A pallet that wants to further narrow down what `RuntimeCall` is. + #[pallet::config] + pub trait Config: frame_system::Config { + type RuntimeCall: IsSubType>; + } + + #[pallet::pallet] + pub struct Pallet(_); + + // note that this pallet needs some `call` to have a `enum Call`. + #[pallet::call] + impl Pallet { + pub fn foo(_origin: OriginFor) -> DispatchResult { + todo!(); + } + } + + #[docify::export(custom_runtime_call_usages)] + impl Pallet { + fn _do_something_useful_with_runtime_call(call: ::RuntimeCall) { + // check if the runtime call given is of this pallet's variant. + let _maybe_my_call: Option<&Call> = call.is_sub_type(); + todo!(); + } + } + + #[docify::export(assert_equality)] + #[pallet::hooks] + impl Hooks> for Pallet { + fn integrity_test() { + use core::any::TypeId; + assert_eq!( + TypeId::of::<::RuntimeCall>(), + TypeId::of::<::RuntimeCall>() + ); + } + } +} + +pub mod runtime_with_specific_runtime_call { + use super::pallet_with_specific_runtime_call; + use frame::{runtime::prelude::*, testing_prelude::*}; + + construct_runtime!( + pub struct Runtime { + System: frame_system, + PalletWithSpecificRuntimeCall: pallet_with_specific_runtime_call, + } + ); + + #[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] + impl frame_system::Config for Runtime { + type Block = MockBlock; + } + + #[docify::export(pallet_with_specific_runtime_call_impl)] + impl pallet_with_specific_runtime_call::Config for Runtime { + // an implementation of `IsSubType` is provided by `construct_runtime`. + type RuntimeCall = RuntimeCall; + } +} diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index c16122ee4287..f6abca4ca381 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -44,15 +44,15 @@ pub mod extrinsic_encoding; pub mod signed_extensions; /// Learn about *"Origin"* A topic in FRAME that enables complex account abstractions to be built. -// TODO: @shawntabrizi https://github.com/paritytech/polkadot-sdk-docs/issues/43 pub mod frame_origin; /// Learn about how to write safe and defensive code in your FRAME runtime. // TODO: @CrackTheCode016 https://github.com/paritytech/polkadot-sdk-docs/issues/44 pub mod safe_defensive_programming; -/// Learn about composite enums in FRAME-based runtimes, such as "RuntimeEvent" and "RuntimeCall". -pub mod frame_composite_enums; +/// Learn about composite enums and other runtime level types, such as "RuntimeEvent" and +/// "RuntimeCall". +pub mod frame_runtime_types; /// Learn about how to make a pallet/runtime that is fee-less and instead uses another mechanism to /// control usage and sybil attacks. @@ -100,3 +100,5 @@ pub mod frame_runtime_migration; /// light-node-first out of the box. // TODO: @jsdw @josepot https://github.com/paritytech/polkadot-sdk-docs/issues/68 pub mod light_nodes; + +// pub mod opinionated_pallets; diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs index a1715ba49001..a2e5d726fdd0 100644 --- a/substrate/frame/src/lib.rs +++ b/substrate/frame/src/lib.rs @@ -163,6 +163,12 @@ pub mod runtime { ConstU32, ConstU64, ConstU8, }; + /// Primary types used to parameterize `EnsureOrigin` and `EnsureRootWithArg`. + pub use frame_system::{ + EnsureNever, EnsureNone, EnsureRoot, EnsureRootWithSuccess, EnsureSigned, + EnsureSignedBy, + }; + /// Types to define your runtime version. pub use sp_version::{create_runtime_str, runtime_version, RuntimeVersion}; diff --git a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs index b421d2aaffab..83049919d01c 100644 --- a/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs +++ b/substrate/frame/support/procedural/src/construct_runtime/expand/origin.rs @@ -104,7 +104,7 @@ pub fn expand_outer_origin( #[doc = #doc_string] #[derive(Clone)] pub struct RuntimeOrigin { - caller: OriginCaller, + pub caller: OriginCaller, filter: #scrate::__private::sp_std::rc::Rc::RuntimeCall) -> bool>>, } diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs index 069217bcee46..c6b5ea6152b5 100644 --- a/substrate/frame/system/src/lib.rs +++ b/substrate/frame/system/src/lib.rs @@ -451,6 +451,7 @@ pub mod pallet { + Clone + OriginTrait; + #[docify::export(system_runtime_call)] /// The aggregated `RuntimeCall` type. #[pallet::no_default_bounds] type RuntimeCall: Parameter From bb3dffebef11763b78c683399a94ba0703578c57 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 15 Feb 2024 21:33:12 +0000 Subject: [PATCH 02/20] make it build --- Cargo.lock | 10 ---------- Cargo.toml | 1 - docs/sdk/src/reference_docs/frame_origin.rs | 4 ++-- 3 files changed, 2 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aaadee36a122..86fd5f17e573 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13302,16 +13302,6 @@ dependencies = [ "substrate-wasm-builder", ] -[[package]] -name = "polkadot-sdk-docs-runtimes" -version = "0.0.1" -dependencies = [ - "frame", - "parity-scale-codec", - "polkadot-sdk-docs", - "scale-info", -] - [[package]] name = "polkadot-service" version = "7.0.0" diff --git a/Cargo.toml b/Cargo.toml index 7395a90f133a..8cbfc7a23fed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -135,7 +135,6 @@ members = [ "cumulus/test/service", "cumulus/xcm/xcm-emulator", "docs/sdk", - "docs/sdk/runtimes", "polkadot", "polkadot/cli", "polkadot/core-primitives", diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index 092878d37e81..0b0ee0b993a3 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -127,8 +127,8 @@ //! //! [^1]: [Reference](https://github.com/paritytech/polkadot-sdk/blob/edd95b3749754d2ed0c5738588e872c87be91624/substrate/frame/democracy/src/lib.rs#L1603-L1633). //! [^2]: Inherents are essentially unsigned extrinsics that need an [`frame_system::ensure_none`] -//! origin check, and through the virtue of being an inherent, are agreed upon by all -//! validators. +//! origin check, and through the virtue of being an inherent, are agreed upon by all +//! validators. use frame::prelude::*; From 39fac8763833c732f16a8dcaa60c3a3041923243 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 15 Feb 2024 21:44:14 +0000 Subject: [PATCH 03/20] add macro docs as well --- substrate/frame/support/procedural/src/lib.rs | 17 +---- substrate/frame/support/src/lib.rs | 68 +++++++++++++++++-- 2 files changed, 64 insertions(+), 21 deletions(-) diff --git a/substrate/frame/support/procedural/src/lib.rs b/substrate/frame/support/procedural/src/lib.rs index 34e68966b823..50386c888e51 100644 --- a/substrate/frame/support/procedural/src/lib.rs +++ b/substrate/frame/support/procedural/src/lib.rs @@ -1477,22 +1477,11 @@ pub fn validate_unsigned(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() } -/// The `#[pallet::origin]` attribute allows you to define some origin for the pallet. /// -/// Item must be either a type alias, an enum, or a struct. It needs to be public. -/// -/// E.g.: -/// -/// ```ignore -/// #[pallet::origin] -/// pub struct Origin(PhantomData<(T)>); -/// ``` -/// -/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin -/// can be stored on-chain (e.g. in `pallet-scheduler`), thus any change must be done with care -/// as it might require some migration. +/// --- /// -/// NOTE: for instantiable pallets, the origin must be generic over `T` and `I`. +/// **Rust-Analyzer users**: See the documentation of the Rust item in +/// `frame_support::pallet_macros::origin`. #[proc_macro_attribute] pub fn origin(_: TokenStream, _: TokenStream) -> TokenStream { pallet_macro_stub() diff --git a/substrate/frame/support/src/lib.rs b/substrate/frame/support/src/lib.rs index 0f6cf05959f5..55a7c017a949 100644 --- a/substrate/frame/support/src/lib.rs +++ b/substrate/frame/support/src/lib.rs @@ -2266,9 +2266,8 @@ pub mod pallet_macros { pub use frame_support_procedural::{ composite_enum, config, disable_frame_system_supertrait_check, error, event, extra_constants, feeless_if, generate_deposit, generate_store, getter, hooks, - import_section, inherent, no_default, no_default_bounds, origin, pallet_section, - storage_prefix, storage_version, type_value, unbounded, validate_unsigned, weight, - whitelist_storage, + import_section, inherent, no_default, no_default_bounds, pallet_section, storage_prefix, + storage_version, type_value, unbounded, validate_unsigned, weight, whitelist_storage, }; /// Allows a pallet to declare a set of functions as a *dispatchable extrinsic*. In @@ -2710,7 +2709,7 @@ pub mod pallet_macros { /// } /// ``` pub use frame_support_procedural::storage; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define the conditions for a /// given work item to be valid. /// @@ -2718,21 +2717,21 @@ pub mod pallet_macros { /// should have the same signature as the function it is attached to, except that it should /// return a `bool` instead. pub use frame_support_procedural::task_condition; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define the index of a given /// work item. /// /// It takes an integer literal as input, which is then used to define the index. This /// index should be unique for each function in the `impl` block. pub use frame_support_procedural::task_index; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) to define an iterator over the /// available work items for a task. /// /// It takes an iterator as input that yields a tuple with same types as the function /// arguments. pub use frame_support_procedural::task_list; - /// This attribute is attached to a function inside an `impl` block annoated with + /// This attribute is attached to a function inside an `impl` block annotated with /// [`pallet::tasks_experimental`](`tasks_experimental`) define the weight of a given work /// item. /// @@ -2765,6 +2764,61 @@ pub mod pallet_macros { /// Now, this can be executed as follows: #[doc = docify::embed!("src/tests/tasks.rs", tasks_work)] pub use frame_support_procedural::tasks_experimental; + + /// Allows a pallet to declare a type as an origin. + /// + /// If defined as such, this type will be amalgamated at the runtime level into + /// `RuntimeOrigin`, very similar to [`call`], [`error`] and [`event`]. See + /// [`composite_enum`] for similar cases. + /// + /// Origin is a complex FRAME topics and is further explained in `polkadot_sdk_docs`. + /// + /// ## Syntax Variants + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// # #[pallet::pallet] + /// # pub struct Pallet(_); + /// /// On the spot declaration. + /// #[pallet::origin] + /// #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + /// pub enum Origin { + /// Foo, + /// Bar, + /// } + /// } + /// ``` + /// + /// Or, more commonly used:/ + /// + /// ``` + /// #[frame_support::pallet] + /// mod pallet { + /// # use frame_support::pallet_prelude::*; + /// # #[pallet::config] + /// # pub trait Config: frame_system::Config {} + /// # #[pallet::pallet] + /// # pub struct Pallet(_); + /// #[derive(PartialEq, Eq, Clone, RuntimeDebug, Encode, Decode, TypeInfo, MaxEncodedLen)] + /// pub enum RawOrigin { + /// Foo, + /// Bar, + /// } + /// + /// #[pallet::origin] + /// pub type Origin = RawOrigin; + /// } + /// ``` + /// + /// ## Warning + /// + /// Modifying any pallet's origin type will cause the runtime level origin type to also + /// change in encoding. If stored anywhere on-chain, this will require a data migration. + pub use frame_support_procedural::origin; } #[deprecated(note = "Will be removed after July 2023; Use `sp_runtime::traits` directly instead.")] From c863d7520dde3734cd59442d8390364d6bb41cf7 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 15 Feb 2024 21:45:54 +0000 Subject: [PATCH 04/20] add diagram --- docs/mermaid/outer_runtime_types.mmd | 3 +++ docs/sdk/src/reference_docs/frame_runtime_types.rs | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) create mode 100644 docs/mermaid/outer_runtime_types.mmd diff --git a/docs/mermaid/outer_runtime_types.mmd b/docs/mermaid/outer_runtime_types.mmd new file mode 100644 index 000000000000..c909df16af1f --- /dev/null +++ b/docs/mermaid/outer_runtime_types.mmd @@ -0,0 +1,3 @@ +flowchart LR + RuntimeCall --"TryInto"--> PalletCall + PalletCall --"Into"--> RuntimeCall diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs index ab3025144d21..6663910c17ad 100644 --- a/docs/sdk/src/reference_docs/frame_runtime_types.rs +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -22,7 +22,7 @@ //! runtime. //! //! Composite enums are generally convertible to their individual parts as such: -//! +#![doc = simple_mermaid::mermaid!("../../../mermaid/outer_runtime_type.mmd")] //! //! In that one can always convert from the inner type into the outer type, but not visa versa. This //! is usually expressed by implementing `From`, `TryFrom`, `From>` and similar traits. From acad0ea1afd9dd74fc553897c0365710d954a073 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Thu, 15 Feb 2024 21:57:06 +0000 Subject: [PATCH 05/20] fix mmd path --- docs/sdk/src/reference_docs/frame_runtime_types.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs index 6663910c17ad..12e9950fddcf 100644 --- a/docs/sdk/src/reference_docs/frame_runtime_types.rs +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -22,7 +22,7 @@ //! runtime. //! //! Composite enums are generally convertible to their individual parts as such: -#![doc = simple_mermaid::mermaid!("../../../mermaid/outer_runtime_type.mmd")] +#![doc = simple_mermaid::mermaid!("../../../mermaid/outer_runtime_types.mmd")] //! //! In that one can always convert from the inner type into the outer type, but not visa versa. This //! is usually expressed by implementing `From`, `TryFrom`, `From>` and similar traits. From 552ba03df1199d099d5598ced9857c353cf8f548 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:32:40 +0000 Subject: [PATCH 06/20] Apply suggestions from code review Co-authored-by: Radha <86818441+DrW3RK@users.noreply.github.com> --- docs/sdk/src/reference_docs/frame_origin.rs | 8 ++++---- docs/sdk/src/reference_docs/frame_runtime_types.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index 0b0ee0b993a3..55d76c75448f 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -11,7 +11,7 @@ //! //! Instead, let's establish the following as the correct definition of an origin: //! -//! > The origin type represent the privilege level of the caller of an extrinsic. +//! > The origin type represents the privilege level of the caller of an extrinsic. //! //! That is, an extrinsic, through checking the origin, can *express what privilege level it wishes //! to impose on the caller of the extrinsic*. One of those checks can be as simple as "*any account @@ -111,13 +111,13 @@ //! //! ## Obtaining Abstract Origins //! -//! So far we have learned that FRAME pallet's can assert on custom and abstract origin types, +//! So far we have learned that FRAME pallets can assert on custom and abstract origin types, //! whether they are defined within the pallet or not. But how can we obtain these abstract origins? //! -//! > All extrinsics that come from outer world can generally only obtained either `signed` or +//! > All extrinsics that come from the outer world can generally only be obtained as either `signed` or //! > `none` origin //! -//! Generally, these abstract origins asd only obtained within the runtime, when a call is +//! Generally, these abstract origins are only obtained within the runtime, when a call is //! dispatched within the runtime. //! //! ## Further References diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs index 12e9950fddcf..643c248f4f08 100644 --- a/docs/sdk/src/reference_docs/frame_runtime_types.rs +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -14,7 +14,7 @@ //! Many types within a FRAME runtime follow the following structure: //! //! * Each individual pallet defines a type, for example `Foo`. -//! * At thr runtime level, these types are amalgamated into a single type, for example +//! * At the runtime level, these types are amalgamated into a single type, for example //! `RuntimeFoo`. //! //! As the names suggest, all composite enums in a FRAME runtime start their name with `Runtime`. @@ -24,7 +24,7 @@ //! Composite enums are generally convertible to their individual parts as such: #![doc = simple_mermaid::mermaid!("../../../mermaid/outer_runtime_types.mmd")] //! -//! In that one can always convert from the inner type into the outer type, but not visa versa. This +//! In that one can always convert from the inner type into the outer type, but not vice versa. This //! is usually expressed by implementing `From`, `TryFrom`, `From>` and similar traits. //! //! ### Example From 26a9dfa5feffa8399e5b36547c86016e2416b074 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 20 Feb 2024 12:17:01 +0000 Subject: [PATCH 07/20] prettify the docs page a bit --- .gitlab/pipeline/build.yml | 2 +- docs/mermaid/IA.mmd | 2 +- docs/sdk/headers/header.html | 139 ++++++++++++++++++++ docs/sdk/headers/theme.css | 16 +++ docs/sdk/headers/toc.html | 54 -------- docs/sdk/src/lib.rs | 5 + docs/sdk/src/meta_contributing.rs | 4 +- docs/sdk/src/reference_docs/frame_origin.rs | 10 +- 8 files changed, 169 insertions(+), 63 deletions(-) create mode 100644 docs/sdk/headers/header.html create mode 100644 docs/sdk/headers/theme.css delete mode 100644 docs/sdk/headers/toc.html diff --git a/.gitlab/pipeline/build.yml b/.gitlab/pipeline/build.yml index c6682f7974ba..20f829f95d45 100644 --- a/.gitlab/pipeline/build.yml +++ b/.gitlab/pipeline/build.yml @@ -91,7 +91,7 @@ build-rustdoc: - .run-immediately variables: SKIP_WASM_BUILD: 1 - RUSTDOCFLAGS: "" + RUSTDOCFLAGS: "--default-theme=ayu --html-in-header $(pwd)/docs/sdk/headers/header.html --extend-css $(pwd)/docs/sdk/headers/theme.css" artifacts: name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}-doc" when: on_success diff --git a/docs/mermaid/IA.mmd b/docs/mermaid/IA.mmd index 93d3e92814cf..4eb50bcf96a8 100644 --- a/docs/mermaid/IA.mmd +++ b/docs/mermaid/IA.mmd @@ -3,7 +3,7 @@ flowchart devhub --> polkadot_sdk devhub --> reference_docs - devhub --> tutorial + devhub --> guides polkadot_sdk --> substrate polkadot_sdk --> frame diff --git a/docs/sdk/headers/header.html b/docs/sdk/headers/header.html new file mode 100644 index 000000000000..68dc5d5509e6 --- /dev/null +++ b/docs/sdk/headers/header.html @@ -0,0 +1,139 @@ + + + diff --git a/docs/sdk/headers/theme.css b/docs/sdk/headers/theme.css new file mode 100644 index 000000000000..bb9254ec4a82 --- /dev/null +++ b/docs/sdk/headers/theme.css @@ -0,0 +1,16 @@ +:root { + --polkadot-pink: #E6007A ; + --polkadot-green: #56F39A ; + --polkadot-lime: #D3FF33 ; + --polkadot-cyan: #00B2FF ; + --polkadot-purple: #552BBF ; + } + +body > nav.sidebar > div.sidebar-crate > a > img { + /* logo width, given that the sidebar width is 200px; */ + width: 190px; +} + +body nav.sidebar { + flex: 0 0 250px; +} diff --git a/docs/sdk/headers/toc.html b/docs/sdk/headers/toc.html deleted file mode 100644 index a4a074cb4f31..000000000000 --- a/docs/sdk/headers/toc.html +++ /dev/null @@ -1,54 +0,0 @@ - - diff --git a/docs/sdk/src/lib.rs b/docs/sdk/src/lib.rs index 9d805bb3f81a..e211476d2514 100644 --- a/docs/sdk/src/lib.rs +++ b/docs/sdk/src/lib.rs @@ -25,6 +25,11 @@ #![doc = simple_mermaid::mermaid!("../../mermaid/IA.mmd")] #![warn(rustdoc::broken_intra_doc_links)] #![warn(rustdoc::private_intra_doc_links)] +#![doc(html_favicon_url = "https://polkadot.network/favicon-32x32.png")] +#![doc( + html_logo_url = "https://europe1.discourse-cdn.com/standard21/uploads/polkadot2/original/1X/eb57081e2bb7c39e5fcb1a98b443e423fa4448ae.svg" +)] +#![doc(issue_tracker_base_url = "https://github.com/paritytech/polkadot-sdk/issues")] /// Meta information about this crate, how it is built, what principles dictates its evolution and /// how one can contribute to it. diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index 9592307e9feb..6d30757ecb3d 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -138,7 +138,9 @@ //! injected, run: //! //! ```sh -//! SKIP_WASM_BUILD=1 RUSTDOCFLAGS="--html-in-header $(pwd)/docs/sdk/headers/toc.html" cargo doc -p polkadot-sdk-docs --no-deps --open +//! SKIP_WASM_BUILD=1 \ +//! RUSTDOCFLAGS='--html-in-header $(pwd)/docs/sdk/headers/header.html --extend-css $(pwd)/docs/sdk/headers/theme.css --default-theme=ayu" \ +//! cargo doc -p polkadot-sdk-docs --no-deps --open //! ``` //! //! If even faster build time for docs is needed, you can temporarily remove most of the diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index 0b0ee0b993a3..d9add9781e04 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -21,10 +21,10 @@ //! example: //! //! * If the majority of token holders agreed upon this. This is more or less what the -//! [`pallet_democracy`] does under the hood[^1]. +//! [`pallet_democracy`] does under the hood ([reference](https://github.com/paritytech/polkadot-sdk/blob/edd95b3749754d2ed0c5738588e872c87be91624/substrate/frame/democracy/src/lib.rs#L1603-L1633)). //! * If a specific ratio of an instance of [`pallet_collective`]/DAO agrees upon this. //! * If another consensus system, for example a bridged network or a parachain, agrees upon this. -//! * If the majority of validator/authority set agrees upon this[^2]. +//! * If the majority of validator/authority set agrees upon this[^1]. //! * If caller holds a particular NFT. //! //! and many more. @@ -125,10 +125,8 @@ //! - [Gavin Wood's speech about FRAME features at Protocol Berg 2023.](https://youtu.be/j7b8Upipmeg?si=83_XUgYuJxMwWX4g&t=195) //! - [A related StackExchange question.](https://substrate.stackexchange.com/questions/10992/how-do-you-find-the-public-key-for-the-medium-spender-track-origin) //! -//! [^1]: [Reference](https://github.com/paritytech/polkadot-sdk/blob/edd95b3749754d2ed0c5738588e872c87be91624/substrate/frame/democracy/src/lib.rs#L1603-L1633). -//! [^2]: Inherents are essentially unsigned extrinsics that need an [`frame_system::ensure_none`] -//! origin check, and through the virtue of being an inherent, are agreed upon by all -//! validators. +//! [^1]: Inherents are essentially unsigned extrinsics that need an [`frame_system::ensure_none`] +//! origin check, and through the virtue of being an inherent, are agreed upon by all validators. use frame::prelude::*; From f71e3a73479adb317ed6b5319e7583bc4586af1a Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 20 Feb 2024 13:23:20 +0000 Subject: [PATCH 08/20] fmt --- docs/sdk/src/reference_docs/frame_origin.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index 4388027294df..f4adeef60f1a 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -114,7 +114,8 @@ //! So far we have learned that FRAME pallets can assert on custom and abstract origin types, //! whether they are defined within the pallet or not. But how can we obtain these abstract origins? //! -//! > All extrinsics that come from the outer world can generally only be obtained as either `signed` or +//! > All extrinsics that come from the outer world can generally only be obtained as either +//! > `signed` or //! > `none` origin //! //! Generally, these abstract origins are only obtained within the runtime, when a call is From 0fc5df90ad172cf634efd4055e2544619ee33547 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 20 Feb 2024 13:23:56 +0000 Subject: [PATCH 09/20] fmt agian --- docs/sdk/src/reference_docs/frame_origin.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index f4adeef60f1a..a50e67633be3 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -115,8 +115,7 @@ //! whether they are defined within the pallet or not. But how can we obtain these abstract origins? //! //! > All extrinsics that come from the outer world can generally only be obtained as either -//! > `signed` or -//! > `none` origin +//! > `signed` or `none` origin //! //! Generally, these abstract origins are only obtained within the runtime, when a call is //! dispatched within the runtime. From ba1d800640575b03f8d3e89f640c4899d50a3fc1 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:18:29 +0000 Subject: [PATCH 10/20] Apply suggestions from code review Co-authored-by: Sebastian Kunert --- docs/sdk/src/meta_contributing.rs | 2 +- docs/sdk/src/reference_docs/frame_origin.rs | 3 +-- docs/sdk/src/reference_docs/frame_runtime_types.rs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/sdk/src/meta_contributing.rs b/docs/sdk/src/meta_contributing.rs index 6d30757ecb3d..fcdcea9934bb 100644 --- a/docs/sdk/src/meta_contributing.rs +++ b/docs/sdk/src/meta_contributing.rs @@ -139,7 +139,7 @@ //! //! ```sh //! SKIP_WASM_BUILD=1 \ -//! RUSTDOCFLAGS='--html-in-header $(pwd)/docs/sdk/headers/header.html --extend-css $(pwd)/docs/sdk/headers/theme.css --default-theme=ayu" \ +//! RUSTDOCFLAGS="--html-in-header $(pwd)/docs/sdk/headers/header.html --extend-css $(pwd)/docs/sdk/headers/theme.css --default-theme=ayu" \ //! cargo doc -p polkadot-sdk-docs --no-deps --open //! ``` //! diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index a50e67633be3..f44d93b36fe4 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -179,10 +179,9 @@ pub mod pallet_with_custom_origin { #[pallet::call] impl Pallet { pub fn only_validators( - // we use the full syntax of `OriginFor` here, but it's not necessary. origin: OriginFor, ) -> DispatchResult { - // first, we convert from `::RuntimeOrigin` to `::RuntimeOrigin` to `::RuntimeOrigin` let local_runtime_origin = <::RuntimeOrigin as From< ::RuntimeOrigin, diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs index 643c248f4f08..e34a90e500ae 100644 --- a/docs/sdk/src/reference_docs/frame_runtime_types.rs +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -95,7 +95,7 @@ //! Another way to look at this is: //! //! `pallet_with_specific_runtime_call::Config::RuntimeCall` are two different representations of -//! the same concrete type that is only know at when the runtime is being constructed. +//! the same concrete type that is only known when the runtime is being constructed. //! //! Now, within this pallet, this new `RuntimeCall` can be used, and it can use its new trait //! bounds, such as being [`frame::traits::IsSubType`]: From e5bcfef94a1a014256c98ec9f1c437df6bc22447 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 23 Feb 2024 10:21:44 +0000 Subject: [PATCH 11/20] fix --- docs/sdk/src/reference_docs/frame_runtime_types.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs index e34a90e500ae..317124781b6d 100644 --- a/docs/sdk/src/reference_docs/frame_runtime_types.rs +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -90,12 +90,13 @@ //! //! > In other words, the degree of specificity that [`frame_system::Config::RuntimeCall`] has is //! > not enough for the pallet to work with. Therefore, the pallet has to define its own associated -//! > type. +//! > type representing `RuntimeCall`. //! //! Another way to look at this is: //! -//! `pallet_with_specific_runtime_call::Config::RuntimeCall` are two different representations of -//! the same concrete type that is only known when the runtime is being constructed. +//! `pallet_with_specific_runtime_call::Config::RuntimeCall` and `frame_system::Config::RuntimeCall` +//! are two different representations of the same concrete type that is only known when the runtime +//! is being constructed. //! //! Now, within this pallet, this new `RuntimeCall` can be used, and it can use its new trait //! bounds, such as being [`frame::traits::IsSubType`]: From bc007069be24ba3e94ffe8493de79e1fbf097efb Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Fri, 23 Feb 2024 10:22:22 +0000 Subject: [PATCH 12/20] Update docs/sdk/src/reference_docs/mod.rs --- docs/sdk/src/reference_docs/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index f6abca4ca381..3811f1d33459 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -100,5 +100,3 @@ pub mod frame_runtime_migration; /// light-node-first out of the box. // TODO: @jsdw @josepot https://github.com/paritytech/polkadot-sdk-docs/issues/68 pub mod light_nodes; - -// pub mod opinionated_pallets; From b817e84ff41df4a354195740de70b6b595d0bf46 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Fri, 23 Feb 2024 10:28:14 +0000 Subject: [PATCH 13/20] fmt --- docs/sdk/src/reference_docs/frame_origin.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index f44d93b36fe4..5e4a02653521 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -178,9 +178,7 @@ pub mod pallet_with_custom_origin { #[docify::export(custom_origin_usage)] #[pallet::call] impl Pallet { - pub fn only_validators( - origin: OriginFor, - ) -> DispatchResult { + pub fn only_validators(origin: OriginFor) -> DispatchResult { // first, we convert from `::RuntimeOrigin` to `::RuntimeOrigin` let local_runtime_origin = <::RuntimeOrigin as From< From c09b83398790bb1724e57eb9a9b68884b9b3b5ff Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Sun, 25 Feb 2024 12:43:51 +0000 Subject: [PATCH 14/20] Update docs/sdk/src/reference_docs/frame_origin.rs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gonçalo Pestana --- docs/sdk/src/reference_docs/frame_origin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index 5e4a02653521..c92af03f8e72 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -115,7 +115,7 @@ //! whether they are defined within the pallet or not. But how can we obtain these abstract origins? //! //! > All extrinsics that come from the outer world can generally only be obtained as either -//! > `signed` or `none` origin +//! > `signed` or `none` origin. //! //! Generally, these abstract origins are only obtained within the runtime, when a call is //! dispatched within the runtime. From 95ccf8e462f7e9c9fdc5072e2bd4133072fb5bd1 Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:14:13 +0000 Subject: [PATCH 15/20] Update docs/sdk/src/reference_docs/mod.rs Co-authored-by: Liam Aharon --- docs/sdk/src/reference_docs/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/src/reference_docs/mod.rs b/docs/sdk/src/reference_docs/mod.rs index 3811f1d33459..760bb442c166 100644 --- a/docs/sdk/src/reference_docs/mod.rs +++ b/docs/sdk/src/reference_docs/mod.rs @@ -43,7 +43,7 @@ pub mod extrinsic_encoding; // TODO: @jsdw https://github.com/paritytech/polkadot-sdk-docs/issues/42 pub mod signed_extensions; -/// Learn about *"Origin"* A topic in FRAME that enables complex account abstractions to be built. +/// Learn about *Origins*, a topic in FRAME that enables complex account abstractions to be built. pub mod frame_origin; /// Learn about how to write safe and defensive code in your FRAME runtime. From 4e18167e4f175e364016fdc47d24ac98e8d13d2e Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:14:28 +0000 Subject: [PATCH 16/20] Update docs/sdk/src/reference_docs/frame_origin.rs Co-authored-by: Liam Aharon --- docs/sdk/src/reference_docs/frame_origin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index c92af03f8e72..fe5f1037bfd1 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -40,7 +40,7 @@ //! //! Note that [`OriginFor`](frame_system::pallet_prelude::OriginFor) is merely a shorthand for //! [`frame_system::Config::RuntimeOrigin`]. Given the name prefix `Runtime`, we can learn that -//! `RuntimeOrigin` is similar to `RuntimeCall` and others, a runtime composite that is amalgamated +//! `RuntimeOrigin` is similar to `RuntimeCall` and others, a runtime composite enum that is amalgamated //! at the runtime level. Read [`crate::reference_docs::frame_runtime_types`] to familiarize //! yourself with these types. //! From 7e99fb8e0c58e4b643f4f7d3f73bd5540aa4dbad Mon Sep 17 00:00:00 2001 From: Kian Paimani <5588131+kianenigma@users.noreply.github.com> Date: Mon, 26 Feb 2024 10:15:54 +0000 Subject: [PATCH 17/20] Update docs/sdk/src/reference_docs/frame_origin.rs Co-authored-by: Liam Aharon --- docs/sdk/src/reference_docs/frame_origin.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index fe5f1037bfd1..2a1aff6fe51f 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -1,6 +1,6 @@ //! # FRAME Origin //! -//! let's start by eliminating a wrong assumption that is a common mistake: +//! Let's start by clarifying a common wrong assumption about Origin: //! //! **ORIGIN IS NOT AN ACCOUNT ID**. //! From 4d60745388414e3f2de542efe1d272ea868449d0 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 27 Feb 2024 10:47:38 +0000 Subject: [PATCH 18/20] fix test --- docs/sdk/src/reference_docs/frame_runtime_types.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/sdk/src/reference_docs/frame_runtime_types.rs b/docs/sdk/src/reference_docs/frame_runtime_types.rs index 317124781b6d..b5838b79e518 100644 --- a/docs/sdk/src/reference_docs/frame_runtime_types.rs +++ b/docs/sdk/src/reference_docs/frame_runtime_types.rs @@ -204,9 +204,7 @@ pub mod pallet_bar { #[pallet::genesis_build] impl BuildGenesisConfig for GenesisConfig { - fn build(&self) { - todo!(); - } + fn build(&self) {} } #[pallet::call] From f300f0b951711487ff735a1a4ca826c6257263d1 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 27 Feb 2024 10:50:00 +0000 Subject: [PATCH 19/20] fmt --- docs/sdk/src/reference_docs/frame_origin.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/sdk/src/reference_docs/frame_origin.rs b/docs/sdk/src/reference_docs/frame_origin.rs index 2a1aff6fe51f..49533157b014 100644 --- a/docs/sdk/src/reference_docs/frame_origin.rs +++ b/docs/sdk/src/reference_docs/frame_origin.rs @@ -40,9 +40,9 @@ //! //! Note that [`OriginFor`](frame_system::pallet_prelude::OriginFor) is merely a shorthand for //! [`frame_system::Config::RuntimeOrigin`]. Given the name prefix `Runtime`, we can learn that -//! `RuntimeOrigin` is similar to `RuntimeCall` and others, a runtime composite enum that is amalgamated -//! at the runtime level. Read [`crate::reference_docs::frame_runtime_types`] to familiarize -//! yourself with these types. +//! `RuntimeOrigin` is similar to `RuntimeCall` and others, a runtime composite enum that is +//! amalgamated at the runtime level. Read [`crate::reference_docs::frame_runtime_types`] to +//! familiarize yourself with these types. //! //! To understand this better, we will next create a pallet with a custom origin, which will add a //! new variant to `RuntimeOrigin`. From bd52990ab32b60337130c6ed5b6d8787e6c45fb3 Mon Sep 17 00:00:00 2001 From: kianenigma Date: Tue, 27 Feb 2024 11:14:33 +0000 Subject: [PATCH 20/20] try and fix rustdocs build --- .gitlab/pipeline/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab/pipeline/build.yml b/.gitlab/pipeline/build.yml index b3a83e94981a..423587c1fb57 100644 --- a/.gitlab/pipeline/build.yml +++ b/.gitlab/pipeline/build.yml @@ -91,7 +91,7 @@ build-rustdoc: - .run-immediately variables: SKIP_WASM_BUILD: 1 - RUSTDOCFLAGS: "--default-theme=ayu --html-in-header $(pwd)/docs/sdk/headers/header.html --extend-css $(pwd)/docs/sdk/headers/theme.css" + RUSTDOCFLAGS: "--default-theme=ayu --html-in-header ./docs/sdk/headers/header.html --extend-css ./docs/sdk/headers/theme.css" artifacts: name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME}-doc" when: on_success