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