Remove Old Service, 2nd try (#1732)

* Restore "Remove service, migrate all to service-new (#1630)"

i.e.
Revert "Revert "Remove service, migrate all to service-new (#1630)" (#1731)"

This reverts commit b4457f555b.

This allows us to get the changeset from #1630 into a new branch
which can be merged sometime in the future after appropriate burnin
tests have completed.

* remove ',)' from codebase outside of macros

* restore bdfl-preferred formatting

* attempt to improve destructuring formatting

* rename polkadot-service-new -> polkadot-service

* Apply suggestions from code review

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

* remove unused import

* Update runtime/rococo-v1/README.md

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>

Co-authored-by: Andronik Ordian <write@reusable.software>
Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
This commit is contained in:
Peter Goodspeed-Niklaus
2020-09-28 10:23:02 +02:00
committed by GitHub
parent 796de5f3e3
commit 96f2615582
31 changed files with 1291 additions and 3145 deletions
+4 -60
View File
@@ -4727,7 +4727,6 @@ dependencies = [
"futures 0.3.5",
"log 0.4.11",
"polkadot-service",
"polkadot-service-new",
"sc-cli",
"sc-client-api",
"sc-client-db",
@@ -5360,65 +5359,6 @@ dependencies = [
[[package]]
name = "polkadot-service"
version = "0.8.24"
dependencies = [
"env_logger",
"frame-benchmarking",
"frame-system-rpc-runtime-api",
"futures 0.3.5",
"hex-literal 0.2.1",
"kusama-runtime",
"lazy_static",
"log 0.4.11",
"pallet-babe",
"pallet-im-online",
"pallet-staking",
"pallet-transaction-payment-rpc-runtime-api",
"parity-scale-codec",
"parking_lot 0.9.0",
"polkadot-primitives",
"polkadot-rpc",
"polkadot-runtime",
"polkadot-test-runtime-client",
"polkadot-validation",
"sc-authority-discovery",
"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-storage",
"sp-transaction-pool",
"sp-trie",
"substrate-prometheus-endpoint",
"westend-runtime",
]
[[package]]
name = "polkadot-service-new"
version = "0.8.3"
dependencies = [
"env_logger",
@@ -5438,10 +5378,12 @@ dependencies = [
"polkadot-node-core-proposer",
"polkadot-node-subsystem",
"polkadot-overseer",
"polkadot-parachain",
"polkadot-primitives",
"polkadot-rpc",
"polkadot-runtime",
"polkadot-test-runtime-client",
"rococo-v1-runtime",
"sc-authority-discovery",
"sc-block-builder",
"sc-chain-spec",
@@ -5545,6 +5487,7 @@ dependencies = [
"polkadot-parachain",
"polkadot-primitives",
"polkadot-runtime-common",
"polkadot-runtime-parachains",
"rustc-hex",
"serde",
"serde_derive",
@@ -5606,6 +5549,7 @@ dependencies = [
"pallet-balances",
"pallet-staking",
"pallet-transaction-payment",
"polkadot-overseer",
"polkadot-primitives",
"polkadot-rpc",
"polkadot-runtime-common",
+1 -6
View File
@@ -14,7 +14,7 @@ readme = "README.md"
[dependencies]
cli = { package = "polkadot-cli", path = "cli" }
futures = "0.3.4"
service = { package = "polkadot-service", path = "service" }
service = { package = "polkadot-service", path = "node/service" }
parity-util-mem = { version = "*", default-features = false, features = ["jemalloc-global"] }
[dev-dependencies]
@@ -36,9 +36,7 @@ members = [
"runtime/westend",
"runtime/test-runtime",
"runtime/test-runtime/client",
"service",
"statement-table",
"service",
"validation",
"node/collation-generation",
@@ -79,9 +77,6 @@ panic = "unwind"
[features]
runtime-benchmarks=["cli/runtime-benchmarks"]
service-rewr= [
"cli/service-rewr",
]
# Configuration for building a .deb package - for use with `cargo-deb`
[package.metadata.deb]
+3 -5
View File
@@ -24,8 +24,7 @@ sc-client-api = { git = "https://github.com/paritytech/substrate", branch = "mas
sc-client-db = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-tracing = { git = "https://github.com/paritytech/substrate", branch = "master" }
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 }
service = { package = "polkadot-service", 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 }
@@ -43,7 +42,7 @@ sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master",
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
[features]
default = [ "wasmtime", "db", "cli", "service-old", "trie-memory-tracker" ]
default = [ "wasmtime", "db", "cli", "full-node", "trie-memory-tracker" ]
wasmtime = [ "sc-cli/wasmtime" ]
db = [ "service/db" ]
cli = [
@@ -52,7 +51,6 @@ cli = [
"sc-service",
"frame-benchmarking-cli",
]
service-old = [ "service/full-node" ]
browser = [
"wasm-bindgen",
"wasm-bindgen-futures",
@@ -60,5 +58,5 @@ browser = [
"service",
]
runtime-benchmarks = [ "service/runtime-benchmarks" ]
service-rewr = [ "service-new/full-node" ]
trie-memory-tracker = [ "sp-trie/memory-tracker" ]
full-node = [ "service/full-node" ]
+4
View File
@@ -79,6 +79,10 @@ pub struct RunCmd {
#[structopt(long = "force-westend")]
pub force_westend: bool,
/// Force using Rococo native runtime.
#[structopt(long = "force-rococo")]
pub force_rococo: bool,
/// Enable the authority discovery module on validator or sentry nodes.
///
/// When enabled:
+18 -10
View File
@@ -15,10 +15,7 @@
// 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_cli::{SubstrateCli, Result, RuntimeVersion, Role};
use crate::cli::{Cli, Subcommand};
use std::sync::Arc;
@@ -48,7 +45,7 @@ impl SubstrateCli for Cli {
fn load_spec(&self, id: &str) -> std::result::Result<Box<dyn sc_service::ChainSpec>, String> {
let id = if id == "" {
let n = get_exec_name().unwrap_or_default();
["polkadot", "kusama", "westend"].iter()
["polkadot", "kusama", "westend", "rococo"].iter()
.cloned()
.find(|&chain| n.starts_with(chain))
.unwrap_or("polkadot")
@@ -66,6 +63,9 @@ impl SubstrateCli for Cli {
"westend-dev" => Box::new(service::chain_spec::westend_development_config()?),
"westend-local" => Box::new(service::chain_spec::westend_local_testnet_config()?),
"westend-staging" => Box::new(service::chain_spec::westend_staging_testnet_config()?),
"rococo-staging" => Box::new(service::chain_spec::rococo_staging_testnet_config()?),
"rococo-local" => Box::new(service::chain_spec::rococo_local_testnet_config()?),
"rococo" => Box::new(service::chain_spec::rococo_config()?),
path => {
let path = std::path::PathBuf::from(path);
@@ -75,7 +75,9 @@ impl SubstrateCli for Cli {
// When `force_*` is given or the file name starts with the name of one of the known chains,
// we use the chain spec for the specific chain.
if self.run.force_kusama || starts_with("kusama") {
if self.run.force_rococo || starts_with("rococo") {
Box::new(service::RococoChainSpec::from_json_file(path)?)
} else if self.run.force_kusama || starts_with("kusama") {
Box::new(service::KusamaChainSpec::from_json_file(path)?)
} else if self.run.force_westend || starts_with("westend") {
Box::new(service::WestendChainSpec::from_json_file(path)?)
@@ -91,6 +93,8 @@ impl SubstrateCli for Cli {
&service::kusama_runtime::VERSION
} else if spec.is_westend() {
&service::westend_runtime::VERSION
} else if spec.is_rococo() {
&service::rococo_runtime::VERSION
} else {
&service::polkadot_runtime::VERSION
}
@@ -147,7 +151,7 @@ pub fn run() -> Result<()> {
None,
authority_discovery_enabled,
grandpa_pause,
).map(|r| r.0),
).map(|full| full.task_manager),
}
})
},
@@ -179,10 +183,14 @@ pub fn run() -> Result<()> {
runner.async_run(|config| {
let chain_spec = config.chain_spec.cloned_box();
let network_config = config.network.clone();
let service::NewFull { task_manager, client, network_status_sinks, .. }
= service::new_full_nongeneric(
config, None, authority_discovery_enabled, grandpa_pause, false,
)?;
let service::NewFull {
task_manager,
client,
network_status_sinks,
..
} = service::build_full(
config, None, authority_discovery_enabled, grandpa_pause,
)?;
let client = Arc::new(client);
Ok((cmd.run(chain_spec, network_config, client, network_status_sinks), task_manager))
+3 -10
View File
@@ -26,17 +26,10 @@ mod cli;
#[cfg(feature = "cli")]
mod command;
#[cfg(not(feature = "service-rewr"))]
pub use service::{
ProvideRuntimeApi, CoreApi, ParachainHost, IdentifyVariant,
Block, self, RuntimeApiCollection, TFullClient
};
#[cfg(feature = "service-rewr")]
pub use service_new::{
self as service,
ProvideRuntimeApi, CoreApi, ParachainHost, IdentifyVariant,
Block, self, RuntimeApiCollection, TFullClient
self,
ProvideRuntimeApi, CoreApi, IdentifyVariant,
Block, RuntimeApiCollection, TFullClient
};
#[cfg(feature = "cli")]
+56 -43
View File
@@ -1,63 +1,76 @@
[package]
name = "polkadot-service-new"
name = "polkadot-service"
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" }
polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../subsystem" }
kusama-runtime = { path = "../../runtime/kusama" }
westend-runtime = { path = "../../runtime/westend" }
polkadot-rpc = { path = "../../rpc" }
polkadot-node-core-proposer = { path = "../core/proposer" }
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" }
# Substrate Client
authority-discovery = { package = "sc-authority-discovery", git = "https://github.com/paritytech/substrate", branch = "master" }
babe = { package = "sc-consensus-babe", git = "https://github.com/paritytech/substrate", branch = "master" }
grandpa = { package = "sc-finality-grandpa", git = "https://github.com/paritytech/substrate", branch = "master" }
sc-block-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-chain-spec = { 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-executor = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-keystore = { git = "https://github.com/paritytech/substrate", branch = "master" }
sc-network = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-trie = { 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" }
sc-transaction-pool = { 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" }
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" }
# Substrate Primitives
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" }
consensus_common = { package = "sp-consensus", 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" }
sp-api = { 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" }
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
codec = { package = "parity-scale-codec", version = "1.3.4" }
sp-session = { 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" }
sp-io = { 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" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-session = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-storage = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-transaction-pool = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" }
# Substrate Pallets
pallet-babe = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-im-online = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
# Substrate Other
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" }
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
prometheus-endpoint = { package = "substrate-prometheus-endpoint", git = "https://github.com/paritytech/substrate", branch = "master" }
# External Crates
codec = { package = "parity-scale-codec", version = "1.3.4" }
futures = "0.3.4"
hex-literal = "0.2.1"
lazy_static = "1.4.0"
log = "0.4.8"
parking_lot = "0.9.0"
serde = { version = "1.0.102", features = ["derive"] }
slog = "2.5.2"
# Polkadot
kusama-runtime = { path = "../../runtime/kusama" }
polkadot-node-core-proposer = { path = "../core/proposer" }
polkadot-overseer = { path = "../overseer" }
polkadot-parachain = { path = "../../parachain" }
polkadot-primitives = { path = "../../primitives" }
polkadot-rpc = { path = "../../rpc" }
polkadot-runtime = { path = "../../runtime/polkadot" }
polkadot-subsystem = { package = "polkadot-node-subsystem", path = "../subsystem" }
rococo-runtime = { package = "rococo-v1-runtime", path = "../../runtime/rococo-v1" }
westend-runtime = { path = "../../runtime/westend" }
[dev-dependencies]
polkadot-test-runtime-client = { path = "../../runtime/test-runtime/client" }
+1
View File
@@ -0,0 +1 @@
!/*.json
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
+68 -1
View File
@@ -24,7 +24,7 @@ use sp_runtime::{
};
use sc_client_api::{Backend as BackendT, BlockchainEvents, KeyIterator};
use sp_storage::{StorageData, StorageKey, ChildInfo, PrefixedStorageKey};
use polkadot_primitives::v1::{Block, ParachainHost, AccountId, Nonce, Balance};
use polkadot_primitives::v1::{Block, ParachainHost, AccountId, Nonce, Balance, Header, BlockNumber, Hash};
use consensus_common::BlockStatus;
/// A set of APIs that polkadot-like runtimes must implement.
@@ -142,6 +142,7 @@ pub enum Client {
Polkadot(Arc<crate::FullClient<polkadot_runtime::RuntimeApi, crate::PolkadotExecutor>>),
Westend(Arc<crate::FullClient<westend_runtime::RuntimeApi, crate::WestendExecutor>>),
Kusama(Arc<crate::FullClient<kusama_runtime::RuntimeApi, crate::KusamaExecutor>>),
Rococo(Arc<crate::FullClient<rococo_runtime::RuntimeApi, crate::RococoExecutor>>),
}
impl ClientHandle for Client {
@@ -156,6 +157,9 @@ impl ClientHandle for Client {
Self::Kusama(client) => {
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
},
Self::Rococo(client) => {
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
}
}
}
}
@@ -166,6 +170,7 @@ impl sc_client_api::UsageProvider<Block> for Client {
Self::Polkadot(client) => client.usage_info(),
Self::Westend(client) => client.usage_info(),
Self::Kusama(client) => client.usage_info(),
Self::Rococo(client) => client.usage_info(),
}
}
}
@@ -179,6 +184,7 @@ impl sc_client_api::BlockBackend<Block> for Client {
Self::Polkadot(client) => client.block_body(id),
Self::Westend(client) => client.block_body(id),
Self::Kusama(client) => client.block_body(id),
Self::Rococo(client) => client.block_body(id),
}
}
@@ -187,6 +193,7 @@ impl sc_client_api::BlockBackend<Block> for Client {
Self::Polkadot(client) => client.block(id),
Self::Westend(client) => client.block(id),
Self::Kusama(client) => client.block(id),
Self::Rococo(client) => client.block(id),
}
}
@@ -195,6 +202,7 @@ impl sc_client_api::BlockBackend<Block> for Client {
Self::Polkadot(client) => client.block_status(id),
Self::Westend(client) => client.block_status(id),
Self::Kusama(client) => client.block_status(id),
Self::Rococo(client) => client.block_status(id),
}
}
@@ -206,6 +214,7 @@ impl sc_client_api::BlockBackend<Block> for Client {
Self::Polkadot(client) => client.justification(id),
Self::Westend(client) => client.justification(id),
Self::Kusama(client) => client.justification(id),
Self::Rococo(client) => client.justification(id),
}
}
@@ -217,6 +226,7 @@ impl sc_client_api::BlockBackend<Block> for Client {
Self::Polkadot(client) => client.block_hash(number),
Self::Westend(client) => client.block_hash(number),
Self::Kusama(client) => client.block_hash(number),
Self::Rococo(client) => client.block_hash(number),
}
}
}
@@ -231,6 +241,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.storage(id, key),
Self::Westend(client) => client.storage(id, key),
Self::Kusama(client) => client.storage(id, key),
Self::Rococo(client) => client.storage(id, key),
}
}
@@ -243,6 +254,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.storage_keys(id, key_prefix),
Self::Westend(client) => client.storage_keys(id, key_prefix),
Self::Kusama(client) => client.storage_keys(id, key_prefix),
Self::Rococo(client) => client.storage_keys(id, key_prefix),
}
}
@@ -255,6 +267,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.storage_hash(id, key),
Self::Westend(client) => client.storage_hash(id, key),
Self::Kusama(client) => client.storage_hash(id, key),
Self::Rococo(client) => client.storage_hash(id, key),
}
}
@@ -267,6 +280,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.storage_pairs(id, key_prefix),
Self::Westend(client) => client.storage_pairs(id, key_prefix),
Self::Kusama(client) => client.storage_pairs(id, key_prefix),
Self::Rococo(client) => client.storage_pairs(id, key_prefix),
}
}
@@ -280,6 +294,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.storage_keys_iter(id, prefix, start_key),
Self::Westend(client) => client.storage_keys_iter(id, prefix, start_key),
Self::Kusama(client) => client.storage_keys_iter(id, prefix, start_key),
Self::Rococo(client) => client.storage_keys_iter(id, prefix, start_key),
}
}
@@ -293,6 +308,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.child_storage(id, child_info, key),
Self::Westend(client) => client.child_storage(id, child_info, key),
Self::Kusama(client) => client.child_storage(id, child_info, key),
Self::Rococo(client) => client.child_storage(id, child_info, key),
}
}
@@ -306,6 +322,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.child_storage_keys(id, child_info, key_prefix),
Self::Westend(client) => client.child_storage_keys(id, child_info, key_prefix),
Self::Kusama(client) => client.child_storage_keys(id, child_info, key_prefix),
Self::Rococo(client) => client.child_storage_keys(id, child_info, key_prefix),
}
}
@@ -319,6 +336,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.child_storage_hash(id, child_info, key),
Self::Westend(client) => client.child_storage_hash(id, child_info, key),
Self::Kusama(client) => client.child_storage_hash(id, child_info, key),
Self::Rococo(client) => client.child_storage_hash(id, child_info, key),
}
}
@@ -331,6 +349,7 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.max_key_changes_range(first, last),
Self::Westend(client) => client.max_key_changes_range(first, last),
Self::Kusama(client) => client.max_key_changes_range(first, last),
Self::Rococo(client) => client.max_key_changes_range(first, last),
}
}
@@ -345,6 +364,54 @@ impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
Self::Polkadot(client) => client.key_changes(first, last, storage_key, key),
Self::Westend(client) => client.key_changes(first, last, storage_key, key),
Self::Kusama(client) => client.key_changes(first, last, storage_key, key),
Self::Rococo(client) => client.key_changes(first, last, storage_key, key),
}
}
}
impl sp_blockchain::HeaderBackend<Block> for Client {
fn header(&self, id: BlockId<Block>) -> sp_blockchain::Result<Option<Header>> {
match self {
Self::Polkadot(client) => client.header(&id),
Self::Westend(client) => client.header(&id),
Self::Kusama(client) => client.header(&id),
Self::Rococo(client) => client.header(&id),
}
}
fn info(&self) -> sp_blockchain::Info<Block> {
match self {
Self::Polkadot(client) => client.info(),
Self::Westend(client) => client.info(),
Self::Kusama(client) => client.info(),
Self::Rococo(client) => client.info(),
}
}
fn status(&self, id: BlockId<Block>) -> sp_blockchain::Result<sp_blockchain::BlockStatus> {
match self {
Self::Polkadot(client) => client.status(id),
Self::Westend(client) => client.status(id),
Self::Kusama(client) => client.status(id),
Self::Rococo(client) => client.status(id),
}
}
fn number(&self, hash: Hash) -> sp_blockchain::Result<Option<BlockNumber>> {
match self {
Self::Polkadot(client) => client.number(hash),
Self::Westend(client) => client.number(hash),
Self::Kusama(client) => client.number(hash),
Self::Rococo(client) => client.number(hash),
}
}
fn hash(&self, number: BlockNumber) -> sp_blockchain::Result<Option<Hash>> {
match self {
Self::Polkadot(client) => client.hash(number),
Self::Westend(client) => client.hash(number),
Self::Kusama(client) => client.hash(number),
Self::Rococo(client) => client.hash(number),
}
}
}
+8 -28
View File
@@ -25,7 +25,8 @@ use sp_runtime::traits::{Block as BlockT, NumberFor};
/// `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
impl<Block, B> grandpa::VotingRule<Block, B> for PauseAfterBlockFor<NumberFor<Block>>
where
Block: BlockT,
B: sp_blockchain::HeaderBackend<Block>,
{
@@ -40,10 +41,7 @@ impl<Block, B> grandpa::VotingRule<Block, B> for PauseAfterBlockFor<NumberFor<Bl
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 find_target = |target_number: NumberFor<Block>, current_header: &Block::Header| {
let mut target_hash = current_header.hash();
let mut target_header = current_header.clone();
@@ -233,10 +231,10 @@ pub(crate) fn kusama_hard_forks() -> Vec<(
#[cfg(test)]
mod tests {
use grandpa::VotingRule;
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;
@@ -279,20 +277,12 @@ mod tests {
// add 10 blocks
push_blocks(10);
assert_eq!(
client.info().best_number,
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),
),
voting_rule.restrict_vote(&*client, &get_header(0), &get_header(10), &get_header(10)),
None,
);
@@ -303,12 +293,7 @@ mod tests {
// 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),
),
voting_rule.restrict_vote(&*client, &get_header(10), &get_header(20), &get_header(20)),
None,
);
@@ -316,12 +301,7 @@ mod tests {
// 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),
),
voting_rule.restrict_vote(&*client, &get_header(10), &get_header(21), &get_header(21)),
Some((pause_block.hash(), *pause_block.number())),
);
+124 -55
View File
@@ -20,41 +20,45 @@ pub mod chain_spec;
mod grandpa_support;
mod client;
use std::sync::Arc;
use std::time::Duration;
use service::{error::Error as ServiceError, RpcHandlers};
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
use sc_executor::native_executor_instance;
use log::info;
use sp_blockchain::HeaderBackend;
use polkadot_node_core_proposer::ProposerFactory;
use polkadot_overseer::{AllSubsystems, BlockInfo, Overseer, OverseerHandler};
use polkadot_subsystem::DummySubsystem;
use polkadot_node_core_proposer::ProposerFactory;
use sp_trie::PrefixedMemoryDB;
use sp_core::traits::SpawnNamed;
use prometheus_endpoint::Registry;
use sc_client_api::ExecutorProvider;
use sc_executor::native_executor_instance;
use service::{error::Error as ServiceError, RpcHandlers};
use sp_blockchain::HeaderBackend;
use sp_core::traits::SpawnNamed;
use sp_trie::PrefixedMemoryDB;
use std::sync::Arc;
use std::time::Duration;
pub use self::client::{AbstractClient, Client, ClientHandle, ExecuteWithClient, RuntimeApiCollection};
pub use chain_spec::{PolkadotChainSpec, KusamaChainSpec, WestendChainSpec, RococoChainSpec};
#[cfg(feature = "full-node")]
pub use codec::Codec;
pub use consensus_common::{Proposal, SelectChain, BlockImport, RecordProof, block_validation::Chain};
pub use polkadot_parachain::wasm_executor::run_worker as run_validation_worker;
pub use polkadot_primitives::v1::{Block, BlockId, CollatorId, Id as ParaId};
pub use sc_client_api::{Backend, ExecutionStrategy, CallExecutor};
pub use sc_consensus::LongestChain;
pub use sc_executor::NativeExecutionDispatch;
pub use service::{
Role, PruningMode, TransactionPoolOptions, Error, RuntimeGenesis,
TFullClient, TLightClient, TFullBackend, TLightBackend, TFullCallExecutor, TLightCallExecutor,
Configuration, ChainSpec, TaskManager,
};
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::v1::{Block, BlockId, CollatorId, Id as ParaId};
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 sp_runtime::traits::{DigestFor, HashFor, NumberFor, Block as BlockT, self as runtime_traits, BlakeTwo256};
pub use kusama_runtime;
pub use polkadot_runtime;
pub use rococo_runtime;
pub use westend_runtime;
use prometheus_endpoint::Registry;
pub use self::client::{AbstractClient, Client, RuntimeApiCollection};
native_executor_instance!(
pub PolkadotExecutor,
@@ -77,6 +81,13 @@ native_executor_instance!(
frame_benchmarking::benchmarking::HostFunctions,
);
native_executor_instance!(
pub RococoExecutor,
rococo_runtime::api::dispatch,
rococo_runtime::native_version,
frame_benchmarking::benchmarking::HostFunctions,
);
/// 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.
@@ -84,6 +95,9 @@ pub trait IdentifyVariant {
/// Returns if this is a configuration for the `Westend` network.
fn is_westend(&self) -> bool;
/// Returns if this is a configuration for the `Rococo` network.
fn is_rococo(&self) -> bool;
}
impl IdentifyVariant for Box<dyn ChainSpec> {
@@ -93,6 +107,9 @@ impl IdentifyVariant for Box<dyn ChainSpec> {
fn is_westend(&self) -> bool {
self.id().starts_with("westend") || self.id().starts_with("wnd")
}
fn is_rococo(&self) -> bool {
self.id().starts_with("rococo") || self.id().starts_with("rco")
}
}
// If we're using prometheus, use a registry with a prefix of `polkadot`.
@@ -104,9 +121,9 @@ fn set_prometheus_registry(config: &mut Configuration) -> Result<(), ServiceErro
Ok(())
}
type FullBackend = service::TFullBackend<Block>;
pub type FullBackend = service::TFullBackend<Block>;
type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
type FullClient<RuntimeApi, Executor> = service::TFullClient<Block, RuntimeApi, Executor>;
pub type FullClient<RuntimeApi, Executor> = service::TFullClient<Block, RuntimeApi, Executor>;
type FullGrandpaBlockImport<RuntimeApi, Executor> = grandpa::GrandpaBlockImport<
FullBackend, Block, FullClient<RuntimeApi, Executor>, FullSelectChain
>;
@@ -281,18 +298,40 @@ fn real_overseer<S: SpawnNamed>(
}
#[cfg(feature = "full-node")]
fn new_full<RuntimeApi, Executor>(
pub struct NewFull<C> {
pub task_manager: TaskManager,
pub client: C,
pub node_handles: OverseerHandler,
pub network: Arc<sc_network::NetworkService<Block, <Block as BlockT>::Hash>>,
pub network_status_sinks: service::NetworkStatusSinks<Block>,
pub rpc_handlers: RpcHandlers,
}
#[cfg(feature = "full-node")]
impl<C> NewFull<C> {
fn with_client(self, func: impl FnOnce(C) -> Client) -> NewFull<Client> {
NewFull {
client: func(self.client),
task_manager: self.task_manager,
node_handles: self.node_handles,
network: self.network,
network_status_sinks: self.network_status_sinks,
rpc_handlers: self.rpc_handlers,
}
}
}
/// Create a new full node of arbitrary runtime and executor.
///
/// This is an advanced feature and not recommended for general use. Generally, `build_full` is
/// a better choice.
#[cfg(feature = "full-node")]
pub fn new_full<RuntimeApi, Executor>(
mut config: Configuration,
collating_for: Option<(CollatorId, ParaId)>,
authority_discovery_enabled: bool,
grandpa_pause: Option<(u32, u32)>,
) -> Result<(
TaskManager,
Arc<FullClient<RuntimeApi, Executor>>,
Arc<sc_network::NetworkService<Block, <Block as BlockT>::Hash>>,
RpcHandlers,
OverseerHandler,
), Error>
) -> Result<NewFull<Arc<FullClient<RuntimeApi, Executor>>>, Error>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, Executor>> + Send + Sync + 'static,
RuntimeApi::RuntimeApi:
@@ -357,7 +396,8 @@ fn new_full<RuntimeApi, Executor>(
on_demand: None,
remote_blockchain: None,
telemetry_connection_sinks: telemetry_connection_sinks.clone(),
network_status_sinks, system_rpc_tx,
network_status_sinks: network_status_sinks.clone(),
system_rpc_tx,
})?;
let (block_import, link_half, babe_link) = import_setup;
@@ -470,10 +510,8 @@ fn new_full<RuntimeApi, Executor>(
grandpa::VotingRulesBuilder::default()
.add(grandpa_support::PauseAfterBlockFor(block, delay))
.build()
},
None =>
grandpa::VotingRulesBuilder::default()
.build(),
}
None => grandpa::VotingRulesBuilder::default().build(),
};
let grandpa_config = grandpa::GrandpaParams {
@@ -539,7 +577,14 @@ fn new_full<RuntimeApi, Executor>(
network_starter.start_network();
Ok((task_manager, client, network, rpc_handlers, handler))
Ok(NewFull {
task_manager,
client,
node_handles: handler,
network,
network_status_sinks,
rpc_handlers,
})
}
/// Builds a new service for a light client.
@@ -567,7 +612,9 @@ fn new_light<Runtime, Dispatch>(mut config: Configuration) -> Result<(TaskManage
));
let grandpa_block_import = grandpa::light_block_import(
client.clone(), backend.clone(), &(client.clone() as Arc<_>),
client.clone(),
backend.clone(),
&(client.clone() as Arc<_>),
Arc::new(on_demand.checker().clone()),
)?;
@@ -615,7 +662,11 @@ fn new_light<Runtime, Dispatch>(mut config: Configuration) -> Result<(TaskManage
if config.offchain_worker.enabled {
service::build_offchain_workers(
&config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(),
&config,
backend.clone(),
task_manager.spawn_handle(),
client.clone(),
network.clone(),
);
}
@@ -651,30 +702,41 @@ fn new_light<Runtime, Dispatch>(mut config: Configuration) -> Result<(TaskManage
/// Builds a new object suitable for chain operations.
#[cfg(feature = "full-node")]
pub fn new_chain_ops<Runtime, Dispatch>(mut config: &mut Configuration) -> Result<
pub fn new_chain_ops(mut config: &mut Configuration) -> Result<
(
Arc<FullClient<Runtime, Dispatch>>,
Arc<Client>,
Arc<FullBackend>,
consensus_common::import_queue::BasicQueue<Block, PrefixedMemoryDB<BlakeTwo256>>,
TaskManager,
),
ServiceError
>
where
Runtime: ConstructRuntimeApi<Block, FullClient<Runtime, Dispatch>> + Send + Sync + 'static,
Runtime::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
Dispatch: NativeExecutionDispatch + 'static,
{
config.keystore = service::config::KeystoreConfig::InMemory;
let service::PartialComponents { client, backend, import_queue, task_manager, .. }
= new_partial::<Runtime, Dispatch>(config)?;
Ok((client, backend, import_queue, task_manager))
if config.chain_spec.is_rococo() {
let service::PartialComponents { client, backend, import_queue, task_manager, .. }
= new_partial::<rococo_runtime::RuntimeApi, RococoExecutor>(config)?;
Ok((Arc::new(Client::Rococo(client)), backend, import_queue, task_manager))
} else if config.chain_spec.is_kusama() {
let service::PartialComponents { client, backend, import_queue, task_manager, .. }
= new_partial::<kusama_runtime::RuntimeApi, KusamaExecutor>(config)?;
Ok((Arc::new(Client::Kusama(client)), backend, import_queue, task_manager))
} else if config.chain_spec.is_westend() {
let service::PartialComponents { client, backend, import_queue, task_manager, .. }
= new_partial::<westend_runtime::RuntimeApi, WestendExecutor>(config)?;
Ok((Arc::new(Client::Westend(client)), backend, import_queue, task_manager))
} else {
let service::PartialComponents { client, backend, import_queue, task_manager, .. }
= new_partial::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(config)?;
Ok((Arc::new(Client::Polkadot(client)), backend, import_queue, task_manager))
}
}
/// Build a new light node.
pub fn build_light(config: Configuration) -> Result<(TaskManager, RpcHandlers), ServiceError> {
if config.chain_spec.is_kusama() {
if config.chain_spec.is_rococo() {
new_light::<rococo_runtime::RuntimeApi, RococoExecutor>(config)
} else if config.chain_spec.is_kusama() {
new_light::<kusama_runtime::RuntimeApi, KusamaExecutor>(config)
} else if config.chain_spec.is_westend() {
new_light::<westend_runtime::RuntimeApi, WestendExecutor>(config)
@@ -689,27 +751,34 @@ pub fn build_full(
collating_for: Option<(CollatorId, ParaId)>,
authority_discovery_enabled: bool,
grandpa_pause: Option<(u32, u32)>,
) -> Result<(TaskManager, Client, OverseerHandler), ServiceError> {
if config.chain_spec.is_kusama() {
) -> Result<NewFull<Client>, ServiceError> {
if config.chain_spec.is_rococo() {
new_full::<rococo_runtime::RuntimeApi, RococoExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
).map(|full| full.with_client(Client::Rococo))
} else if config.chain_spec.is_kusama() {
new_full::<kusama_runtime::RuntimeApi, KusamaExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
).map(|(task_manager, client, _, _, handler)| (task_manager, Client::Kusama(client), handler))
).map(|full| full.with_client(Client::Kusama))
} else if config.chain_spec.is_westend() {
new_full::<westend_runtime::RuntimeApi, WestendExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
).map(|(task_manager, client, _, _, handler)| (task_manager, Client::Westend(client), handler))
).map(|full| full.with_client(Client::Westend))
} else {
new_full::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
).map(|(task_manager, client, _, _, handler)| (task_manager, Client::Polkadot(client), handler))
).map(|full| full.with_client(Client::Polkadot))
}
}
+2 -1
View File
@@ -13,10 +13,11 @@ rand = "0.7.3"
tempfile = "3.1.0"
# Polkadot dependencies
polkadot-overseer = { path = "../overseer" }
polkadot-primitives = { path = "../../primitives" }
polkadot-rpc = { path = "../../rpc" }
polkadot-runtime-common = { path = "../../runtime/common" }
polkadot-service = { path = "../../service" }
polkadot-service = { path = "../service" }
polkadot-test-runtime = { path = "../../runtime/test-runtime" }
# Substrate dependencies
+14 -23
View File
@@ -22,12 +22,13 @@ mod chain_spec;
pub use chain_spec::*;
use futures::future::Future;
use polkadot_overseer::OverseerHandler;
use polkadot_primitives::v0::{
Block, Hash, CollatorId, Id as ParaId,
Block, CollatorId, Id as ParaId,
};
use polkadot_runtime_common::BlockHashCount;
use polkadot_service::{
new_full, NewFull, FullNodeHandles, AbstractClient, ClientHandle, ExecuteWithClient,
new_full, NewFull, FullClient, AbstractClient, ClientHandle, ExecuteWithClient,
};
use polkadot_test_runtime::{Runtime, SignedExtra, SignedPayload, VERSION};
use sc_chain_spec::ChainSpec;
@@ -36,7 +37,7 @@ use sc_executor::native_executor_instance;
use sc_informant::OutputFormat;
use sc_network::{
config::{NetworkConfiguration, TransportConfig},
multiaddr, NetworkService,
multiaddr,
};
use service::{
config::{DatabaseConfig, KeystoreConfig, MultiaddrWithPeerId, WasmExecutionMethod},
@@ -65,25 +66,15 @@ pub fn polkadot_test_new_full(
collating_for: Option<(CollatorId, ParaId)>,
authority_discovery_enabled: bool,
) -> Result<
(
TaskManager,
Arc<polkadot_service::FullClient<polkadot_test_runtime::RuntimeApi, PolkadotTestExecutor>>,
FullNodeHandles,
Arc<NetworkService<Block, Hash>>,
RpcHandlers,
),
NewFull<Arc<FullClient<polkadot_test_runtime::RuntimeApi, PolkadotTestExecutor>>>,
ServiceError,
> {
let NewFull { task_manager, client, node_handles, network, rpc_handlers, .. } =
new_full::<polkadot_test_runtime::RuntimeApi, PolkadotTestExecutor>(
config,
collating_for,
authority_discovery_enabled,
None,
true,
)?;
Ok((task_manager, client, node_handles, network, rpc_handlers))
new_full::<polkadot_test_runtime::RuntimeApi, PolkadotTestExecutor>(
config,
collating_for,
authority_discovery_enabled,
None,
).map_err(Into::into)
}
/// A wrapper for the test client that implements `ClientHandle`.
@@ -206,7 +197,7 @@ pub fn run_test_node(
let config = node_config(storage_update_func, task_executor, key, boot_nodes);
let multiaddr = config.network.listen_addresses[0].clone();
let authority_discovery_enabled = false;
let (task_manager, client, handles, network, rpc_handlers) =
let NewFull {task_manager, client, network, rpc_handlers, node_handles, ..} =
polkadot_test_new_full(config, None, authority_discovery_enabled)
.expect("could not create Polkadot test service");
@@ -216,7 +207,7 @@ pub fn run_test_node(
PolkadotTestNode {
task_manager,
client,
handles,
handles: node_handles,
addr,
rpc_handlers,
}
@@ -229,7 +220,7 @@ pub struct PolkadotTestNode<S, C> {
/// Client's instance.
pub client: Arc<C>,
/// Node's handles.
pub handles: FullNodeHandles,
pub handles: OverseerHandler,
/// The `MultiaddrWithPeerId` to this node. This is useful if you want to pass it as "boot node" to other nodes.
pub addr: MultiaddrWithPeerId,
/// RPCHandlers to make RPC queries.
+3 -3
View File
@@ -24,9 +24,9 @@ use sp_std::prelude::*;
use sp_core::u32_trait::{_1, _2, _3, _4, _5};
use codec::{Encode, Decode};
use primitives::v1::{
AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, ValidatorId,
ValidatorIndex, CoreState, Id, CandidateEvent, ValidationData, OccupiedCoreAssumption,
CommittedCandidateReceipt, PersistedValidationData, GroupRotationInfo, ValidationCode,
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
CoreState, GroupRotationInfo, Hash, Id, Moment, Nonce, OccupiedCoreAssumption,
PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex,
};
use runtime_common::{
claims, SlowAdjustingFeeUpdate,
+3 -3
View File
@@ -32,9 +32,9 @@ use sp_std::prelude::*;
use sp_core::u32_trait::{_1, _2, _3, _4, _5};
use codec::{Encode, Decode};
use primitives::v1::{
AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, ValidatorId,
ValidatorIndex, CoreState, Id, CandidateEvent, ValidationData, OccupiedCoreAssumption,
CommittedCandidateReceipt, PersistedValidationData, GroupRotationInfo, ValidationCode,
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
CoreState, GroupRotationInfo, Hash, Id, Moment, Nonce, OccupiedCoreAssumption,
PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex,
};
use sp_runtime::{
create_runtime_str, generic, impl_opaque_keys, ModuleId, ApplyExtrinsicResult,
+11
View File
@@ -0,0 +1,11 @@
# Rococo: v1
Rococo is a testnet runtime with no stability guarantees.
## How to run
> TODO: figure out how to run this properly.
### Alice
`cargo run --release -- --alice --tmp --validator --chain rococo-local`
+13
View File
@@ -54,6 +54,8 @@ use sp_runtime::{
};
use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
#[cfg(any(feature = "std", test))]
use sp_version::NativeVersion;
use sp_version::RuntimeVersion;
use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
use pallet_grandpa::{AuthorityId as GrandpaId, fg_primitives};
@@ -73,6 +75,7 @@ use runtime_parachains::router as parachains_router;
use runtime_parachains::scheduler as parachains_scheduler;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_staking::StakerStatus;
/// Constant values used within the runtime.
pub mod constants;
@@ -401,6 +404,16 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
transaction_version: 2,
};
/// Native version.
#[cfg(any(feature = "std", test))]
pub fn native_version() -> NativeVersion {
NativeVersion {
runtime_version: VERSION,
can_author_with: Default::default(),
}
}
parameter_types! {
pub const Version: RuntimeVersion = VERSION;
}
+1
View File
@@ -55,6 +55,7 @@ pallet-vesting = { git = "https://github.com/paritytech/substrate", branch = "ma
runtime-common = { package = "polkadot-runtime-common", path = "../common", default-features = false }
primitives = { package = "polkadot-primitives", path = "../../primitives", default-features = false }
polkadot-parachain = { path = "../../parachain", default-features = false }
polkadot-runtime-parachains = { path = "../parachains", default-features = false }
[dev-dependencies]
hex-literal = "0.2.1"
+69 -46
View File
@@ -21,10 +21,20 @@
#![recursion_limit="256"]
use rstd::prelude::*;
use codec::{Encode, Decode};
use primitives::v0 as p_v0;
use codec::Encode;
use polkadot_runtime_parachains::{
configuration,
inclusion,
initializer,
paras,
router,
runtime_api_impl::v1 as runtime_impl,
scheduler,
};
use primitives::v1::{
AccountId, AccountIndex, Balance, BlockNumber, Hash as HashT, Nonce, Signature, Moment,
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
CoreState, GroupRotationInfo, Hash as HashT, Id as ParaId, Moment, Nonce, OccupiedCoreAssumption,
PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex,
};
use runtime_common::{
claims, SlowAdjustingFeeUpdate, impls::CurrencyToVoteHandler,
@@ -419,6 +429,22 @@ impl pallet_sudo::Trait for Runtime {
type Call = Call;
}
impl configuration::Trait for Runtime {}
impl inclusion::Trait for Runtime {
type Event = Event;
}
impl initializer::Trait for Runtime {
type Randomness = RandomnessCollectiveFlip;
}
impl paras::Trait for Runtime {}
impl router::Trait for Runtime {}
impl scheduler::Trait for Runtime {}
construct_runtime! {
pub enum Runtime where
Block = Block,
@@ -452,6 +478,13 @@ construct_runtime! {
// Vesting. Usable initially, but removed once all vesting is finished.
Vesting: pallet_vesting::{Module, Call, Storage, Event<T>, Config<T>},
// Parachains runtime modules
Configuration: configuration::{Module, Call, Storage},
Inclusion: inclusion::{Module, Call, Storage, Event<T>},
Initializer: initializer::{Module, Call, Storage},
Paras: paras::{Module, Call, Storage},
Scheduler: scheduler::{Module, Call, Storage},
// Sudo. Last module.
Sudo: pallet_sudo::{Module, Call, Storage, Config<T>, Event<T>},
}
@@ -556,55 +589,45 @@ sp_api::impl_runtime_apis! {
}
}
// Dummy implementation to continue supporting old parachains runtime temporarily.
impl p_v0::ParachainHost<Block> for Runtime {
fn validators() -> Vec<p_v0::ValidatorId> {
// this is a compile-time check of size equality. note that we don't invoke
// the function and nothing here is unsafe.
let _ = core::mem::transmute::<p_v0::ValidatorId, AccountId>;
impl primitives::v1::ParachainHost<Block, Hash, BlockNumber> for Runtime {
fn validators() -> Vec<ValidatorId> {
runtime_impl::validators::<Runtime>()
}
// Yes, these aren't actually the parachain session keys.
// It doesn't matter, but we shouldn't return a zero-sized vector here.
// As there are no parachains
Session::validators()
.into_iter()
.map(|k| k.using_encoded(|s| Decode::decode(&mut &s[..]))
.expect("correct size and raw-bytes; qed"))
.collect()
fn validator_groups() -> (Vec<Vec<ValidatorIndex>>, GroupRotationInfo<BlockNumber>) {
runtime_impl::validator_groups::<Runtime>()
}
fn duty_roster() -> p_v0::DutyRoster {
let v = Session::validators();
p_v0::DutyRoster { validator_duty: (0..v.len()).map(|_| p_v0::Chain::Relay).collect() }
fn availability_cores() -> Vec<CoreState<BlockNumber>> {
runtime_impl::availability_cores::<Runtime>()
}
fn active_parachains() -> Vec<(p_v0::Id, Option<(p_v0::CollatorId, p_v0::Retriable)>)> {
Vec::new()
}
fn global_validation_data() -> p_v0::GlobalValidationData {
p_v0::GlobalValidationData {
max_code_size: 1,
max_head_data_size: 1,
block_number: System::block_number().saturating_sub(1),
fn full_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
-> Option<ValidationData<BlockNumber>> {
runtime_impl::full_validation_data::<Runtime>(para_id, assumption)
}
}
fn local_validation_data(_id: p_v0::Id) -> Option<p_v0::LocalValidationData> {
None
}
fn parachain_code(_id: p_v0::Id) -> Option<p_v0::ValidationCode> {
None
}
fn get_heads(_extrinsics: Vec<<Block as BlockT>::Extrinsic>)
-> Option<Vec<p_v0::AbridgedCandidateReceipt>>
{
None
}
fn signing_context() -> p_v0::SigningContext {
p_v0::SigningContext {
parent_hash: System::parent_hash(),
session_index: Session::current_index(),
fn persisted_validation_data(para_id: ParaId, assumption: OccupiedCoreAssumption)
-> Option<PersistedValidationData<BlockNumber>> {
runtime_impl::persisted_validation_data::<Runtime>(para_id, assumption)
}
fn session_index_for_child() -> SessionIndex {
runtime_impl::session_index_for_child::<Runtime>()
}
fn downward_messages(_id: p_v0::Id) -> Vec<p_v0::DownwardMessage> {
Vec::new()
fn validation_code(para_id: ParaId, assumption: OccupiedCoreAssumption)
-> Option<ValidationCode> {
runtime_impl::validation_code::<Runtime>(para_id, assumption)
}
fn candidate_pending_availability(para_id: ParaId) -> Option<CommittedCandidateReceipt<Hash>> {
runtime_impl::candidate_pending_availability::<Runtime>(para_id)
}
fn candidate_events() -> Vec<CandidateEvent<Hash>> {
use core::convert::TryInto;
runtime_impl::candidate_events::<Runtime, _>(|trait_event| trait_event.try_into().ok())
}
}
+3 -3
View File
@@ -23,9 +23,9 @@
use sp_std::prelude::*;
use codec::{Encode, Decode};
use primitives::v1::{
AccountId, AccountIndex, Balance, BlockNumber, Hash, Nonce, Signature, Moment, ValidatorId,
ValidatorIndex, CoreState, Id, CandidateEvent, ValidationData, OccupiedCoreAssumption,
CommittedCandidateReceipt, PersistedValidationData, GroupRotationInfo, ValidationCode,
AccountId, AccountIndex, Balance, BlockNumber, CandidateEvent, CommittedCandidateReceipt,
CoreState, GroupRotationInfo, Hash, Id, Moment, Nonce, OccupiedCoreAssumption,
PersistedValidationData, Signature, ValidationCode, ValidationData, ValidatorId, ValidatorIndex,
};
use runtime_common::{
purchase, SlowAdjustingFeeUpdate,
-69
View File
@@ -1,69 +0,0 @@
[package]
name = "polkadot-service"
version = "0.8.24"
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"
consensus = { package = "polkadot-validation", path = "../validation", optional = true }
polkadot-primitives = { path = "../primitives" }
polkadot-runtime = { path = "../runtime/polkadot" }
kusama-runtime = { path = "../runtime/kusama" }
westend-runtime = { path = "../runtime/westend" }
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" }
sp-trie = { 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" }
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" }
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
codec = { package = "parity-scale-codec", version = "1.3.4" }
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" }
sp-storage = { 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 = ["consensus"]
-5
View File
@@ -1,5 +0,0 @@
= Polkadot Service
placeholder
//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159)
-942
View File
@@ -1,942 +0,0 @@
// 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::v0::{AccountId, AccountPublic, 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 pallet_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::v0::Block>,
/// Known bad block hashes.
pub bad_blocks: sc_client_api::BadBlocks<polkadot_primitives::v0::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!("../res/polkadot.json")[..])
}
pub fn kusama_config() -> Result<KusamaChainSpec, String> {
KusamaChainSpec::from_json_bytes(&include_bytes!("../res/kusama.json")[..])
}
pub fn westend_config() -> Result<WestendChainSpec, String> {
WestendChainSpec::from_json_bytes(&include_bytes!("../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(wasm_binary: &[u8]) -> 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 {
frame_system: Some(polkadot::SystemConfig {
code: wasm_binary.to_vec(),
changes_trie_config: Default::default(),
}),
pallet_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(),
}),
pallet_indices: Some(polkadot::IndicesConfig {
indices: vec![],
}),
pallet_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<_>>(),
}),
pallet_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()
}),
pallet_elections_phragmen: Some(Default::default()),
pallet_democracy: Some(Default::default()),
pallet_collective_Instance1: Some(polkadot::CouncilConfig {
members: vec![],
phantom: Default::default(),
}),
pallet_collective_Instance2: Some(polkadot::TechnicalCommitteeConfig {
members: vec![],
phantom: Default::default(),
}),
pallet_membership_Instance1: Some(Default::default()),
pallet_babe: Some(Default::default()),
pallet_grandpa: Some(Default::default()),
pallet_im_online: Some(Default::default()),
pallet_authority_discovery: Some(polkadot::AuthorityDiscoveryConfig {
keys: vec![],
}),
claims: Some(polkadot::ClaimsConfig {
claims: vec![],
vesting: vec![],
}),
pallet_vesting: Some(polkadot::VestingConfig {
vesting: vec![],
}),
}
}
fn westend_staging_testnet_config_genesis(wasm_binary: &[u8]) -> 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 {
frame_system: Some(westend::SystemConfig {
code: wasm_binary.to_vec(),
changes_trie_config: Default::default(),
}),
pallet_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(),
}),
pallet_indices: Some(westend::IndicesConfig {
indices: vec![],
}),
pallet_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<_>>(),
}),
pallet_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()
}),
pallet_babe: Some(Default::default()),
pallet_grandpa: Some(Default::default()),
pallet_im_online: Some(Default::default()),
pallet_authority_discovery: Some(westend::AuthorityDiscoveryConfig {
keys: vec![],
}),
pallet_vesting: Some(westend::VestingConfig {
vesting: vec![],
}),
pallet_sudo: Some(westend::SudoConfig {
key: endowed_accounts[0].clone(),
}),
}
}
fn kusama_staging_testnet_config_genesis(wasm_binary: &[u8]) -> 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 {
frame_system: Some(kusama::SystemConfig {
code: wasm_binary.to_vec(),
changes_trie_config: Default::default(),
}),
pallet_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(),
}),
pallet_indices: Some(kusama::IndicesConfig {
indices: vec![],
}),
pallet_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<_>>(),
}),
pallet_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()
}),
pallet_elections_phragmen: Some(Default::default()),
pallet_democracy: Some(Default::default()),
pallet_collective_Instance1: Some(kusama::CouncilConfig {
members: vec![],
phantom: Default::default(),
}),
pallet_collective_Instance2: Some(kusama::TechnicalCommitteeConfig {
members: vec![],
phantom: Default::default(),
}),
pallet_membership_Instance1: Some(Default::default()),
pallet_babe: Some(Default::default()),
pallet_grandpa: Some(Default::default()),
pallet_im_online: Some(Default::default()),
pallet_authority_discovery: Some(kusama::AuthorityDiscoveryConfig {
keys: vec![],
}),
claims: Some(kusama::ClaimsConfig {
claims: vec![],
vesting: vec![],
}),
pallet_vesting: Some(kusama::VestingConfig {
vesting: vec![],
}),
}
}
/// Polkadot staging testnet config.
pub fn polkadot_staging_testnet_config() -> Result<PolkadotChainSpec, String> {
let wasm_binary = polkadot::WASM_BINARY.ok_or("Polkadot development wasm not available")?;
let boot_nodes = vec![];
Ok(PolkadotChainSpec::from_genesis(
"Polkadot Staging Testnet",
"polkadot_staging_testnet",
ChainType::Live,
move || polkadot_staging_testnet_config_genesis(wasm_binary),
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() -> Result<KusamaChainSpec, String> {
let wasm_binary = kusama::WASM_BINARY.ok_or("Kusama development wasm not available")?;
let boot_nodes = vec![];
Ok(KusamaChainSpec::from_genesis(
"Kusama Staging Testnet",
"kusama_staging_testnet",
ChainType::Live,
move || kusama_staging_testnet_config_genesis(wasm_binary),
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() -> Result<WestendChainSpec, String> {
let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?;
let boot_nodes = vec![];
Ok(WestendChainSpec::from_genesis(
"Westend Staging Testnet",
"westend_staging_testnet",
ChainType::Live,
move || westend_staging_testnet_config_genesis(wasm_binary),
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(
wasm_binary: &[u8],
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 {
frame_system: Some(polkadot::SystemConfig {
code: wasm_binary.to_vec(),
changes_trie_config: Default::default(),
}),
pallet_indices: Some(polkadot::IndicesConfig {
indices: vec![],
}),
pallet_balances: Some(polkadot::BalancesConfig {
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
}),
pallet_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<_>>(),
}),
pallet_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()
}),
pallet_elections_phragmen: Some(Default::default()),
pallet_democracy: Some(polkadot::DemocracyConfig::default()),
pallet_collective_Instance1: Some(polkadot::CouncilConfig {
members: vec![],
phantom: Default::default(),
}),
pallet_collective_Instance2: Some(polkadot::TechnicalCommitteeConfig {
members: vec![],
phantom: Default::default(),
}),
pallet_membership_Instance1: Some(Default::default()),
pallet_babe: Some(Default::default()),
pallet_grandpa: Some(Default::default()),
pallet_im_online: Some(Default::default()),
pallet_authority_discovery: Some(polkadot::AuthorityDiscoveryConfig {
keys: vec![],
}),
claims: Some(polkadot::ClaimsConfig {
claims: vec![],
vesting: vec![],
}),
pallet_vesting: Some(polkadot::VestingConfig {
vesting: vec![],
}),
}
}
/// Helper function to create kusama GenesisConfig for testing
pub fn kusama_testnet_genesis(
wasm_binary: &[u8],
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 {
frame_system: Some(kusama::SystemConfig {
code: wasm_binary.to_vec(),
changes_trie_config: Default::default(),
}),
pallet_indices: Some(kusama::IndicesConfig {
indices: vec![],
}),
pallet_balances: Some(kusama::BalancesConfig {
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
}),
pallet_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<_>>(),
}),
pallet_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()
}),
pallet_elections_phragmen: Some(Default::default()),
pallet_democracy: Some(kusama::DemocracyConfig::default()),
pallet_collective_Instance1: Some(kusama::CouncilConfig {
members: vec![],
phantom: Default::default(),
}),
pallet_collective_Instance2: Some(kusama::TechnicalCommitteeConfig {
members: vec![],
phantom: Default::default(),
}),
pallet_membership_Instance1: Some(Default::default()),
pallet_babe: Some(Default::default()),
pallet_grandpa: Some(Default::default()),
pallet_im_online: Some(Default::default()),
pallet_authority_discovery: Some(kusama::AuthorityDiscoveryConfig {
keys: vec![],
}),
claims: Some(kusama::ClaimsConfig {
claims: vec![],
vesting: vec![],
}),
pallet_vesting: Some(kusama::VestingConfig {
vesting: vec![],
}),
}
}
/// Helper function to create polkadot GenesisConfig for testing
pub fn westend_testnet_genesis(
wasm_binary: &[u8],
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 {
frame_system: Some(westend::SystemConfig {
code: wasm_binary.to_vec(),
changes_trie_config: Default::default(),
}),
pallet_indices: Some(westend::IndicesConfig {
indices: vec![],
}),
pallet_balances: Some(westend::BalancesConfig {
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
}),
pallet_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<_>>(),
}),
pallet_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()
}),
pallet_babe: Some(Default::default()),
pallet_grandpa: Some(Default::default()),
pallet_im_online: Some(Default::default()),
pallet_authority_discovery: Some(westend::AuthorityDiscoveryConfig {
keys: vec![],
}),
pallet_vesting: Some(westend::VestingConfig {
vesting: vec![],
}),
pallet_sudo: Some(westend::SudoConfig {
key: root_key,
}),
}
}
fn polkadot_development_config_genesis(wasm_binary: &[u8]) -> polkadot::GenesisConfig {
polkadot_testnet_genesis(
wasm_binary,
vec![
get_authority_keys_from_seed("Alice"),
],
get_account_id_from_seed::<sr25519::Public>("Alice"),
None,
)
}
fn kusama_development_config_genesis(wasm_binary: &[u8]) -> kusama::GenesisConfig {
kusama_testnet_genesis(
wasm_binary,
vec![
get_authority_keys_from_seed("Alice"),
],
get_account_id_from_seed::<sr25519::Public>("Alice"),
None,
)
}
fn westend_development_config_genesis(wasm_binary: &[u8]) -> westend::GenesisConfig {
westend_testnet_genesis(
wasm_binary,
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() -> Result<PolkadotChainSpec, String> {
let wasm_binary = polkadot::WASM_BINARY.ok_or("Polkadot development wasm not available")?;
Ok(PolkadotChainSpec::from_genesis(
"Development",
"dev",
ChainType::Development,
move || polkadot_development_config_genesis(wasm_binary),
vec![],
None,
Some(DEFAULT_PROTOCOL_ID),
None,
Default::default(),
))
}
/// Kusama development config (single validator Alice)
pub fn kusama_development_config() -> Result<KusamaChainSpec, String> {
let wasm_binary = kusama::WASM_BINARY.ok_or("Kusama development wasm not available")?;
Ok(KusamaChainSpec::from_genesis(
"Development",
"kusama_dev",
ChainType::Development,
move || kusama_development_config_genesis(wasm_binary),
vec![],
None,
Some(DEFAULT_PROTOCOL_ID),
None,
Default::default(),
))
}
/// Westend development config (single validator Alice)
pub fn westend_development_config() -> Result<WestendChainSpec, String> {
let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?;
Ok(WestendChainSpec::from_genesis(
"Development",
"westend_dev",
ChainType::Development,
move || westend_development_config_genesis(wasm_binary),
vec![],
None,
Some(DEFAULT_PROTOCOL_ID),
None,
Default::default(),
))
}
fn polkadot_local_testnet_genesis(wasm_binary: &[u8]) -> polkadot::GenesisConfig {
polkadot_testnet_genesis(
wasm_binary,
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() -> Result<PolkadotChainSpec, String> {
let wasm_binary = polkadot::WASM_BINARY.ok_or("Polkadot development wasm not available")?;
Ok(PolkadotChainSpec::from_genesis(
"Local Testnet",
"local_testnet",
ChainType::Local,
move || polkadot_local_testnet_genesis(wasm_binary),
vec![],
None,
Some(DEFAULT_PROTOCOL_ID),
None,
Default::default(),
))
}
fn kusama_local_testnet_genesis(wasm_binary: &[u8]) -> kusama::GenesisConfig {
kusama_testnet_genesis(
wasm_binary,
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() -> Result<KusamaChainSpec, String> {
let wasm_binary = kusama::WASM_BINARY.ok_or("Kusama development wasm not available")?;
Ok(KusamaChainSpec::from_genesis(
"Kusama Local Testnet",
"kusama_local_testnet",
ChainType::Local,
move || kusama_local_testnet_genesis(wasm_binary),
vec![],
None,
Some(DEFAULT_PROTOCOL_ID),
None,
Default::default(),
))
}
fn westend_local_testnet_genesis(wasm_binary: &[u8]) -> westend::GenesisConfig {
westend_testnet_genesis(
wasm_binary,
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() -> Result<WestendChainSpec, String> {
let wasm_binary = westend::WASM_BINARY.ok_or("Westend development wasm not available")?;
Ok(WestendChainSpec::from_genesis(
"Westend Local Testnet",
"westend_local_testnet",
ChainType::Local,
move || westend_local_testnet_genesis(wasm_binary),
vec![],
None,
Some(DEFAULT_PROTOCOL_ID),
None,
Default::default(),
))
}
-394
View File
@@ -1,394 +0,0 @@
// 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 abstractions.
use std::sync::Arc;
use sp_api::{ProvideRuntimeApi, CallApiAt, NumberFor};
use sp_blockchain::HeaderBackend;
use sp_runtime::{
Justification, generic::{BlockId, SignedBlock}, traits::{Block as BlockT, BlakeTwo256},
};
use consensus_common::BlockStatus;
use sp_storage::{StorageData, StorageKey, ChildInfo, PrefixedStorageKey};
use sc_client_api::{Backend as BackendT, BlockchainEvents, KeyIterator};
use polkadot_primitives::v0::{Block, AccountId, Nonce, Balance};
/// A set of APIs that polkadot-like runtimes must implement.
pub trait RuntimeApiCollection:
sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block>
+ sp_api::ApiExt<Block, Error = sp_blockchain::Error>
+ babe_primitives::BabeApi<Block>
+ grandpa_primitives::GrandpaApi<Block>
+ sp_block_builder::BlockBuilder<Block>
+ frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
+ sp_api::Metadata<Block>
+ sp_offchain::OffchainWorkerApi<Block>
+ sp_session::SessionKeys<Block>
+ authority_discovery_primitives::AuthorityDiscoveryApi<Block>
where
<Self as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
{}
impl<Api> RuntimeApiCollection 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>
+ sp_block_builder::BlockBuilder<Block>
+ frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce>
+ pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance>
+ sp_api::Metadata<Block>
+ sp_offchain::OffchainWorkerApi<Block>
+ sp_session::SessionKeys<Block>
+ authority_discovery_primitives::AuthorityDiscoveryApi<Block>,
<Self as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
{}
/// Trait that abstracts over all available client implementations.
///
/// For a concrete type there exists [`Client`].
pub trait AbstractClient<Block, Backend>:
BlockchainEvents<Block> + Sized + Send + Sync
+ ProvideRuntimeApi<Block>
+ HeaderBackend<Block>
+ CallApiAt<
Block,
Error = sp_blockchain::Error,
StateBackend = Backend::State
>
where
Block: BlockT,
Backend: BackendT<Block>,
Backend::State: sp_api::StateBackend<BlakeTwo256>,
Self::Api: RuntimeApiCollection<StateBackend = Backend::State>,
{}
impl<Block, Backend, Client> AbstractClient<Block, Backend> for Client
where
Block: BlockT,
Backend: BackendT<Block>,
Backend::State: sp_api::StateBackend<BlakeTwo256>,
Client: BlockchainEvents<Block> + ProvideRuntimeApi<Block> + HeaderBackend<Block>
+ Sized + Send + Sync
+ CallApiAt<
Block,
Error = sp_blockchain::Error,
StateBackend = Backend::State
>,
Client::Api: RuntimeApiCollection<StateBackend = Backend::State>,
{}
/// Execute something with the client instance.
///
/// As there exist multiple chains inside Polkadot, like Polkadot itself, Kusama, Westend etc,
/// there can exist different kinds of client types. As these client types differ in the generics
/// that are being used, we can not easily return them from a function. For returning them from a
/// function there exists [`Client`]. However, the problem on how to use this client instance still
/// exists. This trait "solves" it in a dirty way. It requires a type to implement this trait and
/// than the [`execute_with_client`](ExecuteWithClient::execute_with_client) function can be called
/// with any possible client instance.
///
/// In a perfect world, we could make a closure work in this way.
pub trait ExecuteWithClient {
/// The return type when calling this instance.
type Output;
/// Execute whatever should be executed with the given client instance.
fn execute_with_client<Client, Api, Backend>(self, client: Arc<Client>) -> Self::Output
where
<Api as sp_api::ApiExt<Block>>::StateBackend: sp_api::StateBackend<BlakeTwo256>,
Backend: sc_client_api::Backend<Block>,
Backend::State: sp_api::StateBackend<BlakeTwo256>,
Api: crate::RuntimeApiCollection<StateBackend = Backend::State>,
Client: AbstractClient<Block, Backend, Api = Api> + 'static;
}
/// A handle to a Polkadot client instance.
///
/// The Polkadot service supports multiple different runtimes (Westend, Polkadot itself, etc). As each runtime has a
/// specialized client, we need to hide them behind a trait. This is this trait.
///
/// When wanting to work with the inner client, you need to use `execute_with`.
///
/// See [`ExecuteWithClient`](trait.ExecuteWithClient.html) for more information.
pub trait ClientHandle {
/// Execute the given something with the client.
fn execute_with<T: ExecuteWithClient>(&self, t: T) -> T::Output;
}
/// A client instance of Polkadot.
///
/// See [`ExecuteWithClient`] for more information.
#[derive(Clone)]
pub enum Client {
Polkadot(Arc<crate::FullClient<polkadot_runtime::RuntimeApi, crate::PolkadotExecutor>>),
Westend(Arc<crate::FullClient<westend_runtime::RuntimeApi, crate::WestendExecutor>>),
Kusama(Arc<crate::FullClient<kusama_runtime::RuntimeApi, crate::KusamaExecutor>>),
}
impl ClientHandle for Client {
fn execute_with<T: ExecuteWithClient>(&self, t: T) -> T::Output {
match self {
Self::Polkadot(client) => {
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
},
Self::Westend(client) => {
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
},
Self::Kusama(client) => {
T::execute_with_client::<_, _, crate::FullBackend>(t, client.clone())
},
}
}
}
impl sc_client_api::UsageProvider<Block> for Client {
fn usage_info(&self) -> sc_client_api::ClientInfo<Block> {
match self {
Self::Polkadot(client) => client.usage_info(),
Self::Westend(client) => client.usage_info(),
Self::Kusama(client) => client.usage_info(),
}
}
}
impl sc_client_api::BlockBackend<Block> for Client {
fn block_body(
&self,
id: &BlockId<Block>
) -> sp_blockchain::Result<Option<Vec<<Block as BlockT>::Extrinsic>>> {
match self {
Self::Polkadot(client) => client.block_body(id),
Self::Westend(client) => client.block_body(id),
Self::Kusama(client) => client.block_body(id),
}
}
fn block(&self, id: &BlockId<Block>) -> sp_blockchain::Result<Option<SignedBlock<Block>>> {
match self {
Self::Polkadot(client) => client.block(id),
Self::Westend(client) => client.block(id),
Self::Kusama(client) => client.block(id),
}
}
fn block_status(&self, id: &BlockId<Block>) -> sp_blockchain::Result<BlockStatus> {
match self {
Self::Polkadot(client) => client.block_status(id),
Self::Westend(client) => client.block_status(id),
Self::Kusama(client) => client.block_status(id),
}
}
fn justification(
&self,
id: &BlockId<Block>
) -> sp_blockchain::Result<Option<Justification>> {
match self {
Self::Polkadot(client) => client.justification(id),
Self::Westend(client) => client.justification(id),
Self::Kusama(client) => client.justification(id),
}
}
fn block_hash(
&self,
number: NumberFor<Block>
) -> sp_blockchain::Result<Option<<Block as BlockT>::Hash>> {
match self {
Self::Polkadot(client) => client.block_hash(number),
Self::Westend(client) => client.block_hash(number),
Self::Kusama(client) => client.block_hash(number),
}
}
}
impl sc_client_api::StorageProvider<Block, crate::FullBackend> for Client {
fn storage(
&self,
id: &BlockId<Block>,
key: &StorageKey,
) -> sp_blockchain::Result<Option<StorageData>> {
match self {
Self::Polkadot(client) => client.storage(id, key),
Self::Westend(client) => client.storage(id, key),
Self::Kusama(client) => client.storage(id, key),
}
}
fn storage_keys(
&self,
id: &BlockId<Block>,
key_prefix: &StorageKey,
) -> sp_blockchain::Result<Vec<StorageKey>> {
match self {
Self::Polkadot(client) => client.storage_keys(id, key_prefix),
Self::Westend(client) => client.storage_keys(id, key_prefix),
Self::Kusama(client) => client.storage_keys(id, key_prefix),
}
}
fn storage_hash(
&self,
id: &BlockId<Block>,
key: &StorageKey,
) -> sp_blockchain::Result<Option<<Block as BlockT>::Hash>> {
match self {
Self::Polkadot(client) => client.storage_hash(id, key),
Self::Westend(client) => client.storage_hash(id, key),
Self::Kusama(client) => client.storage_hash(id, key),
}
}
fn storage_pairs(
&self,
id: &BlockId<Block>,
key_prefix: &StorageKey,
) -> sp_blockchain::Result<Vec<(StorageKey, StorageData)>> {
match self {
Self::Polkadot(client) => client.storage_pairs(id, key_prefix),
Self::Westend(client) => client.storage_pairs(id, key_prefix),
Self::Kusama(client) => client.storage_pairs(id, key_prefix),
}
}
fn storage_keys_iter<'a>(
&self,
id: &BlockId<Block>,
prefix: Option<&'a StorageKey>,
start_key: Option<&StorageKey>,
) -> sp_blockchain::Result<KeyIterator<'a, <crate::FullBackend as sc_client_api::Backend<Block>>::State, Block>> {
match self {
Self::Polkadot(client) => client.storage_keys_iter(id, prefix, start_key),
Self::Westend(client) => client.storage_keys_iter(id, prefix, start_key),
Self::Kusama(client) => client.storage_keys_iter(id, prefix, start_key),
}
}
fn child_storage(
&self,
id: &BlockId<Block>,
child_info: &ChildInfo,
key: &StorageKey,
) -> sp_blockchain::Result<Option<StorageData>> {
match self {
Self::Polkadot(client) => client.child_storage(id, child_info, key),
Self::Westend(client) => client.child_storage(id, child_info, key),
Self::Kusama(client) => client.child_storage(id, child_info, key),
}
}
fn child_storage_keys(
&self,
id: &BlockId<Block>,
child_info: &ChildInfo,
key_prefix: &StorageKey,
) -> sp_blockchain::Result<Vec<StorageKey>> {
match self {
Self::Polkadot(client) => client.child_storage_keys(id, child_info, key_prefix),
Self::Westend(client) => client.child_storage_keys(id, child_info, key_prefix),
Self::Kusama(client) => client.child_storage_keys(id, child_info, key_prefix),
}
}
fn child_storage_hash(
&self,
id: &BlockId<Block>,
child_info: &ChildInfo,
key: &StorageKey,
) -> sp_blockchain::Result<Option<<Block as BlockT>::Hash>> {
match self {
Self::Polkadot(client) => client.child_storage_hash(id, child_info, key),
Self::Westend(client) => client.child_storage_hash(id, child_info, key),
Self::Kusama(client) => client.child_storage_hash(id, child_info, key),
}
}
fn max_key_changes_range(
&self,
first: NumberFor<Block>,
last: BlockId<Block>,
) -> sp_blockchain::Result<Option<(NumberFor<Block>, BlockId<Block>)>> {
match self {
Self::Polkadot(client) => client.max_key_changes_range(first, last),
Self::Westend(client) => client.max_key_changes_range(first, last),
Self::Kusama(client) => client.max_key_changes_range(first, last),
}
}
fn key_changes(
&self,
first: NumberFor<Block>,
last: BlockId<Block>,
storage_key: Option<&PrefixedStorageKey>,
key: &StorageKey,
) -> sp_blockchain::Result<Vec<(NumberFor<Block>, u32)>> {
match self {
Self::Polkadot(client) => client.key_changes(first, last, storage_key, key),
Self::Westend(client) => client.key_changes(first, last, storage_key, key),
Self::Kusama(client) => client.key_changes(first, last, storage_key, key),
}
}
}
impl sp_blockchain::HeaderBackend<Block> for Client {
fn header(&self, id: BlockId<Block>) -> sp_blockchain::Result<Option<<Block as BlockT>::Header>> {
match self {
Self::Polkadot(client) => client.header(&id),
Self::Westend(client) => client.header(&id),
Self::Kusama(client) => client.header(&id),
}
}
fn info(&self) -> sp_blockchain::Info<Block> {
match self {
Self::Polkadot(client) => client.info(),
Self::Westend(client) => client.info(),
Self::Kusama(client) => client.info(),
}
}
fn status(&self, id: BlockId<Block>) -> sp_blockchain::Result<sp_blockchain::BlockStatus> {
match self {
Self::Polkadot(client) => client.status(id),
Self::Westend(client) => client.status(id),
Self::Kusama(client) => client.status(id),
}
}
fn number(
&self,
hash: <Block as BlockT>::Hash
) -> sp_blockchain::Result<Option<NumberFor<Block>>> {
match self {
Self::Polkadot(client) => client.number(hash),
Self::Westend(client) => client.number(hash),
Self::Kusama(client) => client.number(hash),
}
}
fn hash(&self, number: NumberFor<Block>) -> sp_blockchain::Result<Option<<Block as BlockT>::Hash>> {
match self {
Self::Polkadot(client) => client.hash(number),
Self::Westend(client) => client.hash(number),
Self::Kusama(client) => client.hash(number),
}
}
}
-367
View File
@@ -1,367 +0,0 @@
// 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::v0::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 struct PauseAfterBlockFor<N>(pub N, pub 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::v0::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();
let mut base = 0;
move |n| {
for i in 0..n {
let mut builder = client.new_block(Default::default()).unwrap();
for extrinsic in polkadot_test_runtime_client::needed_extrinsics(base + i) {
builder.push(extrinsic).unwrap()
}
let block = builder.build().unwrap().block;
client.import(BlockOrigin::Own, block).unwrap();
}
base += n;
}
};
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,
);
}
}
-771
View File
@@ -1,771 +0,0 @@
// 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;
pub mod grandpa_support;
mod client;
use std::sync::Arc;
use std::time::Duration;
use polkadot_primitives::v0 as parachain;
use service::error::Error as ServiceError;
use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
use sc_executor::native_executor_instance;
use log::info;
use sp_trie::PrefixedMemoryDB;
use sc_client_api::ExecutorProvider;
use prometheus_endpoint::Registry;
pub use service::{
Role, PruningMode, TransactionPoolOptions, Error, RuntimeGenesis, RpcHandlers,
TFullClient, TLightClient, TFullBackend, TLightBackend, TFullCallExecutor, TLightCallExecutor,
Configuration, ChainSpec, TaskManager,
};
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::{Core as CoreApi, ConstructRuntimeApi, ProvideRuntimeApi, StateBackend};
pub use sp_runtime::traits::{HashFor, NumberFor};
pub use consensus_common::{SelectChain, BlockImport, block_validation::Chain};
pub use polkadot_primitives::v0::{Block, CollatorId, ParachainHost};
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 consensus::run_validation_worker;
pub use codec::Codec;
pub use polkadot_runtime;
pub use kusama_runtime;
pub use westend_runtime;
pub use self::client::*;
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,
);
/// 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")
}
}
/// Polkadot's full backend.
pub type FullBackend = service::TFullBackend<Block>;
/// Polkadot's select chain.
pub type FullSelectChain = sc_consensus::LongestChain<FullBackend, Block>;
/// Polkadot's full client.
pub type FullClient<RuntimeApi, Executor> = service::TFullClient<Block, RuntimeApi, Executor>;
/// Polkadot's full Grandpa block import.
pub type FullGrandpaBlockImport<RuntimeApi, Executor> = grandpa::GrandpaBlockImport<
FullBackend, Block, FullClient<RuntimeApi, Executor>, FullSelectChain
>;
/// Polkadot's light backend.
pub type LightBackend = service::TLightBackendWithHash<Block, sp_runtime::traits::BlakeTwo256>;
/// Polkadot's light client.
pub type LightClient<RuntimeApi, Executor> =
service::TLightClientWithBackend<Block, RuntimeApi, Executor, LightBackend>;
#[cfg(feature = "full-node")]
pub fn new_partial<RuntimeApi, Executor>(config: &mut Configuration, test: bool) -> Result<
service::PartialComponents<
FullClient<RuntimeApi, Executor>, FullBackend, FullSelectChain,
consensus_common::DefaultImportQueue<Block, FullClient<RuntimeApi, Executor>>,
sc_transaction_pool::FullPool<Block, FullClient<RuntimeApi, Executor>>,
(
impl Fn(
polkadot_rpc::DenyUnsafe,
polkadot_rpc::SubscriptionTaskExecutor,
) -> polkadot_rpc::RpcExtension,
(
babe::BabeBlockImport<
Block, FullClient<RuntimeApi, Executor>, FullGrandpaBlockImport<RuntimeApi, Executor>
>,
grandpa::LinkHalf<Block, FullClient<RuntimeApi, Executor>, FullSelectChain>,
babe::BabeLink<Block>
),
(
grandpa::SharedVoterState,
Arc<GrandpaFinalityProofProvider<FullBackend, Block>>,
),
)
>,
Error
>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, Executor>> + Send + Sync + 'static,
RuntimeApi::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
Executor: NativeExecutionDispatch + 'static,
{
if !test {
// If we're using prometheus, use a registry with a prefix of `polkadot`.
if let Some(PrometheusConfig { registry, .. }) = config.prometheus_config.as_mut() {
*registry = Registry::new_custom(Some("polkadot".into()), None)?;
}
}
let inherent_data_providers = inherents::InherentDataProviders::new();
let (client, backend, keystore, task_manager) =
service::new_full_parts::<Block, RuntimeApi, Executor>(&config)?;
let client = Arc::new(client);
let select_chain = sc_consensus::LongestChain::new(backend.clone());
let transaction_pool = sc_transaction_pool::BasicPool::new_full(
config.transaction_pool.clone(),
config.prometheus_registry(),
task_manager.spawn_handle(),
client.clone(),
);
let grandpa_hard_forks = if config.chain_spec.is_kusama() && !test {
crate::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.clone(),
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.clone(),
select_chain.clone(),
inherent_data_providers.clone(),
&task_manager.spawn_handle(),
config.prometheus_registry(),
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone()),
)?;
let justification_stream = grandpa_link.justification_stream();
let shared_authority_set = grandpa_link.shared_authority_set().clone();
let shared_voter_state = grandpa::SharedVoterState::empty();
let finality_proof_provider =
GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());
let import_setup = (block_import.clone(), grandpa_link, babe_link.clone());
let rpc_setup = (shared_voter_state.clone(), finality_proof_provider.clone());
let babe_config = babe_link.config().clone();
let shared_epoch_changes = babe_link.epoch_changes().clone();
let rpc_extensions_builder = {
let client = client.clone();
let keystore = keystore.clone();
let transaction_pool = transaction_pool.clone();
let select_chain = select_chain.clone();
move |deny_unsafe, subscription_executor| -> polkadot_rpc::RpcExtension {
let deps = polkadot_rpc::FullDeps {
client: client.clone(),
pool: transaction_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(),
justification_stream: justification_stream.clone(),
subscription_executor,
finality_provider: finality_proof_provider.clone(),
},
};
polkadot_rpc::create_full(deps)
}
};
Ok(service::PartialComponents {
client, backend, task_manager, keystore, select_chain, import_queue, transaction_pool,
inherent_data_providers,
other: (rpc_extensions_builder, import_setup, rpc_setup)
})
}
#[cfg(feature = "full-node")]
pub struct NewFull<C> {
pub task_manager: TaskManager,
pub client: C,
pub node_handles: FullNodeHandles,
pub network: Arc<sc_network::NetworkService<Block, <Block as BlockT>::Hash>>,
pub network_status_sinks: service::NetworkStatusSinks<Block>,
pub rpc_handlers: RpcHandlers,
}
#[cfg(feature = "full-node")]
impl<C> NewFull<C> {
fn with_client(self, func: impl FnOnce(C) -> Client) -> NewFull<Client> {
NewFull {
client: func(self.client),
task_manager: self.task_manager,
node_handles: self.node_handles,
network: self.network,
network_status_sinks: self.network_status_sinks,
rpc_handlers: self.rpc_handlers,
}
}
}
#[cfg(feature = "full-node")]
pub fn new_full<RuntimeApi, Executor>(
mut config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>,
authority_discovery_enabled: bool,
grandpa_pause: Option<(u32, u32)>,
test: bool,
) -> Result<NewFull<Arc<FullClient<RuntimeApi, Executor>>>, Error>
where
RuntimeApi: ConstructRuntimeApi<Block, FullClient<RuntimeApi, Executor>> + Send + Sync + 'static,
RuntimeApi::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<FullBackend, Block>>,
Executor: NativeExecutionDispatch + 'static,
{
use sc_network::Event;
use futures::stream::StreamExt;
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 service::PartialComponents {
client, backend, mut task_manager, keystore, select_chain, import_queue, transaction_pool,
inherent_data_providers,
other: (rpc_extensions_builder, import_setup, rpc_setup)
} = new_partial::<RuntimeApi, Executor>(&mut config, test)?;
let prometheus_registry = config.prometheus_registry().cloned();
let (shared_voter_state, finality_proof_provider) = rpc_setup;
let (network, network_status_sinks, system_rpc_tx, network_starter) =
service::build_network(service::BuildNetworkParams {
config: &config,
client: client.clone(),
transaction_pool: transaction_pool.clone(),
spawn_handle: task_manager.spawn_handle(),
import_queue,
on_demand: None,
block_announce_validator_builder: None,
finality_proof_request_builder: None,
finality_proof_provider: Some(finality_proof_provider.clone()),
})?;
if config.offchain_worker.enabled {
service::build_offchain_workers(
&config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(),
);
}
let telemetry_connection_sinks = service::TelemetryConnectionSinks::default();
let rpc_handlers = service::spawn_tasks(service::SpawnTasksParams {
config,
backend: backend.clone(),
client: client.clone(),
keystore: keystore.clone(),
network: network.clone(),
rpc_extensions_builder: Box::new(rpc_extensions_builder),
transaction_pool: transaction_pool.clone(),
task_manager: &mut task_manager,
on_demand: None,
remote_blockchain: None,
telemetry_connection_sinks: telemetry_connection_sinks.clone(),
network_status_sinks: network_status_sinks.clone(),
system_rpc_tx,
})?;
let (block_import, link_half, babe_link) = import_setup;
if role.is_authority() {
let proposer = consensus::ProposerFactory::new(
client.clone(),
transaction_pool,
prometheus_registry.as_ref(),
);
let can_author_with =
consensus_common::CanAuthorWithNativeVersion::new(client.executor().clone());
let babe_config = babe::BabeParams {
keystore: keystore.clone(),
client: client.clone(),
select_chain,
block_import,
env: proposer,
sync_oracle: network.clone(),
inherent_data_providers: inherent_data_providers.clone(),
force_authoring,
babe_link,
can_author_with,
};
let babe = babe::start_babe(babe_config)?;
task_manager.spawn_essential_handle().spawn_blocking("babe", babe);
}
if matches!(role, Role::Authority{..} | Role::Sentry{..}) {
if authority_discovery_enabled {
let (sentries, authority_discovery_role) = match role {
Role::Authority { ref sentry_nodes } => (
sentry_nodes.clone(),
authority_discovery::Role::Authority (
keystore.clone(),
),
),
Role::Sentry {..} => (
vec![],
authority_discovery::Role::Sentry,
),
_ => unreachable!("Due to outer matches! constraint; qed."),
};
let network_event_stream = network.event_stream("authority-discovery");
let dht_event_stream = network_event_stream.filter_map(|e| async move { match e {
Event::Dht(e) => Some(e),
_ => None,
}}).boxed();
let (authority_discovery_worker, _service) = authority_discovery::new_worker_and_service(
client.clone(),
network.clone(),
sentries,
dht_event_stream,
authority_discovery_role,
prometheus_registry.clone(),
);
task_manager.spawn_handle().spawn("authority-discovery-worker", authority_discovery_worker);
}
}
// 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(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(crate::grandpa_support::PauseAfterBlockFor(block, delay))
.build()
},
None =>
grandpa::VotingRulesBuilder::default()
.build(),
};
let grandpa_config = grandpa::GrandpaParams {
config,
link: link_half,
network: network.clone(),
inherent_data_providers: inherent_data_providers.clone(),
telemetry_on_connect: Some(telemetry_connection_sinks.on_connect_stream()),
voting_rule,
prometheus_registry: prometheus_registry.clone(),
shared_voter_state,
};
task_manager.spawn_essential_handle().spawn_blocking(
"grandpa-voter",
grandpa::run_grandpa_voter(grandpa_config)?
);
} else {
grandpa::setup_disabled_grandpa(
client.clone(),
&inherent_data_providers,
network.clone(),
)?;
}
network_starter.start_network();
Ok(NewFull {
task_manager, client, node_handles: FullNodeHandles, network, network_status_sinks,
rpc_handlers,
})
}
#[cfg(feature = "full-node")]
pub fn new_full_nongeneric(
config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>,
authority_discovery_enabled: bool,
grandpa_pause: Option<(u32, u32)>,
test: bool,
) -> Result<NewFull<Client>, Error> {
if config.chain_spec.is_kusama() {
new_full::<kusama_runtime::RuntimeApi, KusamaExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
test,
).map(|full| full.with_client(Client::Kusama))
} else if config.chain_spec.is_westend() {
new_full::<westend_runtime::RuntimeApi, WestendExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
false,
).map(|full| full.with_client(Client::Westend))
} else {
new_full::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
false,
).map(|full| full.with_client(Client::Polkadot))
}
}
/// Builds a new service for a light client.
fn new_light<Runtime, Dispatch>(mut config: Configuration) -> Result<(TaskManager, RpcHandlers), Error>
where
Runtime: 'static + Send + Sync + ConstructRuntimeApi<Block, LightClient<Runtime, Dispatch>>,
<Runtime as ConstructRuntimeApi<Block, LightClient<Runtime, Dispatch>>>::RuntimeApi:
RuntimeApiCollection<StateBackend = sc_client_api::StateBackendFor<LightBackend, Block>>,
Dispatch: NativeExecutionDispatch + 'static,
{
use sc_client_api::backend::RemoteBackend;
// If we're using prometheus, use a registry with a prefix of `polkadot`.
if let Some(PrometheusConfig { registry, .. }) = config.prometheus_config.as_mut() {
*registry = Registry::new_custom(Some("polkadot".into()), None)?;
}
let (client, backend, keystore, mut task_manager, on_demand) =
service::new_light_parts::<Block, Runtime, Dispatch>(&config)?;
let select_chain = sc_consensus::LongestChain::new(backend.clone());
let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light(
config.transaction_pool.clone(),
config.prometheus_registry(),
task_manager.spawn_handle(),
client.clone(),
on_demand.clone(),
));
let grandpa_block_import = grandpa::light_block_import(
client.clone(), backend.clone(), &(client.clone() as Arc<_>),
Arc::new(on_demand.checker().clone()),
)?;
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(),
)?;
let inherent_data_providers = inherents::InherentDataProviders::new();
// 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.clone(),
select_chain.clone(),
inherent_data_providers.clone(),
&task_manager.spawn_handle(),
config.prometheus_registry(),
consensus_common::NeverCanAuthor,
)?;
let finality_proof_provider =
GrandpaFinalityProofProvider::new_for_service(backend.clone(), client.clone());
let (network, network_status_sinks, system_rpc_tx, network_starter) =
service::build_network(service::BuildNetworkParams {
config: &config,
client: client.clone(),
transaction_pool: transaction_pool.clone(),
spawn_handle: task_manager.spawn_handle(),
import_queue,
on_demand: Some(on_demand.clone()),
block_announce_validator_builder: None,
finality_proof_request_builder: Some(finality_proof_request_builder),
finality_proof_provider: Some(finality_proof_provider),
})?;
if config.offchain_worker.enabled {
service::build_offchain_workers(
&config, backend.clone(), task_manager.spawn_handle(), client.clone(), network.clone(),
);
}
let light_deps = polkadot_rpc::LightDeps {
remote_blockchain: backend.remote_blockchain(),
fetcher: on_demand.clone(),
client: client.clone(),
pool: transaction_pool.clone(),
};
let rpc_extensions = polkadot_rpc::create_light(light_deps);
let rpc_handlers = service::spawn_tasks(service::SpawnTasksParams {
on_demand: Some(on_demand),
remote_blockchain: Some(backend.remote_blockchain()),
rpc_extensions_builder: Box::new(service::NoopRpcExtensionBuilder(rpc_extensions)),
task_manager: &mut task_manager,
telemetry_connection_sinks: service::TelemetryConnectionSinks::default(),
config, keystore, backend, transaction_pool, client, network, network_status_sinks,
system_rpc_tx,
})?;
network_starter.start_network();
Ok((task_manager, rpc_handlers))
}
/// Builds a new object suitable for chain operations.
#[cfg(feature = "full-node")]
pub fn new_chain_ops(mut config: &mut Configuration) -> Result<
(
Arc<crate::Client>,
Arc<FullBackend>,
consensus_common::import_queue::BasicQueue<Block, PrefixedMemoryDB<BlakeTwo256>>,
TaskManager,
),
ServiceError
> {
config.keystore = service::config::KeystoreConfig::InMemory;
if config.chain_spec.is_kusama() {
let service::PartialComponents { client, backend, import_queue, task_manager, .. }
= new_partial::<kusama_runtime::RuntimeApi, KusamaExecutor>(config, false)?;
Ok((Arc::new(Client::Kusama(client)), backend, import_queue, task_manager))
} else if config.chain_spec.is_westend() {
let service::PartialComponents { client, backend, import_queue, task_manager, .. }
= new_partial::<westend_runtime::RuntimeApi, WestendExecutor>(config, false)?;
Ok((Arc::new(Client::Westend(client)), backend, import_queue, task_manager))
} else {
let service::PartialComponents { client, backend, import_queue, task_manager, .. }
= new_partial::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(config, false)?;
Ok((Arc::new(Client::Polkadot(client)), backend, import_queue, task_manager))
}
}
/// Create a new Polkadot service for a full node.
#[cfg(feature = "full-node")]
pub fn polkadot_new_full(
config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>,
authority_discovery_enabled: bool,
grandpa_pause: Option<(u32, u32)>,
)
-> Result<(
TaskManager,
Arc<impl AbstractClient<Block, FullBackend>>,
FullNodeHandles,
), ServiceError>
{
let NewFull {
task_manager, client, node_handles, ..
} = new_full::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
false,
)?;
Ok((task_manager, client, node_handles))
}
/// Create a new Kusama service for a full node.
#[cfg(feature = "full-node")]
pub fn kusama_new_full(
config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>,
authority_discovery_enabled: bool,
grandpa_pause: Option<(u32, u32)>,
) -> Result<(
TaskManager,
Arc<impl AbstractClient<Block, FullBackend>>,
FullNodeHandles
), ServiceError>
{
let NewFull {
task_manager, client, node_handles, ..
} = new_full::<kusama_runtime::RuntimeApi, KusamaExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
false,
)?;
Ok((task_manager, client, node_handles))
}
/// Create a new Westend service for a full node.
#[cfg(feature = "full-node")]
pub fn westend_new_full(
config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>,
authority_discovery_enabled: bool,
grandpa_pause: Option<(u32, u32)>,
)
-> Result<(
TaskManager,
Arc<impl AbstractClient<Block, FullBackend>>,
FullNodeHandles,
), ServiceError>
{
let NewFull {
task_manager, client, node_handles, ..
} = new_full::<westend_runtime::RuntimeApi, WestendExecutor>(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
false,
)?;
Ok((task_manager, client, node_handles))
}
/// Handles to other sub-services that full nodes instantiate, which consumers
/// of the node may use.
#[cfg(feature = "full-node")]
#[derive(Default)]
pub struct FullNodeHandles;
/// Build a new light node.
pub fn build_light(config: Configuration) -> Result<(TaskManager, RpcHandlers), ServiceError> {
if config.chain_spec.is_kusama() {
new_light::<kusama_runtime::RuntimeApi, KusamaExecutor>(config)
} else if config.chain_spec.is_westend() {
new_light::<westend_runtime::RuntimeApi, WestendExecutor>(config)
} else {
new_light::<polkadot_runtime::RuntimeApi, PolkadotExecutor>(config)
}
}
/// Build a new full node.
#[cfg(feature = "full-node")]
pub fn build_full(
config: Configuration,
collating_for: Option<(CollatorId, parachain::Id)>,
authority_discovery_enabled: bool,
grandpa_pause: Option<(u32, u32)>,
) -> Result<(TaskManager, Client, FullNodeHandles), ServiceError> {
new_full_nongeneric(
config,
collating_for,
authority_discovery_enabled,
grandpa_pause,
false,
).map(|NewFull { task_manager, client, node_handles, .. }| (task_manager, client, node_handles))
}