referrerpolicy=no-referrer-when-downgrade

polkadot_test_service/
chain_spec.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Polkadot.
3
4// Polkadot is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8
9// Polkadot is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12// GNU General Public License for more details.
13
14// You should have received a copy of the GNU General Public License
15// along with Polkadot.  If not, see <http://www.gnu.org/licenses/>.
16
17//! Chain specifications for the test runtime.
18
19use pallet_staking::Forcing;
20use polkadot_primitives::{
21	node_features, AccountId, AssignmentId, NodeFeatures, SchedulerParams, ValidatorId,
22	MAX_CODE_SIZE, MAX_POV_SIZE,
23};
24use polkadot_service::chain_spec::Extensions;
25use polkadot_test_runtime::BABE_GENESIS_EPOCH_CONFIG;
26use sc_chain_spec::{ChainSpec, ChainType};
27use sc_consensus_grandpa::AuthorityId as GrandpaId;
28use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
29use sp_consensus_babe::AuthorityId as BabeId;
30use sp_core::{crypto::get_public_from_string_or_panic, sr25519};
31use sp_keyring::Sr25519Keyring;
32use sp_runtime::Perbill;
33use test_runtime_constants::currency::DOTS;
34
35const DEFAULT_PROTOCOL_ID: &str = "dot";
36
37/// The `ChainSpec` parameterized for polkadot test runtime.
38pub type PolkadotChainSpec = sc_service::GenericChainSpec<Extensions>;
39
40/// Returns the properties for the [`PolkadotChainSpec`].
41pub fn polkadot_chain_spec_properties() -> serde_json::map::Map<String, serde_json::Value> {
42	serde_json::json!({
43		"tokenDecimals": 10,
44	})
45	.as_object()
46	.expect("Map given; qed")
47	.clone()
48}
49
50/// Local testnet config (multivalidator Alice + Bob)
51pub fn polkadot_local_testnet_config() -> PolkadotChainSpec {
52	PolkadotChainSpec::builder(
53		polkadot_test_runtime::WASM_BINARY.expect("Wasm binary must be built for testing"),
54		Default::default(),
55	)
56	.with_name("Local Testnet")
57	.with_id("local_testnet")
58	.with_chain_type(ChainType::Local)
59	.with_genesis_config_patch(polkadot_local_testnet_genesis())
60	.with_protocol_id(DEFAULT_PROTOCOL_ID)
61	.with_properties(polkadot_chain_spec_properties())
62	.build()
63}
64
65/// Local testnet genesis config (multivalidator Alice + Bob)
66pub fn polkadot_local_testnet_genesis() -> serde_json::Value {
67	polkadot_testnet_genesis(
68		vec![get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")],
69		Sr25519Keyring::Alice.to_account_id(),
70		None,
71	)
72}
73
74/// Helper function to generate stash, controller and session key from seed
75fn get_authority_keys_from_seed(
76	seed: &str,
77) -> (AccountId, AccountId, BabeId, GrandpaId, ValidatorId, AssignmentId, AuthorityDiscoveryId) {
78	(
79		get_public_from_string_or_panic::<sr25519::Public>(&format!("{}//stash", seed)).into(),
80		get_public_from_string_or_panic::<sr25519::Public>(seed).into(),
81		get_public_from_string_or_panic::<BabeId>(seed),
82		get_public_from_string_or_panic::<GrandpaId>(seed),
83		get_public_from_string_or_panic::<ValidatorId>(seed),
84		get_public_from_string_or_panic::<AssignmentId>(seed),
85		get_public_from_string_or_panic::<AuthorityDiscoveryId>(seed),
86	)
87}
88
89fn testnet_accounts() -> Vec<AccountId> {
90	Sr25519Keyring::well_known().map(|k| k.to_account_id()).collect()
91}
92
93/// Helper function to create polkadot `RuntimeGenesisConfig` for testing
94fn polkadot_testnet_genesis(
95	initial_authorities: Vec<(
96		AccountId,
97		AccountId,
98		BabeId,
99		GrandpaId,
100		ValidatorId,
101		AssignmentId,
102		AuthorityDiscoveryId,
103	)>,
104	root_key: AccountId,
105	endowed_accounts: Option<Vec<AccountId>>,
106) -> serde_json::Value {
107	use polkadot_test_runtime as runtime;
108
109	let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
110
111	const ENDOWMENT: u128 = 1_000_000 * DOTS;
112	const STASH: u128 = 100 * DOTS;
113
114	// Prepare node features with V2 receipts
115	// and elastic scaling enabled.
116	let mut node_features = NodeFeatures::new();
117	node_features.resize(node_features::FeatureIndex::FirstUnassigned as usize + 1, false);
118
119	node_features.set(node_features::FeatureIndex::CandidateReceiptV2 as u8 as usize, true);
120	node_features.set(node_features::FeatureIndex::ElasticScalingMVP as u8 as usize, true);
121
122	serde_json::json!({
123		"balances": {
124			"balances": endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::<Vec<_>>(),
125		},
126		"session": {
127			"keys": initial_authorities
128				.iter()
129				.map(|x| {
130					(
131						x.0.clone(),
132						x.0.clone(),
133						runtime::SessionKeys {
134							babe: x.2.clone(),
135							grandpa: x.3.clone(),
136							para_validator: x.4.clone(),
137							para_assignment: x.5.clone(),
138							authority_discovery: x.6.clone(),
139						},
140					)
141				})
142				.collect::<Vec<_>>(),
143		},
144		"staking": {
145			"minimumValidatorCount": 1,
146			"validatorCount": 2,
147			"stakers": initial_authorities
148				.iter()
149				.map(|x| (x.0.clone(), x.0.clone(), STASH, runtime::StakerStatus::<AccountId>::Validator))
150				.collect::<Vec<_>>(),
151			"invulnerables": initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
152			"forceEra": Forcing::NotForcing,
153			"slashRewardFraction": Perbill::from_percent(10),
154		},
155		"babe": {
156			"epochConfig": Some(BABE_GENESIS_EPOCH_CONFIG),
157		},
158		"sudo": { "key": Some(root_key) },
159		"configuration": {
160			"config": polkadot_runtime_parachains::configuration::HostConfiguration {
161				validation_upgrade_cooldown: 10u32,
162				validation_upgrade_delay: 5,
163				code_retention_period: 1200,
164				max_code_size: MAX_CODE_SIZE,
165				max_pov_size: MAX_POV_SIZE,
166				max_head_data_size: 32 * 1024,
167				no_show_slots: 10,
168				minimum_validation_upgrade_delay: 5,
169				max_downward_message_size: 1024,
170				node_features,
171				scheduler_params: SchedulerParams {
172					group_rotation_frequency: 20,
173					paras_availability_period: 4,
174					..Default::default()
175				},
176				..Default::default()
177			},
178		}
179	})
180}
181
182/// Can be called for a `Configuration` to check if it is a configuration for the `Test` network.
183pub trait IdentifyVariant {
184	/// Returns if this is a configuration for the `Test` network.
185	fn is_test(&self) -> bool;
186}
187
188impl IdentifyVariant for Box<dyn ChainSpec> {
189	fn is_test(&self) -> bool {
190		self.id().starts_with("test")
191	}
192}