// Copyright (C) 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 . //! Chain specifications for the test runtime. use babe_primitives::AuthorityId as BabeId; use grandpa::AuthorityId as GrandpaId; use pallet_staking::Forcing; use polkadot_primitives::{AccountId, AssignmentId, ValidatorId, MAX_CODE_SIZE, MAX_POV_SIZE}; use polkadot_service::chain_spec::{get_account_id_from_seed, get_from_seed, Extensions}; use polkadot_test_runtime::BABE_GENESIS_EPOCH_CONFIG; use sc_chain_spec::{ChainSpec, ChainType}; use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId; use sp_core::sr25519; use sp_runtime::Perbill; use test_runtime_constants::currency::DOTS; const DEFAULT_PROTOCOL_ID: &str = "dot"; /// The `ChainSpec` parameterized for polkadot test runtime. pub type PolkadotChainSpec = sc_service::GenericChainSpec<(), Extensions>; /// Returns the properties for the [`PolkadotChainSpec`]. pub fn polkadot_chain_spec_properties() -> serde_json::map::Map { serde_json::json!({ "tokenDecimals": 10, }) .as_object() .expect("Map given; qed") .clone() } /// Local testnet config (multivalidator Alice + Bob) pub fn polkadot_local_testnet_config() -> PolkadotChainSpec { PolkadotChainSpec::builder( polkadot_test_runtime::WASM_BINARY.expect("Wasm binary must be built for testing"), Default::default(), ) .with_name("Local Testnet") .with_id("local_testnet") .with_chain_type(ChainType::Local) .with_genesis_config_patch(polkadot_local_testnet_genesis()) .with_protocol_id(DEFAULT_PROTOCOL_ID) .with_properties(polkadot_chain_spec_properties()) .build() } /// Local testnet genesis config (multivalidator Alice + Bob) pub fn polkadot_local_testnet_genesis() -> serde_json::Value { polkadot_testnet_genesis( vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")], get_account_id_from_seed::("Alice"), None, ) } /// Helper function to generate stash, controller and session key from seed fn get_authority_keys_from_seed( seed: &str, ) -> (AccountId, AccountId, BabeId, GrandpaId, ValidatorId, AssignmentId, AuthorityDiscoveryId) { ( get_account_id_from_seed::(&format!("{}//stash", seed)), get_account_id_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), get_from_seed::(seed), ) } fn testnet_accounts() -> Vec { vec![ get_account_id_from_seed::("Alice"), get_account_id_from_seed::("Bob"), get_account_id_from_seed::("Charlie"), get_account_id_from_seed::("Dave"), get_account_id_from_seed::("Eve"), get_account_id_from_seed::("Ferdie"), get_account_id_from_seed::("Alice//stash"), get_account_id_from_seed::("Bob//stash"), get_account_id_from_seed::("Charlie//stash"), get_account_id_from_seed::("Dave//stash"), get_account_id_from_seed::("Eve//stash"), get_account_id_from_seed::("Ferdie//stash"), ] } /// Helper function to create polkadot `RuntimeGenesisConfig` for testing fn polkadot_testnet_genesis( initial_authorities: Vec<( AccountId, AccountId, BabeId, GrandpaId, ValidatorId, AssignmentId, AuthorityDiscoveryId, )>, root_key: AccountId, endowed_accounts: Option>, ) -> serde_json::Value { use polkadot_test_runtime as runtime; let endowed_accounts: Vec = endowed_accounts.unwrap_or_else(testnet_accounts); const ENDOWMENT: u128 = 1_000_000 * DOTS; const STASH: u128 = 100 * DOTS; serde_json::json!({ "balances": { "balances": endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::>(), }, "session": { "keys": initial_authorities .iter() .map(|x| { ( x.0.clone(), x.0.clone(), runtime::SessionKeys { babe: x.2.clone(), grandpa: x.3.clone(), para_validator: x.4.clone(), para_assignment: x.5.clone(), authority_discovery: x.6.clone(), }, ) }) .collect::>(), }, "staking": { "minimumValidatorCount": 1, "validatorCount": 2, "stakers": initial_authorities .iter() .map(|x| (x.0.clone(), x.0.clone(), STASH, runtime::StakerStatus::::Validator)) .collect::>(), "invulnerables": initial_authorities.iter().map(|x| x.0.clone()).collect::>(), "forceEra": Forcing::NotForcing, "slashRewardFraction": Perbill::from_percent(10), }, "babe": { "epochConfig": Some(BABE_GENESIS_EPOCH_CONFIG), }, "sudo": { "key": Some(root_key) }, "configuration": { "config": polkadot_runtime_parachains::configuration::HostConfiguration { validation_upgrade_cooldown: 10u32, validation_upgrade_delay: 5, code_retention_period: 1200, max_code_size: MAX_CODE_SIZE, max_pov_size: MAX_POV_SIZE, max_head_data_size: 32 * 1024, group_rotation_frequency: 20, paras_availability_period: 4, no_show_slots: 10, minimum_validation_upgrade_delay: 5, ..Default::default() }, } }) } /// Can be called for a `Configuration` to check if it is a configuration for the `Test` network. pub trait IdentifyVariant { /// Returns if this is a configuration for the `Test` network. fn is_test(&self) -> bool; } impl IdentifyVariant for Box { fn is_test(&self) -> bool { self.id().starts_with("test") } }