mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-08 12:28:01 +00:00
New service initial commit (#1234)
* New service initial commit * More separation of the new and old services * Fix review comments * Adds polkadot.json * Fix browser build * Remove unused import * Update node/service/src/lib.rs Co-authored-by: Fedor Sakharov <fedor.sakharov@gmail.com> * Remove duplicate json files Co-authored-by: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
Generated
+62
@@ -4071,6 +4071,7 @@ dependencies = [
|
||||
"nix 0.17.0",
|
||||
"parity-util-mem",
|
||||
"polkadot-cli",
|
||||
"polkadot-collator",
|
||||
"polkadot-service",
|
||||
"tempfile",
|
||||
]
|
||||
@@ -4109,6 +4110,7 @@ dependencies = [
|
||||
"futures 0.3.5",
|
||||
"log 0.4.8",
|
||||
"polkadot-service",
|
||||
"polkadot-service-new",
|
||||
"sc-cli",
|
||||
"sc-client-api",
|
||||
"sc-client-db",
|
||||
@@ -4137,6 +4139,7 @@ dependencies = [
|
||||
"polkadot-network",
|
||||
"polkadot-primitives",
|
||||
"polkadot-service",
|
||||
"polkadot-service-new",
|
||||
"polkadot-validation",
|
||||
"sc-cli",
|
||||
"sc-client-api",
|
||||
@@ -4521,6 +4524,65 @@ dependencies = [
|
||||
"westend-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polkadot-service-new"
|
||||
version = "0.8.3"
|
||||
dependencies = [
|
||||
"env_logger",
|
||||
"frame-benchmarking",
|
||||
"frame-system-rpc-runtime-api",
|
||||
"futures 0.3.5",
|
||||
"hex-literal",
|
||||
"kusama-runtime",
|
||||
"lazy_static",
|
||||
"log 0.4.8",
|
||||
"pallet-babe",
|
||||
"pallet-im-online",
|
||||
"pallet-staking",
|
||||
"pallet-transaction-payment-rpc-runtime-api",
|
||||
"parity-scale-codec",
|
||||
"parking_lot 0.9.0",
|
||||
"polkadot-network",
|
||||
"polkadot-overseer",
|
||||
"polkadot-primitives",
|
||||
"polkadot-rpc",
|
||||
"polkadot-runtime",
|
||||
"polkadot-test-runtime-client",
|
||||
"sc-authority-discovery",
|
||||
"sc-basic-authorship",
|
||||
"sc-block-builder",
|
||||
"sc-chain-spec",
|
||||
"sc-client-api",
|
||||
"sc-client-db",
|
||||
"sc-consensus",
|
||||
"sc-consensus-babe",
|
||||
"sc-executor",
|
||||
"sc-finality-grandpa",
|
||||
"sc-keystore",
|
||||
"sc-network",
|
||||
"sc-service",
|
||||
"sc-telemetry",
|
||||
"sc-transaction-pool",
|
||||
"serde",
|
||||
"slog",
|
||||
"sp-api",
|
||||
"sp-authority-discovery",
|
||||
"sp-block-builder",
|
||||
"sp-blockchain",
|
||||
"sp-consensus",
|
||||
"sp-consensus-babe",
|
||||
"sp-core",
|
||||
"sp-finality-grandpa",
|
||||
"sp-inherents",
|
||||
"sp-io",
|
||||
"sp-offchain",
|
||||
"sp-runtime",
|
||||
"sp-session",
|
||||
"sp-transaction-pool",
|
||||
"substrate-prometheus-endpoint",
|
||||
"westend-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polkadot-statement-table"
|
||||
version = "0.8.7"
|
||||
|
||||
@@ -10,6 +10,8 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
cli = { package = "polkadot-cli", path = "cli" }
|
||||
# It looks like this is the only way to pass features to it
|
||||
collator = { package = "polkadot-collator", path = "collator" }
|
||||
futures = "0.3.4"
|
||||
service = { package = "polkadot-service", path = "service" }
|
||||
parity-util-mem = { version = "*", default-features = false, features = ["jemalloc-global"] }
|
||||
@@ -42,6 +44,7 @@ members = [
|
||||
|
||||
"node/messages",
|
||||
"node/overseer",
|
||||
"node/service",
|
||||
|
||||
"parachain/test-parachains",
|
||||
"parachain/test-parachains/adder",
|
||||
@@ -64,3 +67,7 @@ panic = "unwind"
|
||||
|
||||
[features]
|
||||
runtime-benchmarks=["cli/runtime-benchmarks"]
|
||||
service-rewr= [
|
||||
"cli/service-rewr",
|
||||
"collator/service-rewr",
|
||||
]
|
||||
|
||||
@@ -23,7 +23,8 @@ sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master
|
||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
service = { package = "polkadot-service", path = "../service", default-features = false }
|
||||
service = { package = "polkadot-service", path = "../service", default-features = false, optional = true }
|
||||
service-new = { package = "polkadot-service-new", path = "../node/service", default-features = false, optional = true }
|
||||
|
||||
tokio = { version = "0.2.13", features = ["rt-threaded"], optional = true }
|
||||
frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master", optional = true }
|
||||
@@ -38,7 +39,7 @@ browser-utils = { package = "substrate-browser-utils", git = "https://github.com
|
||||
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = [ "wasmtime", "db", "cli" ]
|
||||
default = [ "wasmtime", "db", "cli", "service-old" ]
|
||||
wasmtime = [ "sc-cli/wasmtime" ]
|
||||
db = [ "service/db" ]
|
||||
cli = [
|
||||
@@ -46,11 +47,13 @@ cli = [
|
||||
"sc-cli",
|
||||
"sc-service",
|
||||
"frame-benchmarking-cli",
|
||||
"service/full-node",
|
||||
]
|
||||
service-old = [ "service/full-node" ]
|
||||
browser = [
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"browser-utils",
|
||||
"service",
|
||||
]
|
||||
runtime-benchmarks = ["service/runtime-benchmarks"]
|
||||
runtime-benchmarks = [ "service/runtime-benchmarks" ]
|
||||
service-rewr = [ "service-new/full-node" ]
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use log::info;
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
use service::{IdentifyVariant, self};
|
||||
#[cfg(feature = "service-rewr")]
|
||||
use service_new::{IdentifyVariant, self as service};
|
||||
use sc_executor::NativeExecutionDispatch;
|
||||
use sc_cli::{SubstrateCli, Result};
|
||||
use crate::cli::{Cli, Subcommand};
|
||||
@@ -206,7 +209,7 @@ pub fn run() -> Result<()> {
|
||||
if cfg!(feature = "browser") {
|
||||
Err(sc_cli::Error::Input("Cannot run validation worker in browser".into()))
|
||||
} else {
|
||||
#[cfg(not(feature = "browser"))]
|
||||
#[cfg(all(not(feature = "browser"), not(feature = "service-rewr")))]
|
||||
service::run_validation_worker(&cmd.mem_id)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -26,11 +26,19 @@ mod cli;
|
||||
#[cfg(feature = "cli")]
|
||||
mod command;
|
||||
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
pub use service::{
|
||||
AbstractService, ProvideRuntimeApi, CoreApi, ParachainHost, IdentifyVariant,
|
||||
Block, self, RuntimeApiCollection, TFullClient
|
||||
};
|
||||
|
||||
#[cfg(feature = "service-rewr")]
|
||||
pub use service_new::{
|
||||
self as service,
|
||||
AbstractService, ProvideRuntimeApi, CoreApi, ParachainHost, IdentifyVariant,
|
||||
Block, self, RuntimeApiCollection, TFullClient
|
||||
};
|
||||
|
||||
#[cfg(feature = "cli")]
|
||||
pub use cli::*;
|
||||
|
||||
|
||||
@@ -21,7 +21,8 @@ polkadot-primitives = { path = "../primitives" }
|
||||
polkadot-cli = { path = "../cli" }
|
||||
polkadot-network = { path = "../network" }
|
||||
polkadot-validation = { path = "../validation" }
|
||||
polkadot-service = { path = "../service" }
|
||||
polkadot-service = { path = "../service", optional = true}
|
||||
polkadot-service-new = { path = "../node/service", optional = true }
|
||||
log = "0.4.8"
|
||||
tokio = "0.2.13"
|
||||
futures-timer = "2.0"
|
||||
@@ -29,3 +30,8 @@ codec = { package = "parity-scale-codec", version = "1.3.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
keyring = { package = "sp-keyring", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = ["service-old"]
|
||||
service-old = [ "polkadot-service" ]
|
||||
service-rewr = [ "polkadot-service-new" ]
|
||||
|
||||
@@ -74,7 +74,13 @@ pub use sc_network::PeerId;
|
||||
pub use service::RuntimeApiCollection;
|
||||
pub use sc_cli::SubstrateCli;
|
||||
use sp_api::{ConstructRuntimeApi, ApiExt, HashFor};
|
||||
use polkadot_service::PolkadotClient;
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
use polkadot_service::{FullNodeHandles, PolkadotClient};
|
||||
#[cfg(feature = "service-rewr")]
|
||||
use polkadot_service_new::{
|
||||
self as polkadot_service,
|
||||
Error as ServiceError, FullNodeHandles, PolkadotClient,
|
||||
};
|
||||
|
||||
const COLLATION_TIMEOUT: Duration = Duration::from_secs(30);
|
||||
|
||||
@@ -201,9 +207,46 @@ pub async fn collate<P>(
|
||||
Ok(collation)
|
||||
}
|
||||
|
||||
#[cfg(feature = "service-rewr")]
|
||||
fn build_collator_service<SP, P, C, R, Extrinsic>(
|
||||
_spawner: SP,
|
||||
_handles: FullNodeHandles,
|
||||
_client: Arc<C>,
|
||||
_para_id: ParaId,
|
||||
_key: Arc<CollatorPair>,
|
||||
_build_parachain_context: P,
|
||||
) -> Result<future::Ready<()>, polkadot_service::Error>
|
||||
where
|
||||
C: PolkadotClient<
|
||||
service::Block,
|
||||
service::TFullBackend<service::Block>,
|
||||
R
|
||||
> + 'static,
|
||||
R: ConstructRuntimeApi<service::Block, C> + Sync + Send,
|
||||
<R as ConstructRuntimeApi<service::Block, C>>::RuntimeApi:
|
||||
sp_api::ApiExt<
|
||||
service::Block,
|
||||
StateBackend = <service::TFullBackend<service::Block> as service::Backend<service::Block>>::State,
|
||||
>
|
||||
+ RuntimeApiCollection<
|
||||
Extrinsic,
|
||||
StateBackend = <service::TFullBackend<service::Block> as service::Backend<service::Block>>::State,
|
||||
>
|
||||
+ Sync + Send,
|
||||
P: BuildParachainContext,
|
||||
P::ParachainContext: Send + 'static,
|
||||
<P::ParachainContext as ParachainContext>::ProduceCandidate: Send,
|
||||
Extrinsic: service::Codec + Send + Sync + 'static,
|
||||
SP: Spawn + Clone + Send + Sync + 'static,
|
||||
{
|
||||
Err("Collator is not functional with the new service yet".into())
|
||||
}
|
||||
|
||||
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
fn build_collator_service<SP, P, C, R, Extrinsic>(
|
||||
spawner: SP,
|
||||
handles: polkadot_service::FullNodeHandles,
|
||||
handles: FullNodeHandles,
|
||||
client: Arc<C>,
|
||||
para_id: ParaId,
|
||||
key: Arc<CollatorPair>,
|
||||
@@ -408,6 +451,7 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "service-rewr"))]
|
||||
fn compute_targets(para_id: ParaId, session_keys: &[ValidatorId], roster: DutyRoster) -> HashSet<ValidatorId> {
|
||||
use polkadot_primitives::parachain::Chain;
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@
|
||||
|
||||
use std::fmt::Debug;
|
||||
use std::pin::Pin;
|
||||
use std::sync::Arc;
|
||||
use std::task::Poll;
|
||||
use std::time::Duration;
|
||||
use std::collections::HashSet;
|
||||
@@ -232,7 +233,7 @@ impl OverseerHandler {
|
||||
/// [`Overseer`]: struct.Overseer.html
|
||||
/// [`OverseerHandler`]: struct.OverseerHandler.html
|
||||
pub async fn forward_events<P: BlockchainEvents<Block>>(
|
||||
client: P,
|
||||
client: Arc<P>,
|
||||
mut handler: OverseerHandler,
|
||||
) -> SubsystemResult<()> {
|
||||
let mut finality = client.finality_notification_stream();
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
[package]
|
||||
name = "polkadot-service-new"
|
||||
version = "0.8.3"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
parking_lot = "0.9.0"
|
||||
serde = { version = "1.0.102", features = ["derive"] }
|
||||
lazy_static = "1.4.0"
|
||||
log = "0.4.8"
|
||||
futures = "0.3.4"
|
||||
slog = "2.5.2"
|
||||
hex-literal = "0.2.1"
|
||||
polkadot-primitives = { path = "../../primitives" }
|
||||
polkadot-runtime = { path = "../../runtime/polkadot" }
|
||||
polkadot-overseer = { path = "../overseer" }
|
||||
kusama-runtime = { path = "../../runtime/kusama" }
|
||||
westend-runtime = { path = "../../runtime/westend" }
|
||||
polkadot-network = { path = "../../network", optional = true }
|
||||
polkadot-rpc = { path = "../../rpc" }
|
||||
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-blockchain = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-consensus = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
consensus_common = { package = "sp-consensus", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
grandpa = { package = "sc-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
grandpa_primitives = { package = "sp-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
inherents = { package = "sp-inherents", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
service = { package = "sc-service", git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
telemetry = { package = "sc-telemetry", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
im-online = { package = "pallet-im-online", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
authority-discovery = { package = "sc-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
authority-discovery-primitives = { package = "sp-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
babe = { package = "sc-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
babe-primitives = { package = "sp-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
system_rpc_runtime_api = { package = "frame-system-rpc-runtime-api", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
codec = { package = "parity-scale-codec", version = "1.3.0" }
|
||||
sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-offchain = { package = "sp-offchain", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
prometheus-endpoint = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[dev-dependencies]
|
||||
polkadot-test-runtime-client = { path = "../../runtime/test-runtime/client" }
|
||||
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
env_logger = "0.7.0"
|
||||
|
||||
[features]
|
||||
default = ["db", "full-node"]
|
||||
db = ["service/db"]
|
||||
runtime-benchmarks = ["polkadot-runtime/runtime-benchmarks", "kusama-runtime/runtime-benchmarks", "westend-runtime/runtime-benchmarks"]
|
||||
full-node = []
|
||||
@@ -0,0 +1,5 @@
|
||||
|
||||
= Polkadot Service
|
||||
|
||||
placeholder
|
||||
//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159)
|
||||
@@ -0,0 +1,963 @@
|
||||
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot 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
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Polkadot chain configurations.
|
||||
|
||||
use sp_core::{Pair, Public, crypto::UncheckedInto, sr25519};
|
||||
use polkadot_primitives::{AccountId, AccountPublic, parachain::ValidatorId};
|
||||
use polkadot_runtime as polkadot;
|
||||
use kusama_runtime as kusama;
|
||||
use westend_runtime as westend;
|
||||
use polkadot::constants::currency::DOTS;
|
||||
use kusama::constants::currency::DOTS as KSM;
|
||||
use westend::constants::currency::DOTS as WND;
|
||||
use sc_chain_spec::{ChainSpecExtension, ChainType};
|
||||
use sp_runtime::{traits::IdentifyAccount, Perbill};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use telemetry::TelemetryEndpoints;
|
||||
use hex_literal::hex;
|
||||
use babe_primitives::AuthorityId as BabeId;
|
||||
use grandpa::AuthorityId as GrandpaId;
|
||||
use im_online::sr25519::{AuthorityId as ImOnlineId};
|
||||
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
|
||||
use pallet_staking::Forcing;
|
||||
|
||||
const POLKADOT_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
|
||||
const KUSAMA_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
|
||||
const WESTEND_STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
|
||||
const DEFAULT_PROTOCOL_ID: &str = "dot";
|
||||
|
||||
/// Node `ChainSpec` extensions.
|
||||
///
|
||||
/// Additional parameters for some Substrate core modules,
|
||||
/// customizable from the chain spec.
|
||||
#[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Extensions {
|
||||
/// Block numbers with known hashes.
|
||||
pub fork_blocks: sc_client_api::ForkBlocks<polkadot_primitives::Block>,
|
||||
/// Known bad block hashes.
|
||||
pub bad_blocks: sc_client_api::BadBlocks<polkadot_primitives::Block>,
|
||||
}
|
||||
|
||||
/// The `ChainSpec parametrised for polkadot runtime`.
|
||||
pub type PolkadotChainSpec = service::GenericChainSpec<
|
||||
polkadot::GenesisConfig,
|
||||
Extensions,
|
||||
>;
|
||||
|
||||
/// The `ChainSpec parametrised for kusama runtime`.
|
||||
pub type KusamaChainSpec = service::GenericChainSpec<
|
||||
kusama::GenesisConfig,
|
||||
Extensions,
|
||||
>;
|
||||
|
||||
/// The `ChainSpec parametrised for westend runtime`.
|
||||
pub type WestendChainSpec = service::GenericChainSpec<
|
||||
westend::GenesisConfig,
|
||||
Extensions,
|
||||
>;
|
||||
|
||||
pub fn polkadot_config() -> Result<PolkadotChainSpec, String> {
|
||||
PolkadotChainSpec::from_json_bytes(&include_bytes!("../../../service/res/polkadot.json")[..])
|
||||
}
|
||||
|
||||
pub fn kusama_config() -> Result<KusamaChainSpec, String> {
|
||||
KusamaChainSpec::from_json_bytes(&include_bytes!("../../../service/res/kusama.json")[..])
|
||||
}
|
||||
|
||||
pub fn westend_config() -> Result<PolkadotChainSpec, String> {
|
||||
PolkadotChainSpec::from_json_bytes(&include_bytes!("../../../service/res/westend.json")[..])
|
||||
}
|
||||
|
||||
fn polkadot_session_keys(
|
||||
babe: BabeId,
|
||||
grandpa: GrandpaId,
|
||||
im_online: ImOnlineId,
|
||||
parachain_validator: ValidatorId,
|
||||
authority_discovery: AuthorityDiscoveryId
|
||||
) -> polkadot::SessionKeys {
|
||||
polkadot::SessionKeys { babe, grandpa, im_online, parachain_validator, authority_discovery }
|
||||
}
|
||||
|
||||
fn kusama_session_keys(
|
||||
babe: BabeId,
|
||||
grandpa: GrandpaId,
|
||||
im_online: ImOnlineId,
|
||||
parachain_validator: ValidatorId,
|
||||
authority_discovery: AuthorityDiscoveryId
|
||||
) -> kusama::SessionKeys {
|
||||
kusama::SessionKeys { babe, grandpa, im_online, parachain_validator, authority_discovery }
|
||||
}
|
||||
|
||||
fn westend_session_keys(
|
||||
babe: BabeId,
|
||||
grandpa: GrandpaId,
|
||||
im_online: ImOnlineId,
|
||||
parachain_validator: ValidatorId,
|
||||
authority_discovery: AuthorityDiscoveryId
|
||||
) -> westend::SessionKeys {
|
||||
westend::SessionKeys { babe, grandpa, im_online, parachain_validator, authority_discovery }
|
||||
}
|
||||
|
||||
fn polkadot_staging_testnet_config_genesis() -> polkadot::GenesisConfig {
|
||||
// subkey inspect "$SECRET"
|
||||
let endowed_accounts = vec![];
|
||||
|
||||
let initial_authorities: Vec<(
|
||||
AccountId,
|
||||
AccountId,
|
||||
BabeId,
|
||||
GrandpaId,
|
||||
ImOnlineId,
|
||||
ValidatorId,
|
||||
AuthorityDiscoveryId
|
||||
)> = vec![];
|
||||
|
||||
const ENDOWMENT: u128 = 1_000_000 * DOTS;
|
||||
const STASH: u128 = 100 * DOTS;
|
||||
|
||||
polkadot::GenesisConfig {
|
||||
system: Some(polkadot::SystemConfig {
|
||||
code: polkadot::WASM_BINARY.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
}),
|
||||
balances: Some(polkadot::BalancesConfig {
|
||||
balances: endowed_accounts.iter()
|
||||
.map(|k: &AccountId| (k.clone(), ENDOWMENT))
|
||||
.chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
|
||||
.collect(),
|
||||
}),
|
||||
indices: Some(polkadot::IndicesConfig {
|
||||
indices: vec![],
|
||||
}),
|
||||
session: Some(polkadot::SessionConfig {
|
||||
keys: initial_authorities.iter().map(|x| (
|
||||
x.0.clone(),
|
||||
x.0.clone(),
|
||||
polkadot_session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone(), x.6.clone()),
|
||||
)).collect::<Vec<_>>(),
|
||||
}),
|
||||
staking: Some(polkadot::StakingConfig {
|
||||
validator_count: 50,
|
||||
minimum_validator_count: 4,
|
||||
stakers: initial_authorities
|
||||
.iter()
|
||||
.map(|x| (x.0.clone(), x.1.clone(), STASH, polkadot::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::ForceNone,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
.. Default::default()
|
||||
}),
|
||||
elections_phragmen: Some(Default::default()),
|
||||
democracy: Some(Default::default()),
|
||||
collective_Instance1: Some(polkadot::CouncilConfig {
|
||||
members: vec![],
|
||||
phantom: Default::default(),
|
||||
}),
|
||||
collective_Instance2: Some(polkadot::TechnicalCommitteeConfig {
|
||||
members: vec![],
|
||||
phantom: Default::default(),
|
||||
}),
|
||||
membership_Instance1: Some(Default::default()),
|
||||
babe: Some(Default::default()),
|
||||
grandpa: Some(Default::default()),
|
||||
im_online: Some(Default::default()),
|
||||
authority_discovery: Some(polkadot::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
}),
|
||||
parachains: Some(polkadot::ParachainsConfig {
|
||||
authorities: vec![],
|
||||
}),
|
||||
registrar: Some(polkadot::RegistrarConfig {
|
||||
parachains: vec![],
|
||||
_phdata: Default::default(),
|
||||
}),
|
||||
claims: Some(polkadot::ClaimsConfig {
|
||||
claims: vec![],
|
||||
vesting: vec![],
|
||||
}),
|
||||
vesting: Some(polkadot::VestingConfig {
|
||||
vesting: vec![],
|
||||
}),
|
||||
sudo: Some(polkadot::SudoConfig {
|
||||
key: endowed_accounts[0].clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn westend_staging_testnet_config_genesis() -> westend::GenesisConfig {
|
||||
// subkey inspect "$SECRET"
|
||||
let endowed_accounts = vec![
|
||||
// 5ENpP27BrVdJTdUfY6djmcw3d3xEJ6NzSUU52CCPmGpMrdEY
|
||||
hex!["6648d7f3382690650c681aba1b993cd11e54deb4df21a3a18c3e2177de9f7342"].into(),
|
||||
];
|
||||
|
||||
// for i in 1 2 3 4; do for j in stash controller; do subkey inspect "$SECRET//$i//$j"; done; done
|
||||
// for i in 1 2 3 4; do for j in babe; do subkey --sr25519 inspect "$SECRET//$i//$j"; done; done
|
||||
// for i in 1 2 3 4; do for j in grandpa; do subkey --ed25519 inspect "$SECRET//$i//$j"; done; done
|
||||
// for i in 1 2 3 4; do for j in im_online; do subkey --sr25519 inspect "$SECRET//$i//$j"; done; done
|
||||
// for i in 1 2 3 4; do for j in parachains; do subkey --sr25519 inspect "$SECRET//$i//$j"; done; done
|
||||
let initial_authorities: Vec<(
|
||||
AccountId,
|
||||
AccountId,
|
||||
BabeId,
|
||||
GrandpaId,
|
||||
ImOnlineId,
|
||||
ValidatorId,
|
||||
AuthorityDiscoveryId
|
||||
)> = vec![(
|
||||
// 5FZoQhgUCmqBxnkHX7jCqThScS2xQWiwiF61msg63CFL3Y8f
|
||||
hex!["9ae581fef1fc06828723715731adcf810e42ce4dadad629b1b7fa5c3c144a81d"].into(),
|
||||
// 5ExdKyXFhtrjiFhexnyQPDyGSP8xU9qHc4KDwVrtWxaP2RP6
|
||||
hex!["8011fb3641f0641f5570ba8787a64a0ff7d9c9999481f333d7207c4abd7e981c"].into(),
|
||||
// 5Ef8qY8LRV6RFd4bThrwxBhhWfLjzqmd4rK8nX3Xs7zJqqp7
|
||||
hex!["72bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001"].unchecked_into(),
|
||||
// 5FSscBiPfaPaEhFbAt2qRhcYjryKBKf714X76F5nFfwtdXLa
|
||||
hex!["959cebf18fecb305b96fd998c95f850145f52cbbb64b3ef937c0575cc7ebd652"].unchecked_into(),
|
||||
// 5Ef8qY8LRV6RFd4bThrwxBhhWfLjzqmd4rK8nX3Xs7zJqqp7
|
||||
hex!["72bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001"].unchecked_into(),
|
||||
// 5Ef8qY8LRV6RFd4bThrwxBhhWfLjzqmd4rK8nX3Xs7zJqqp7
|
||||
hex!["72bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001"].unchecked_into(),
|
||||
// 5Ef8qY8LRV6RFd4bThrwxBhhWfLjzqmd4rK8nX3Xs7zJqqp7
|
||||
hex!["72bae70a1398c0ba52f815cc5dfbc9ec5c013771e541ae28e05d1129243e3001"].unchecked_into(),
|
||||
),(
|
||||
// 5G1ojzh47Yt8KoYhuAjXpHcazvsoCXe3G8LZchKDvumozJJJ
|
||||
hex!["aebb0211dbb07b4d335a657257b8ac5e53794c901e4f616d4a254f2490c43934"].into(),
|
||||
// 5GeoZ1Mzix6Xnj32X8Xpj7q89X1SQHU5XTK1cnUVNXKTvXdK
|
||||
hex!["caf27345aebc2fefeca85c9a67f4859eab3178d28ef92244714402290f3f415a"].into(),
|
||||
// 5Et8y49AyE7ncVKiSRgzN6zbqbYtMK6y7kKuUaS8YqvfLBD9
|
||||
hex!["7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a"].unchecked_into(),
|
||||
// 5Hpn3HVViECsuxMDFtinWjRj2dNfpRp1kB24nZHvQCJsSUek
|
||||
hex!["feca0be2c87141f6074b221c919c0161a1c468d9173c5c1be59b68fab9a0ff93"].unchecked_into(),
|
||||
// 5Et8y49AyE7ncVKiSRgzN6zbqbYtMK6y7kKuUaS8YqvfLBD9
|
||||
hex!["7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a"].unchecked_into(),
|
||||
// 5Et8y49AyE7ncVKiSRgzN6zbqbYtMK6y7kKuUaS8YqvfLBD9
|
||||
hex!["7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a"].unchecked_into(),
|
||||
// 5Et8y49AyE7ncVKiSRgzN6zbqbYtMK6y7kKuUaS8YqvfLBD9
|
||||
hex!["7ca58770eb41c1a68ef77e92255e4635fc11f665cb89aee469e920511c48343a"].unchecked_into(),
|
||||
),(
|
||||
// 5HYYWyhyUQ7Ae11f8fCid58bhJ7ikLHM9bU8A6Ynwoc3dStR
|
||||
hex!["f268995cc38974ce0686df1364875f26f2c32b246ddc18835512c3f9969f5836"].into(),
|
||||
// 5DnUXT3xiQn6ZRttFT6eSCJbT9P2tiLdexr5WsvnbLG8igqW
|
||||
hex!["4c17a9bfdd19411f452fa32420fa7acab622e87e57351f4ba3248ae40ce75123"].into(),
|
||||
// 5EhnN1SumSv5KxwLAdwE8ugJaw1S8xARZb8V2BMYCKaD7ure
|
||||
hex!["74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e"].unchecked_into(),
|
||||
// 5Hmvd2qjb1zatrJTkPwgFicxPfZuwaTwa2L7adSRmz6mVxfb
|
||||
hex!["fc9d33059580a69454179ffa41cbae6de2bc8d2bd2c3f1d018fe5484a5a91956"].unchecked_into(),
|
||||
// 5EhnN1SumSv5KxwLAdwE8ugJaw1S8xARZb8V2BMYCKaD7ure
|
||||
hex!["74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e"].unchecked_into(),
|
||||
// 5EhnN1SumSv5KxwLAdwE8ugJaw1S8xARZb8V2BMYCKaD7ure
|
||||
hex!["74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e"].unchecked_into(),
|
||||
// 5EhnN1SumSv5KxwLAdwE8ugJaw1S8xARZb8V2BMYCKaD7ure
|
||||
hex!["74bfb70627416e6e6c4785e928ced384c6c06e5c8dd173a094bc3118da7b673e"].unchecked_into(),
|
||||
),(
|
||||
// 5CFPcUJgYgWryPaV1aYjSbTpbTLu42V32Ytw1L9rfoMAsfGh
|
||||
hex!["08264834504a64ace1373f0c8ed5d57381ddf54a2f67a318fa42b1352681606d"].into(),
|
||||
// 5F6z64cYZFRAmyMUhp7rnge6jaZmbY6o7XfA9czJyuAUiaFD
|
||||
hex!["8671d451c3d4f6de8c16ea0bc61cf714914d6b2ffa2899872620525419327478"].into(),
|
||||
// 5Ft7o2uqDq5pXCK4g5wR94BctmtLEzCBy5MvPqRa8753ZemD
|
||||
hex!["a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f"].unchecked_into(),
|
||||
// 5FgBijJLL6p7nDZgQed56L3BM7ovgwc4t4FYsv9apYtRGAGv
|
||||
hex!["9fc415cce1d0b2eed702c9e05f476217d23b46a8723fd56f08cddad650be7c2d"].unchecked_into(),
|
||||
// 5Ft7o2uqDq5pXCK4g5wR94BctmtLEzCBy5MvPqRa8753ZemD
|
||||
hex!["a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f"].unchecked_into(),
|
||||
// 5Ft7o2uqDq5pXCK4g5wR94BctmtLEzCBy5MvPqRa8753ZemD
|
||||
hex!["a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f"].unchecked_into(),
|
||||
// 5Ft7o2uqDq5pXCK4g5wR94BctmtLEzCBy5MvPqRa8753ZemD
|
||||
hex!["a8ddd0891e14725841cd1b5581d23806a97f41c28a25436db6473c86e15dcd4f"].unchecked_into(),
|
||||
)];
|
||||
|
||||
const ENDOWMENT: u128 = 1_000_000 * WND;
|
||||
const STASH: u128 = 100 * WND;
|
||||
|
||||
westend::GenesisConfig {
|
||||
system: Some(westend::SystemConfig {
|
||||
code: westend::WASM_BINARY.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
}),
|
||||
balances: Some(westend::BalancesConfig {
|
||||
balances: endowed_accounts.iter()
|
||||
.map(|k: &AccountId| (k.clone(), ENDOWMENT))
|
||||
.chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
|
||||
.collect(),
|
||||
}),
|
||||
indices: Some(westend::IndicesConfig {
|
||||
indices: vec![],
|
||||
}),
|
||||
session: Some(westend::SessionConfig {
|
||||
keys: initial_authorities.iter().map(|x| (
|
||||
x.0.clone(),
|
||||
x.0.clone(),
|
||||
westend_session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone(), x.6.clone()),
|
||||
)).collect::<Vec<_>>(),
|
||||
}),
|
||||
staking: Some(westend::StakingConfig {
|
||||
validator_count: 50,
|
||||
minimum_validator_count: 4,
|
||||
stakers: initial_authorities
|
||||
.iter()
|
||||
.map(|x| (x.0.clone(), x.1.clone(), STASH, westend::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::ForceNone,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
.. Default::default()
|
||||
}),
|
||||
babe: Some(Default::default()),
|
||||
grandpa: Some(Default::default()),
|
||||
im_online: Some(Default::default()),
|
||||
authority_discovery: Some(westend::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
}),
|
||||
parachains: Some(westend::ParachainsConfig {
|
||||
authorities: vec![],
|
||||
}),
|
||||
registrar: Some(westend::RegistrarConfig {
|
||||
parachains: vec![],
|
||||
_phdata: Default::default(),
|
||||
}),
|
||||
vesting: Some(westend::VestingConfig {
|
||||
vesting: vec![],
|
||||
}),
|
||||
sudo: Some(westend::SudoConfig {
|
||||
key: endowed_accounts[0].clone(),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn kusama_staging_testnet_config_genesis() -> kusama::GenesisConfig {
|
||||
// subkey inspect "$SECRET"
|
||||
let endowed_accounts = vec![
|
||||
// 5CVFESwfkk7NmhQ6FwHCM9roBvr9BGa4vJHFYU8DnGQxrXvz
|
||||
hex!["12b782529c22032ed4694e0f6e7d486be7daa6d12088f6bc74d593b3900b8438"].into(),
|
||||
];
|
||||
|
||||
// for i in 1 2 3 4; do for j in stash controller; do subkey inspect "$SECRET//$i//$j"; done; done
|
||||
// for i in 1 2 3 4; do for j in babe; do subkey --sr25519 inspect "$SECRET//$i//$j"; done; done
|
||||
// for i in 1 2 3 4; do for j in grandpa; do subkey --ed25519 inspect "$SECRET//$i//$j"; done; done
|
||||
// for i in 1 2 3 4; do for j in im_online; do subkey --sr25519 inspect "$SECRET//$i//$j"; done; done
|
||||
// for i in 1 2 3 4; do for j in parachains; do subkey --sr25519 inspect "$SECRET//$i//$j"; done; done
|
||||
let initial_authorities: Vec<(
|
||||
AccountId,
|
||||
AccountId,
|
||||
BabeId,
|
||||
GrandpaId,
|
||||
ImOnlineId,
|
||||
ValidatorId,
|
||||
AuthorityDiscoveryId
|
||||
)> = vec![(
|
||||
// 5DD7Q4VEfPTLEdn11CnThoHT5f9xKCrnofWJL5SsvpTghaAT
|
||||
hex!["32a5718e87d16071756d4b1370c411bbbb947eb62f0e6e0b937d5cbfc0ea633b"].into(),
|
||||
// 5GNzaEqhrZAtUQhbMe2gn9jBuNWfamWFZHULryFwBUXyd1cG
|
||||
hex!["bee39fe862c85c91aaf343e130d30b643c6ea0b4406a980206f1df8331f7093b"].into(),
|
||||
// 5FpewyS2VY8Cj3tKgSckq8ECkjd1HKHvBRnWhiHqRQsWfFC1
|
||||
hex!["a639b507ee1585e0b6498ff141d6153960794523226866d1b44eba3f25f36356"].unchecked_into(),
|
||||
// 5EjvdwATjyFFikdZibVvx1q5uBHhphS2Mnsq5c7yfaYK25vm
|
||||
hex!["76620f7c98bce8619979c2b58cf2b0aff71824126d2b039358729dad993223db"].unchecked_into(),
|
||||
// 5FpewyS2VY8Cj3tKgSckq8ECkjd1HKHvBRnWhiHqRQsWfFC1
|
||||
hex!["a639b507ee1585e0b6498ff141d6153960794523226866d1b44eba3f25f36356"].unchecked_into(),
|
||||
// 5FpewyS2VY8Cj3tKgSckq8ECkjd1HKHvBRnWhiHqRQsWfFC1
|
||||
hex!["a639b507ee1585e0b6498ff141d6153960794523226866d1b44eba3f25f36356"].unchecked_into(),
|
||||
// 5FpewyS2VY8Cj3tKgSckq8ECkjd1HKHvBRnWhiHqRQsWfFC1
|
||||
hex!["a639b507ee1585e0b6498ff141d6153960794523226866d1b44eba3f25f36356"].unchecked_into(),
|
||||
),(
|
||||
// 5G9VGb8ESBeS8Ca4or43RfhShzk9y7T5iTmxHk5RJsjZwsRx
|
||||
hex!["b496c98a405ceab59b9e970e59ef61acd7765a19b704e02ab06c1cdfe171e40f"].into(),
|
||||
// 5F7V9Y5FcxKXe1aroqvPeRiUmmeQwTFcL3u9rrPXcMuMiCNx
|
||||
hex!["86d3a7571dd60139d297e55d8238d0c977b2e208c5af088f7f0136b565b0c103"].into(),
|
||||
// 5GvuM53k1Z4nAB5zXJFgkRSHv4Bqo4BsvgbQWNWkiWZTMwWY
|
||||
hex!["765e46067adac4d1fe6c783aa2070dfa64a19f84376659e12705d1734b3eae01"].unchecked_into(),
|
||||
// 5HBDAaybNqjmY7ww8ZcZZY1L5LHxvpnyfqJwoB7HhR6raTmG
|
||||
hex!["e2234d661bee4a04c38392c75d1566200aa9e6ae44dd98ee8765e4cc9af63cb7"].unchecked_into(),
|
||||
// 5GvuM53k1Z4nAB5zXJFgkRSHv4Bqo4BsvgbQWNWkiWZTMwWY
|
||||
hex!["765e46067adac4d1fe6c783aa2070dfa64a19f84376659e12705d1734b3eae01"].unchecked_into(),
|
||||
// 5GvuM53k1Z4nAB5zXJFgkRSHv4Bqo4BsvgbQWNWkiWZTMwWY
|
||||
hex!["765e46067adac4d1fe6c783aa2070dfa64a19f84376659e12705d1734b3eae01"].unchecked_into(),
|
||||
// 5GvuM53k1Z4nAB5zXJFgkRSHv4Bqo4BsvgbQWNWkiWZTMwWY
|
||||
hex!["765e46067adac4d1fe6c783aa2070dfa64a19f84376659e12705d1734b3eae01"].unchecked_into(),
|
||||
),(
|
||||
// 5FzwpgGvk2kk9agow6KsywLYcPzjYc8suKej2bne5G5b9YU3
|
||||
hex!["ae12f70078a22882bf5135d134468f77301927aa67c376e8c55b7ff127ace115"].into(),
|
||||
// 5EqoZhVC2BcsM4WjvZNidu2muKAbu5THQTBKe3EjvxXkdP7A
|
||||
hex!["7addb914ec8486bbc60643d2647685dcc06373401fa80e09813b630c5831d54b"].into(),
|
||||
// 5CXNq1mSKJT4Sc2CbyBBdANeSkbUvdWvE4czJjKXfBHi9sX5
|
||||
hex!["664eae1ca4713dd6abf8c15e6c041820cda3c60df97dc476c2cbf7cb82cb2d2e"].unchecked_into(),
|
||||
// 5E8ULLQrDAtWhfnVfZmX41Yux86zNAwVJYguWJZVWrJvdhBe
|
||||
hex!["5b57ed1443c8967f461db1f6eb2ada24794d163a668f1cf9d9ce3235dfad8799"].unchecked_into(),
|
||||
// 5CXNq1mSKJT4Sc2CbyBBdANeSkbUvdWvE4czJjKXfBHi9sX5
|
||||
hex!["664eae1ca4713dd6abf8c15e6c041820cda3c60df97dc476c2cbf7cb82cb2d2e"].unchecked_into(),
|
||||
// 5CXNq1mSKJT4Sc2CbyBBdANeSkbUvdWvE4czJjKXfBHi9sX5
|
||||
hex!["664eae1ca4713dd6abf8c15e6c041820cda3c60df97dc476c2cbf7cb82cb2d2e"].unchecked_into(),
|
||||
// 5CXNq1mSKJT4Sc2CbyBBdANeSkbUvdWvE4czJjKXfBHi9sX5
|
||||
hex!["664eae1ca4713dd6abf8c15e6c041820cda3c60df97dc476c2cbf7cb82cb2d2e"].unchecked_into(),
|
||||
),(
|
||||
// 5CFj6Kg9rmVn1vrqpyjau2ztyBzKeVdRKwNPiA3tqhB5HPqq
|
||||
hex!["0867dbb49721126df589db100dda728dc3b475cbf414dad8f72a1d5e84897252"].into(),
|
||||
// 5CwQXP6nvWzigFqNhh2jvCaW9zWVzkdveCJY3tz2MhXMjTon
|
||||
hex!["26ab2b4b2eba2263b1e55ceb48f687bb0018130a88df0712fbdaf6a347d50e2a"].into(),
|
||||
// 5FCd9Y7RLNyxz5wnCAErfsLbXGG34L2BaZRHzhiJcMUMd5zd
|
||||
hex!["2adb17a5cafbddc7c3e00ec45b6951a8b12ce2264235b4def342513a767e5d3d"].unchecked_into(),
|
||||
// 5HGLmrZsiTFTPp3QoS1W8w9NxByt8PVq79reqvdxNcQkByqK
|
||||
hex!["e60d23f49e93c1c1f2d7c115957df5bbd7faf5ebf138d1e9d02e8b39a1f63df0"].unchecked_into(),
|
||||
// 5FCd9Y7RLNyxz5wnCAErfsLbXGG34L2BaZRHzhiJcMUMd5zd
|
||||
hex!["2adb17a5cafbddc7c3e00ec45b6951a8b12ce2264235b4def342513a767e5d3d"].unchecked_into(),
|
||||
// 5FCd9Y7RLNyxz5wnCAErfsLbXGG34L2BaZRHzhiJcMUMd5zd
|
||||
hex!["2adb17a5cafbddc7c3e00ec45b6951a8b12ce2264235b4def342513a767e5d3d"].unchecked_into(),
|
||||
// 5FCd9Y7RLNyxz5wnCAErfsLbXGG34L2BaZRHzhiJcMUMd5zd
|
||||
hex!["2adb17a5cafbddc7c3e00ec45b6951a8b12ce2264235b4def342513a767e5d3d"].unchecked_into(),
|
||||
)];
|
||||
|
||||
const ENDOWMENT: u128 = 1_000_000 * KSM;
|
||||
const STASH: u128 = 100 * KSM;
|
||||
|
||||
kusama::GenesisConfig {
|
||||
system: Some(kusama::SystemConfig {
|
||||
code: kusama::WASM_BINARY.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
}),
|
||||
balances: Some(kusama::BalancesConfig {
|
||||
balances: endowed_accounts.iter()
|
||||
.map(|k: &AccountId| (k.clone(), ENDOWMENT))
|
||||
.chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
|
||||
.collect(),
|
||||
}),
|
||||
indices: Some(kusama::IndicesConfig {
|
||||
indices: vec![],
|
||||
}),
|
||||
session: Some(kusama::SessionConfig {
|
||||
keys: initial_authorities.iter().map(|x| (
|
||||
x.0.clone(),
|
||||
x.0.clone(),
|
||||
kusama_session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone(), x.6.clone()),
|
||||
)).collect::<Vec<_>>(),
|
||||
}),
|
||||
staking: Some(kusama::StakingConfig {
|
||||
validator_count: 50,
|
||||
minimum_validator_count: 4,
|
||||
stakers: initial_authorities
|
||||
.iter()
|
||||
.map(|x| (x.0.clone(), x.1.clone(), STASH, kusama::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::ForceNone,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
.. Default::default()
|
||||
}),
|
||||
elections_phragmen: Some(Default::default()),
|
||||
democracy: Some(Default::default()),
|
||||
collective_Instance1: Some(kusama::CouncilConfig {
|
||||
members: vec![],
|
||||
phantom: Default::default(),
|
||||
}),
|
||||
collective_Instance2: Some(kusama::TechnicalCommitteeConfig {
|
||||
members: vec![],
|
||||
phantom: Default::default(),
|
||||
}),
|
||||
membership_Instance1: Some(Default::default()),
|
||||
babe: Some(Default::default()),
|
||||
grandpa: Some(Default::default()),
|
||||
im_online: Some(Default::default()),
|
||||
authority_discovery: Some(kusama::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
}),
|
||||
parachains: Some(kusama::ParachainsConfig {
|
||||
authorities: vec![],
|
||||
}),
|
||||
registrar: Some(kusama::RegistrarConfig {
|
||||
parachains: vec![],
|
||||
_phdata: Default::default(),
|
||||
}),
|
||||
claims: Some(kusama::ClaimsConfig {
|
||||
claims: vec![],
|
||||
vesting: vec![],
|
||||
}),
|
||||
vesting: Some(kusama::VestingConfig {
|
||||
vesting: vec![],
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Polkadot staging testnet config.
|
||||
pub fn polkadot_staging_testnet_config() -> PolkadotChainSpec {
|
||||
let boot_nodes = vec![];
|
||||
PolkadotChainSpec::from_genesis(
|
||||
"Polkadot Staging Testnet",
|
||||
"polkadot_staging_testnet",
|
||||
ChainType::Live,
|
||||
polkadot_staging_testnet_config_genesis,
|
||||
boot_nodes,
|
||||
Some(TelemetryEndpoints::new(vec![(POLKADOT_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Polkadot Staging telemetry url is valid; qed")),
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Staging testnet config.
|
||||
pub fn kusama_staging_testnet_config() -> KusamaChainSpec {
|
||||
let boot_nodes = vec![];
|
||||
KusamaChainSpec::from_genesis(
|
||||
"Kusama Staging Testnet",
|
||||
"kusama_staging_testnet",
|
||||
ChainType::Live,
|
||||
kusama_staging_testnet_config_genesis,
|
||||
boot_nodes,
|
||||
Some(TelemetryEndpoints::new(vec![(KUSAMA_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Kusama Staging telemetry url is valid; qed")),
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Westend staging testnet config.
|
||||
pub fn westend_staging_testnet_config() -> WestendChainSpec {
|
||||
let boot_nodes = vec![];
|
||||
WestendChainSpec::from_genesis(
|
||||
"Westend Staging Testnet",
|
||||
"westend_staging_testnet",
|
||||
ChainType::Live,
|
||||
westend_staging_testnet_config_genesis,
|
||||
boot_nodes,
|
||||
Some(TelemetryEndpoints::new(vec![(WESTEND_STAGING_TELEMETRY_URL.to_string(), 0)])
|
||||
.expect("Westend Staging telemetry url is valid; qed")),
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Helper function to generate a crypto pair from seed
|
||||
pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
|
||||
TPublic::Pair::from_string(&format!("//{}", seed), None)
|
||||
.expect("static values are valid; qed")
|
||||
.public()
|
||||
}
|
||||
|
||||
|
||||
/// Helper function to generate an account ID from seed
|
||||
pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId where
|
||||
AccountPublic: From<<TPublic::Pair as Pair>::Public>
|
||||
{
|
||||
AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
|
||||
}
|
||||
|
||||
/// Helper function to generate stash, controller and session key from seed
|
||||
pub fn get_authority_keys_from_seed(seed: &str) -> (
|
||||
AccountId,
|
||||
AccountId,
|
||||
BabeId,
|
||||
GrandpaId,
|
||||
ImOnlineId,
|
||||
ValidatorId,
|
||||
AuthorityDiscoveryId
|
||||
) {
|
||||
(
|
||||
get_account_id_from_seed::<sr25519::Public>(&format!("{}//stash", seed)),
|
||||
get_account_id_from_seed::<sr25519::Public>(seed),
|
||||
get_from_seed::<BabeId>(seed),
|
||||
get_from_seed::<GrandpaId>(seed),
|
||||
get_from_seed::<ImOnlineId>(seed),
|
||||
get_from_seed::<ValidatorId>(seed),
|
||||
get_from_seed::<AuthorityDiscoveryId>(seed),
|
||||
)
|
||||
}
|
||||
|
||||
fn testnet_accounts() -> Vec<AccountId> {
|
||||
vec![
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
|
||||
]
|
||||
}
|
||||
|
||||
/// Helper function to create polkadot GenesisConfig for testing
|
||||
pub fn polkadot_testnet_genesis(
|
||||
initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId, ImOnlineId, ValidatorId, AuthorityDiscoveryId)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> polkadot::GenesisConfig {
|
||||
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
|
||||
|
||||
const ENDOWMENT: u128 = 1_000_000 * DOTS;
|
||||
const STASH: u128 = 100 * DOTS;
|
||||
|
||||
polkadot::GenesisConfig {
|
||||
system: Some(polkadot::SystemConfig {
|
||||
code: polkadot::WASM_BINARY.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
}),
|
||||
indices: Some(polkadot::IndicesConfig {
|
||||
indices: vec![],
|
||||
}),
|
||||
balances: Some(polkadot::BalancesConfig {
|
||||
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
|
||||
}),
|
||||
session: Some(polkadot::SessionConfig {
|
||||
keys: initial_authorities.iter().map(|x| (
|
||||
x.0.clone(),
|
||||
x.0.clone(),
|
||||
polkadot_session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone(), x.6.clone()),
|
||||
)).collect::<Vec<_>>(),
|
||||
}),
|
||||
staking: Some(polkadot::StakingConfig {
|
||||
minimum_validator_count: 1,
|
||||
validator_count: 2,
|
||||
stakers: initial_authorities.iter()
|
||||
.map(|x| (x.0.clone(), x.1.clone(), STASH, polkadot::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::NotForcing,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
.. Default::default()
|
||||
}),
|
||||
elections_phragmen: Some(Default::default()),
|
||||
democracy: Some(polkadot::DemocracyConfig::default()),
|
||||
collective_Instance1: Some(polkadot::CouncilConfig {
|
||||
members: vec![],
|
||||
phantom: Default::default(),
|
||||
}),
|
||||
collective_Instance2: Some(polkadot::TechnicalCommitteeConfig {
|
||||
members: vec![],
|
||||
phantom: Default::default(),
|
||||
}),
|
||||
membership_Instance1: Some(Default::default()),
|
||||
babe: Some(Default::default()),
|
||||
grandpa: Some(Default::default()),
|
||||
im_online: Some(Default::default()),
|
||||
authority_discovery: Some(polkadot::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
}),
|
||||
parachains: Some(polkadot::ParachainsConfig {
|
||||
authorities: vec![],
|
||||
}),
|
||||
registrar: Some(polkadot::RegistrarConfig{
|
||||
parachains: vec![],
|
||||
_phdata: Default::default(),
|
||||
}),
|
||||
claims: Some(polkadot::ClaimsConfig {
|
||||
claims: vec![],
|
||||
vesting: vec![],
|
||||
}),
|
||||
vesting: Some(polkadot::VestingConfig {
|
||||
vesting: vec![],
|
||||
}),
|
||||
sudo: Some(polkadot::SudoConfig {
|
||||
key: root_key,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to create kusama GenesisConfig for testing
|
||||
pub fn kusama_testnet_genesis(
|
||||
initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId, ImOnlineId, ValidatorId, AuthorityDiscoveryId)>,
|
||||
_root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> kusama::GenesisConfig {
|
||||
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
|
||||
|
||||
const ENDOWMENT: u128 = 1_000_000 * KSM;
|
||||
const STASH: u128 = 100 * KSM;
|
||||
|
||||
kusama::GenesisConfig {
|
||||
system: Some(kusama::SystemConfig {
|
||||
code: kusama::WASM_BINARY.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
}),
|
||||
indices: Some(kusama::IndicesConfig {
|
||||
indices: vec![],
|
||||
}),
|
||||
balances: Some(kusama::BalancesConfig {
|
||||
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
|
||||
}),
|
||||
session: Some(kusama::SessionConfig {
|
||||
keys: initial_authorities.iter().map(|x| (
|
||||
x.0.clone(),
|
||||
x.0.clone(),
|
||||
kusama_session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone(), x.6.clone()),
|
||||
)).collect::<Vec<_>>(),
|
||||
}),
|
||||
staking: Some(kusama::StakingConfig {
|
||||
minimum_validator_count: 1,
|
||||
validator_count: 2,
|
||||
stakers: initial_authorities.iter()
|
||||
.map(|x| (x.0.clone(), x.1.clone(), STASH, kusama::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::NotForcing,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
.. Default::default()
|
||||
}),
|
||||
elections_phragmen: Some(Default::default()),
|
||||
democracy: Some(kusama::DemocracyConfig::default()),
|
||||
collective_Instance1: Some(kusama::CouncilConfig {
|
||||
members: vec![],
|
||||
phantom: Default::default(),
|
||||
}),
|
||||
collective_Instance2: Some(kusama::TechnicalCommitteeConfig {
|
||||
members: vec![],
|
||||
phantom: Default::default(),
|
||||
}),
|
||||
membership_Instance1: Some(Default::default()),
|
||||
babe: Some(Default::default()),
|
||||
grandpa: Some(Default::default()),
|
||||
im_online: Some(Default::default()),
|
||||
authority_discovery: Some(kusama::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
}),
|
||||
parachains: Some(kusama::ParachainsConfig {
|
||||
authorities: vec![],
|
||||
}),
|
||||
registrar: Some(kusama::RegistrarConfig{
|
||||
parachains: vec![],
|
||||
_phdata: Default::default(),
|
||||
}),
|
||||
claims: Some(kusama::ClaimsConfig {
|
||||
claims: vec![],
|
||||
vesting: vec![],
|
||||
}),
|
||||
vesting: Some(kusama::VestingConfig {
|
||||
vesting: vec![],
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// Helper function to create polkadot GenesisConfig for testing
|
||||
pub fn westend_testnet_genesis(
|
||||
initial_authorities: Vec<(AccountId, AccountId, BabeId, GrandpaId, ImOnlineId, ValidatorId, AuthorityDiscoveryId)>,
|
||||
root_key: AccountId,
|
||||
endowed_accounts: Option<Vec<AccountId>>,
|
||||
) -> westend::GenesisConfig {
|
||||
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
|
||||
|
||||
const ENDOWMENT: u128 = 1_000_000 * DOTS;
|
||||
const STASH: u128 = 100 * DOTS;
|
||||
|
||||
westend::GenesisConfig {
|
||||
system: Some(westend::SystemConfig {
|
||||
code: westend::WASM_BINARY.to_vec(),
|
||||
changes_trie_config: Default::default(),
|
||||
}),
|
||||
indices: Some(westend::IndicesConfig {
|
||||
indices: vec![],
|
||||
}),
|
||||
balances: Some(westend::BalancesConfig {
|
||||
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
|
||||
}),
|
||||
session: Some(westend::SessionConfig {
|
||||
keys: initial_authorities.iter().map(|x| (
|
||||
x.0.clone(),
|
||||
x.0.clone(),
|
||||
westend_session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone(), x.6.clone()),
|
||||
)).collect::<Vec<_>>(),
|
||||
}),
|
||||
staking: Some(westend::StakingConfig {
|
||||
minimum_validator_count: 1,
|
||||
validator_count: 2,
|
||||
stakers: initial_authorities.iter()
|
||||
.map(|x| (x.0.clone(), x.1.clone(), STASH, westend::StakerStatus::Validator))
|
||||
.collect(),
|
||||
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
||||
force_era: Forcing::NotForcing,
|
||||
slash_reward_fraction: Perbill::from_percent(10),
|
||||
.. Default::default()
|
||||
}),
|
||||
babe: Some(Default::default()),
|
||||
grandpa: Some(Default::default()),
|
||||
im_online: Some(Default::default()),
|
||||
authority_discovery: Some(westend::AuthorityDiscoveryConfig {
|
||||
keys: vec![],
|
||||
}),
|
||||
parachains: Some(westend::ParachainsConfig {
|
||||
authorities: vec![],
|
||||
}),
|
||||
registrar: Some(westend::RegistrarConfig{
|
||||
parachains: vec![],
|
||||
_phdata: Default::default(),
|
||||
}),
|
||||
vesting: Some(westend::VestingConfig {
|
||||
vesting: vec![],
|
||||
}),
|
||||
sudo: Some(westend::SudoConfig {
|
||||
key: root_key,
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn polkadot_development_config_genesis() -> polkadot::GenesisConfig {
|
||||
polkadot_testnet_genesis(
|
||||
vec![
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
fn kusama_development_config_genesis() -> kusama::GenesisConfig {
|
||||
kusama_testnet_genesis(
|
||||
vec![
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
fn westend_development_config_genesis() -> westend::GenesisConfig {
|
||||
westend_testnet_genesis(
|
||||
vec![
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
/// Polkadot development config (single validator Alice)
|
||||
pub fn polkadot_development_config() -> PolkadotChainSpec {
|
||||
PolkadotChainSpec::from_genesis(
|
||||
"Development",
|
||||
"dev",
|
||||
ChainType::Development,
|
||||
polkadot_development_config_genesis,
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Kusama development config (single validator Alice)
|
||||
pub fn kusama_development_config() -> KusamaChainSpec {
|
||||
KusamaChainSpec::from_genesis(
|
||||
"Development",
|
||||
"kusama_dev",
|
||||
ChainType::Development,
|
||||
kusama_development_config_genesis,
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
/// Westend development config (single validator Alice)
|
||||
pub fn westend_development_config() -> WestendChainSpec {
|
||||
WestendChainSpec::from_genesis(
|
||||
"Development",
|
||||
"westend_dev",
|
||||
ChainType::Development,
|
||||
westend_development_config_genesis,
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn polkadot_local_testnet_genesis() -> polkadot::GenesisConfig {
|
||||
polkadot_testnet_genesis(
|
||||
vec![
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
get_authority_keys_from_seed("Bob"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
/// Polkadot local testnet config (multivalidator Alice + Bob)
|
||||
pub fn polkadot_local_testnet_config() -> PolkadotChainSpec {
|
||||
PolkadotChainSpec::from_genesis(
|
||||
"Local Testnet",
|
||||
"local_testnet",
|
||||
ChainType::Local,
|
||||
polkadot_local_testnet_genesis,
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn kusama_local_testnet_genesis() -> kusama::GenesisConfig {
|
||||
kusama_testnet_genesis(
|
||||
vec![
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
get_authority_keys_from_seed("Bob"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
/// Kusama local testnet config (multivalidator Alice + Bob)
|
||||
pub fn kusama_local_testnet_config() -> KusamaChainSpec {
|
||||
KusamaChainSpec::from_genesis(
|
||||
"Kusama Local Testnet",
|
||||
"kusama_local_testnet",
|
||||
ChainType::Local,
|
||||
kusama_local_testnet_genesis,
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
|
||||
fn westend_local_testnet_genesis() -> westend::GenesisConfig {
|
||||
westend_testnet_genesis(
|
||||
vec![
|
||||
get_authority_keys_from_seed("Alice"),
|
||||
get_authority_keys_from_seed("Bob"),
|
||||
],
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
||||
/// Westend local testnet config (multivalidator Alice + Bob)
|
||||
pub fn westend_local_testnet_config() -> WestendChainSpec {
|
||||
WestendChainSpec::from_genesis(
|
||||
"Westend Local Testnet",
|
||||
"westend_local_testnet",
|
||||
ChainType::Local,
|
||||
westend_local_testnet_genesis,
|
||||
vec![],
|
||||
None,
|
||||
Some(DEFAULT_PROTOCOL_ID),
|
||||
None,
|
||||
Default::default(),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot 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
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Polkadot Client meta trait
|
||||
|
||||
use sp_api::{ProvideRuntimeApi, ConstructRuntimeApi, CallApiAt};
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use sc_client_api::{Backend as BackendT, BlockchainEvents};
|
||||
|
||||
/// Polkadot client abstraction, this super trait only pulls in functionality required for
|
||||
/// polkadot internal crates like polkadot-collator.
|
||||
pub trait PolkadotClient<Block, Backend, Runtime>:
|
||||
BlockchainEvents<Block> + Sized + Send + Sync
|
||||
+ ProvideRuntimeApi<Block, Api = Runtime::RuntimeApi>
|
||||
+ HeaderBackend<Block>
|
||||
+ CallApiAt<
|
||||
Block,
|
||||
Error = sp_blockchain::Error,
|
||||
StateBackend = Backend ::State
|
||||
>
|
||||
where
|
||||
Block: BlockT,
|
||||
Backend: BackendT<Block>,
|
||||
Runtime: ConstructRuntimeApi<Block, Self>
|
||||
{}
|
||||
|
||||
impl<Block, Backend, Runtime, Client> PolkadotClient<Block, Backend, Runtime> for Client
|
||||
where
|
||||
Block: BlockT,
|
||||
Runtime: ConstructRuntimeApi<Block, Self>,
|
||||
Backend: BackendT<Block>,
|
||||
Client: BlockchainEvents<Block> + ProvideRuntimeApi<Block, Api = Runtime::RuntimeApi> + HeaderBackend<Block>
|
||||
+ Sized + Send + Sync
|
||||
+ CallApiAt<
|
||||
Block,
|
||||
Error = sp_blockchain::Error,
|
||||
StateBackend = Backend ::State
|
||||
>
|
||||
{}
|
||||
@@ -0,0 +1,363 @@
|
||||
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot 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
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Polkadot-specific GRANDPA integration utilities.
|
||||
|
||||
use polkadot_primitives::Hash;
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor};
|
||||
|
||||
/// A custom GRANDPA voting rule that "pauses" voting (i.e. keeps voting for the
|
||||
/// same last finalized block) after a given block at height `N` has been
|
||||
/// finalized and for a delay of `M` blocks, i.e. until the best block reaches
|
||||
/// `N` + `M`, the voter will keep voting for block `N`.
|
||||
pub(crate) struct PauseAfterBlockFor<N>(pub(crate) N, pub(crate) N);
|
||||
|
||||
impl<Block, B> grandpa::VotingRule<Block, B> for PauseAfterBlockFor<NumberFor<Block>> where
|
||||
Block: BlockT,
|
||||
B: sp_blockchain::HeaderBackend<Block>,
|
||||
{
|
||||
fn restrict_vote(
|
||||
&self,
|
||||
backend: &B,
|
||||
base: &Block::Header,
|
||||
best_target: &Block::Header,
|
||||
current_target: &Block::Header,
|
||||
) -> Option<(Block::Hash, NumberFor<Block>)> {
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_runtime::traits::Header as _;
|
||||
|
||||
// walk backwards until we find the target block
|
||||
let find_target = |
|
||||
target_number: NumberFor<Block>,
|
||||
current_header: &Block::Header
|
||||
| {
|
||||
let mut target_hash = current_header.hash();
|
||||
let mut target_header = current_header.clone();
|
||||
|
||||
loop {
|
||||
if *target_header.number() < target_number {
|
||||
unreachable!(
|
||||
"we are traversing backwards from a known block; \
|
||||
blocks are stored contiguously; \
|
||||
qed"
|
||||
);
|
||||
}
|
||||
|
||||
if *target_header.number() == target_number {
|
||||
return Some((target_hash, target_number));
|
||||
}
|
||||
|
||||
target_hash = *target_header.parent_hash();
|
||||
target_header = backend.header(BlockId::Hash(target_hash)).ok()?
|
||||
.expect("Header known to exist due to the existence of one of its descendents; qed");
|
||||
}
|
||||
};
|
||||
|
||||
// only restrict votes targeting a block higher than the block
|
||||
// we've set for the pause
|
||||
if *current_target.number() > self.0 {
|
||||
// if we're past the pause period (i.e. `self.0 + self.1`)
|
||||
// then we no longer need to restrict any votes
|
||||
if *best_target.number() > self.0 + self.1 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// if we've finalized the pause block, just keep returning it
|
||||
// until best number increases enough to pass the condition above
|
||||
if *base.number() >= self.0 {
|
||||
return Some((base.hash(), *base.number()));
|
||||
}
|
||||
|
||||
// otherwise find the target header at the pause block
|
||||
// to vote on
|
||||
return find_target(self.0, current_target);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// GRANDPA hard forks due to borked migration of session keys after a runtime
|
||||
/// upgrade (at #1491596), the signalled authority set changes were invalid
|
||||
/// (blank keys) and were impossible to finalize. The authorities for these
|
||||
/// intermediary pending changes are replaced with a static list comprised of
|
||||
/// w3f validators and randomly selected validators from the latest session (at
|
||||
/// #1500988).
|
||||
pub(crate) fn kusama_hard_forks() -> Vec<(
|
||||
grandpa_primitives::SetId,
|
||||
(Hash, polkadot_primitives::BlockNumber),
|
||||
grandpa_primitives::AuthorityList,
|
||||
)> {
|
||||
use sp_core::crypto::Ss58Codec;
|
||||
use std::str::FromStr;
|
||||
|
||||
let forks = vec![
|
||||
(
|
||||
623,
|
||||
"01e94e1e7e9cf07b3b0bf4e1717fce7448e5563901c2ef2e3b8e9ecaeba088b1",
|
||||
1492283,
|
||||
),
|
||||
(
|
||||
624,
|
||||
"ddc4323c5e8966844dfaa87e0c2f74ef6b43115f17bf8e4ff38845a62d02b9a9",
|
||||
1492436,
|
||||
),
|
||||
(
|
||||
625,
|
||||
"38ba115b296663e424e32d7b1655cd795719cef4fd7d579271a6d01086cf1628",
|
||||
1492586,
|
||||
),
|
||||
(
|
||||
626,
|
||||
"f3172b6b8497c10fc772f5dada4eeb1f4c4919c97de9de2e1a439444d5a057ff",
|
||||
1492955,
|
||||
),
|
||||
(
|
||||
627,
|
||||
"b26526aea299e9d24af29fdacd5cf4751a663d24894e3d0a37833aa14c58424a",
|
||||
1493338,
|
||||
),
|
||||
(
|
||||
628,
|
||||
"3980d024327d53b8d01ef0d198a052cd058dd579508d8ed6283fe3614e0a3694",
|
||||
1493913,
|
||||
),
|
||||
(
|
||||
629,
|
||||
"31f22997a786c25ee677786373368cae6fd501fd1bc4b212b8e267235c88179d",
|
||||
1495083,
|
||||
),
|
||||
(
|
||||
630,
|
||||
"1c65eb250cf54b466c64f1a4003d1415a7ee275e49615450c0e0525179857eef",
|
||||
1497404,
|
||||
),
|
||||
(
|
||||
631,
|
||||
"9e44116467cc9d7e224e36487bf2cf571698cae16b25f54a7430f1278331fdd8",
|
||||
1498598,
|
||||
),
|
||||
];
|
||||
|
||||
let authorities = vec![
|
||||
"CwjLJ1zPWK5Ao9WChAFp7rWGEgN3AyXXjTRPrqgm5WwBpoS",
|
||||
"Dp8FHpZTzvoKXztkfrUAkF6xNf6sjVU5ZLZ29NEGUazouou",
|
||||
"DtK7YfkhNWU6wEPF1dShsFdhtosVAuJPLkoGhKhG1r5LjKq",
|
||||
"FLnHYBuoyThzqJ45tdb8P6yMLdocM7ir27Pg1AnpYoygm1K",
|
||||
"FWEfJ5UMghr52UopgYjawAg6hQg3ztbQek75pfeRtLVi8pB",
|
||||
"ECoLHAu7HKWGTB9od82HAtequYj6hvNHigkGSB9g3ApxAwB",
|
||||
"GL1Tg3Uppo8GYL9NjKj4dWKcS6tW98REop9G5hpu7HgFwTa",
|
||||
"ExnjU5LZMktrgtQBE3An6FsQfvaKG1ukxPqwhJydgdgarmY",
|
||||
"CagLpgCBu5qJqYF2tpFX6BnU4yHvMGSjc7r3Ed1jY3tMbQt",
|
||||
"DsrtmMsD4ijh3n4uodxPoiW9NZ7v7no5wVvPVj8fL1dfrWB",
|
||||
"HQB4EctrVR68ozZDyBiRJzLRAEGh1YKgCkAsFjJcegL9RQA",
|
||||
"H2YTYbXTFkDY1cGnv164ecnDT3hsD2bQXtyiDbcQuXcQZUV",
|
||||
"H5WL8jXmbkCoEcLfvqJkbLUeGrDFsJiMXkhhRWn3joct1tE",
|
||||
"DpB37GDrJDYcmg2df2eqsrPKMay1u8hyZ6sQi2FuUiUeNLu",
|
||||
"FR8yjKRA9MTjvFGK8kfzrdC23Fr6xd7rfBvZXSjAsmuxURE",
|
||||
"DxHPty3B9fpj3duu6Gc6gCSCAvsydJHJEY5G3oVYT8S5BYJ",
|
||||
"DbVKC8ZJjevrhqSnZyJMMvmPL7oPPL4ed1roxawYnHVgyin",
|
||||
"DVJV81kab2J6oTyRJ9T3NCwW2DSrysbWCssvMcE6cwZHnAd",
|
||||
"Fg4rDAyzoVzf39Zo8JFPo4W314ntNWNwm3shr4xKe8M1fJg",
|
||||
"GUaNcnAruMVxHGTs7gGpSUpigRJboQYQBBQyPohkFcP6NMH",
|
||||
"J4BMGF4W9yWiJz4pkhQW73X6QMGpKUzmPppVnqzBCqw5dQq",
|
||||
"E1cR61L1tdDEop4WdWVqcq1H1x6VqsDpSHvFyUeC41uruVJ",
|
||||
"GoWLzBsj1f23YtdDpyntnvN1LwXKhF5TEeZvBeTVxofgWGR",
|
||||
"CwHwmbogSwtRbrkajVBNubPvWmHBGU4bhMido54M9CjuKZD",
|
||||
"FLT63y9oVXJnyiWMAL4RvWxsQx21Vymw9961Z7NRFmSG7rw",
|
||||
"FoQ2y6JuHuHTG4rHFL3f2hCxfJMvtrq8wwPWdv8tsdkcyA8",
|
||||
"D7QQKqqs8ocGorRA12h4QoBSHDia1DkHeXT4eMfjWQ483QH",
|
||||
"J6z7FP35F9DiiU985bhkDTS3WxyeTBeoo9MtLdLoD3GiWPj",
|
||||
"EjapydCK25AagodRbDECavHAy8yQY1tmeRhwUXhVWx4cFPv",
|
||||
"H8admATcRkGCrF1dTDDBCjQDsYjMkuPaN9YwR2mSCj4DWMQ",
|
||||
"FtHMRU1fxsoswJjBvyCGvECepC7gP2X77QbNpyikYSqqR6k",
|
||||
"DzY5gwr45GVRUFzRMmeg8iffpqYF47nm3XbJhmjG97FijaE",
|
||||
"D3HKWAihSUmg8HrfeFrftSwNK7no261yA9RNr3LUUdsuzuJ",
|
||||
"D82DwwGJGTcSvtB3SmNrZejnSertbPzpkYvDUp3ibScL3ne",
|
||||
"FTPxLXLQvMDQYFA6VqNLGwWPKhemMYP791XVj8TmDpFuV3b",
|
||||
"FzGfKmS7N8Z1tvCBU5JH1eBXZQ9pCtRNoMUnNVv38wZNq72",
|
||||
"GDfm1MyLAQ7Rh8YPtF6FtMweV4hz91zzeDy2sSABNNqAbmg",
|
||||
"DiVQbq7sozeKp7PXPM1HLFc2m7ih8oepKLRK99oBY3QZak1",
|
||||
"HErWh7D2RzrjWWB2fTJfcAejD9MJpadeWWZM2Wnk7LiNWfG",
|
||||
"Es4DbDauYZYyRJbr6VxrhdcM1iufP9GtdBYf3YtSEvdwNyb",
|
||||
"EBgXT6FaVo4WsN2LmfnB2jnpDFf4zay3E492RGSn6v1tY99",
|
||||
"Dr9Zg4fxZurexParztL9SezFeHsPwdP8uGgULeRMbk8DDHJ",
|
||||
"JEnSTZJpLh91cSryptj57RtFxq9xXqf4U5wBH3qoP91ZZhN",
|
||||
"DqtRkrmtPANa8wrYR7Ce2LxJxk2iNFtiCxv1cXbx54uqdTN",
|
||||
"GaxmF53xbuTFKopVEseWiaCTa8fC6f99n4YfW8MGPSPYX3s",
|
||||
"EiCesgkAaighBKMpwFSAUdvwE4mRjBjNmmd5fP6d4FG8DAx",
|
||||
"HVbwWGUx7kCgUGap1Mfcs37g6JAZ5qsfsM7TsDRcSqvfxmd",
|
||||
"G45bc8Ajrd6YSXav77gQwjjGoAsR2qiGd1aLzkMy7o1RLwd",
|
||||
"Cqix2rD93Mdf7ytg8tBavAig2TvhXPgPZ2mejQvkq7qgRPq",
|
||||
"GpodE2S5dPeVjzHB4Drm8R9rEwcQPtwAspXqCVz1ooFWf5K",
|
||||
"CwfmfRmzPKLj3ntSCejuVwYmQ1F9iZWY4meQrAVoJ2G8Kce",
|
||||
"Fhp5NPvutRCJ4Gx3G8vCYGaveGcU3KgTwfrn5Zr8sLSgwVx",
|
||||
"GeYRRPkyi23wSF3cJGjq82117fKJZUbWsAGimUnzb5RPbB1",
|
||||
"DzCJ4y5oT611dfKQwbBDVbtCfENTdMCjb4KGMU3Mq6nyUMu",
|
||||
];
|
||||
|
||||
let authorities = authorities
|
||||
.into_iter()
|
||||
.map(|address| {
|
||||
(
|
||||
grandpa_primitives::AuthorityId::from_ss58check(address)
|
||||
.expect("hard fork authority addresses are static and they should be carefully defined; qed."),
|
||||
1,
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
forks
|
||||
.into_iter()
|
||||
.map(|(set_id, hash, number)| {
|
||||
let hash = Hash::from_str(hash)
|
||||
.expect("hard fork hashes are static and they should be carefully defined; qed.");
|
||||
|
||||
(set_id, (hash, number), authorities.clone())
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use polkadot_test_runtime_client::prelude::*;
|
||||
use polkadot_test_runtime_client::sp_consensus::BlockOrigin;
|
||||
use sc_block_builder::BlockBuilderProvider;
|
||||
use grandpa::VotingRule;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_runtime::generic::BlockId;
|
||||
use sp_runtime::traits::Header;
|
||||
use std::sync::Arc;
|
||||
|
||||
#[test]
|
||||
fn grandpa_pause_voting_rule_works() {
|
||||
let _ = env_logger::try_init();
|
||||
|
||||
let client = Arc::new(polkadot_test_runtime_client::new());
|
||||
|
||||
let mut push_blocks = {
|
||||
let mut client = client.clone();
|
||||
move |n| {
|
||||
for _ in 0..n {
|
||||
let mut builder = client.new_block(Default::default()).unwrap();
|
||||
|
||||
for extrinsic in polkadot_test_runtime_client::needed_extrinsics(vec![]) {
|
||||
builder.push(extrinsic).unwrap()
|
||||
}
|
||||
|
||||
let block = builder.build().unwrap().block;
|
||||
client.import(BlockOrigin::Own, block).unwrap();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let get_header = {
|
||||
let client = client.clone();
|
||||
move |n| client.header(&BlockId::Number(n)).unwrap().unwrap()
|
||||
};
|
||||
|
||||
// the rule should filter all votes after block #20
|
||||
// is finalized until block #50 is imported.
|
||||
let voting_rule = super::PauseAfterBlockFor(20, 30);
|
||||
|
||||
// add 10 blocks
|
||||
push_blocks(10);
|
||||
assert_eq!(
|
||||
client.info().best_number,
|
||||
10,
|
||||
);
|
||||
|
||||
// we have not reached the pause block
|
||||
// therefore nothing should be restricted
|
||||
assert_eq!(
|
||||
voting_rule.restrict_vote(
|
||||
&*client,
|
||||
&get_header(0),
|
||||
&get_header(10),
|
||||
&get_header(10),
|
||||
),
|
||||
None,
|
||||
);
|
||||
|
||||
// add 15 more blocks
|
||||
// best block: #25
|
||||
push_blocks(15);
|
||||
|
||||
// we are targeting the pause block,
|
||||
// the vote should not be restricted
|
||||
assert_eq!(
|
||||
voting_rule.restrict_vote(
|
||||
&*client,
|
||||
&get_header(10),
|
||||
&get_header(20),
|
||||
&get_header(20),
|
||||
),
|
||||
None,
|
||||
);
|
||||
|
||||
// we are past the pause block, votes should
|
||||
// be limited to the pause block.
|
||||
let pause_block = get_header(20);
|
||||
assert_eq!(
|
||||
voting_rule.restrict_vote(
|
||||
&*client,
|
||||
&get_header(10),
|
||||
&get_header(21),
|
||||
&get_header(21),
|
||||
),
|
||||
Some((pause_block.hash(), *pause_block.number())),
|
||||
);
|
||||
|
||||
// we've finalized the pause block, so we'll keep
|
||||
// restricting our votes to it.
|
||||
assert_eq!(
|
||||
voting_rule.restrict_vote(
|
||||
&*client,
|
||||
&pause_block, // #20
|
||||
&get_header(21),
|
||||
&get_header(21),
|
||||
),
|
||||
Some((pause_block.hash(), *pause_block.number())),
|
||||
);
|
||||
|
||||
// add 30 more blocks
|
||||
// best block: #55
|
||||
push_blocks(30);
|
||||
|
||||
// we're at the last block of the pause, this block
|
||||
// should still be considered in the pause period
|
||||
assert_eq!(
|
||||
voting_rule.restrict_vote(
|
||||
&*client,
|
||||
&pause_block, // #20
|
||||
&get_header(50),
|
||||
&get_header(50),
|
||||
),
|
||||
Some((pause_block.hash(), *pause_block.number())),
|
||||
);
|
||||
|
||||
// we're past the pause period, no votes should be filtered
|
||||
assert_eq!(
|
||||
voting_rule.restrict_vote(
|
||||
&*client,
|
||||
&pause_block, // #20
|
||||
&get_header(51),
|
||||
&get_header(51),
|
||||
),
|
||||
None,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,729 @@
|
||||
// Copyright 2017-2020 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot 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
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Polkadot service. Specialized wrapper over substrate service.
|
||||
|
||||
pub mod chain_spec;
|
||||
mod grandpa_support;
|
||||
mod client;
|
||||
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use polkadot_primitives::{parachain, AccountId, Nonce, Balance};
|
||||
#[cfg(feature = "full-node")]
|
||||
use service::{error::Error as ServiceError, ServiceBuilder};
|
||||
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
|
||||
use sc_executor::native_executor_instance;
|
||||
use log::info;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use polkadot_overseer::{
|
||||
self as overseer,
|
||||
BlockInfo, Overseer, OverseerHandler, Subsystem, SubsystemContext, SpawnedSubsystem,
|
||||
ValidationSubsystemMessage, CandidateBackingSubsystemMessage,
|
||||
};
|
||||
pub use service::{
|
||||
AbstractService, Role, PruningMode, TransactionPoolOptions, Error, RuntimeGenesis,
|
||||
TFullClient, TLightClient, TFullBackend, TLightBackend, TFullCallExecutor, TLightCallExecutor,
|
||||
Configuration, ChainSpec, ServiceBuilderCommand,
|
||||
};
|
||||
pub use service::config::{DatabaseConfig, PrometheusConfig};
|
||||
pub use sc_executor::NativeExecutionDispatch;
|
||||
pub use sc_client_api::{Backend, ExecutionStrategy, CallExecutor};
|
||||
pub use sc_consensus::LongestChain;
|
||||
pub use sp_api::{ApiRef, Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend};
|
||||
pub use sp_runtime::traits::{DigestFor, HashFor, NumberFor};
|
||||
pub use consensus_common::{Proposal, SelectChain, BlockImport, RecordProof, block_validation::Chain};
|
||||
pub use polkadot_primitives::parachain::{CollatorId, ParachainHost};
|
||||
pub use polkadot_primitives::{Block, BlockId};
|
||||
pub use sp_runtime::traits::{Block as BlockT, self as runtime_traits, BlakeTwo256};
|
||||
pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec};
|
||||
#[cfg(feature = "full-node")]
|
||||
pub use codec::Codec;
|
||||
pub use polkadot_runtime;
|
||||
pub use kusama_runtime;
|
||||
pub use westend_runtime;
|
||||
use prometheus_endpoint::Registry;
|
||||
pub use self::client::PolkadotClient;
|
||||
|
||||
native_executor_instance!(
|
||||
pub PolkadotExecutor,
|
||||
polkadot_runtime::api::dispatch,
|
||||
polkadot_runtime::native_version,
|
||||
frame_benchmarking::benchmarking::HostFunctions,
|
||||
);
|
||||
|
||||
native_executor_instance!(
|
||||
pub KusamaExecutor,
|
||||
kusama_runtime::api::dispatch,
|
||||
kusama_runtime::native_version,
|
||||
frame_benchmarking::benchmarking::HostFunctions,
|
||||
);
|
||||
|
||||
native_executor_instance!(
|
||||
pub WestendExecutor,
|
||||
westend_runtime::api::dispatch,
|
||||
westend_runtime::native_version,
|
||||
frame_benchmarking::benchmarking::HostFunctions,
|
||||
);
|
||||
|
||||
/// A set of APIs that polkadot-like runtimes must implement.
|
||||
pub trait RuntimeApiCollection<Extrinsic: codec::Codec + Send + Sync + 'static>:
|
||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
|
||||
+ babe_primitives::BabeApi<Block>
|
||||
+ grandpa_primitives::GrandpaApi<Block>
|
||||
+ ParachainHost<Block>
|
||||
+ sp_block_builder::BlockBuilder<Block>
|
||||
+ system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
|
||||
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance, Extrinsic>
|
||||
+ sp_api::Metadata<Block>
|
||||
+ sp_offchain::OffchainWorkerApi<Block>
|
||||
+ sp_session::SessionKeys<Block>
|
||||
+ authority_discovery_primitives::AuthorityDiscoveryApi<Block>
|
||||
where
|
||||
Extrinsic: RuntimeExtrinsic,
|
||||
<Self as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
||||
{}
|
||||
|
||||
impl<Api, Extrinsic> RuntimeApiCollection<Extrinsic> for Api
|
||||
where
|
||||
Api:
|
||||
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
|
||||
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
|
||||
+ babe_primitives::BabeApi<Block>
|
||||
+ grandpa_primitives::GrandpaApi<Block>
|
||||
+ ParachainHost<Block>
|
||||
+ sp_block_builder::BlockBuilder<Block>
|
||||
+ system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
|
||||
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance, Extrinsic>
|
||||
+ sp_api::Metadata<Block>
|
||||
+ sp_offchain::OffchainWorkerApi<Block>
|
||||
+ sp_session::SessionKeys<Block>
|
||||
+ authority_discovery_primitives::AuthorityDiscoveryApi<Block>,
|
||||
Extrinsic: RuntimeExtrinsic,
|
||||
<Self as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
||||
{}
|
||||
|
||||
pub trait RuntimeExtrinsic: codec::Codec + Send + Sync + 'static {}
|
||||
|
||||
impl<E> RuntimeExtrinsic for E where E: codec::Codec + Send + Sync + 'static {}
|
||||
|
||||
/// Can be called for a `Configuration` to check if it is a configuration for the `Kusama` network.
|
||||
pub trait IdentifyVariant {
|
||||
/// Returns if this is a configuration for the `Kusama` network.
|
||||
fn is_kusama(&self) -> bool;
|
||||
|
||||
/// Returns if this is a configuration for the `Westend` network.
|
||||
fn is_westend(&self) -> bool;
|
||||
}
|
||||
|
||||
impl IdentifyVariant for Box<dyn ChainSpec> {
|
||||
fn is_kusama(&self) -> bool {
|
||||
self.id().starts_with("kusama") || self.id().starts_with("ksm")
|
||||
}
|
||||
fn is_westend(&self) -> bool {
|
||||
self.id().starts_with("westend") || self.id().starts_with("wnd")
|
||||
}
|
||||
}
|
||||
|
||||
// If we're using prometheus, use a registry with a prefix of `polkadot`.
|
||||
fn set_prometheus_registry(config: &mut Configuration) -> Result<(), ServiceError> {
|
||||
if let Some(PrometheusConfig { registry, .. }) = config.prometheus_config.as_mut() {
|
||||
*registry = Registry::new_custom(Some("polkadot".into()), None)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Starts a `ServiceBuilder` for a full service.
|
||||
///
|
||||
/// Use this macro if you don't actually need the full service, but just the builder in order to
|
||||
/// be able to perform chain operations.
|
||||
macro_rules! new_full_start {
|
||||
($config:expr, $runtime:ty, $executor:ty, $informant_prefix:expr $(,)?) => {{
|
||||
set_prometheus_registry(&mut $config)?;
|
||||
|
||||
let mut import_setup = None;
|
||||
let mut rpc_setup = None;
|
||||
let inherent_data_providers = inherents::InherentDataProviders::new();
|
||||
let builder = service::ServiceBuilder::new_full::<
|
||||
Block, $runtime, $executor
|
||||
>($config)?
|
||||
.with_informant_prefix($informant_prefix.unwrap_or_default())?
|
||||
.with_select_chain(|_, backend| {
|
||||
Ok(sc_consensus::LongestChain::new(backend.clone()))
|
||||
})?
|
||||
.with_transaction_pool(|builder| {
|
||||
let pool_api = sc_transaction_pool::FullChainApi::new(builder.client().clone());
|
||||
let pool = sc_transaction_pool::BasicPool::new(
|
||||
builder.config().transaction_pool.clone(),
|
||||
std::sync::Arc::new(pool_api),
|
||||
builder.prometheus_registry(),
|
||||
);
|
||||
Ok(pool)
|
||||
})?
|
||||
.with_import_queue(|
|
||||
config,
|
||||
client,
|
||||
mut select_chain,
|
||||
_,
|
||||
spawn_task_handle,
|
||||
registry,
|
||||
| {
|
||||
let select_chain = select_chain.take()
|
||||
.ok_or_else(|| service::Error::SelectChainRequired)?;
|
||||
|
||||
let grandpa_hard_forks = if config.chain_spec.is_kusama() {
|
||||
grandpa_support::kusama_hard_forks()
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
|
||||
let (grandpa_block_import, grandpa_link) =
|
||||
grandpa::block_import_with_authority_set_hard_forks(
|
||||
client.clone(),
|
||||
&(client.clone() as Arc<_>),
|
||||
select_chain,
|
||||
grandpa_hard_forks,
|
||||
)?;
|
||||
|
||||
let justification_import = grandpa_block_import.clone();
|
||||
|
||||
let (block_import, babe_link) = babe::block_import(
|
||||
babe::Config::get_or_compute(&*client)?,
|
||||
grandpa_block_import,
|
||||
client.clone(),
|
||||
)?;
|
||||
|
||||
let import_queue = babe::import_queue(
|
||||
babe_link.clone(),
|
||||
block_import.clone(),
|
||||
Some(Box::new(justification_import)),
|
||||
None,
|
||||
client,
|
||||
inherent_data_providers.clone(),
|
||||
spawn_task_handle,
|
||||
registry,
|
||||
)?;
|
||||
|
||||
import_setup = Some((block_import, grandpa_link, babe_link));
|
||||
Ok(import_queue)
|
||||
})?
|
||||
.with_rpc_extensions_builder(|builder| {
|
||||
let grandpa_link = import_setup.as_ref().map(|s| &s.1)
|
||||
.expect("GRANDPA LinkHalf is present for full services or set up failed; qed.");
|
||||
|
||||
let shared_authority_set = grandpa_link.shared_authority_set().clone();
|
||||
let shared_voter_state = grandpa::SharedVoterState::empty();
|
||||
|
||||
rpc_setup = Some((shared_voter_state.clone()));
|
||||
|
||||
let babe_link = import_setup.as_ref().map(|s| &s.2)
|
||||
.expect("BabeLink is present for full services or set up faile; qed.");
|
||||
|
||||
let babe_config = babe_link.config().clone();
|
||||
let shared_epoch_changes = babe_link.epoch_changes().clone();
|
||||
|
||||
let client = builder.client().clone();
|
||||
let pool = builder.pool().clone();
|
||||
let select_chain = builder.select_chain().cloned()
|
||||
.expect("SelectChain is present for full services or set up failed; qed.");
|
||||
let keystore = builder.keystore().clone();
|
||||
|
||||
Ok(move |deny_unsafe| -> polkadot_rpc::RpcExtension {
|
||||
let deps = polkadot_rpc::FullDeps {
|
||||
client: client.clone(),
|
||||
pool: pool.clone(),
|
||||
select_chain: select_chain.clone(),
|
||||
deny_unsafe,
|
||||
babe: polkadot_rpc::BabeDeps {
|
||||
babe_config: babe_config.clone(),
|
||||
shared_epoch_changes: shared_epoch_changes.clone(),
|
||||
keystore: keystore.clone(),
|
||||
},
|
||||
grandpa: polkadot_rpc::GrandpaDeps {
|
||||
shared_voter_state: shared_voter_state.clone(),
|
||||
shared_authority_set: shared_authority_set.clone(),
|
||||
},
|
||||
};
|
||||
|
||||
polkadot_rpc::create_full(deps)
|
||||
})
|
||||
})?;
|
||||
|
||||
(builder, import_setup, inherent_data_providers, rpc_setup)
|
||||
}}
|
||||
}
|
||||
|
||||
struct ValidationSubsystem;
|
||||
|
||||
impl Subsystem<ValidationSubsystemMessage> for ValidationSubsystem {
|
||||
fn start(&mut self, mut ctx: SubsystemContext<ValidationSubsystemMessage>) -> SpawnedSubsystem {
|
||||
SpawnedSubsystem(Box::pin(async move {
|
||||
while let Ok(_) = ctx.recv().await {}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
struct CandidateBackingSubsystem;
|
||||
|
||||
impl Subsystem<CandidateBackingSubsystemMessage> for CandidateBackingSubsystem {
|
||||
fn start(&mut self, mut ctx: SubsystemContext<CandidateBackingSubsystemMessage>) -> SpawnedSubsystem {
|
||||
SpawnedSubsystem(Box::pin(async move {
|
||||
while let Ok(_) = ctx.recv().await {}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
fn real_overseer<S: futures::task::Spawn>(
|
||||
leaves: impl IntoIterator<Item = BlockInfo>,
|
||||
s: S,
|
||||
) -> Result<(Overseer<S>, OverseerHandler), ServiceError> {
|
||||
let validation = Box::new(ValidationSubsystem);
|
||||
let candidate_backing = Box::new(CandidateBackingSubsystem);
|
||||
Overseer::new(leaves, validation, candidate_backing, s)
|
||||
.map_err(|e| ServiceError::Other(format!("Failed to create an Overseer: {:?}", e)))
|
||||
}
|
||||
|
||||
/// Builds a new service for a full client.
|
||||
#[macro_export]
|
||||
macro_rules! new_full {
|
||||
(
|
||||
$config:expr,
|
||||
$collating_for:expr,
|
||||
$authority_discovery_enabled:expr,
|
||||
$grandpa_pause:expr,
|
||||
$runtime:ty,
|
||||
$dispatch:ty,
|
||||
$informant_prefix:expr $(,)?
|
||||
) => {{
|
||||
use sc_client_api::ExecutorProvider;
|
||||
use sp_core::traits::BareCryptoStorePtr;
|
||||
|
||||
let is_collator = $collating_for.is_some();
|
||||
let role = $config.role.clone();
|
||||
let is_authority = role.is_authority() && !is_collator;
|
||||
let force_authoring = $config.force_authoring;
|
||||
let disable_grandpa = $config.disable_grandpa;
|
||||
let name = $config.network.node_name.clone();
|
||||
|
||||
let (builder, mut import_setup, inherent_data_providers, mut rpc_setup) =
|
||||
new_full_start!($config, $runtime, $dispatch, $informant_prefix);
|
||||
|
||||
let service = builder
|
||||
.with_finality_proof_provider(|client, backend| {
|
||||
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
|
||||
Ok(Arc::new(GrandpaFinalityProofProvider::new(backend, provider)) as _)
|
||||
})?
|
||||
.build_full()?;
|
||||
|
||||
let (block_import, link_half, babe_link) = import_setup.take()
|
||||
.expect("Link Half and Block Import are present for Full Services or setup failed before. qed");
|
||||
|
||||
let shared_voter_state = rpc_setup.take()
|
||||
.expect("The SharedVoterState is present for Full Services or setup failed before. qed");
|
||||
|
||||
let client = service.client();
|
||||
|
||||
let overseer_client = service.client();
|
||||
let spawner = service.spawn_task_handle();
|
||||
let leaves: Vec<_> = service.select_chain().ok_or(ServiceError::SelectChainRequired)?
|
||||
.leaves()
|
||||
.unwrap_or_else(|_| vec![])
|
||||
.into_iter()
|
||||
.filter_map(|hash| {
|
||||
let number = client.number(hash).ok()??;
|
||||
let parent_hash = client.header(&BlockId::Hash(hash)).ok()??.parent_hash;
|
||||
|
||||
Some(BlockInfo {
|
||||
hash,
|
||||
parent_hash,
|
||||
number,
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
|
||||
let (overseer, handler) = real_overseer(leaves, spawner)?;
|
||||
|
||||
service.spawn_essential_task("overseer", Box::pin(async move {
|
||||
use futures::{pin_mut, select, FutureExt};
|
||||
|
||||
let forward = overseer::forward_events(overseer_client, handler);
|
||||
|
||||
let forward = forward.fuse();
|
||||
let overseer_fut = overseer.run().fuse();
|
||||
|
||||
pin_mut!(overseer_fut);
|
||||
pin_mut!(forward);
|
||||
|
||||
loop {
|
||||
select! {
|
||||
_ = forward => break,
|
||||
_ = overseer_fut => break,
|
||||
complete => break,
|
||||
}
|
||||
}
|
||||
}));
|
||||
|
||||
if role.is_authority() {
|
||||
let select_chain = service.select_chain().ok_or(ServiceError::SelectChainRequired)?;
|
||||
let can_author_with =
|
||||
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone());
|
||||
|
||||
// TODO: custom proposer (https://github.com/paritytech/polkadot/issues/1248)
|
||||
let proposer = sc_basic_authorship::ProposerFactory::new(
|
||||
client.clone(),
|
||||
service.transaction_pool(),
|
||||
None,
|
||||
);
|
||||
|
||||
let babe_config = babe::BabeParams {
|
||||
keystore: service.keystore(),
|
||||
client: client.clone(),
|
||||
select_chain,
|
||||
block_import,
|
||||
env: proposer,
|
||||
sync_oracle: service.network(),
|
||||
inherent_data_providers: inherent_data_providers.clone(),
|
||||
force_authoring,
|
||||
babe_link,
|
||||
can_author_with,
|
||||
};
|
||||
|
||||
let babe = babe::start_babe(babe_config)?;
|
||||
service.spawn_essential_task("babe", babe);
|
||||
}
|
||||
|
||||
// if the node isn't actively participating in consensus then it doesn't
|
||||
// need a keystore, regardless of which protocol we use below.
|
||||
let keystore = if is_authority {
|
||||
Some(service.keystore() as BareCryptoStorePtr)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let config = grandpa::Config {
|
||||
// FIXME substrate#1578 make this available through chainspec
|
||||
gossip_duration: Duration::from_millis(1000),
|
||||
justification_period: 512,
|
||||
name: Some(name),
|
||||
observer_enabled: false,
|
||||
keystore,
|
||||
is_authority: role.is_network_authority(),
|
||||
};
|
||||
|
||||
let enable_grandpa = !disable_grandpa;
|
||||
if enable_grandpa {
|
||||
// start the full GRANDPA voter
|
||||
// NOTE: unlike in substrate we are currently running the full
|
||||
// GRANDPA voter protocol for all full nodes (regardless of whether
|
||||
// they're validators or not). at this point the full voter should
|
||||
// provide better guarantees of block and vote data availability than
|
||||
// the observer.
|
||||
|
||||
// add a custom voting rule to temporarily stop voting for new blocks
|
||||
// after the given pause block is finalized and restarting after the
|
||||
// given delay.
|
||||
let voting_rule = match $grandpa_pause {
|
||||
Some((block, delay)) => {
|
||||
info!("GRANDPA scheduled voting pause set for block #{} with a duration of {} blocks.",
|
||||
block,
|
||||
delay,
|
||||
);
|
||||
|
||||
grandpa::VotingRulesBuilder::default()
|
||||
.add(grandpa_support::PauseAfterBlockFor(block, delay))
|
||||
.build()
|
||||
},
|
||||
None =>
|
||||
grandpa::VotingRulesBuilder::default()
|
||||
.build(),
|
||||
};
|
||||
|
||||
let grandpa_config = grandpa::GrandpaParams {
|
||||
config,
|
||||
link: link_half,
|
||||
network: service.network(),
|
||||
inherent_data_providers: inherent_data_providers.clone(),
|
||||
telemetry_on_connect: Some(service.telemetry_on_connect_stream()),
|
||||
voting_rule,
|
||||
prometheus_registry: service.prometheus_registry(),
|
||||
shared_voter_state,
|
||||
};
|
||||
|
||||
service.spawn_essential_task(
|
||||
"grandpa-voter",
|
||||
grandpa::run_grandpa_voter(grandpa_config)?
|
||||
);
|
||||
} else {
|
||||
grandpa::setup_disabled_grandpa(
|
||||
client.clone(),
|
||||
&inherent_data_providers,
|
||||
service.network(),
|
||||
)?;
|
||||
}
|
||||
|
||||
(service, client)
|
||||
}}
|
||||
}
|
||||
|
||||
pub struct FullNodeHandles;
|
||||
|
||||
/// Builds a new service for a light client.
|
||||
#[macro_export]
|
||||
macro_rules! new_light {
|
||||
($config:expr, $runtime:ty, $dispatch:ty) => {{
|
||||
crate::set_prometheus_registry(&mut $config)?;
|
||||
let inherent_data_providers = inherents::InherentDataProviders::new();
|
||||
|
||||
ServiceBuilder::new_light::<Block, $runtime, $dispatch>($config)?
|
||||
.with_select_chain(|_, backend| {
|
||||
Ok(sc_consensus::LongestChain::new(backend.clone()))
|
||||
})?
|
||||
.with_transaction_pool(|builder| {
|
||||
let fetcher = builder.fetcher()
|
||||
.ok_or_else(|| "Trying to start light transaction pool without active fetcher")?;
|
||||
let pool_api = sc_transaction_pool::LightChainApi::new(
|
||||
builder.client().clone(),
|
||||
fetcher,
|
||||
);
|
||||
let pool = sc_transaction_pool::BasicPool::with_revalidation_type(
|
||||
builder.config().transaction_pool.clone(),
|
||||
Arc::new(pool_api),
|
||||
builder.prometheus_registry(),
|
||||
sc_transaction_pool::RevalidationType::Light,
|
||||
);
|
||||
Ok(pool)
|
||||
})?
|
||||
.with_import_queue_and_fprb(|
|
||||
_config,
|
||||
client,
|
||||
backend,
|
||||
fetcher,
|
||||
_select_chain,
|
||||
_,
|
||||
spawn_task_handle,
|
||||
registry,
|
||||
| {
|
||||
let fetch_checker = fetcher
|
||||
.map(|fetcher| fetcher.checker().clone())
|
||||
.ok_or_else(|| "Trying to start light import queue without active fetch checker")?;
|
||||
let grandpa_block_import = grandpa::light_block_import(
|
||||
client.clone(), backend, &(client.clone() as Arc<_>), Arc::new(fetch_checker)
|
||||
)?;
|
||||
|
||||
let finality_proof_import = grandpa_block_import.clone();
|
||||
let finality_proof_request_builder =
|
||||
finality_proof_import.create_finality_proof_request_builder();
|
||||
|
||||
let (babe_block_import, babe_link) = babe::block_import(
|
||||
babe::Config::get_or_compute(&*client)?,
|
||||
grandpa_block_import,
|
||||
client.clone(),
|
||||
)?;
|
||||
|
||||
// FIXME: pruning task isn't started since light client doesn't do `AuthoritySetup`.
|
||||
let import_queue = babe::import_queue(
|
||||
babe_link,
|
||||
babe_block_import,
|
||||
None,
|
||||
Some(Box::new(finality_proof_import)),
|
||||
client,
|
||||
inherent_data_providers.clone(),
|
||||
spawn_task_handle,
|
||||
registry,
|
||||
)?;
|
||||
|
||||
Ok((import_queue, finality_proof_request_builder))
|
||||
})?
|
||||
.with_finality_proof_provider(|client, backend| {
|
||||
let provider = client as Arc<dyn grandpa::StorageAndProofProvider<_, _>>;
|
||||
Ok(Arc::new(grandpa::FinalityProofProvider::new(backend, provider)) as _)
|
||||
})?
|
||||
.with_rpc_extensions(|builder| {
|
||||
let fetcher = builder.fetcher()
|
||||
.ok_or_else(|| "Trying to start node RPC without active fetcher")?;
|
||||
let remote_blockchain = builder.remote_backend()
|
||||
.ok_or_else(|| "Trying to start node RPC without active remote blockchain")?;
|
||||
|
||||
let light_deps = polkadot_rpc::LightDeps {
|
||||
remote_blockchain,
|
||||
fetcher,
|
||||
client: builder.client().clone(),
|
||||
pool: builder.pool(),
|
||||
};
|
||||
Ok(polkadot_rpc::create_light(light_deps))
|
||||
})?
|
||||
.build_light()
|
||||
}}
|
||||
}
|
||||
|
||||
/// Builds a new object suitable for chain operations.
|
||||
pub fn new_chain_ops<Runtime, Dispatch, Extrinsic>(mut config: Configuration)
|
||||
-> Result<impl ServiceBuilderCommand<Block=Block>, ServiceError>
|
||||
where
|
||||
Runtime: ConstructRuntimeApi<Block, service::TFullClient<Block, Runtime, Dispatch>> + Send + Sync + 'static,
|
||||
Runtime::RuntimeApi:
|
||||
RuntimeApiCollection<Extrinsic, StateBackend = sc_client_api::StateBackendFor<TFullBackend<Block>, Block>>,
|
||||
Dispatch: NativeExecutionDispatch + 'static,
|
||||
Extrinsic: RuntimeExtrinsic,
|
||||
<Runtime::RuntimeApi as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
|
||||
{
|
||||
config.keystore = service::config::KeystoreConfig::InMemory;
|
||||
Ok(new_full_start!(config, Runtime, Dispatch, None).0)
|
||||
}
|
||||
|
||||
/// Create a new Polkadot service for a full node.
|
||||
#[cfg(feature = "full-node")]
|
||||
pub fn polkadot_new_full(
|
||||
mut config: Configuration,
|
||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||
_max_block_data_size: Option<u64>,
|
||||
_authority_discovery_enabled: bool,
|
||||
_slot_duration: u64,
|
||||
grandpa_pause: Option<(u32, u32)>,
|
||||
informant_prefix: Option<String>,
|
||||
)
|
||||
-> Result<(
|
||||
impl AbstractService,
|
||||
Arc<impl PolkadotClient<
|
||||
Block,
|
||||
TFullBackend<Block>,
|
||||
polkadot_runtime::RuntimeApi
|
||||
>>,
|
||||
FullNodeHandles,
|
||||
), ServiceError>
|
||||
{
|
||||
let (service, client) = new_full!(
|
||||
config,
|
||||
collating_for,
|
||||
authority_discovery_enabled,
|
||||
grandpa_pause,
|
||||
polkadot_runtime::RuntimeApi,
|
||||
PolkadotExecutor,
|
||||
informant_prefix,
|
||||
);
|
||||
|
||||
Ok((service, client, FullNodeHandles))
|
||||
}
|
||||
|
||||
/// Create a new Kusama service for a full node.
|
||||
#[cfg(feature = "full-node")]
|
||||
pub fn kusama_new_full(
|
||||
mut config: Configuration,
|
||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||
_max_block_data_size: Option<u64>,
|
||||
_authority_discovery_enabled: bool,
|
||||
_slot_duration: u64,
|
||||
grandpa_pause: Option<(u32, u32)>,
|
||||
informant_prefix: Option<String>,
|
||||
) -> Result<(
|
||||
impl AbstractService,
|
||||
Arc<impl PolkadotClient<
|
||||
Block,
|
||||
TFullBackend<Block>,
|
||||
kusama_runtime::RuntimeApi
|
||||
>
|
||||
>,
|
||||
FullNodeHandles,
|
||||
), ServiceError>
|
||||
{
|
||||
let (service, client) = new_full!(
|
||||
config,
|
||||
collating_for,
|
||||
authority_discovery_enabled,
|
||||
grandpa_pause,
|
||||
kusama_runtime::RuntimeApi,
|
||||
KusamaExecutor,
|
||||
informant_prefix,
|
||||
);
|
||||
|
||||
Ok((service, client, FullNodeHandles))
|
||||
}
|
||||
|
||||
/// Create a new Kusama service for a full node.
|
||||
#[cfg(feature = "full-node")]
|
||||
pub fn westend_new_full(
|
||||
mut config: Configuration,
|
||||
collating_for: Option<(CollatorId, parachain::Id)>,
|
||||
_max_block_data_size: Option<u64>,
|
||||
_authority_discovery_enabled: bool,
|
||||
_slot_duration: u64,
|
||||
grandpa_pause: Option<(u32, u32)>,
|
||||
informant_prefix: Option<String>,
|
||||
)
|
||||
-> Result<(
|
||||
impl AbstractService,
|
||||
Arc<impl PolkadotClient<
|
||||
Block,
|
||||
TFullBackend<Block>,
|
||||
westend_runtime::RuntimeApi
|
||||
>>,
|
||||
FullNodeHandles,
|
||||
), ServiceError>
|
||||
{
|
||||
let (service, client) = new_full!(
|
||||
config,
|
||||
collating_for,
|
||||
authority_discovery_enabled,
|
||||
grandpa_pause,
|
||||
westend_runtime::RuntimeApi,
|
||||
WestendExecutor,
|
||||
informant_prefix,
|
||||
);
|
||||
|
||||
Ok((service, client, FullNodeHandles))
|
||||
}
|
||||
|
||||
/// Create a new Polkadot service for a light client.
|
||||
pub fn polkadot_new_light(mut config: Configuration) -> Result<
|
||||
impl AbstractService<
|
||||
Block = Block,
|
||||
RuntimeApi = polkadot_runtime::RuntimeApi,
|
||||
Backend = TLightBackend<Block>,
|
||||
SelectChain = LongestChain<TLightBackend<Block>, Block>,
|
||||
CallExecutor = TLightCallExecutor<Block, PolkadotExecutor>,
|
||||
>, ServiceError>
|
||||
{
|
||||
new_light!(config, polkadot_runtime::RuntimeApi, PolkadotExecutor)
|
||||
}
|
||||
|
||||
/// Create a new Kusama service for a light client.
|
||||
pub fn kusama_new_light(mut config: Configuration) -> Result<
|
||||
impl AbstractService<
|
||||
Block = Block,
|
||||
RuntimeApi = kusama_runtime::RuntimeApi,
|
||||
Backend = TLightBackend<Block>,
|
||||
SelectChain = LongestChain<TLightBackend<Block>, Block>,
|
||||
CallExecutor = TLightCallExecutor<Block, KusamaExecutor>,
|
||||
>, ServiceError>
|
||||
{
|
||||
new_light!(config, kusama_runtime::RuntimeApi, KusamaExecutor)
|
||||
}
|
||||
|
||||
/// Create a new Westend service for a light client.
|
||||
pub fn westend_new_light(mut config: Configuration, ) -> Result<
|
||||
impl AbstractService<
|
||||
Block = Block,
|
||||
RuntimeApi = westend_runtime::RuntimeApi,
|
||||
Backend = TLightBackend<Block>,
|
||||
SelectChain = LongestChain<TLightBackend<Block>, Block>,
|
||||
CallExecutor = TLightCallExecutor<Block, KusamaExecutor>
|
||||
>,
|
||||
ServiceError>
|
||||
{
|
||||
new_light!(config, westend_runtime::RuntimeApi, KusamaExecutor)
|
||||
}
|
||||
Reference in New Issue
Block a user