mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-26 16:57:58 +00:00
5b8ebf7baf
* Move Service::new to a macro * Move function calls to macros * Extract offchain_workers and start_rpc in separate function In follow-up commits, we want to be able to directly call maintain_transaction_pool, offchain_workers, and start_rpc, without having to implement the Components trait. This commit is a preliminary step: we extract the code to freestanding functions. * Introduce an AbstractService trait * Introduce NewService as an implementation detail of Service * Implement traits on NewService instead Instead of implementing AbstractService, Future, and Executor on Service, we implement them on NewService instead. The implementations of AbstractService, Future, and Executor on Service still exist, but they just wrap to the respective implementations for NewService. * Move components creation back to macro invocation Instead of having multiple $build_ parameters passed to the macro, let's group them all into one. This change is necessary for the follow-up commits, because we are going to call new_impl! only after all the components have already been built. * Add a $block parameter to new_impl This makes it possible to be explicit as what the generic parameter of the NewServiceis, without relying on type inference. * Introduce the ServiceBuilder struct Introduces a new builder-like ServiceBuilder struct that creates a NewService. * Macro-ify import_blocks, export_blocks and revert_chain Similar to the introduction of new_impl!, we extract the actual code into a macro, letting us get rid of the Components and Factory traits * Add export_blocks, import_blocks and revert_chain methods on ServiceBuilder Can be used as a replacement for the chain_ops::* methods * Add run_with_builder Instead of just run, adds run_with_builder to ParseAndPrepareExport/Import/Revert. This lets you run these operations with a ServiceBuilder instead of a ServiceFactory. * Transition node and node-template to ServiceBuilder * Transition transaction-factory to the new service factory This is technically a breaking change, but the transaction-factory crate is only ever used from within substrate-node, which this commit updates as well. * Remove old service factory * Adjust the AbstractService trait to be more usable We slightly change the trait bounds in order to make all the methods usable. * Make substrate-service-test compile * Fix the node-cli tests * Remove the old API * Remove the components module * Fix indentation on chain_ops * Line widths * Fix bad line widths commit * Line widths again 🤦 * Fix the sync test * Apply suggestions from code review Co-Authored-By: Gavin Wood <i@gavwood.com> * Address some concerns * Remove TelemetryOnConnect * Remove informant::start * Update jsonrpc * Rename factory to builder * Line widths 😩
405 lines
13 KiB
Rust
405 lines
13 KiB
Rust
// Copyright 2018-2019 Parity Technologies (UK) Ltd.
|
|
// This file is part of Substrate.
|
|
|
|
// Substrate 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.
|
|
|
|
// Substrate 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 Substrate. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
//! Substrate chain configurations.
|
|
|
|
use primitives::{Pair, Public, crypto::UncheckedInto};
|
|
pub use node_primitives::{AccountId, Balance};
|
|
use node_runtime::{
|
|
AuthorityDiscoveryConfig, BabeConfig, BalancesConfig, ContractsConfig, CouncilConfig, DemocracyConfig,
|
|
ElectionsConfig, GrandpaConfig, ImOnlineConfig, IndicesConfig, SessionConfig, SessionKeys, StakerStatus,
|
|
StakingConfig, SudoConfig, SystemConfig, TechnicalCommitteeConfig, WASM_BINARY,
|
|
};
|
|
use node_runtime::constants::{time::*, currency::*};
|
|
pub use node_runtime::GenesisConfig;
|
|
use substrate_service;
|
|
use hex_literal::hex;
|
|
use substrate_telemetry::TelemetryEndpoints;
|
|
use grandpa_primitives::{AuthorityId as GrandpaId};
|
|
use babe_primitives::{AuthorityId as BabeId};
|
|
use im_online::AuthorityId as ImOnlineId;
|
|
use sr_primitives::Perbill;
|
|
|
|
const STAGING_TELEMETRY_URL: &str = "wss://telemetry.polkadot.io/submit/";
|
|
|
|
/// Specialized `ChainSpec`.
|
|
pub type ChainSpec = substrate_service::ChainSpec<GenesisConfig>;
|
|
|
|
/// Flaming Fir testnet generator
|
|
pub fn flaming_fir_config() -> Result<ChainSpec, String> {
|
|
ChainSpec::from_json_bytes(&include_bytes!("../res/flaming-fir.json")[..])
|
|
}
|
|
|
|
fn session_keys(grandpa: GrandpaId, babe: BabeId, im_online: ImOnlineId) -> SessionKeys {
|
|
SessionKeys { grandpa, babe, im_online, }
|
|
}
|
|
|
|
fn staging_testnet_config_genesis() -> GenesisConfig {
|
|
// stash, controller, session-key
|
|
// generated with secret:
|
|
// for i in 1 2 3 4 ; do for j in stash controller; do subkey inspect "$secret"/fir/$j/$i; done; done
|
|
// and
|
|
// for i in 1 2 3 4 ; do for j in session; do subkey --ed25519 inspect "$secret"//fir//$j//$i; done; done
|
|
|
|
let initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)> = vec![(
|
|
// 5Fbsd6WXDGiLTxunqeK5BATNiocfCqu9bS1yArVjCgeBLkVy
|
|
hex!["9c7a2ee14e565db0c69f78c7b4cd839fbf52b607d867e9e9c5a79042898a0d12"].unchecked_into(),
|
|
// 5EnCiV7wSHeNhjW3FSUwiJNkcc2SBkPLn5Nj93FmbLtBjQUq
|
|
hex!["781ead1e2fa9ccb74b44c19d29cb2a7a4b5be3972927ae98cd3877523976a276"].unchecked_into(),
|
|
// 5Fb9ayurnxnaXj56CjmyQLBiadfRCqUbL2VWNbbe1nZU6wiC
|
|
hex!["9becad03e6dcac03cee07edebca5475314861492cdfc96a2144a67bbe9699332"].unchecked_into(),
|
|
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
|
|
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
|
|
// 5EZaeQ8djPcq9pheJUhgerXQZt9YaHnMJpiHMRhwQeinqUW8
|
|
hex!["6e7e4eb42cbd2e0ab4cae8708ce5509580b8c04d11f6758dbf686d50fe9f9106"].unchecked_into(),
|
|
),(
|
|
// 5ERawXCzCWkjVq3xz1W5KGNtVx2VdefvZ62Bw1FEuZW4Vny2
|
|
hex!["68655684472b743e456907b398d3a44c113f189e56d1bbfd55e889e295dfde78"].unchecked_into(),
|
|
// 5Gc4vr42hH1uDZc93Nayk5G7i687bAQdHHc9unLuyeawHipF
|
|
hex!["c8dc79e36b29395413399edaec3e20fcca7205fb19776ed8ddb25d6f427ec40e"].unchecked_into(),
|
|
// 5EockCXN6YkiNCDjpqqnbcqd4ad35nU4RmA1ikM4YeRN4WcE
|
|
hex!["7932cff431e748892fa48e10c63c17d30f80ca42e4de3921e641249cd7fa3c2f"].unchecked_into(),
|
|
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
|
|
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
|
|
// 5DhLtiaQd1L1LU9jaNeeu9HJkP6eyg3BwXA7iNMzKm7qqruQ
|
|
hex!["482dbd7297a39fa145c570552249c2ca9dd47e281f0c500c971b59c9dcdcd82e"].unchecked_into(),
|
|
),(
|
|
// 5DyVtKWPidondEu8iHZgi6Ffv9yrJJ1NDNLom3X9cTDi98qp
|
|
hex!["547ff0ab649283a7ae01dbc2eb73932eba2fb09075e9485ff369082a2ff38d65"].unchecked_into(),
|
|
// 5FeD54vGVNpFX3PndHPXJ2MDakc462vBCD5mgtWRnWYCpZU9
|
|
hex!["9e42241d7cd91d001773b0b616d523dd80e13c6c2cab860b1234ef1b9ffc1526"].unchecked_into(),
|
|
// 5E1jLYfLdUQKrFrtqoKgFrRvxM3oQPMbf6DfcsrugZZ5Bn8d
|
|
hex!["5633b70b80a6c8bb16270f82cca6d56b27ed7b76c8fd5af2986a25a4788ce440"].unchecked_into(),
|
|
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
|
|
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
|
|
// 5DhKqkHRkndJu8vq7pi2Q5S3DfftWJHGxbEUNH43b46qNspH
|
|
hex!["482a3389a6cf42d8ed83888cfd920fec738ea30f97e44699ada7323f08c3380a"].unchecked_into(),
|
|
),(
|
|
// 5HYZnKWe5FVZQ33ZRJK1rG3WaLMztxWrrNDb1JRwaHHVWyP9
|
|
hex!["f26cdb14b5aec7b2789fd5ca80f979cef3761897ae1f37ffb3e154cbcc1c2663"].unchecked_into(),
|
|
// 5EPQdAQ39WQNLCRjWsCk5jErsCitHiY5ZmjfWzzbXDoAoYbn
|
|
hex!["66bc1e5d275da50b72b15de072a2468a5ad414919ca9054d2695767cf650012f"].unchecked_into(),
|
|
// 5DMa31Hd5u1dwoRKgC4uvqyrdK45RHv3CpwvpUC1EzuwDit4
|
|
hex!["3919132b851ef0fd2dae42a7e734fe547af5a6b809006100f48944d7fae8e8ef"].unchecked_into(),
|
|
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
|
|
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
|
|
// 5C4vDQxA8LTck2xJEy4Yg1hM9qjDt4LvTQaMo4Y8ne43aU6x
|
|
hex!["00299981a2b92f878baaf5dbeba5c18d4e70f2a1fcd9c61b32ea18daf38f4378"].unchecked_into(),
|
|
)];
|
|
|
|
// generated with secret: subkey inspect "$secret"/fir
|
|
let endowed_accounts: Vec<AccountId> = vec![
|
|
// 5Ff3iXP75ruzroPWRP2FYBHWnmGGBSb63857BgnzCoXNxfPo
|
|
hex!["9ee5e5bdc0ec239eb164f865ecc345ce4c88e76ee002e0f7e318097347471809"].unchecked_into(),
|
|
];
|
|
|
|
const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
|
|
const STASH: Balance = 100 * DOLLARS;
|
|
|
|
GenesisConfig {
|
|
system: Some(SystemConfig {
|
|
code: WASM_BINARY.to_vec(),
|
|
changes_trie_config: Default::default(),
|
|
}),
|
|
balances: Some(BalancesConfig {
|
|
balances: endowed_accounts.iter().cloned()
|
|
.map(|k| (k, ENDOWMENT))
|
|
.chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
|
|
.collect(),
|
|
vesting: vec![],
|
|
}),
|
|
indices: Some(IndicesConfig {
|
|
ids: endowed_accounts.iter().cloned()
|
|
.chain(initial_authorities.iter().map(|x| x.0.clone()))
|
|
.collect::<Vec<_>>(),
|
|
}),
|
|
session: Some(SessionConfig {
|
|
keys: initial_authorities.iter().map(|x| {
|
|
(x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone()))
|
|
}).collect::<Vec<_>>(),
|
|
}),
|
|
staking: Some(StakingConfig {
|
|
current_era: 0,
|
|
validator_count: 7,
|
|
minimum_validator_count: 4,
|
|
stakers: initial_authorities.iter().map(|x| {
|
|
(x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)
|
|
}).collect(),
|
|
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
|
slash_reward_fraction: Perbill::from_percent(10),
|
|
.. Default::default()
|
|
}),
|
|
democracy: Some(DemocracyConfig::default()),
|
|
collective_Instance1: Some(CouncilConfig {
|
|
members: vec![],
|
|
phantom: Default::default(),
|
|
}),
|
|
collective_Instance2: Some(TechnicalCommitteeConfig {
|
|
members: vec![],
|
|
phantom: Default::default(),
|
|
}),
|
|
elections: Some(ElectionsConfig {
|
|
members: vec![],
|
|
presentation_duration: 1 * DAYS,
|
|
term_duration: 28 * DAYS,
|
|
desired_seats: 0,
|
|
}),
|
|
contracts: Some(ContractsConfig {
|
|
current_schedule: Default::default(),
|
|
gas_price: 1 * MILLICENTS,
|
|
}),
|
|
sudo: Some(SudoConfig {
|
|
key: endowed_accounts[0].clone(),
|
|
}),
|
|
babe: Some(BabeConfig {
|
|
authorities: vec![],
|
|
}),
|
|
im_online: Some(ImOnlineConfig {
|
|
keys: vec![],
|
|
}),
|
|
authority_discovery: Some(AuthorityDiscoveryConfig{
|
|
keys: vec![],
|
|
}),
|
|
grandpa: Some(GrandpaConfig {
|
|
authorities: vec![],
|
|
}),
|
|
membership_Instance1: Some(Default::default()),
|
|
}
|
|
}
|
|
|
|
/// Staging testnet config.
|
|
pub fn staging_testnet_config() -> ChainSpec {
|
|
let boot_nodes = vec![];
|
|
ChainSpec::from_genesis(
|
|
"Staging Testnet",
|
|
"staging_testnet",
|
|
staging_testnet_config_genesis,
|
|
boot_nodes,
|
|
Some(TelemetryEndpoints::new(vec![(STAGING_TELEMETRY_URL.to_string(), 0)])),
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
}
|
|
|
|
/// 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 stash, controller and session key from seed
|
|
pub fn get_authority_keys_from_seed(seed: &str) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId) {
|
|
(
|
|
get_from_seed::<AccountId>(&format!("{}//stash", seed)),
|
|
get_from_seed::<AccountId>(seed),
|
|
get_from_seed::<GrandpaId>(seed),
|
|
get_from_seed::<BabeId>(seed),
|
|
get_from_seed::<ImOnlineId>(seed),
|
|
)
|
|
}
|
|
|
|
/// Helper function to create GenesisConfig for testing
|
|
pub fn testnet_genesis(
|
|
initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)>,
|
|
root_key: AccountId,
|
|
endowed_accounts: Option<Vec<AccountId>>,
|
|
enable_println: bool,
|
|
) -> GenesisConfig {
|
|
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(|| {
|
|
vec![
|
|
get_from_seed::<AccountId>("Alice"),
|
|
get_from_seed::<AccountId>("Bob"),
|
|
get_from_seed::<AccountId>("Charlie"),
|
|
get_from_seed::<AccountId>("Dave"),
|
|
get_from_seed::<AccountId>("Eve"),
|
|
get_from_seed::<AccountId>("Ferdie"),
|
|
get_from_seed::<AccountId>("Alice//stash"),
|
|
get_from_seed::<AccountId>("Bob//stash"),
|
|
get_from_seed::<AccountId>("Charlie//stash"),
|
|
get_from_seed::<AccountId>("Dave//stash"),
|
|
get_from_seed::<AccountId>("Eve//stash"),
|
|
get_from_seed::<AccountId>("Ferdie//stash"),
|
|
]
|
|
});
|
|
|
|
const ENDOWMENT: Balance = 10_000_000 * DOLLARS;
|
|
const STASH: Balance = 100 * DOLLARS;
|
|
|
|
let desired_seats = (endowed_accounts.len() / 2 - initial_authorities.len()) as u32;
|
|
|
|
GenesisConfig {
|
|
system: Some(SystemConfig {
|
|
code: WASM_BINARY.to_vec(),
|
|
changes_trie_config: Default::default(),
|
|
}),
|
|
indices: Some(IndicesConfig {
|
|
ids: endowed_accounts.clone(),
|
|
}),
|
|
balances: Some(BalancesConfig {
|
|
balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect(),
|
|
vesting: vec![],
|
|
}),
|
|
session: Some(SessionConfig {
|
|
keys: initial_authorities.iter().map(|x| {
|
|
(x.0.clone(), session_keys(x.2.clone(), x.3.clone(), x.4.clone()))
|
|
}).collect::<Vec<_>>(),
|
|
}),
|
|
staking: Some(StakingConfig {
|
|
current_era: 0,
|
|
minimum_validator_count: 1,
|
|
validator_count: 2,
|
|
stakers: initial_authorities.iter().map(|x| {
|
|
(x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator)
|
|
}).collect(),
|
|
invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
|
|
slash_reward_fraction: Perbill::from_percent(10),
|
|
.. Default::default()
|
|
}),
|
|
democracy: Some(DemocracyConfig::default()),
|
|
collective_Instance1: Some(CouncilConfig {
|
|
members: vec![],
|
|
phantom: Default::default(),
|
|
}),
|
|
collective_Instance2: Some(TechnicalCommitteeConfig {
|
|
members: vec![],
|
|
phantom: Default::default(),
|
|
}),
|
|
elections: Some(ElectionsConfig {
|
|
members: endowed_accounts.iter()
|
|
.filter(|&endowed| initial_authorities.iter().find(|&(_, controller, ..)| controller == endowed).is_none())
|
|
.map(|a| (a.clone(), 1000000)).collect(),
|
|
presentation_duration: 10,
|
|
term_duration: 1000000,
|
|
desired_seats: desired_seats,
|
|
}),
|
|
contracts: Some(ContractsConfig {
|
|
current_schedule: contracts::Schedule {
|
|
enable_println, // this should only be enabled on development chains
|
|
..Default::default()
|
|
},
|
|
gas_price: 1 * MILLICENTS,
|
|
}),
|
|
sudo: Some(SudoConfig {
|
|
key: root_key,
|
|
}),
|
|
babe: Some(BabeConfig {
|
|
authorities: vec![],
|
|
}),
|
|
im_online: Some(ImOnlineConfig {
|
|
keys: vec![],
|
|
}),
|
|
authority_discovery: Some(AuthorityDiscoveryConfig{
|
|
keys: vec![],
|
|
}),
|
|
grandpa: Some(GrandpaConfig {
|
|
authorities: vec![],
|
|
}),
|
|
membership_Instance1: Some(Default::default()),
|
|
}
|
|
}
|
|
|
|
fn development_config_genesis() -> GenesisConfig {
|
|
testnet_genesis(
|
|
vec![
|
|
get_authority_keys_from_seed("Alice"),
|
|
],
|
|
get_from_seed::<AccountId>("Alice"),
|
|
None,
|
|
true,
|
|
)
|
|
}
|
|
|
|
/// Development config (single validator Alice)
|
|
pub fn development_config() -> ChainSpec {
|
|
ChainSpec::from_genesis("Development", "dev", development_config_genesis, vec![], None, None, None, None)
|
|
}
|
|
|
|
fn local_testnet_genesis() -> GenesisConfig {
|
|
testnet_genesis(
|
|
vec![
|
|
get_authority_keys_from_seed("Alice"),
|
|
get_authority_keys_from_seed("Bob"),
|
|
],
|
|
get_from_seed::<AccountId>("Alice"),
|
|
None,
|
|
false,
|
|
)
|
|
}
|
|
|
|
/// Local testnet config (multivalidator Alice + Bob)
|
|
pub fn local_testnet_config() -> ChainSpec {
|
|
ChainSpec::from_genesis("Local Testnet", "local_testnet", local_testnet_genesis, vec![], None, None, None, None)
|
|
}
|
|
|
|
#[cfg(test)]
|
|
pub(crate) mod tests {
|
|
use super::*;
|
|
use crate::service::{new_full, new_light};
|
|
use service_test;
|
|
|
|
fn local_testnet_genesis_instant_single() -> GenesisConfig {
|
|
testnet_genesis(
|
|
vec![
|
|
get_authority_keys_from_seed("Alice"),
|
|
],
|
|
get_from_seed::<AccountId>("Alice"),
|
|
None,
|
|
false,
|
|
)
|
|
}
|
|
|
|
/// Local testnet config (single validator - Alice)
|
|
pub fn integration_test_config_with_single_authority() -> ChainSpec {
|
|
ChainSpec::from_genesis(
|
|
"Integration Test",
|
|
"test",
|
|
local_testnet_genesis_instant_single,
|
|
vec![],
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
}
|
|
|
|
/// Local testnet config (multivalidator Alice + Bob)
|
|
pub fn integration_test_config_with_two_authorities() -> ChainSpec {
|
|
ChainSpec::from_genesis(
|
|
"Integration Test",
|
|
"test",
|
|
local_testnet_genesis,
|
|
vec![],
|
|
None,
|
|
None,
|
|
None,
|
|
None,
|
|
)
|
|
}
|
|
|
|
#[test]
|
|
#[ignore]
|
|
fn test_connectivity() {
|
|
service_test::connectivity(
|
|
integration_test_config_with_two_authorities(),
|
|
|config| new_full(config),
|
|
|config| new_light(config),
|
|
);
|
|
}
|
|
}
|