mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 20:27:58 +00:00
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:
committed by
GitHub
parent
796de5f3e3
commit
96f2615582
Generated
+4
-60
@@ -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
@@ -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]
|
||||
|
||||
@@ -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" ]
|
||||
|
||||
@@ -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
@@ -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
@@ -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")]
|
||||
|
||||
@@ -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" }
|
||||
|
||||
@@ -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
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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())),
|
||||
);
|
||||
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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`
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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"]
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
= Polkadot Service
|
||||
|
||||
placeholder
|
||||
//TODO Write content :) (https://github.com/paritytech/polkadot/issues/159)
|
||||
@@ -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(),
|
||||
))
|
||||
}
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -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))
|
||||
}
|
||||
Reference in New Issue
Block a user