Skip to content

Commit

Permalink
Add PoV-reclaim enablement guide to polkadot-sdk-docs (paritytech#4244)
Browse files Browse the repository at this point in the history
This adds a small guide on how to prepare your parachain for pov-reclaim
usage.
  • Loading branch information
skunert authored and TarekkMA committed Aug 2, 2024
1 parent 3484749 commit f821788
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 2 deletions.
6 changes: 6 additions & 0 deletions Cargo.lock

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

7 changes: 6 additions & 1 deletion docs/sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ sc-consensus-grandpa = { path = "../../substrate/client/consensus/grandpa" }
sc-consensus-beefy = { path = "../../substrate/client/consensus/beefy" }
sc-consensus-manual-seal = { path = "../../substrate/client/consensus/manual-seal" }
sc-consensus-pow = { path = "../../substrate/client/consensus/pow" }
sc-executor = { path = "../../substrate/client/executor" }
sc-service = { path = "../../substrate/client/service" }

substrate-wasm-builder = { path = "../../substrate/utils/wasm-builder" }

Expand All @@ -61,9 +63,12 @@ cumulus-pallet-parachain-system = { path = "../../cumulus/pallets/parachain-syst
"parameterized-consensus-hook",
] }
parachain-info = { package = "staging-parachain-info", path = "../../cumulus/parachains/pallets/parachain-info" }
pallet-aura = { path = "../../substrate/frame/aura", default-features = false }
cumulus-primitives-proof-size-hostfunction = { path = "../../cumulus/primitives/proof-size-hostfunction" }
cumulus-client-service = { path = "../../cumulus/client/service" }
cumulus-primitives-storage-weight-reclaim = { path = "../../cumulus/primitives/storage-weight-reclaim" }

# Pallets and FRAME internals
pallet-aura = { path = "../../substrate/frame/aura" }
pallet-timestamp = { path = "../../substrate/frame/timestamp" }
pallet-balances = { path = "../../substrate/frame/balances" }
pallet-assets = { path = "../../substrate/frame/assets" }
Expand Down
84 changes: 84 additions & 0 deletions docs/sdk/src/guides/enable_pov_reclaim.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
//! This guide will teach you how to enable storage weight reclaiming for a parachain. The
//! explanations in this guide assume a project structure similar to the one detailed in
//! the [substrate documentation](crate::polkadot_sdk::substrate#anatomy-of-a-binary-crate). Full
//! technical details are available in the original [pull request](https://github.com/paritytech/polkadot-sdk/pull/3002).
//!
//! # What is PoV reclaim?
//! When a parachain submits a block to a relay chain like Polkadot or Kusama, it sends the block
//! itself and a storage proof. Together they form the Proof-of-Validity (PoV). The PoV allows the
//! relay chain to validate the parachain block by re-executing it. Relay chain
//! validators distribute this PoV among themselves over the network. This distribution is costly
//! and limits the size of the storage proof. The storage weight dimension of FRAME weights reflects
//! this cost and limits the size of the storage proof. However, the storage weight determined
//! during [benchmarking](crate::reference_docs::frame_benchmarking_weight) represents the worst
//! case. In reality, runtime operations often consume less space in the storage proof. PoV reclaim
//! offers a mechanism to reclaim the difference between the benchmarked worst-case and the real
//! proof-size consumption.
//!
//!
//! # How to enable PoV reclaim
//! ## 1. Add the host function to your node
//!
//! To reclaim excess storage weight, a parachain runtime needs the
//! ability to fetch the size of the storage proof from the node. The reclaim
//! mechanism uses the
//! [`storage_proof_size`](cumulus_primitives_proof_size_hostfunction::storage_proof_size)
//! host function for this purpose. For convenience, cumulus provides
//! [`ParachainHostFunctions`](cumulus_client_service::ParachainHostFunctions), a set of
//! host functions typically used by cumulus-based parachains. In the binary crate of your
//! parachain, find the instantiation of the [`WasmExecutor`](sc_executor::WasmExecutor) and set the
//! correct generic type.
//!
//! This example from the parachain-template shows a type definition that includes the correct
//! host functions.
#![doc = docify::embed!("../../templates/parachain/node/src/service.rs", wasm_executor)]
//!
//! > **Note:**
//! >
//! > If you see error `runtime requires function imports which are not present on the host:
//! > 'env:ext_storage_proof_size_storage_proof_size_version_1'`, it is likely
//! > that this step in the guide was not set up correctly.
//!
//! ## 2. Enable storage proof recording during import
//!
//! The reclaim mechanism reads the size of the currently recorded storage proof multiple times
//! during block authoring and block import. Proof recording during authoring is already enabled on
//! parachains. You must also ensure that storage proof recording is enabled during block import.
//! Find where your node builds the fundamental substrate components by calling
//! [`new_full_parts`](sc_service::new_full_parts). Replace this
//! with [`new_full_parts_record_import`](sc_service::new_full_parts_record_import) and
//! pass `true` as the last parameter to enable import recording.
#![doc = docify::embed!("../../templates/parachain/node/src/service.rs", component_instantiation)]
//!
//! > **Note:**
//! >
//! > If you see error `Storage root must match that calculated.` during block import, it is likely
//! > that this step in the guide was not
//! > set up correctly.
//!
//! ## 3. Add the SignedExtension to your runtime
//!
//! In your runtime, you will find a list of SignedExtensions.
//! To enable the reclaiming,
//! add [`StorageWeightReclaim`](cumulus_primitives_storage_weight_reclaim::StorageWeightReclaim)
//! to that list. For maximum efficiency, make sure that `StorageWeightReclaim` is last in the list.
//! The extension will check the size of the storage proof before and after an extrinsic execution.
//! It reclaims the difference between the calculated size and the benchmarked size.
#![doc = docify::embed!("../../templates/parachain/runtime/src/lib.rs", template_signed_extra)]
//!
//! ## Optional: Verify that reclaim works
//!
//! Start your node with the log target `runtime::storage_reclaim` set to `trace` to enable full
//! logging for `StorageWeightReclaim`. The following log is an example from a local testnet. To
//! trigger the log, execute any extrinsic on the network.
//!
//! ```ignore
//! ...
//! 2024-04-22 17:31:48.014 TRACE runtime::storage_reclaim: [ferdie] Reclaiming storage weight. benchmarked: 3593, consumed: 265 unspent: 0
//! ...
//! ```
//!
//! In the above example we see a benchmarked size of 3593 bytes, while the extrinsic only consumed
//! 265 bytes of proof size. This results in 3328 bytes of reclaim.
#![deny(rustdoc::broken_intra_doc_links)]
#![deny(rustdoc::private_intra_doc_links)]
3 changes: 3 additions & 0 deletions docs/sdk/src/guides/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,6 @@ 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;

/// How to enable storage weight reclaiming in a parachain node and runtime.
pub mod enable_pov_reclaim;
2 changes: 1 addition & 1 deletion docs/sdk/src/meta_contributing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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/assets/header.html --extend-css $(pwd)/docs/sdk/assets/theme.css --default-theme=ayu" \
//! cargo doc -p polkadot-sdk-docs --no-deps --open
//! ```
//!
Expand Down
1 change: 1 addition & 0 deletions templates/parachain/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ serde = { features = ["derive"], workspace = true, default-features = true }
jsonrpsee = { version = "0.22", features = ["server"] }
futures = "0.3.28"
serde_json = { workspace = true, default-features = true }
docify = "0.2.8"

# Local
parachain-template-runtime = { path = "../runtime" }
Expand Down
2 changes: 2 additions & 0 deletions templates/parachain/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use sc_transaction_pool_api::OffchainTransactionPoolFactory;
use sp_keystore::KeystorePtr;
use substrate_prometheus_endpoint::Registry;

#[docify::export(wasm_executor)]
type ParachainExecutor = WasmExecutor<ParachainHostFunctions>;

type ParachainClient = TFullClient<Block, RuntimeApi, ParachainExecutor>;
Expand All @@ -61,6 +62,7 @@ pub type Service = PartialComponents<
///
/// Use this macro if you don't actually need the full service, but just the builder in order to
/// be able to perform chain operations.
#[docify::export(component_instantiation)]
pub fn new_partial(config: &Configuration) -> Result<Service, sc_service::Error> {
let telemetry = config
.telemetry_endpoints
Expand Down
1 change: 1 addition & 0 deletions templates/parachain/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ scale-info = { version = "2.11.1", default-features = false, features = [
"derive",
] }
smallvec = "1.11.0"
docify = "0.2.8"

# Local
pallet-parachain-template = { path = "../pallets/template", default-features = false }
Expand Down
1 change: 1 addition & 0 deletions templates/parachain/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ pub type SignedBlock = generic::SignedBlock<Block>;
pub type BlockId = generic::BlockId<Block>;

/// The SignedExtension to the basic transaction logic.
#[docify::export(template_signed_extra)]
pub type SignedExtra = (
frame_system::CheckNonZeroSender<Runtime>,
frame_system::CheckSpecVersion<Runtime>,
Expand Down

0 comments on commit f821788

Please sign in to comment.