1use 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
37pub type PolkadotChainSpec = sc_service::GenericChainSpec<Extensions>;
39
40pub 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
50pub 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
65pub 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
74fn 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
93fn 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 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
182pub trait IdentifyVariant {
184 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}