diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 0793c31dbb87..8ec3660307d4 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -32,8 +32,8 @@ jobs: - uses: actions/checkout@6d193bf28034eafb982f37bd894289fe649468fc # v4.1.7 - name: script run: | - forklift cargo clippy --all-targets --locked --workspace --quiet - forklift cargo clippy --all-targets --all-features --locked --workspace --quiet + cargo clippy --all-targets --locked --workspace --quiet + cargo clippy --all-targets --all-features --locked --workspace --quiet check-try-runtime: runs-on: ${{ needs.preflight.outputs.RUNNER }} needs: [preflight] diff --git a/.github/workflows/misc-sync-templates.yml b/.github/workflows/misc-sync-templates.yml index b5db0538569b..7ff0705fe249 100644 --- a/.github/workflows/misc-sync-templates.yml +++ b/.github/workflows/misc-sync-templates.yml @@ -83,6 +83,12 @@ jobs: homepage = "https://paritytech.github.io/polkadot-sdk/" [workspace] + EOF + + [ ${{ matrix.template }} != "solochain" ] && echo "# Leave out the node compilation from regular template usage." \ + && echo "\"default-members\" = [\"pallets/template\", \"runtime\"]" >> Cargo.toml + [ ${{ matrix.template }} == "solochain" ] && echo "# The node isn't yet replaceable by Omni Node." + cat << EOF >> Cargo.toml members = [ "node", "pallets/template", diff --git a/Cargo.lock b/Cargo.lock index 520b088f913c..14ce58be7faa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3077,6 +3077,32 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" +[[package]] +name = "cmd_lib" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "371c15a3c178d0117091bd84414545309ca979555b1aad573ef591ad58818d41" +dependencies = [ + "cmd_lib_macros", + "env_logger 0.10.1", + "faccess", + "lazy_static", + "log", + "os_pipe", +] + +[[package]] +name = "cmd_lib_macros" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb844bd05be34d91eb67101329aeba9d3337094c04fd8507d821db7ebb488eaf" +dependencies = [ + "proc-macro-error2", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.82", +] + [[package]] name = "coarsetime" version = "0.1.23" @@ -5389,18 +5415,18 @@ checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" [[package]] name = "docify" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2f138ad521dc4a2ced1a4576148a6a610b4c5923933b062a263130a6802ce" +checksum = "a772b62b1837c8f060432ddcc10b17aae1453ef17617a99bc07789252d2a5896" dependencies = [ "docify_macros", ] [[package]] name = "docify_macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a081e51fb188742f5a7a1164ad752121abcb22874b21e2c3b0dd040c515fdad" +checksum = "60e6be249b0a462a14784a99b19bf35a667bb5e09de611738bb7362fa4c95ff7" dependencies = [ "common-path", "derive-syn-parse", @@ -5899,6 +5925,17 @@ dependencies = [ "once_cell", ] +[[package]] +name = "faccess" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ae66425802d6a903e268ae1a08b8c38ba143520f227a205edf4e9c7e3e26d5" +dependencies = [ + "bitflags 1.3.2", + "libc", + "winapi", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -10733,6 +10770,16 @@ dependencies = [ "num-traits", ] +[[package]] +name = "os_pipe" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffd2b0a5634335b135d5728d84c5e0fd726954b87111f7506a61c502280d982" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + [[package]] name = "os_str_bytes" version = "6.5.1" @@ -16771,6 +16818,28 @@ dependencies = [ "version_check", ] +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.82", +] + [[package]] name = "proc-macro-hack" version = "0.5.20+deprecated" @@ -23493,6 +23562,8 @@ name = "staging-chain-spec-builder" version = "1.6.1" dependencies = [ "clap 4.5.13", + "cmd_lib", + "docify", "log", "sc-chain-spec", "serde", @@ -26744,7 +26815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" dependencies = [ "windows-core 0.52.0", - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -26762,7 +26833,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", ] [[package]] @@ -26789,7 +26860,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", ] [[package]] @@ -26824,17 +26904,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -26851,9 +26932,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -26869,9 +26950,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -26887,9 +26968,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -26905,9 +26992,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -26923,9 +27010,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -26941,9 +27028,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -26959,9 +27046,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" diff --git a/Cargo.toml b/Cargo.toml index e451529431ba..f3042a8a3bdf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -556,7 +556,13 @@ default-members = [ [workspace.lints.rust] suspicious_double_ref_op = { level = "allow", priority = 2 } # `substrate_runtime` is a common `cfg` condition name used in the repo. -unexpected_cfgs = { level = "warn", check-cfg = ['cfg(build_opt_level, values("3"))', 'cfg(build_profile, values("debug", "release"))', 'cfg(enable_alloc_error_handler)', 'cfg(fuzzing)', 'cfg(substrate_runtime)'] } +unexpected_cfgs = { level = "warn", check-cfg = [ + 'cfg(build_opt_level, values("3"))', + 'cfg(build_profile, values("debug", "release"))', + 'cfg(enable_alloc_error_handler)', + 'cfg(fuzzing)', + 'cfg(substrate_runtime)', +] } [workspace.lints.clippy] all = { level = "allow", priority = 0 } @@ -677,6 +683,7 @@ cid = { version = "0.9.0" } clap = { version = "4.5.13" } clap-num = { version = "1.0.2" } clap_complete = { version = "4.5.13" } +cmd_lib = { version = "1.9.5" } coarsetime = { version = "0.1.22" } codec = { version = "3.6.12", default-features = false, package = "parity-scale-codec" } collectives-westend-emulated-chain = { path = "cumulus/parachains/integration-tests/emulated/chains/parachains/collectives/collectives-westend" } @@ -735,7 +742,7 @@ derive_more = { version = "0.99.17", default-features = false } digest = { version = "0.10.3", default-features = false } directories = { version = "5.0.1" } dlmalloc = { version = "0.2.4" } -docify = { version = "0.2.8" } +docify = { version = "0.2.9" } dyn-clonable = { version = "0.9.0" } dyn-clone = { version = "1.0.16" } ed25519-dalek = { version = "2.1", default-features = false } @@ -1087,7 +1094,9 @@ polkavm-derive = "0.9.1" polkavm-linker = "0.9.2" portpicker = { version = "0.1.1" } pretty_assertions = { version = "1.3.0" } -primitive-types = { version = "0.13.1", default-features = false, features = ["num-traits"] } +primitive-types = { version = "0.13.1", default-features = false, features = [ + "num-traits", +] } proc-macro-crate = { version = "3.0.0" } proc-macro-warning = { version = "1.0.0", default-features = false } proc-macro2 = { version = "1.0.86" } diff --git a/cumulus/polkadot-omni-node/README.md b/cumulus/polkadot-omni-node/README.md new file mode 100644 index 000000000000..d87b3b63c407 --- /dev/null +++ b/cumulus/polkadot-omni-node/README.md @@ -0,0 +1,65 @@ +# Polkadot Omni Node + +This is a white labeled implementation based on [`polkadot-omni-node-lib`](https://crates.io/crates/polkadot-omni-node-lib). +It can be used to start a parachain node from a provided chain spec file. It is only compatible with runtimes that use block +number `u32` and `Aura` consensus. + +## Installation + +Download & expose it via `PATH`: + +```bash +# Download and set it on PATH. +wget https://github.com/paritytech/polkadot-sdk/releases/download//polkadot-omni-node +chmod +x polkadot-omni-node +export PATH="$PATH:`pwd`" +``` + +Compile & install via `cargo`: + +```bash +# Assuming ~/.cargo/bin is on the PATH +cargo install polkadot-omni-node +``` + +## Usage + +A basic example for an Omni Node run starts from a runtime which implements the [`sp_genesis_builder::GenesisBuilder`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html). +The interface mandates the runtime to expose a [`named-preset`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/#generate-chain-spec-using-runtime-provided-genesis-config-preset). + +### 1. Install chain-spec-builder + +**Note**: `chain-spec-builder` binary is published on [`crates.io`](https://crates.io) under +[`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) due to a name conflict. +Install it with `cargo` like bellow : + +```bash +cargo install staging-chain-spec-builder +``` + +### 2. Generate a chain spec + +Omni Node expects for the chain spec to contain parachains related fields like `relay_chain` and `para_id`. +These fields can be introduced by running [`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) +with additional flags: + +```bash +chain-spec-builder create --relay-chain --para-id -r named-preset +``` + +### 3. Run Omni Node + +And now with the generated chain spec we can start Omni Node like so: + +```bash +polkadot-omni-node --chain +``` + +## Useful links + +* [`Omni Node Polkadot SDK Docs`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html) +* [`Chain Spec Genesis Reference Docs`](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/chain_spec_genesis/index.html) +* [`polkadot-parachain-bin`](https://crates.io/crates/polkadot-parachain-bin) +* [`polkadot-sdk-parachain-template`](https://github.com/paritytech/polkadot-sdk-parachain-template) +* [`frame-omni-bencher`](https://crates.io/crates/frame-omni-bencher) +* [`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) diff --git a/cumulus/polkadot-omni-node/lib/README.md b/cumulus/polkadot-omni-node/lib/README.md new file mode 100644 index 000000000000..5789a35a1016 --- /dev/null +++ b/cumulus/polkadot-omni-node/lib/README.md @@ -0,0 +1,26 @@ +# Polkadot Omni Node Library + +Helper library that can be used to run a parachain node. + +## Overview + +This library can be used to run a parachain node while also customizing the chain specs +that are supported by default by the `--chain-spec` argument of the node's `CLI` +and the parameters of the runtime that is associated with each of these chain specs. + +## API + +The library exposes the possibility to provide a [`RunConfig`]. Through this structure +2 optional configurations can be provided: +- a chain spec loader (an implementation of [`chain_spec::LoadSpec`]): this can be used for + providing the chain specs that are supported by default by the `--chain-spec` argument of the + node's `CLI` and the actual chain config associated with each one. +- a runtime resolver (an implementation of [`runtime::RuntimeResolver`]): this can be used for + providing the parameters of the runtime that is associated with each of the chain specs + +Apart from this, a [`CliConfig`] can also be provided, that can be used to customize some +user-facing binary author, support url, etc. + +## Examples + +For an example, see the [`polkadot-parachain-bin`](https://crates.io/crates/polkadot-parachain-bin) crate. diff --git a/cumulus/polkadot-omni-node/lib/src/lib.rs b/cumulus/polkadot-omni-node/lib/src/lib.rs index 3f01f4211144..ccc1b542b253 100644 --- a/cumulus/polkadot-omni-node/lib/src/lib.rs +++ b/cumulus/polkadot-omni-node/lib/src/lib.rs @@ -14,40 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Cumulus. If not, see . -//! # Polkadot Omni Node Library -//! -//! Helper library that can be used to run a parachain node. -//! -//! ## Overview -//! -//! This library can be used to run a parachain node while also customizing the chain specs -//! that are supported by default by the `--chain-spec` argument of the node's `CLI` -//! and the parameters of the runtime that is associated with each of these chain specs. -//! -//! ## API -//! -//! The library exposes the possibility to provide a [`RunConfig`]. Through this structure -//! 2 optional configurations can be provided: -//! - a chain spec loader (an implementation of [`chain_spec::LoadSpec`]): this can be used for -//! providing the chain specs that are supported by default by the `--chain-spec` argument of the -//! node's `CLI` and the actual chain config associated with each one. -//! - a runtime resolver (an implementation of [`runtime::RuntimeResolver`]): this can be used for -//! providing the parameters of the runtime that is associated with each of the chain specs -//! -//! Apart from this, a [`CliConfig`] can also be provided, that can be used to customize some -//! user-facing binary author, support url, etc. -//! -//! ## Examples -//! -//! For an example, see the [`polkadot-parachain-bin`](https://crates.io/crates/polkadot-parachain-bin) crate. -//! -//! ## Binary -//! -//! It can be used to start a parachain node from a provided chain spec file. -//! It is only compatible with runtimes that use block number `u32` and `Aura` consensus. -//! -//! Example: `polkadot-omni-node --chain ` - +#![doc = include_str!("../README.md")] #![deny(missing_docs)] pub mod cli; diff --git a/prdoc/pr_5954.prdoc b/prdoc/pr_5954.prdoc new file mode 100644 index 000000000000..2c9efcce7a6a --- /dev/null +++ b/prdoc/pr_5954.prdoc @@ -0,0 +1,19 @@ +# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0 +# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json + +title: "templates: make node compilation optional" + +doc: + - audience: [Node Dev, Runtime Dev] + description: | + Node compilation for minimal and parachain templates is made optional, not part of the + templates `default-members` list. At the same time, we introduce OmniNode as alternative + to run the templates. + +crates: + - name: polkadot-omni-node + bump: patch + - name: polkadot-omni-node-lib + bump: patch + - name: staging-chain-spec-builder + bump: patch diff --git a/substrate/bin/utils/chain-spec-builder/Cargo.toml b/substrate/bin/utils/chain-spec-builder/Cargo.toml index f2fe8cb7e166..b71e935a918f 100644 --- a/substrate/bin/utils/chain-spec-builder/Cargo.toml +++ b/substrate/bin/utils/chain-spec-builder/Cargo.toml @@ -21,15 +21,28 @@ path = "bin/main.rs" name = "chain-spec-builder" [lib] -crate-type = ["rlib"] +# Docs tests are not needed since the code samples that would be executed +# are exercised already in the context of unit/integration tests, by virtue +# of using a combination of encapsulation in functions + `docify::export`. +# This is a practice we should use for new code samples if any. +doctest = false [dependencies] clap = { features = ["derive"], workspace = true } +docify = { workspace = true } log = { workspace = true, default-features = true } -sc-chain-spec = { features = ["clap"], workspace = true, default-features = true } +sc-chain-spec = { features = [ + "clap", +], workspace = true, default-features = true } serde_json = { workspace = true, default-features = true } serde = { workspace = true, default-features = true } sp-tracing = { workspace = true, default-features = true } [dev-dependencies] substrate-test-runtime = { workspace = true } +cmd_lib = { workspace = true } +docify = { workspace = true } + +[features] +# `cargo build --feature=generate-readme` updates the `README.md` file. +generate-readme = [] diff --git a/substrate/bin/utils/chain-spec-builder/README.docify.md b/substrate/bin/utils/chain-spec-builder/README.docify.md new file mode 100644 index 000000000000..bb4db4c666e0 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/README.docify.md @@ -0,0 +1,102 @@ +# Chain Spec Builder + +Substrate's chain spec builder utility. + +A chain-spec is short for `chain-specification`. See the [`sc-chain-spec`](https://crates.io/docs.rs/sc-chain-spec/latest/sc_chain_spec) +for more information. + +_Note:_ this binary is a more flexible alternative to the `build-spec` subcommand, contained in typical Substrate-based nodes. +This particular binary is capable of interacting with [`sp-genesis-builder`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/index.html) +implementation of any provided runtime allowing to build chain-spec JSON files. + +See [`ChainSpecBuilderCmd`](https://docs.rs/staging-chain-spec-builder/6.0.0/staging_chain_spec_builder/enum.ChainSpecBuilderCmd.html) +for a list of available commands. + +## Installation + +```bash +cargo install staging-chain-spec-builder +``` + +_Note:_ `chain-spec-builder` binary is published on [crates.io](https://crates.io) under +[`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) due to a name conflict. + +## Usage + +Please note that below usage is backed by integration tests. The commands' examples are wrapped +around by the `bash!(...)` macro calls. + +### Generate chains-spec using default config from runtime + +Query the default genesis config from the provided runtime WASM blob and use it in the chain spec. + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### Display the runtime's default `GenesisConfig` + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### Display the `GenesisConfig` preset with given name + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### List the names of `GenesisConfig` presets provided by runtime + + + +_Note:_ [`GenesisBuilder::preset_names`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.preset_names) +runtime function is called. + +### Generate chain spec using runtime provided genesis config preset + +Patch the runtime's default genesis config with the named preset provided by the runtime and generate the plain +version of chain spec: + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime functions are called. + +### Generate raw storage chain spec using genesis config patch + +Patch the runtime's default genesis config with provided `patch.json` and generate raw +storage (`-s`) version of chain spec: + + + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +and +[`GenesisBuilder::build_state`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state) +runtime functions are called. + +### Generate raw storage chain spec using full genesis config + +Build the chain spec using provided full genesis config json file. No defaults will be used: + + + +_Note_: [`GenesisBuilder::build_state`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state) +runtime function is called. + +### Generate human readable chain spec using provided genesis config patch + + + +### Generate human readable chain spec using provided full genesis config + + + +### Extra tools + +The `chain-spec-builder` provides also some extra utilities: [`VerifyCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.VerifyCmd.html), +[`ConvertToRawCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.ConvertToRawCmd.html), +[`UpdateCodeCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.UpdateCodeCmd.html). diff --git a/substrate/bin/utils/chain-spec-builder/README.md b/substrate/bin/utils/chain-spec-builder/README.md new file mode 100644 index 000000000000..e03c710ce1b3 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/README.md @@ -0,0 +1,140 @@ +# Chain Spec Builder + +Substrate's chain spec builder utility. + +A chain-spec is short for `chain-specification`. See the [`sc-chain-spec`](https://crates.io/docs.rs/sc-chain-spec/latest/sc_chain_spec) +for more information. + +_Note:_ this binary is a more flexible alternative to the `build-spec` subcommand, contained in typical Substrate-based nodes. +This particular binary is capable of interacting with [`sp-genesis-builder`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/index.html) +implementation of any provided runtime allowing to build chain-spec JSON files. + +See [`ChainSpecBuilderCmd`](https://docs.rs/staging-chain-spec-builder/6.0.0/staging_chain_spec_builder/enum.ChainSpecBuilderCmd.html) +for a list of available commands. + +## Installation + +```bash +cargo install staging-chain-spec-builder +``` + +_Note:_ `chain-spec-builder` binary is published on [crates.io](https://crates.io) under +[`staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder) due to a name conflict. + +## Usage + +Please note that below usage is backed by integration tests. The commands' examples are wrapped +around by the `bash!(...)` macro calls. + +### Generate chains-spec using default config from runtime + +Query the default genesis config from the provided runtime WASM blob and use it in the chain spec. + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path default +) +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### Display the runtime's default `GenesisConfig` + +```rust,ignore +bash!( + chain-spec-builder display-preset -r $runtime_path +) +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### Display the `GenesisConfig` preset with given name + +```rust,ignore +fn cmd_display_preset(runtime_path: &str) -> String { + bash!( + chain-spec-builder display-preset -r $runtime_path -p "staging" + ) +} +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime function is called. + +### List the names of `GenesisConfig` presets provided by runtime + +```rust,ignore +bash!( + chain-spec-builder list-presets -r $runtime_path +) +``` + +_Note:_ [`GenesisBuilder::preset_names`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.preset_names) +runtime function is called. + +### Generate chain spec using runtime provided genesis config preset + +Patch the runtime's default genesis config with the named preset provided by the runtime and generate the plain +version of chain spec: + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" --para-id 1000 -r $runtime_path named-preset "staging" +) +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +runtime functions are called. + +### Generate raw storage chain spec using genesis config patch + +Patch the runtime's default genesis config with provided `patch.json` and generate raw +storage (`-s`) version of chain spec: + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path patch "tests/input/patch.json" +) +``` + +_Note:_ [`GenesisBuilder::get_preset`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset) +and +[`GenesisBuilder::build_state`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state) +runtime functions are called. + +### Generate raw storage chain spec using full genesis config + +Build the chain spec using provided full genesis config json file. No defaults will be used: + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path full "tests/input/full.json" +) +``` + +_Note_: [`GenesisBuilder::build_state`](https://docs.rs/sp-genesis-builder/latest/sp_genesis_builder/trait.GenesisBuilder.html#method.build_state) +runtime function is called. + +### Generate human readable chain spec using provided genesis config patch + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path patch "tests/input/patch.json" +) +``` + +### Generate human readable chain spec using provided full genesis config + +```rust,ignore +bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path full "tests/input/full.json" +) +``` + +### Extra tools + +The `chain-spec-builder` provides also some extra utilities: [`VerifyCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.VerifyCmd.html), +[`ConvertToRawCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.ConvertToRawCmd.html), +[`UpdateCodeCmd`](https://docs.rs/staging-chain-spec-builder/latest/staging_chain_spec_builder/struct.UpdateCodeCmd.html). diff --git a/substrate/bin/utils/chain-spec-builder/src/lib.rs b/substrate/bin/utils/chain-spec-builder/src/lib.rs index 629edcf68568..98ff480b8ceb 100644 --- a/substrate/bin/utils/chain-spec-builder/src/lib.rs +++ b/substrate/bin/utils/chain-spec-builder/src/lib.rs @@ -15,107 +15,9 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . - -//! Substrate's chain spec builder utility. -//! -//! A chain-spec is short for `chain-configuration`. See the [`sc-chain-spec`] for more information. -//! -//! Note that this binary is analogous to the `build-spec` subcommand, contained in typical -//! substrate-based nodes. This particular binary is capable of interacting with -//! [`sp-genesis-builder`] implementation of any provided runtime allowing to build chain-spec JSON -//! files. -//! -//! See [`ChainSpecBuilderCmd`] for a list of available commands. -//! -//! ## Typical use-cases. -//! ##### Generate chains-spec using default config from runtime. -//! -//! Query the default genesis config from the provided `runtime.wasm` and use it in the chain -//! spec. -//! ```bash -//! chain-spec-builder create -r runtime.wasm default -//! ``` -//! -//! _Note:_ [`GenesisBuilder::get_preset`][sp-genesis-builder-get-preset] runtime function is -//! called. -//! -//! -//! ##### Display the runtime's default `GenesisConfig` -//! -//! Displays the content of the runtime's default `GenesisConfig` -//! ```bash -//! chain-spec-builder display-preset -r runtime.wasm -//! ``` -//! -//! _Note:_ [`GenesisBuilder::get_preset`][sp-genesis-builder-get-preset] runtime function is called. -//! -//! ##### Display the `GenesisConfig` preset with given name -//! -//! Displays the content of the `GenesisConfig` preset for given name -//! ```bash -//! chain-spec-builder display-preset -r runtime.wasm -p "staging" -//! ``` -//! -//! _Note:_ [`GenesisBuilder::get_preset`][sp-genesis-builder-get-preset] runtime function is called. -//! -//! ##### List the names of `GenesisConfig` presets provided by runtime. -//! -//! Displays the names of the presets of `GenesisConfigs` provided by runtime. -//! ```bash -//! chain-spec-builder list-presets -r runtime.wasm -//! ``` -//! -//! _Note:_ [`GenesisBuilder::preset_names`][sp-genesis-builder-list] runtime function is called. -//! -//! ##### Generate chain spec using runtime provided genesis config preset. -//! -//! Patch the runtime's default genesis config with the named preset provided by the runtime and generate the plain -//! version of chain spec: -//! ```bash -//! chain-spec-builder create -r runtime.wasm named-preset "staging" -//! ``` -//! -//! _Note:_ [`GenesisBuilder::get_preset`][sp-genesis-builder-get-preset] and [`GenesisBuilder::build_state`][sp-genesis-builder-build] runtime functions are called. -//! -//! ##### Generate raw storage chain spec using genesis config patch. -//! -//! Patch the runtime's default genesis config with provided `patch.json` and generate raw -//! storage (`-s`) version of chain spec: -//! ```bash -//! chain-spec-builder create -s -r runtime.wasm patch patch.json -//! ``` -//! -//! _Note:_ [`GenesisBuilder::build_state`][sp-genesis-builder-build] runtime function is called. -//! -//! ##### Generate raw storage chain spec using full genesis config. -//! -//! Build the chain spec using provided full genesis config json file. No defaults will be used: -//! ```bash -//! chain-spec-builder create -s -r runtime.wasm full full-genesis-config.json -//! ``` -//! -//! _Note_: [`GenesisBuilder::build_state`][sp-genesis-builder-build] runtime function is called. -//! -//! ##### Generate human readable chain spec using provided genesis config patch. -//! ```bash -//! chain-spec-builder create -r runtime.wasm patch patch.json -//! ``` -//! -//! ##### Generate human readable chain spec using provided full genesis config. -//! ```bash -//! chain-spec-builder create -r runtime.wasm full full-genesis-config.json -//! ``` -//! -//! ##### Extra tools. -//! The `chain-spec-builder` provides also some extra utilities: [`VerifyCmd`], [`ConvertToRawCmd`], -//! [`UpdateCodeCmd`]. -//! -//! [`sc-chain-spec`]: ../sc_chain_spec/index.html -//! [`node-cli`]: ../node_cli/index.html -//! [`sp-genesis-builder`]: ../sp_genesis_builder/index.html -//! [sp-genesis-builder-build]: ../sp_genesis_builder/trait.GenesisBuilder.html#method.build_state -//! [sp-genesis-builder-list]: ../sp_genesis_builder/trait.GenesisBuilder.html#method.preset_names -//! [sp-genesis-builder-get-preset]: ../sp_genesis_builder/trait.GenesisBuilder.html#method.get_preset +#![doc = include_str!("../README.md")] +#[cfg(feature = "generate-readme")] +docify::compile_markdown!("README.docify.md", "README.md"); use clap::{Parser, Subcommand}; use sc_chain_spec::{ diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/create_with_full.json b/substrate/bin/utils/chain-spec-builder/tests/expected/create_with_full.json index 6d127b6c0aca..10071670179a 100644 --- a/substrate/bin/utils/chain-spec-builder/tests/expected/create_with_full.json +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/create_with_full.json @@ -16,9 +16,18 @@ "config": { "babe": { "authorities": [ - "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", - "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", - "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b" + [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + 1 + ], + [ + "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", + 1 + ], + [ + "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b", + 1 + ] ], "epochConfig": { "allowed_slots": "PrimaryAndSecondaryVRFSlots", diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_default.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_default.json new file mode 100644 index 000000000000..203b6716cb26 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_default.json @@ -0,0 +1,36 @@ +{ + "name": "Custom", + "id": "custom", + "chainType": "Live", + "bootNodes": [], + "telemetryEndpoints": null, + "protocolId": null, + "properties": { + "tokenDecimals": 12, + "tokenSymbol": "UNIT" + }, + "codeSubstitutes": {}, + "genesis": { + "runtimeGenesis": { + "config": { + "babe": { + "authorities": [], + "epochConfig": { + "allowed_slots": "PrimaryAndSecondaryVRFSlots", + "c": [ + 1, + 4 + ] + } + }, + "balances": { + "balances": [] + }, + "substrateTest": { + "authorities": [] + }, + "system": {} + } + } + } +} \ No newline at end of file diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_full_plain.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_full_plain.json new file mode 100644 index 000000000000..26868c3241a1 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_full_plain.json @@ -0,0 +1,66 @@ +{ + "name": "Custom", + "id": "custom", + "chainType": "Live", + "bootNodes": [], + "telemetryEndpoints": null, + "protocolId": null, + "properties": { + "tokenDecimals": 12, + "tokenSymbol": "UNIT" + }, + "codeSubstitutes": {}, + "genesis": { + "runtimeGenesis": { + "config": { + "babe": { + "authorities": [ + [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + 1 + ], + [ + "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", + 1 + ], + [ + "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b", + 1 + ] + ], + "epochConfig": { + "allowed_slots": "PrimaryAndSecondaryVRFSlots", + "c": [ + 2, + 4 + ] + } + }, + "balances": { + "balances": [ + [ + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + 2000000000000000 + ], + [ + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + 2000000000000000 + ], + [ + "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b", + 5000000000000000 + ] + ] + }, + "substrateTest": { + "authorities": [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", + "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b" + ] + }, + "system": {} + } + } + } +} \ No newline at end of file diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_full_raw.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_full_raw.json new file mode 100644 index 000000000000..523a266fc439 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_full_raw.json @@ -0,0 +1,39 @@ +{ + "name": "Custom", + "id": "custom", + "chainType": "Live", + "bootNodes": [], + "telemetryEndpoints": null, + "protocolId": null, + "properties": { + "tokenDecimals": 12, + "tokenSymbol": "UNIT" + }, + "codeSubstitutes": {}, + "genesis": { + "raw": { + "top": { + "0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e", + "0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1cb6f36e027abb2091cfb5110ab5087f5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c0100000000000000186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e0100000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", + "0x1cb6f36e027abb2091cfb5110ab5087faacf00b9b41fda7a9268821c2a2b3e4c": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d01000000000000001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c0100000000000000186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e0100000000000000", + "0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0200000000000000040000000000000002", + "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92c2a60ec6dd16cd8ab911865ecf7555b186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e": "0x00000000000000000000000001000000000000000080e03779c311000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x000000000000000000000000010000000000000000008d49fd1a07000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x000000000000000000000000010000000000000000008d49fd1a07000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x0080faca73f91f00" + }, + "childrenDefault": {} + } + } +} diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_named_preset_staging.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_named_preset_staging.json new file mode 100644 index 000000000000..5cf51554b2cb --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_named_preset_staging.json @@ -0,0 +1,39 @@ +{ + "bootNodes": [], + "chainType": "Live", + "codeSubstitutes": {}, + "genesis": { + "runtimeGenesis": { + "patch": { + "balances": { + "balances": [ + [ + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + 1000000000000000 + ], + [ + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + 1000000000000000 + ] + ] + }, + "substrateTest": { + "authorities": [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL" + ] + } + } + } + }, + "id": "custom", + "name": "Custom", + "para_id": 1000, + "properties": { + "tokenDecimals": 12, + "tokenSymbol": "UNIT" + }, + "protocolId": null, + "relay_chain": "dev", + "telemetryEndpoints": null +} \ No newline at end of file diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_patch_plain.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_patch_plain.json new file mode 100644 index 000000000000..b243534c0d61 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_patch_plain.json @@ -0,0 +1,42 @@ +{ + "name": "Custom", + "id": "custom", + "chainType": "Live", + "bootNodes": [], + "telemetryEndpoints": null, + "protocolId": null, + "properties": { + "tokenDecimals": 12, + "tokenSymbol": "UNIT" + }, + "codeSubstitutes": {}, + "genesis": { + "runtimeGenesis": { + "patch": { + "balances": { + "balances": [ + [ + "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty", + 1000000000000000 + ], + [ + "5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y", + 1000000000000000 + ], + [ + "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b", + 5000000000000000 + ] + ] + }, + "substrateTest": { + "authorities": [ + "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", + "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", + "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b" + ] + } + } + } + } +} \ No newline at end of file diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_patch_raw.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_patch_raw.json new file mode 100644 index 000000000000..c4ac1cbe8ea1 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/create_with_patch_raw.json @@ -0,0 +1,37 @@ +{ + "name": "Custom", + "id": "custom", + "chainType": "Live", + "bootNodes": [], + "telemetryEndpoints": null, + "protocolId": null, + "properties": { + "tokenDecimals": 12, + "tokenSymbol": "UNIT" + }, + "codeSubstitutes": {}, + "genesis": { + "raw": { + "top": { + "0x00771836bebdd29870ff246d305c578c4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x00771836bebdd29870ff246d305c578c5e0621c4869aa60c02be9adcc98a0d1d": "0x0cd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e", + "0x1cb6f36e027abb2091cfb5110ab5087f4e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x1cb6f36e027abb2091cfb5110ab5087f66e8f035c8adbe7f1547b43c51e6f8a4": "0x00000000", + "0x1cb6f36e027abb2091cfb5110ab5087fdc6b171b77304263c292cc3ea5ed31ef": "0x0100000000000000040000000000000002", + "0x26aa394eea5630e07c48ae0c9558cef74e7b9012096b41c4eb3aaf947f6ea429": "0x0000", + "0x26aa394eea5630e07c48ae0c9558cef75684a022a34dd8bfa2baaf44f172b710": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef78a42f33323cb5ced3b44dd825fda9fcc": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a44704b568d21667356a5a050c118746bb1bdbcacd6ac9340000000000000000": "0x4545454545454545454545454545454545454545454545454545454545454545", + "0x26aa394eea5630e07c48ae0c9558cef7a7fd6c28836b9a28522dc924110cf439": "0x01", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92c2a60ec6dd16cd8ab911865ecf7555b186e1bafbb1430668c95d89b77217a402a74f64c3e103137b69e95e4b6e06b1e": "0x00000000000000000000000001000000000000000080e03779c311000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da94f9aea1afa791265fae359272badc1cf8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da9b0edae20838083f2cde1c4080db8cf8090b5ab205c6974c9ea841be688864633dc9ca8a357843eeacf2314649965fe22": "0x00000000000000000000000001000000000000000080c6a47e8d03000000000000000000000000000000000000000000000000000000000000000080", + "0x26aa394eea5630e07c48ae0c9558cef7f9cce9c888469bb1a0dceaa129672ef8": "0x0000", + "0x3a65787472696e7369635f696e646578": "0x00000000", + "0xc2261276cc9d1f8598ea4b6a74b15c2f4e7b9012096b41c4eb3aaf947f6ea429": "0x0100", + "0xc2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80": "0x00806d8176de1800" + }, + "childrenDefault": {} + } + } +} diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/display_preset.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/display_preset.json new file mode 100644 index 000000000000..6aa6799af771 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/display_preset.json @@ -0,0 +1 @@ +{"babe":{"authorities":[],"epochConfig":{"allowed_slots":"PrimaryAndSecondaryVRFSlots","c":[1,4]}},"balances":{"balances":[]},"substrateTest":{"authorities":[]},"system":{}} diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/display_preset_staging.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/display_preset_staging.json new file mode 100644 index 000000000000..b0c8e40c23a9 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/display_preset_staging.json @@ -0,0 +1 @@ +{"balances":{"balances":[["5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty",1000000000000000],["5FLSigC9HGRKVhB9FiEo4Y3koPsNmBmLJbpXg2mp1hXcS59Y",1000000000000000]]},"substrateTest":{"authorities":["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY","5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL"]}} diff --git a/substrate/bin/utils/chain-spec-builder/tests/expected/doc/list_presets.json b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/list_presets.json new file mode 100644 index 000000000000..882462391888 --- /dev/null +++ b/substrate/bin/utils/chain-spec-builder/tests/expected/doc/list_presets.json @@ -0,0 +1 @@ +{"presets":["foobar","staging"]} diff --git a/substrate/bin/utils/chain-spec-builder/tests/input/full.json b/substrate/bin/utils/chain-spec-builder/tests/input/full.json index f05e3505a2bb..e34aede52cbe 100644 --- a/substrate/bin/utils/chain-spec-builder/tests/input/full.json +++ b/substrate/bin/utils/chain-spec-builder/tests/input/full.json @@ -1,9 +1,9 @@ { "babe": { "authorities": [ - "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", - "5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", - "5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b" + ["5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY", 1], + ["5CiPPseXPECbkjWCa6MnjNokrgYjMqmKndv2rSnekmSK2DjL", 1], + ["5CcjiSgG2KLuKAsqkE2Nak1S2FbAcMr5SxRASUuwR3zSNV2b", 1] ], "epochConfig": { "allowed_slots": "PrimaryAndSecondaryVRFSlots", diff --git a/substrate/bin/utils/chain-spec-builder/tests/test.rs b/substrate/bin/utils/chain-spec-builder/tests/test.rs index f553f05f20a0..5ac687d75fd4 100644 --- a/substrate/bin/utils/chain-spec-builder/tests/test.rs +++ b/substrate/bin/utils/chain-spec-builder/tests/test.rs @@ -19,7 +19,10 @@ use std::fs::File; use clap::Parser; + +use cmd_lib::spawn_with_output; use sc_chain_spec::update_code_in_json_chain_spec; +use serde_json::{from_reader, from_str, Value}; use staging_chain_spec_builder::ChainSpecBuilder; // note: the runtime path will not be read, runtime code will be set directly, to avoid hassle with @@ -28,6 +31,44 @@ const DUMMY_PATH: &str = "fake-runtime-path"; const OUTPUT_FILE: &str = "/tmp/chain_spec_builder.test_output_file.json"; +// Used for running commands visually pleasing in doc tests. +macro_rules! bash( + ( chain-spec-builder $($a:tt)* ) => {{ + let bin_path = env!("CARGO_BIN_EXE_chain-spec-builder"); + spawn_with_output!( + $bin_path $($a)* + ) + .expect("a process running. qed") + .wait_with_output() + .expect("to get output. qed.") + }} +); + +// Used specifically in docs tests. +fn doc_assert(output: String, expected_output_path: &str, remove_code: bool) { + let expected: Value = + from_reader(File::open(expected_output_path).unwrap()).expect("a valid JSON. qed."); + let output = if remove_code { + let mut output: Value = from_str(output.as_str()).expect("a valid JSON. qed."); + // Remove code sections gracefully for both `plain` & `raw`. + output + .get_mut("genesis") + .and_then(|inner| inner.get_mut("runtimeGenesis")) + .and_then(|inner| inner.as_object_mut()) + .and_then(|inner| inner.remove("code")); + output + .get_mut("genesis") + .and_then(|inner| inner.get_mut("raw")) + .and_then(|inner| inner.get_mut("top")) + .and_then(|inner| inner.as_object_mut()) + .and_then(|inner| inner.remove("0x3a636f6465")); + output + } else { + from_str::(output.as_str()).expect("a valid JSON. qed.") + }; + assert_eq!(output, expected); +} + /// Asserts that the JSON in output file matches the JSON in expected file. /// /// This helper function reads the JSON content from the file at `OUTPUT_FILE + suffix` path. If the @@ -192,3 +233,165 @@ fn test_add_code_substitute() { builder.run().unwrap(); assert_output_eq_expected(true, SUFFIX, "tests/expected/add_code_substitute.json"); } + +#[docify::export_content] +fn cmd_create_default(runtime_path: &str) -> String { + bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path default + ) +} + +#[test] +fn create_default() { + doc_assert( + cmd_create_default( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"), + ), + "tests/expected/doc/create_default.json", + true, + ); +} + +#[docify::export_content] +fn cmd_display_default_preset(runtime_path: &str) -> String { + bash!( + chain-spec-builder display-preset -r $runtime_path + ) +} + +#[test] +fn display_default_preset() { + doc_assert( + cmd_display_default_preset( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed."), + ), + "tests/expected/doc/display_preset.json", + false, + ); +} + +#[docify::export] +fn cmd_display_preset(runtime_path: &str) -> String { + bash!( + chain-spec-builder display-preset -r $runtime_path -p "staging" + ) +} + +#[test] +fn display_preset() { + doc_assert( + cmd_display_preset( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"), + ), + "tests/expected/doc/display_preset_staging.json", + false, + ); +} + +#[docify::export_content] +fn cmd_list_presets(runtime_path: &str) -> String { + bash!( + chain-spec-builder list-presets -r $runtime_path + ) +} + +#[test] +fn list_presets() { + doc_assert( + cmd_list_presets( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"), + ), + "tests/expected/doc/list_presets.json", + false, + ); +} + +#[docify::export_content] +fn cmd_create_with_named_preset(runtime_path: &str) -> String { + bash!( + chain-spec-builder -c "/dev/stdout" create --relay-chain "dev" --para-id 1000 -r $runtime_path named-preset "staging" + ) +} + +#[test] +fn create_with_named_preset() { + doc_assert( + cmd_create_with_named_preset( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"), + ), + "tests/expected/doc/create_with_named_preset_staging.json", + true, + ) +} + +#[docify::export_content] +fn cmd_create_with_patch_raw(runtime_path: &str) -> String { + bash!( + chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path patch "tests/input/patch.json" + ) +} + +#[test] +fn create_with_patch_raw() { + doc_assert( + cmd_create_with_patch_raw( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"), + ), + "tests/expected/doc/create_with_patch_raw.json", + true, + ); +} + +#[docify::export_content] +fn cmd_create_with_patch_plain(runtime_path: &str) -> String { + bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path patch "tests/input/patch.json" + ) +} + +#[test] +fn create_with_patch_plain() { + doc_assert( + cmd_create_with_patch_plain( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"), + ), + "tests/expected/doc/create_with_patch_plain.json", + true, + ); +} + +#[docify::export_content] +fn cmd_create_full_plain(runtime_path: &str) -> String { + bash!( + chain-spec-builder -c "/dev/stdout" create -r $runtime_path full "tests/input/full.json" + ) +} + +#[test] +fn create_full_plain() { + doc_assert( + cmd_create_full_plain( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"), + ), + "tests/expected/doc/create_full_plain.json", + true, + ); +} + +#[docify::export_content] +fn cmd_create_full_raw(runtime_path: &str) -> String { + bash!( + chain-spec-builder -c "/dev/stdout" create -s -r $runtime_path full "tests/input/full.json" + ) +} + +#[test] +fn create_full_raw() { + doc_assert( + cmd_create_full_raw( + substrate_test_runtime::WASM_BINARY_PATH.expect("to be a valid path. qed"), + ), + "tests/expected/doc/create_full_raw.json", + true, + ); +} diff --git a/substrate/utils/wasm-builder/src/builder.rs b/substrate/utils/wasm-builder/src/builder.rs index eb761a103d62..a40aafe1d812 100644 --- a/substrate/utils/wasm-builder/src/builder.rs +++ b/substrate/utils/wasm-builder/src/builder.rs @@ -303,7 +303,8 @@ fn provide_dummy_wasm_binary_if_not_exist(file_path: &Path) { if !file_path.exists() { crate::write_file_if_changed( file_path, - "pub const WASM_BINARY: Option<&[u8]> = None;\ + "pub const WASM_BINARY_PATH: Option<&str> = None;\ + pub const WASM_BINARY: Option<&[u8]> = None;\ pub const WASM_BINARY_BLOATY: Option<&[u8]> = None;", ); } @@ -378,9 +379,11 @@ fn build_project( file_name, format!( r#" + pub const WASM_BINARY_PATH: Option<&str> = Some("{wasm_binary_path}"); pub const WASM_BINARY: Option<&[u8]> = Some(include_bytes!("{wasm_binary}")); pub const WASM_BINARY_BLOATY: Option<&[u8]> = Some(include_bytes!("{wasm_binary_bloaty}")); "#, + wasm_binary_path = wasm_binary, wasm_binary = wasm_binary, wasm_binary_bloaty = wasm_binary_bloaty, ), diff --git a/substrate/utils/wasm-builder/src/lib.rs b/substrate/utils/wasm-builder/src/lib.rs index e3f2ff5cd733..420ecd63e1dc 100644 --- a/substrate/utils/wasm-builder/src/lib.rs +++ b/substrate/utils/wasm-builder/src/lib.rs @@ -48,6 +48,8 @@ //! This will include the generated Wasm binary as two constants `WASM_BINARY` and //! `WASM_BINARY_BLOATY`. The former is a compact Wasm binary and the latter is the Wasm binary as //! being generated by the compiler. Both variables have `Option<&'static [u8]>` as type. +//! Additionally it will create the `WASM_BINARY_PATH` which is the path to the WASM blob on the +//! filesystem. //! //! ### Feature //! diff --git a/templates/minimal/Dockerfile b/templates/minimal/Dockerfile index 0c59192208fe..422f7f726a7e 100644 --- a/templates/minimal/Dockerfile +++ b/templates/minimal/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /polkadot COPY . /polkadot RUN cargo fetch -RUN cargo build --locked --release +RUN cargo build --workspace --locked --release FROM docker.io/parity/base-bin:latest diff --git a/templates/minimal/README.md b/templates/minimal/README.md index fe1317a033c7..cf43d71d8849 100644 --- a/templates/minimal/README.md +++ b/templates/minimal/README.md @@ -11,30 +11,54 @@ -* ๐Ÿค This template is a minimal (in terms of complexity and the number of components) +## Table of Contents + +- [Intro](#intro) + +- [Template Structure](#template-structure) + +- [Getting Started](#getting-started) + +- [Starting a Minimal Template Chain](#starting-a-minimal-template-chain) + + - [Omni Node](#omni-node) + - [Minimal Template Node](#minimal-template-node) + - [Zombienet with Omni Node](#zombienet-with-omni-node) + - [Zombienet with Minimal Template Node](#zombienet-with-minimal-template-node) + - [Connect with the Polkadot-JS Apps Front-End](#connect-with-the-polkadot-js-apps-front-end) + - [Takeaways](#takeaways) + +- [Contributing](#contributing) + +- [Getting Help](#getting-help) + +## Intro + +- ๐Ÿค This template is a minimal (in terms of complexity and the number of components) template for building a blockchain node. -* ๐Ÿ”ง Its runtime is configured with a single custom pallet as a starting point, and a handful of ready-made pallets +- ๐Ÿ”ง Its runtime is configured with a single custom pallet as a starting point, and a handful of ready-made pallets such as a [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html). -* ๐Ÿ‘ค The template has no consensus configured - it is best for experimenting with a single node network. +- ๐Ÿ‘ค The template has no consensus configured - it is best for experimenting with a single node network. ## Template Structure A Polkadot SDK based project such as this one consists of: -* ๐Ÿ’ฟ a [Node](./node/README.md) - the binary application. -* ๐Ÿงฎ the [Runtime](./runtime/README.md) - the core logic of the blockchain. -* ๐ŸŽจ the [Pallets](./pallets/README.md) - from which the runtime is constructed. +- ๐Ÿงฎ the [Runtime](./runtime/README.md) - the core logic of the blockchain. +- ๐ŸŽจ the [Pallets](./pallets/README.md) - from which the runtime is constructed. +- ๐Ÿ’ฟ a [Node](./node/README.md) - the binary application (which is not part of the cargo default-members list and is not +compiled unless building the entire workspace). ## Getting Started -* ๐Ÿฆ€ The template is using the Rust language. +- ๐Ÿฆ€ The template is using the Rust language. -* ๐Ÿ‘‰ Check the +- ๐Ÿ‘‰ Check the [Rust installation instructions](https://www.rust-lang.org/tools/install) for your system. -* ๐Ÿ› ๏ธ Depending on your operating system and Rust version, there might be additional +- ๐Ÿ› ๏ธ Depending on your operating system and Rust version, there might be additional packages required to compile this template - please take note of the Rust compiler output. Fetch minimal template code: @@ -45,65 +69,152 @@ git clone https://github.com/paritytech/polkadot-sdk-minimal-template.git minima cd minimal-template ``` -### Build +## Starting a Minimal Template Chain + +### Omni Node + +[Omni Node](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html) can +be used to run the minimal template's runtime. `polkadot-omni-node` binary crate usage is described at a high-level +[on crates.io](https://crates.io/crates/polkadot-omni-node). + +#### Install `polkadot-omni-node` + +Please see installation section on [crates.io/omni-node](https://crates.io/crates/polkadot-omni-node). + +#### Build `minimal-template-runtime` + +```sh +cargo build -p minimal-template-runtime --release +``` + +#### Install `staging-chain-spec-builder` -๐Ÿ”จ Use the following command to build the node without launching it: +Please see the installation section at [`crates.io/staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder). + +#### Use chain-spec-builder to generate the chain_spec.json file ```sh -cargo build --release +chain-spec-builder create --relay-chain "dev" --para-id 1000 --runtime \ + target/release/wbuild/minimal-template-runtime/minimal_template_runtime.wasm named-preset development ``` -๐Ÿณ Alternatively, build the docker image: +**Note**: the `relay-chain` and `para-id` flags are extra bits of information required to +configure the node for the case of representing a parachain that is connected to a relay chain. +They are not relevant to minimal template business logic, but they are mandatory information for +Omni Node, nonetheless. + +#### Run Omni Node + +Start Omni Node with manual seal (3 seconds block times), minimal template runtime based +chain spec. We'll use `--tmp` flag to start the node with its configurations stored in a +temporary directory, which will be deleted at the end of the process. + +```sh +polkadot-omni-node --chain --dev-block-time 3000 --tmp +``` + +### Minimal Template Node + +#### Build both node & runtime + +```sh +cargo build --workspace --release +``` + +๐Ÿณ Alternatively, build the docker image which builds all the workspace members, +and has as entry point the node binary: ```sh docker build . -t polkadot-sdk-minimal-template ``` -### Single-Node Development Chain +#### Start the `minimal-template-node` -๐Ÿ‘ค The following command starts a single-node development chain: +The `minimal-template-node` has dependency on the `minimal-template-runtime`. It will use +the `minimal_template_runtime::WASM_BINARY` constant (which holds the WASM blob as a byte +array) for chain spec building, while starting. This is in contrast to Omni Node which doesn't +depend on a specific runtime, but asks for the chain spec at startup. ```sh -./target/release/minimal-template-node --dev + --tmp --consensus manual-seal-3000 +# or via docker +docker run --rm polkadot-sdk-minimal-template +``` + +### Zombienet with Omni Node + +#### Install `zombienet` + +We can install `zombienet` as described [here](https://paritytech.github.io/zombienet/install.html#installation), +and `zombienet-omni-node.toml` contains the network specification we want to start. + +#### Update `zombienet-omni-node.toml` with a valid chain spec path + +Before starting the network with zombienet we must update the network specification +with a valid chain spec path. If we need to generate one, we can look up at the previous +section for chain spec creation [here](#use-chain-spec-builder-to-generate-the-chain_specjson-file). -# docker version: -docker run --rm polkadot-sdk-minimal-template --dev +Then make the changes in the network specification like so: + +```toml +# ... +chain = "dev" +chain_spec_path = "" +default_args = ["--dev-block-time 3000"] +# .. +``` + +#### Start the network + +```sh +zombienet --provider native spawn zombienet-omni-node.toml ``` -Development chains: +### Zombienet with `minimal-template-node` -* ๐Ÿงน Do not persist the state. -* ๐Ÿ’ฐ Are pre-configured with a genesis state that includes several pre-funded development accounts. -* ๐Ÿง‘โ€โš–๏ธ One development account (`ALICE`) is used as `sudo` accounts. +For this one we just need to have `zombienet` installed and run: + +```sh +zombienet --provider native spawn zombienet-multi-node.toml +``` ### Connect with the Polkadot-JS Apps Front-End -* ๐ŸŒ You can interact with your local node using the +- ๐ŸŒ You can interact with your local node using the hosted version of the [Polkadot/Substrate Portal](https://polkadot.js.org/apps/#/explorer?rpc=ws://localhost:9944). -* ๐Ÿช A hosted version is also +- ๐Ÿช A hosted version is also available on [IPFS](https://dotapps.io/). -* ๐Ÿง‘โ€๐Ÿ”ง You can also find the source code and instructions for hosting your own instance in the +- ๐Ÿง‘โ€๐Ÿ”ง You can also find the source code and instructions for hosting your own instance in the [`polkadot-js/apps`](https://github.com/polkadot-js/apps) repository. +### Takeaways + +Previously minimal template's development chains: + +- โŒ Started in a multi-node setup will produce forks because minimal lacks consensus. +- ๐Ÿงน Do not persist the state. +- ๐Ÿ’ฐ Are pre-configured with a genesis state that includes several pre-funded development accounts. +- ๐Ÿง‘โ€โš–๏ธ One development account (`ALICE`) is used as `sudo` accounts. + ## Contributing -* ๐Ÿ”„ This template is automatically updated after releases in the main [Polkadot SDK monorepo](https://github.com/paritytech/polkadot-sdk). +- ๐Ÿ”„ This template is automatically updated after releases in the main [Polkadot SDK monorepo](https://github.com/paritytech/polkadot-sdk). -* โžก๏ธ Any pull requests should be directed to this [source](https://github.com/paritytech/polkadot-sdk/tree/master/templates/minimal). +- โžก๏ธ Any pull requests should be directed to this [source](https://github.com/paritytech/polkadot-sdk/tree/master/templates/minimal). -* ๐Ÿ˜‡ Please refer to the monorepo's +- ๐Ÿ˜‡ Please refer to the monorepo's [contribution guidelines](https://github.com/paritytech/polkadot-sdk/blob/master/docs/contributor/CONTRIBUTING.md) and [Code of Conduct](https://github.com/paritytech/polkadot-sdk/blob/master/docs/contributor/CODE_OF_CONDUCT.md). ## Getting Help -* ๐Ÿง‘โ€๐Ÿซ To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point. +- ๐Ÿง‘โ€๐Ÿซ To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point. -* ๐Ÿง‘โ€๐Ÿ”ง For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are +- ๐Ÿง‘โ€๐Ÿ”ง For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources. -* ๐Ÿ‘ฅ Additionally, there are [GitHub issues](https://github.com/paritytech/polkadot-sdk/issues) and +- ๐Ÿ‘ฅ Additionally, there are [GitHub issues](https://github.com/paritytech/polkadot-sdk/issues) and [Substrate StackExchange](https://substrate.stackexchange.com/). diff --git a/templates/minimal/node/src/cli.rs b/templates/minimal/node/src/cli.rs index 54107df75a36..f349f8c8da04 100644 --- a/templates/minimal/node/src/cli.rs +++ b/templates/minimal/node/src/cli.rs @@ -21,6 +21,7 @@ use polkadot_sdk::{sc_cli::RunCmd, *}; pub enum Consensus { ManualSeal(u64), InstantSeal, + None, } impl std::str::FromStr for Consensus { @@ -31,6 +32,8 @@ impl std::str::FromStr for Consensus { Consensus::InstantSeal } else if let Some(block_time) = s.strip_prefix("manual-seal-") { Consensus::ManualSeal(block_time.parse().map_err(|_| "invalid block time")?) + } else if s.to_lowercase() == "none" { + Consensus::None } else { return Err("incorrect consensus identifier".into()); }) diff --git a/templates/minimal/node/src/service.rs b/templates/minimal/node/src/service.rs index 169993e2e93a..f9a9d1e0f3cf 100644 --- a/templates/minimal/node/src/service.rs +++ b/templates/minimal/node/src/service.rs @@ -273,6 +273,7 @@ pub fn new_full::Ha authorship_future, ); }, + _ => {}, } network_starter.start_network(); diff --git a/templates/minimal/zombienet-omni-node.toml b/templates/minimal/zombienet-omni-node.toml new file mode 100644 index 000000000000..33b0fceba68c --- /dev/null +++ b/templates/minimal/zombienet-omni-node.toml @@ -0,0 +1,9 @@ +[relaychain] +default_command = "polkadot-omni-node" +chain = "dev" +chain_spec_path = "" +default_args = ["--dev-block-time 3000"] + +[[relaychain.nodes]] +name = "alice" +ws_port = 9944 diff --git a/templates/minimal/zombienet.toml b/templates/minimal/zombienet.toml new file mode 100644 index 000000000000..89df054bf652 --- /dev/null +++ b/templates/minimal/zombienet.toml @@ -0,0 +1,30 @@ +# The setup bellow allows only one node to produce +# blocks and the rest will follow. + +[relaychain] +chain = "dev" +default_command = "minimal-template-node" + +[[relaychain.nodes]] +name = "alice" +args = ["--consensus manual-seal-3000"] +validator = true +ws_port = 9944 + +[[relaychain.nodes]] +name = "bob" +args = ["--consensus None"] +validator = true +ws_port = 9955 + +[[relaychain.nodes]] +name = "charlie" +args = ["--consensus None"] +validator = true +ws_port = 9966 + +[[relaychain.nodes]] +name = "dave" +args = ["--consensus None"] +validator = true +ws_port = 9977 diff --git a/templates/parachain/Dockerfile b/templates/parachain/Dockerfile index 72a8f19fe79a..da1353d5fb9c 100644 --- a/templates/parachain/Dockerfile +++ b/templates/parachain/Dockerfile @@ -4,7 +4,7 @@ WORKDIR /polkadot COPY . /polkadot RUN cargo fetch -RUN cargo build --locked --release +RUN cargo build --workspace --locked --release FROM docker.io/parity/base-bin:latest diff --git a/templates/parachain/README.md b/templates/parachain/README.md index 3de85cbeb4dc..65a6979041f2 100644 --- a/templates/parachain/README.md +++ b/templates/parachain/README.md @@ -11,32 +11,55 @@ -* โซ This template provides a starting point to build a [parachain](https://wiki.polkadot.network/docs/learn-parachains). +## Table of Contents -* โ˜๏ธ It is based on the +- [Intro](#intro) + +- [Template Structure](#template-structure) + +- [Getting Started](#getting-started) + +- [Starting a Development Chain](#starting-a-development-chain) + + - [Omni Node](#omni-node-prerequisites) + - [Zombienet setup with Omni Node](#zombienet-setup-with-omni-node) + - [Parachain Template Node](#parachain-template-node) + - [Connect with the Polkadot-JS Apps Front-End](#connect-with-the-polkadot-js-apps-front-end) + - [Takeaways](#takeaways) + +- [Contributing](#contributing) +- [Getting Help](#getting-help) + +## Intro + +- โซ This template provides a starting point to build a [parachain](https://wiki.polkadot.network/docs/learn-parachains). + +- โ˜๏ธ It is based on the [Cumulus](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/polkadot_sdk/cumulus/index.html) framework. -* ๐Ÿ”ง Its runtime is configured with a single custom pallet as a starting point, and a handful of ready-made pallets +- ๐Ÿ”ง Its runtime is configured with a single custom pallet as a starting point, and a handful of ready-made pallets such as a [Balances pallet](https://paritytech.github.io/polkadot-sdk/master/pallet_balances/index.html). -* ๐Ÿ‘‰ Learn more about parachains [here](https://wiki.polkadot.network/docs/learn-parachains) +- ๐Ÿ‘‰ Learn more about parachains [here](https://wiki.polkadot.network/docs/learn-parachains) ## Template Structure A Polkadot SDK based project such as this one consists of: -* ๐Ÿ’ฟ a [Node](./node/README.md) - the binary application. -* ๐Ÿงฎ the [Runtime](./runtime/README.md) - the core logic of the parachain. -* ๐ŸŽจ the [Pallets](./pallets/README.md) - from which the runtime is constructed. +- ๐Ÿงฎ the [Runtime](./runtime/README.md) - the core logic of the parachain. +- ๐ŸŽจ the [Pallets](./pallets/README.md) - from which the runtime is constructed. +- ๐Ÿ’ฟ a [Node](./node/README.md) - the binary application, not part of the project default-members list and not compiled unless +building the project with `--workspace` flag, which builds all workspace members, and is an alternative to +[Omni Node](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html). ## Getting Started -* ๐Ÿฆ€ The template is using the Rust language. +- ๐Ÿฆ€ The template is using the Rust language. -* ๐Ÿ‘‰ Check the +- ๐Ÿ‘‰ Check the [Rust installation instructions](https://www.rust-lang.org/tools/install) for your system. -* ๐Ÿ› ๏ธ Depending on your operating system and Rust version, there might be additional +- ๐Ÿ› ๏ธ Depending on your operating system and Rust version, there might be additional packages required to compile this template - please take note of the Rust compiler output. Fetch parachain template code: @@ -47,90 +70,149 @@ git clone https://github.com/paritytech/polkadot-sdk-parachain-template.git para cd parachain-template ``` -### Build +## Starting a Development Chain + +### Omni Node Prerequisites -๐Ÿ”จ Use the following command to build the node without launching it: +[Omni Node](https://paritytech.github.io/polkadot-sdk/master/polkadot_sdk_docs/reference_docs/omni_node/index.html) can +be used to run the parachain template's runtime. `polkadot-omni-node` binary crate usage is described at a high-level +[on crates.io](https://crates.io/crates/polkadot-omni-node). + +#### Install `polkadot-omni-node` + +Please see the installation section at [`crates.io/omni-node`](https://crates.io/crates/polkadot-omni-node). + +#### Build `parachain-template-runtime` ```sh cargo build --release ``` -๐Ÿณ Alternatively, build the docker image: +#### Install `staging-chain-spec-builder` + +Please see the installation section at [`crates.io/staging-chain-spec-builder`](https://crates.io/crates/staging-chain-spec-builder). + +#### Use `chain-spec-builder` to generate the `chain_spec.json` file ```sh -docker build . -t polkadot-sdk-parachain-template +chain-spec-builder create --relay-chain "rococo-local" --para-id 1000 --runtime \ + target/release/wbuild/parachain-template-runtime/parachain_template_runtime.wasm named-preset development ``` -### Local Development Chain +**Note**: the `relay-chain` and `para-id` flags are mandatory information required by +Omni Node, and for parachain template case the value for `para-id` must be set to `1000`, since this +is also the value injected through [ParachainInfo](https://docs.rs/staging-parachain-info/0.17.0/staging_parachain_info/) +pallet into the `parachain-template-runtime`'s storage. The `relay-chain` value is set in accordance +with the relay chain ID where this instantiation of parachain-template will connect to. -๐ŸงŸ This project uses [Zombienet](https://github.com/paritytech/zombienet) to orchestrate the relaychain and parachain nodes. -You can grab a [released binary](https://github.com/paritytech/zombienet/releases/latest) or use an [npm version](https://www.npmjs.com/package/@zombienet/cli). +#### Run Omni Node -This template produces a parachain node. -You can install it in your environment by running: +Start Omni Node with the generated chain spec. We'll start it development mode (without a relay chain config), +with a temporary directory for configuration (given `--tmp`), and block production set to create a block with +every second. + +```bash +polkadot-omni-node --chain --tmp --dev-block-time 1000 -```sh -cargo install --path node ``` -You still need a relaychain node - you can download the `polkadot` -(and the accompanying `polkadot-prepare-worker` and `polkadot-execute-worker`) -binaries from [Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases/latest). +However, such a setup is not close to what would run in production, and for that we need to setup a local +relay chain network that will help with the block finalization. In this guide we'll setup a local relay chain +as well. We'll not do it manually, by starting one node at a time, but we'll use [zombienet](https://paritytech.github.io/zombienet/intro.html). + +Follow through the next section for more details on how to do it. -In addition to the installed parachain node, make sure to bring -`zombienet`, `polkadot`, `polkadot-prepare-worker`, and `polkadot-execute-worker` -into `PATH`, for example: +### Zombienet setup with Omni Node + +Assuming we continue from the last step of the previous section, we have a chain spec and we need to setup a relay chain. +We can install `zombienet` as described [here](https://paritytech.github.io/zombienet/install.html#installation), and +`zombienet-omni-node.toml` contains the network specification we want to start. + +#### Relay chain prerequisites + +Download the `polkadot` (and the accompanying `polkadot-prepare-worker` and `polkadot-execute-worker`) binaries from +[Polkadot SDK releases](https://github.com/paritytech/polkadot-sdk/releases). Then expose them on `PATH` like so: ```sh -export PATH=":$PATH" +export PATH="$PATH:" ``` -This way, we can conveniently use them in the following steps. +#### Update `zombienet-omni-node.toml` with a valid chain spec path + +```toml +# ... +[[parachains]] +id = 1000 +chain_spec_path = "" +# ... +``` -๐Ÿ‘ฅ The following command starts a local development chain, with a single relay chain node and a single parachain collator: +#### Start the network ```sh -zombienet --provider native spawn ./zombienet.toml +zombienet --provider native spawn zombienet-omni-node.toml +``` + +### Parachain Template Node + +As mentioned in the `Template Structure` section, the `node` crate is optionally compiled and it is an alternative +to `Omni Node`. Similarly, it requires setting up a relay chain, and we'll use `zombienet` once more. + +#### Install the `parachain-template-node` -# Alternatively, the npm version: -npx --yes @zombienet/cli --provider native spawn ./zombienet.toml +```sh +cargo install --path node ``` -Development chains: +#### Setup and start the network + +For setup, please consider the instructions for `zombienet` installation [here](https://paritytech.github.io/zombienet/install.html#installation) +and [relay chain prerequisites](#relay-chain-prerequisites). -* ๐Ÿงน Do not persist the state. -* ๐Ÿ’ฐ Are preconfigured with a genesis state that includes several prefunded development accounts. -* ๐Ÿง‘โ€โš–๏ธ Development accounts are used as validators, collators, and `sudo` accounts. +We're left just with starting the network: + +```sh +zombienet --provider native spawn zombienet.toml +``` ### Connect with the Polkadot-JS Apps Front-End -* ๐ŸŒ You can interact with your local node using the +- ๐ŸŒ You can interact with your local node using the hosted version of the Polkadot/Substrate Portal: [relay chain](https://polkadot.js.org/apps/#/explorer?rpc=ws://localhost:9944) and [parachain](https://polkadot.js.org/apps/#/explorer?rpc=ws://localhost:9988). -* ๐Ÿช A hosted version is also +- ๐Ÿช A hosted version is also available on [IPFS](https://dotapps.io/). -* ๐Ÿง‘โ€๐Ÿ”ง You can also find the source code and instructions for hosting your own instance in the +- ๐Ÿง‘โ€๐Ÿ”ง You can also find the source code and instructions for hosting your own instance in the [`polkadot-js/apps`](https://github.com/polkadot-js/apps) repository. +### Takeaways + +Development parachains: + +- ๐Ÿ”— Connect to relay chains, and we showcased how to connect to a local one. +- ๐Ÿงน Do not persist the state. +- ๐Ÿ’ฐ Are preconfigured with a genesis state that includes several prefunded development accounts. +- ๐Ÿง‘โ€โš–๏ธ Development accounts are used as validators, collators, and `sudo` accounts. + ## Contributing -* ๐Ÿ”„ This template is automatically updated after releases in the main [Polkadot SDK monorepo](https://github.com/paritytech/polkadot-sdk). +- ๐Ÿ”„ This template is automatically updated after releases in the main [Polkadot SDK monorepo](https://github.com/paritytech/polkadot-sdk). -* โžก๏ธ Any pull requests should be directed to this [source](https://github.com/paritytech/polkadot-sdk/tree/master/templates/parachain). +- โžก๏ธ Any pull requests should be directed to this [source](https://github.com/paritytech/polkadot-sdk/tree/master/templates/parachain). -* ๐Ÿ˜‡ Please refer to the monorepo's +- ๐Ÿ˜‡ Please refer to the monorepo's [contribution guidelines](https://github.com/paritytech/polkadot-sdk/blob/master/docs/contributor/CONTRIBUTING.md) and [Code of Conduct](https://github.com/paritytech/polkadot-sdk/blob/master/docs/contributor/CODE_OF_CONDUCT.md). ## Getting Help -* ๐Ÿง‘โ€๐Ÿซ To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point. +- ๐Ÿง‘โ€๐Ÿซ To learn about Polkadot in general, [Polkadot.network](https://polkadot.network/) website is a good starting point. -* ๐Ÿง‘โ€๐Ÿ”ง For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are +- ๐Ÿง‘โ€๐Ÿ”ง For technical introduction, [here](https://github.com/paritytech/polkadot-sdk#-documentation) are the Polkadot SDK documentation resources. -* ๐Ÿ‘ฅ Additionally, there are [GitHub issues](https://github.com/paritytech/polkadot-sdk/issues) and +- ๐Ÿ‘ฅ Additionally, there are [GitHub issues](https://github.com/paritytech/polkadot-sdk/issues) and [Substrate StackExchange](https://substrate.stackexchange.com/). diff --git a/templates/parachain/runtime/src/genesis_config_presets.rs b/templates/parachain/runtime/src/genesis_config_presets.rs index 394bde0be770..9091db357005 100644 --- a/templates/parachain/runtime/src/genesis_config_presets.rs +++ b/templates/parachain/runtime/src/genesis_config_presets.rs @@ -15,6 +15,8 @@ use sp_keyring::Sr25519Keyring; /// The default XCM version to set in genesis config. const SAFE_XCM_VERSION: u32 = xcm::prelude::XCM_VERSION; +/// Parachain id used for gensis config presets of parachain template. +const PARACHAIN_ID: u32 = 1000; /// Generate the session keys from individual elements. /// @@ -76,9 +78,7 @@ fn local_testnet_genesis() -> Value { ], Sr25519Keyring::well_known().map(|k| k.to_account_id()).collect(), Sr25519Keyring::Alice.to_account_id(), - // TODO: this is super opaque, how should one know they should configure this? add to - // README! - 1000.into(), + PARACHAIN_ID.into(), ) } @@ -91,7 +91,7 @@ fn development_config_genesis() -> Value { ], Sr25519Keyring::well_known().map(|k| k.to_account_id()).collect(), Sr25519Keyring::Alice.to_account_id(), - 1000.into(), + PARACHAIN_ID.into(), ) } diff --git a/templates/parachain/zombienet-omni-node.toml b/templates/parachain/zombienet-omni-node.toml new file mode 100644 index 000000000000..29e99cfcd493 --- /dev/null +++ b/templates/parachain/zombienet-omni-node.toml @@ -0,0 +1,22 @@ +[relaychain] +default_command = "polkadot" +chain = "rococo-local" + +[[relaychain.nodes]] +name = "alice" +validator = true +ws_port = 9944 + +[[relaychain.nodes]] +name = "bob" +validator = true +ws_port = 9955 + +[[parachains]] +id = 1000 +chain_spec_path = "" + +[parachains.collator] +name = "charlie" +ws_port = 9988 +command = "polkadot-omni-node" diff --git a/templates/zombienet/tests/smoke.rs b/templates/zombienet/tests/smoke.rs index ba5f42142f31..c0c9646d4e9c 100644 --- a/templates/zombienet/tests/smoke.rs +++ b/templates/zombienet/tests/smoke.rs @@ -7,28 +7,74 @@ //! `cargo build --package minimal-template-node --release` //! `export PATH=/target/release:$PATH //! -//! The you can run the test with -//! `cargo test -p template-zombienet-tests` +//! There are also some tests related to omni node which run basaed on pre-generated chain specs, +//! so to be able to run them you would need to generate the right chain spec (just minimal and +//! parachain tests supported for now). +//! +//! You can run the following command to generate a minimal chainspec, once the runtime wasm file is +//! compiled: +//!`chain-spec-builder create --relay-chain --para-id 1000 -r \ +//! named-preset development` +//! +//! Once the files are generated, you must export an environment variable called +//! `CHAIN_SPECS_DIR` which should point to the absolute path of the directory +//! that holds the generated chain specs. The chain specs file names should be +//! `minimal_chain_spec.json` for minimal and `parachain_chain_spec.json` for parachain +//! templates. +//! +//! To start all tests here we should run: +//! `cargo test -p template-zombienet-tests --features zombienet` #[cfg(feature = "zombienet")] mod smoke { + use std::path::PathBuf; + use anyhow::anyhow; use zombienet_sdk::{NetworkConfig, NetworkConfigBuilder, NetworkConfigExt}; - pub fn get_config(cmd: &str, para_cmd: Option<&str>) -> Result { - let chain = if cmd == "polkadot" { "rococo-local" } else { "dev" }; + const CHAIN_SPECS_DIR_PATH: &str = "CHAIN_SPECS_DIR"; + const PARACHAIN_ID: u32 = 1000; + + #[inline] + fn expect_env_var(var_name: &str) -> String { + std::env::var(var_name) + .unwrap_or_else(|_| panic!("{CHAIN_SPECS_DIR_PATH} environment variable is set. qed.")) + } + + #[derive(Default)] + struct NetworkSpec { + relaychain_cmd: &'static str, + relaychain_spec_path: Option, + // TODO: update the type to something like Option> after + // `zombienet-sdk` exposes `shared::types::Arg`. + relaychain_cmd_args: Option>, + para_cmd: Option<&'static str>, + para_cmd_args: Option>, + } + + fn get_config(network_spec: NetworkSpec) -> Result { + let chain = if network_spec.relaychain_cmd == "polkadot" { "rococo-local" } else { "dev" }; let config = NetworkConfigBuilder::new().with_relaychain(|r| { - r.with_chain(chain) - .with_default_command(cmd) - .with_node(|node| node.with_name("alice")) + let mut r = r.with_chain(chain).with_default_command(network_spec.relaychain_cmd); + if let Some(path) = network_spec.relaychain_spec_path { + r = r.with_chain_spec_path(path); + } + + if let Some(args) = network_spec.relaychain_cmd_args { + r = r.with_default_args(args.into_iter().map(|arg| arg.into()).collect()); + } + + r.with_node(|node| node.with_name("alice")) .with_node(|node| node.with_name("bob")) }); - let config = if let Some(para_cmd) = para_cmd { + let config = if let Some(para_cmd) = network_spec.para_cmd { config.with_parachain(|p| { - p.with_id(1000) - .with_default_command(para_cmd) - .with_collator(|n| n.with_name("collator")) + let mut p = p.with_id(PARACHAIN_ID).with_default_command(para_cmd); + if let Some(args) = network_spec.para_cmd_args { + p = p.with_default_args(args.into_iter().map(|arg| arg.into()).collect()); + } + p.with_collator(|n| n.with_name("collator")) }) } else { config @@ -46,14 +92,18 @@ mod smoke { env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), ); - let config = get_config("polkadot", Some("parachain-template-node"))?; + let config = get_config(NetworkSpec { + relaychain_cmd: "polkadot", + para_cmd: Some("parachain-template-node"), + ..Default::default() + })?; let network = config.spawn_native().await?; // wait 6 blocks of the para let collator = network.get_node("collator")?; assert!(collator - .wait_metric("block_height{status=\"best\"}", |b| b > 5_f64) + .wait_metric("block_height{status=\"finalized\"}", |b| b > 5_f64) .await .is_ok()); @@ -66,13 +116,19 @@ mod smoke { env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), ); - let config = get_config("solochain-template-node", None)?; + let config = get_config(NetworkSpec { + relaychain_cmd: "solochain-template-node", + ..Default::default() + })?; let network = config.spawn_native().await?; // wait 6 blocks let alice = network.get_node("alice")?; - assert!(alice.wait_metric("block_height{status=\"best\"}", |b| b > 5_f64).await.is_ok()); + assert!(alice + .wait_metric("block_height{status=\"finalized\"}", |b| b > 5_f64) + .await + .is_ok()); Ok(()) } @@ -83,13 +139,73 @@ mod smoke { env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), ); - let config = get_config("minimal-template-node", None)?; + let config = get_config(NetworkSpec { + relaychain_cmd: "minimal-template-node", + ..Default::default() + })?; + + let network = config.spawn_native().await?; + + // wait 6 blocks + let alice = network.get_node("alice")?; + assert!(alice + .wait_metric("block_height{status=\"finalized\"}", |b| b > 5_f64) + .await + .is_ok()); + + Ok(()) + } + + #[tokio::test(flavor = "multi_thread")] + async fn omni_node_with_minimal_runtime_block_production_test() -> Result<(), anyhow::Error> { + let _ = env_logger::try_init_from_env( + env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), + ); + let chain_spec_path = expect_env_var(CHAIN_SPECS_DIR_PATH) + "/minimal_chain_spec.json"; + let config = get_config(NetworkSpec { + relaychain_cmd: "polkadot-omni-node", + relaychain_cmd_args: Some(vec![("--dev-block-time", "1000")]), + relaychain_spec_path: Some(chain_spec_path.into()), + ..Default::default() + })?; let network = config.spawn_native().await?; // wait 6 blocks let alice = network.get_node("alice")?; - assert!(alice.wait_metric("block_height{status=\"best\"}", |b| b > 5_f64).await.is_ok()); + assert!(alice + .wait_metric("block_height{status=\"finalized\"}", |b| b > 5_f64) + .await + .is_ok()); + + Ok(()) + } + + #[tokio::test(flavor = "multi_thread")] + async fn omni_node_with_parachain_runtime_block_production_test() -> Result<(), anyhow::Error> { + let _ = env_logger::try_init_from_env( + env_logger::Env::default().filter_or(env_logger::DEFAULT_FILTER_ENV, "info"), + ); + + let chain_spec_path = expect_env_var(CHAIN_SPECS_DIR_PATH) + "/parachain_chain_spec.json"; + + let config = get_config(NetworkSpec { + relaychain_cmd: "polkadot", + para_cmd: Some("polkadot-omni-node"), + // Leaking the `String` to be able to use it below as a static str, + // required by the `FromStr` implementation for zombienet-configuration + // `Arg` type, which is not exposed yet through `zombienet-sdk`. + para_cmd_args: Some(vec![("--chain", chain_spec_path.leak())]), + ..Default::default() + })?; + let network = config.spawn_native().await?; + + // wait 6 blocks + let alice = network.get_node("collator")?; + assert!(alice + .wait_metric("block_height{status=\"finalized\"}", |b| b > 5_f64) + .await + .is_ok()); Ok(()) }