Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 76 additions & 0 deletions cumulus/polkadot-omni-node/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# 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/<stable_release_tag>/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 --locked
```

## 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 --locked
```

### 2. Generate a chain spec

Omni Node requires the chain spec to include a JSON key named `relay_chain`. It is set to a chain id,
representing the chain name, e.g. `westend`, `paseo`, `rococo`, `polkadot`, or `kusama`, but
there are also local variants that can be used for testing, like `rococo-local` or `westend-local`. The
local variants are available only for a build of `polkadot-omni-node` with
`westend-native` and `rococo-native` features respectively.

<!-- TODO: https://github.com/paritytech/polkadot-sdk/issues/8747 -->
Additionaly, the `--para-id` flag can be used to set the JSON key named `para_id`. This flag is used
by nodes to determine the parachain id, and it is especially useful when the parachain id can not be
fetched from the runtime, when the state points to a runtime that does not implement the
`cumulus_primitives_core::GetParachainInfo` runtime API. It is recommended for runtimes to implement
the runtime API and be upgraded on chain.

Example command bellow:

```bash
chain-spec-builder create --relay-chain <relay_chain_id> --para-id <id> -r <runtime.wasm> named-preset <preset_name>
```

### 3. Run Omni Node

And now with the generated chain spec we can start the node in development mode like so:

```bash
polkadot-omni-node --dev --chain <chain_spec.json>
```

## 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)
102 changes: 102 additions & 0 deletions cumulus/polkadot-omni-node/lib/src/common/chain_spec.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
// Copyright (C) Parity Technologies (UK) Ltd.
// This file is part of Cumulus.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Chain spec primitives.

pub use sc_chain_spec::ChainSpec;
use sc_chain_spec::ChainSpecExtension;
use serde::{Deserialize, Serialize};
use std::fmt::Debug;

/// Helper trait used for loading/building a chain spec starting from the chain ID.
pub trait LoadSpec {
/// Load/Build a chain spec starting from the chain ID.
fn load_spec(&self, id: &str) -> Result<Box<dyn ChainSpec>, String>;
}

/// Default implementation for `LoadSpec` that just reads a chain spec from the disk.
pub struct DiskChainSpecLoader;

impl LoadSpec for DiskChainSpecLoader {
fn load_spec(&self, path: &str) -> Result<Box<dyn ChainSpec>, String> {
Ok(Box::new(GenericChainSpec::from_json_file(path.into())?))
}
}

/// Generic extensions for Parachain ChainSpecs used for extracting the extensions from chain specs.
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecExtension)]
pub struct Extensions {
/// The relay chain of the Parachain. It is kept here only for compatibility reasons until
/// people migrate to using the new `Extensions` struct and associated logic in the node
/// corresponding to pulling the parachain id from the runtime.
#[serde(alias = "relayChain", alias = "RelayChain")]
relay_chain: String,
/// The id of the Parachain.
#[serde(alias = "paraId", alias = "ParaId")]
para_id: Option<u32>,
}

impl Extensions {
/// Try to get the extension from the given `ChainSpec`.
pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
sc_chain_spec::get_extension(chain_spec.extensions())
}

/// Create the extensions only with the relay_chain.
pub fn new_with_relay_chain(relay_chain: String) -> Self {
Extensions { relay_chain, para_id: None }
}

/// Initialize extensions based on given parameters.
pub fn new(relay_chain: String, para_id: u32) -> Self {
Extensions { relay_chain, para_id: Some(para_id) }
}

/// Para id field getter
pub fn para_id(&self) -> Option<u32> {
self.para_id
}

/// Relay chain field getter
pub fn relay_chain(&self) -> String {
self.relay_chain.clone()
}
}

/// Generic chain spec for all polkadot-parachain runtimes
pub type GenericChainSpec = sc_service::GenericChainSpec<Extensions>;

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn can_decode_extension_camel_and_snake_case() {
let camel_case = r#"{"relayChain":"relay","paraId":1}"#;
let snake_case = r#"{"relay_chain":"relay","para_id":1}"#;
let pascal_case = r#"{"RelayChain":"relay","ParaId":1}"#;
let para_id_missing = r#"{"RelayChain":"westend"}"#;

let camel_case_extension: Extensions = serde_json::from_str(camel_case).unwrap();
let snake_case_extension: Extensions = serde_json::from_str(snake_case).unwrap();
let pascal_case_extension: Extensions = serde_json::from_str(pascal_case).unwrap();
let missing_paraid_extension: Extensions = serde_json::from_str(para_id_missing).unwrap();
assert_eq!(camel_case_extension, snake_case_extension);
assert_eq!(snake_case_extension, pascal_case_extension);
assert_eq!(missing_paraid_extension.relay_chain, "westend".to_string());
assert!(missing_paraid_extension.para_id.is_none());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ impl<Config: CliConfig> RelayChainCli<Config> {
let base = FromArgMatches::from_arg_matches(&matches).unwrap_or_else(|e| e.exit());

let extension = Extensions::try_get(&*para_config.chain_spec);
let chain_id = extension.map(|e| e.relay_chain.clone());
let chain_id = extension.map(|e| e.relay_chain());

let base_path = para_config.base_path.path().join("polkadot");
Self { base, chain_id, base_path: Some(base_path), _phantom: Default::default() }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs
// Cumulus is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Expand All @@ -20,6 +21,19 @@ use crate::common::{
types::{
ParachainBackend, ParachainBlockImport, ParachainClient, ParachainHostFunctions,
ParachainService,
=======
use crate::{
chain_spec::Extensions,
common::{
command::NodeCommandRunner,
rpc::BuildRpcExtensions,
statement_store::{build_statement_store, new_statement_handler_proto},
types::{
ParachainBackend, ParachainBlockImport, ParachainClient, ParachainHostFunctions,
ParachainService,
},
ConstructNodeRuntimeApi, NodeBlock, NodeExtraArgs,
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)):cumulus/polkadot-omni-node/lib/src/common/spec.rs
},
ConstructNodeRuntimeApi, NodeBlock, NodeExtraArgs,
};
Expand All @@ -39,7 +53,14 @@ use sc_network::{config::FullNetworkConfiguration, NetworkBackend, NetworkBlock}
use sc_service::{Configuration, ImportQueue, PartialComponents, TaskManager};
use sc_sysinfo::HwBench;
use sc_telemetry::{TelemetryHandle, TelemetryWorker};
<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs
use sc_transaction_pool::FullPool;
=======
use sc_tracing::tracing::Instrument;
use sc_transaction_pool::TransactionPoolHandle;
use sc_transaction_pool_api::OffchainTransactionPoolFactory;
use sp_api::{ApiExt, ProvideRuntimeApi};
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)):cumulus/polkadot-omni-node/lib/src/common/spec.rs
use sp_keystore::KeystorePtr;
use std::{future::Future, pin::Pin, sync::Arc, time::Duration};

Expand Down Expand Up @@ -109,7 +130,49 @@ pub(crate) trait NodeSpec {

type StartConsensus: StartConsensus<Self::Block, Self::RuntimeApi>;

<<<<<<< HEAD:cumulus/polkadot-parachain/polkadot-parachain-lib/src/common/spec.rs
const SYBIL_RESISTANCE: CollatorSybilResistance;
=======
/// Retrieves parachain id.
fn parachain_id(
client: &ParachainClient<Self::Block, Self::RuntimeApi>,
parachain_config: &Configuration,
) -> Option<ParaId> {
let best_hash = client.chain_info().best_hash;
let para_id = if client
.runtime_api()
.has_api::<dyn GetParachainInfo<Self::Block>>(best_hash)
.ok()
.filter(|has_api| *has_api)
.is_some()
{
client
.runtime_api()
.parachain_id(best_hash)
.inspect_err(|err| {
log::error!(
"`cumulus_primitives_core::GetParachainInfo` runtime API call errored with {}",
err
);
})
.ok()?
} else {
ParaId::from(
Extensions::try_get(&*parachain_config.chain_spec).and_then(|ext| ext.para_id())?,
)
};

let parachain_account =
AccountIdConversion::<polkadot_primitives::AccountId>::into_account_truncating(
&para_id,
);

info!("🪪 Parachain id: {:?}", para_id);
info!("🧾 Parachain Account: {}", parachain_account);

Some(para_id)
}
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201)):cumulus/polkadot-omni-node/lib/src/common/spec.rs

/// Starts a `ServiceBuilder` for a full service.
///
Expand Down
28 changes: 24 additions & 4 deletions cumulus/polkadot-parachain/src/chain_spec/asset_hubs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ pub fn asset_hub_westend_development_config() -> GenericChainSpec {
GenericChainSpec::builder(
asset_hub_westend_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
<<<<<<< HEAD
Extensions { relay_chain: "westend".into(), para_id: 1000 },
=======
Extensions::new_with_relay_chain("westend".into()),
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201))
)
.with_name("Westend Asset Hub Development")
.with_id("asset-hub-westend-dev")
Expand All @@ -43,7 +47,11 @@ pub fn asset_hub_westend_local_config() -> GenericChainSpec {
GenericChainSpec::builder(
asset_hub_westend_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
<<<<<<< HEAD
Extensions { relay_chain: "westend-local".into(), para_id: 1000 },
=======
Extensions::new_with_relay_chain("westend-local".into()),
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201))
)
.with_name("Westend Asset Hub Local")
.with_id("asset-hub-westend-local")
Expand All @@ -61,7 +69,11 @@ pub fn asset_hub_westend_config() -> GenericChainSpec {
GenericChainSpec::builder(
asset_hub_westend_runtime::WASM_BINARY
.expect("WASM binary was not built, please build it!"),
<<<<<<< HEAD
Extensions { relay_chain: "westend".into(), para_id: 1000 },
=======
Extensions::new_with_relay_chain("westend".into()),
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201))
)
.with_name("Westend Asset Hub")
.with_id("asset-hub-westend")
Expand All @@ -80,19 +92,21 @@ pub fn asset_hub_rococo_development_config() -> GenericChainSpec {
properties,
"Rococo Asset Hub Development",
"asset-hub-rococo-dev",
1000,
)
}

fn asset_hub_rococo_like_development_config(
properties: sc_chain_spec::Properties,
name: &str,
chain_id: &str,
para_id: u32,
) -> GenericChainSpec {
GenericChainSpec::builder(
asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
<<<<<<< HEAD
Extensions { relay_chain: "rococo-dev".into(), para_id },
=======
Extensions::new_with_relay_chain("rococo-dev".into()),
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201))
)
.with_name(name)
.with_id(chain_id)
Expand All @@ -111,19 +125,21 @@ pub fn asset_hub_rococo_local_config() -> GenericChainSpec {
properties,
"Rococo Asset Hub Local",
"asset-hub-rococo-local",
1000,
)
}

fn asset_hub_rococo_like_local_config(
properties: sc_chain_spec::Properties,
name: &str,
chain_id: &str,
para_id: u32,
) -> GenericChainSpec {
GenericChainSpec::builder(
asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
<<<<<<< HEAD
Extensions { relay_chain: "rococo-local".into(), para_id },
=======
Extensions::new_with_relay_chain("rococo-local".into()),
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201))
)
.with_name(name)
.with_id(chain_id)
Expand All @@ -140,7 +156,11 @@ pub fn asset_hub_rococo_genesis_config() -> GenericChainSpec {
let para_id = 1000;
GenericChainSpec::builder(
asset_hub_rococo_runtime::WASM_BINARY.expect("WASM binary was not built, please build it!"),
<<<<<<< HEAD
Extensions { relay_chain: "rococo".into(), para_id },
=======
Extensions::new_with_relay_chain("rococo".into()),
>>>>>>> 2660bf5f (`polkadot-omni-node`: fixes and changes related to `GetParachainInfo` (#9201))
)
.with_name("Rococo Asset Hub")
.with_id("asset-hub-rococo")
Expand Down
Loading
Loading