Improve Signed Extension and Block Decoding Examples/Book (#1357)

* asset hub example and book adjustment

* formatting

* recursive derives

* polkadot monitor example and book adjustments

* formatting

* adjust docs and examples, add dynamic example

* james suggestions

* fmt

* chore(subxt/src): typo fix (#1370)

* rpcmethods

* followstr

* mod and else

* Weekly Cronjob fetching artifacts and generating polkadot.rs file. (#1352)

* github CI action cronjob

* add commit message

* fix the CI yml files

* binary crate for CI script with substrate-runner

* update the CI script

* correct the artifacts script

* remove bash script

---------

Co-authored-by: James Wilson <james@jsdw.me>
Co-authored-by: Pan chao <152830401+Pan-chao@users.noreply.github.com>
This commit is contained in:
Tadeo Hepperle
2024-01-18 16:39:17 +01:00
committed by GitHub
parent e36f4ad270
commit 05825bed49
7 changed files with 243 additions and 15 deletions
+12
View File
@@ -152,3 +152,15 @@
//! ```rust,ignore
#![doc = include_str ! ("../../../examples/setup_config_custom.rs")]
//! ```
//!
//! ### Using a type from the metadata as a config parameter
//!
//! You can also use types that are generated from chain metadata as type parameters of the Config trait.
//! Just make sure all trait bounds are satisfied. This can often be achieved by using custom derives with the subxt macro.
//! For example, the AssetHub Parachain expects tips to include a `MultiLocation`, which is a type we can draw from the metadata.
//!
//! This example shows what using the `MultiLocation` struct as part of your config would look like in subxt:
//!
//! ```rust,ignore
#![doc = include_str ! ("../../../examples/setup_config_assethub.rs")]
//! ```
+63 -4
View File
@@ -27,13 +27,72 @@
//! Aside from these links to other Subxt APIs, the main thing that we can do here is iterate over and
//! decode the extrinsics in a block body.
//!
//! ## Example
//! ## Decoding Extrinsics
//!
//! Given a block, you can [download the block body](crate::blocks::Block::extrinsics()) and iterate over
//! the extrinsics stored within it. From there, you can decode the extrinsics and access various details,
//! including the associated events:
//! Given a block, you can [download the block body](crate::blocks::Block::extrinsics()) and [iterate over
//! the extrinsics](crate::blocks::Extrinsics::iter()) stored within it. The extrinsics yielded are of type
//! [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), which is just a blob of bytes that also stores which
//! pallet and call in that pallet it belongs to. It also contains information about signed extensions that
//! have been used for submitting this extrinsic.
//!
//! To use the extrinsic, you probably want to decode it into a concrete Rust type. These Rust types representing
//! extrinsics from different pallets can be generated from metadata using the subxt macro or the CLI tool.
//!
//! When decoding the extrinsic into a static type you have two options:
//!
//! ### Statically decode the extrinsics into [the root extrinsic type](crate::blocks::ExtrinsicDetails::as_root_extrinsic())
//!
//! The root extrinsic type generated by subxt is a Rust enum with one variant for each pallet. Each of these
//! variants has a field that is another enum whose variants cover all calls of the respective pallet.
//! If the extrinsic bytes are valid and your metadata matches the chain's metadata, decoding the bytes of an extrinsic into
//! this root extrinsic type should always succeed.
//!
//! This example shows how to subscribe to blocks and decode the extrinsics in each block into the root extrinsic type.
//! Once we get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails), we can decode it statically or dynamically.
//! We can also access details about the extrinsic, including the associated events and signed extensions.
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/blocks_subscribing.rs")]
//! ```
//!
//! ### Statically decode the extrinsic into [a specific pallet call](crate::blocks::ExtrinsicDetails::as_extrinsic())
//!
//! This is useful if you are expecting a specific extrinsic to be part of some block. If the extrinsic you try to decode
//! is a different extrinsic, an `Ok(None)` value is returned from [`as_extrinsic::<T>()`](crate::blocks::ExtrinsicDetails::as_extrinsic());
//!
//! If you are only interested in finding specific extrinsics in a block, you can also [iterate over all of them](crate::blocks::Extrinsics::find),
//! get only [the first one](crate::blocks::Extrinsics::find_first), or [the last one](crate::blocks::Extrinsics::find_last).
//!
//! The following example monitors `TransferKeepAlive` extrinsics on the Polkadot network.
//! We statically decode them and access the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and [account nonce](crate::blocks::ExtrinsicSignedExtensions::nonce()) signed extensions.
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/block_decoding_static.rs")]
//! ```
//!
//! ### Dynamically decode the extrinsic
//!
//! Sometimes you might use subxt with metadata that is not known at compile time. In this case, you do not have access to a statically generated
//! interface module that contains the relevant Rust types. You can [decode ExtrinsicDetails dynamically](crate::blocks::ExtrinsicDetails::field_values()),
//! which gives you access to it's fields as a [scale value composite](scale_value::Composite).
//! The following example looks for signed extrinsics on the Polkadot network and retrieves their pallet name, variant name, data fields and signed extensions dynamically.
//! Notice how we do not need to use code generation via the subxt macro. The only fixed component we provide is the [PolkadotConfig](crate::config::PolkadotConfig).
//! Other than that it works in a chain-agnostic way:
//!
//! ```rust,ignore
#![doc = include_str!("../../../examples/block_decoding_dynamic.rs")]
//! ```
//!
//! ## Decoding signed extensions
//!
//! Extrinsics can contain signed extensions. The signed extensions can be different across chains.
//! The [Config](crate::Config) implementation for your chain defines which signed extensions you expect.
//! Once you get hold of the [ExtrinsicDetails](crate::blocks::ExtrinsicDetails) for an extrinsic you are interested in,
//! you can try to [get its signed extensions](crate::blocks::ExtrinsicDetails::signed_extensions()).
//! These are only available on signed extrinsics. You can try to [find a specific signed extension](crate::blocks::ExtrinsicSignedExtensions::find),
//! in the returned [signed extensions](crate::blocks::ExtrinsicSignedExtensions).
//!
//! Subxt also provides utility functions to get the [tip](crate::blocks::ExtrinsicSignedExtensions::tip()) and the
//! [account nonce](crate::blocks::ExtrinsicSignedExtensions::tip()) associated with an extrinsic, given its signed extensions.
//! If you prefer to do things dynamically you can get the data of the signed extension as a [scale value](crate::blocks::ExtrinsicSignedExtension::value()).
//!