1use crate::{
20 BabeConfig, BalancesConfig, ConfigurationConfig, RegistrarConfig, RuntimeGenesisConfig,
21 SessionConfig, SessionKeys, StakingConfig, SudoConfig, BABE_GENESIS_EPOCH_CONFIG,
22};
23#[cfg(not(feature = "std"))]
24use alloc::format;
25use alloc::{vec, vec::Vec};
26use frame_support::build_struct_json_patch;
27use pallet_staking::{Forcing, StakerStatus};
28use polkadot_primitives::{AccountId, AssignmentId, SchedulerParams, ValidatorId};
29use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
30use sp_consensus_babe::AuthorityId as BabeId;
31use sp_consensus_beefy::ecdsa_crypto::AuthorityId as BeefyId;
32use sp_consensus_grandpa::AuthorityId as GrandpaId;
33use sp_core::{crypto::get_public_from_string_or_panic, sr25519};
34use sp_genesis_builder::PresetId;
35use sp_keyring::Sr25519Keyring;
36use sp_runtime::Perbill;
37use westend_runtime_constants::currency::UNITS as WND;
38
39fn get_authority_keys_from_seed(
41 seed: &str,
42) -> (
43 AccountId,
44 AccountId,
45 BabeId,
46 GrandpaId,
47 ValidatorId,
48 AssignmentId,
49 AuthorityDiscoveryId,
50 BeefyId,
51) {
52 let keys = get_authority_keys_from_seed_no_beefy(seed);
53 (
54 keys.0,
55 keys.1,
56 keys.2,
57 keys.3,
58 keys.4,
59 keys.5,
60 keys.6,
61 get_public_from_string_or_panic::<BeefyId>(seed),
62 )
63}
64
65fn get_authority_keys_from_seed_no_beefy(
67 seed: &str,
68) -> (AccountId, AccountId, BabeId, GrandpaId, ValidatorId, AssignmentId, AuthorityDiscoveryId) {
69 (
70 get_public_from_string_or_panic::<sr25519::Public>(&format!("{}//stash", seed)).into(),
71 get_public_from_string_or_panic::<sr25519::Public>(seed).into(),
72 get_public_from_string_or_panic::<BabeId>(seed),
73 get_public_from_string_or_panic::<GrandpaId>(seed),
74 get_public_from_string_or_panic::<ValidatorId>(seed),
75 get_public_from_string_or_panic::<AssignmentId>(seed),
76 get_public_from_string_or_panic::<AuthorityDiscoveryId>(seed),
77 )
78}
79
80fn testnet_accounts() -> Vec<AccountId> {
81 Sr25519Keyring::well_known().map(|k| k.to_account_id()).collect()
82}
83
84fn westend_session_keys(
85 babe: BabeId,
86 grandpa: GrandpaId,
87 para_validator: ValidatorId,
88 para_assignment: AssignmentId,
89 authority_discovery: AuthorityDiscoveryId,
90 beefy: BeefyId,
91) -> SessionKeys {
92 SessionKeys { babe, grandpa, para_validator, para_assignment, authority_discovery, beefy }
93}
94
95fn default_parachains_host_configuration(
96) -> polkadot_runtime_parachains::configuration::HostConfiguration<polkadot_primitives::BlockNumber>
97{
98 use polkadot_primitives::{
99 node_features::FeatureIndex, ApprovalVotingParams, AsyncBackingParams, MAX_CODE_SIZE,
100 MAX_POV_SIZE,
101 };
102
103 polkadot_runtime_parachains::configuration::HostConfiguration {
104 validation_upgrade_cooldown: 2u32,
105 validation_upgrade_delay: 2,
106 code_retention_period: 1200,
107 max_code_size: MAX_CODE_SIZE,
108 max_pov_size: MAX_POV_SIZE,
109 max_head_data_size: 32 * 1024,
110 max_upward_queue_count: 8,
111 max_upward_queue_size: 1024 * 1024,
112 max_downward_message_size: 1024 * 1024,
113 max_upward_message_size: 50 * 1024,
114 max_upward_message_num_per_candidate: 5,
115 hrmp_sender_deposit: 0,
116 hrmp_recipient_deposit: 0,
117 hrmp_channel_max_capacity: 8,
118 hrmp_channel_max_total_size: 8 * 1024,
119 hrmp_max_parachain_inbound_channels: 4,
120 hrmp_channel_max_message_size: 1024 * 1024,
121 hrmp_max_parachain_outbound_channels: 4,
122 hrmp_max_message_num_per_candidate: 5,
123 dispute_period: 6,
124 no_show_slots: 2,
125 n_delay_tranches: 25,
126 needed_approvals: 2,
127 relay_vrf_modulo_samples: 2,
128 zeroth_delay_tranche_width: 0,
129 minimum_validation_upgrade_delay: 5,
130 async_backing_params: AsyncBackingParams {
131 max_candidate_depth: 0,
132 allowed_ancestry_len: 0,
133 },
134 node_features: bitvec::vec::BitVec::from_element(
135 (1u8 << (FeatureIndex::ElasticScalingMVP as usize)) |
136 (1u8 << (FeatureIndex::EnableAssignmentsV2 as usize)) |
137 (1u8 << (FeatureIndex::CandidateReceiptV2 as usize)),
138 ),
139 scheduler_params: SchedulerParams {
140 lookahead: 3,
141 group_rotation_frequency: 20,
142 paras_availability_period: 4,
143 ..Default::default()
144 },
145 approval_voting_params: ApprovalVotingParams { max_approval_coalesce_count: 5 },
146 ..Default::default()
147 }
148}
149
150#[test]
151fn default_parachains_host_configuration_is_consistent() {
152 default_parachains_host_configuration().panic_if_not_consistent();
153}
154
155fn westend_testnet_genesis(
157 initial_authorities: Vec<(
158 AccountId,
159 AccountId,
160 BabeId,
161 GrandpaId,
162 ValidatorId,
163 AssignmentId,
164 AuthorityDiscoveryId,
165 BeefyId,
166 )>,
167 root_key: AccountId,
168 endowed_accounts: Option<Vec<AccountId>>,
169) -> serde_json::Value {
170 let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(testnet_accounts);
171
172 const ENDOWMENT: u128 = 1_000_000 * WND;
173 const STASH: u128 = 100 * WND;
174
175 build_struct_json_patch!(RuntimeGenesisConfig {
176 balances: BalancesConfig {
177 balances: endowed_accounts.iter().map(|k| (k.clone(), ENDOWMENT)).collect::<Vec<_>>(),
178 },
179 session: SessionConfig {
180 keys: initial_authorities
181 .iter()
182 .map(|x| {
183 (
184 x.0.clone(),
185 x.0.clone(),
186 westend_session_keys(
187 x.2.clone(),
188 x.3.clone(),
189 x.4.clone(),
190 x.5.clone(),
191 x.6.clone(),
192 x.7.clone(),
193 ),
194 )
195 })
196 .collect::<Vec<_>>(),
197 },
198 staking: StakingConfig {
199 minimum_validator_count: 1,
200 validator_count: initial_authorities.len() as u32,
201 stakers: initial_authorities
202 .iter()
203 .map(|x| (x.0.clone(), x.0.clone(), STASH, StakerStatus::<AccountId>::Validator))
204 .collect::<Vec<_>>(),
205 invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
206 force_era: Forcing::NotForcing,
207 slash_reward_fraction: Perbill::from_percent(10),
208 },
209 babe: BabeConfig { epoch_config: BABE_GENESIS_EPOCH_CONFIG },
210 sudo: SudoConfig { key: Some(root_key) },
211 configuration: ConfigurationConfig { config: default_parachains_host_configuration() },
212 registrar: RegistrarConfig { next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID },
213 })
214}
215
216fn westend_staging_testnet_config_genesis() -> serde_json::Value {
218 use hex_literal::hex;
219 use sp_core::crypto::UncheckedInto;
220
221 let endowed_accounts: Vec<AccountId> = vec![
227 hex!["c416837e232d9603e83162ef4bda08e61580eeefe60fe92fc044aa508559ae42"].into(),
229 ];
230 let initial_authorities: Vec<(
232 AccountId,
233 AccountId,
234 BabeId,
235 GrandpaId,
236 ValidatorId,
237 AssignmentId,
238 AuthorityDiscoveryId,
239 BeefyId,
240 )> = Vec::from([
241 (
242 hex!["7ecfd50629cdd246649959d88d490b31508db511487e111a52a392e6e458f518"].into(),
244 hex!["eca2cca09bdc66a7e6d8c3d9499a0be2ad4690061be8a9834972e17d13d2fe7e"].into(),
246 hex!["ae27367cb77850fb195fe1f9c60b73210409e68c5ad953088070f7d8513d464c"]
248 .unchecked_into(),
249 hex!["6faae44b21c6f2681a7f60df708e9f79d340f7d441d28bd987fab8d05c6487e8"]
251 .unchecked_into(),
252 hex!["a6c1a5b501985a83cb1c37630c5b41e6b0a15b3675b2fd94694758e6cfa6794d"]
254 .unchecked_into(),
255 hex!["485051748ab9c15732f19f3fbcf1fd00a6d9709635f084505107fbb059c33d2f"]
257 .unchecked_into(),
258 hex!["be59ed75a72f7b47221ce081ba4262cf2e1ea7867e30e0b3781822f942b97677"]
260 .unchecked_into(),
261 hex!["0207e43990799e1d02b0507451e342a1240ff836ea769c57297589a5fd072ad8f4"]
263 .unchecked_into(),
264 ),
265 (
266 hex!["34b7b3efd35fcc3c1926ca065381682b1af29b57dabbcd091042c6de1d541b7d"].into(),
268 hex!["4226796fa792ac78875e023ff2e30e3c2cf79f0b7b3431254cd0f14a3007bc0e"].into(),
270 hex!["0e9b60f04be3bffe362eb2212ea99d2b909b052f4bff7c714e13c2416a797f5d"]
272 .unchecked_into(),
273 hex!["98f4d81cb383898c2c3d54dab28698c0f717c81b509cb32dc6905af3cc697b18"]
275 .unchecked_into(),
276 hex!["162508accd470e379b04cb0c7c60b35a7d5357e84407a89ed2dd48db4b726960"]
278 .unchecked_into(),
279 hex!["4a559c028b69a7f784ce553393e547bec0aa530352157603396d515f9c83463b"]
281 .unchecked_into(),
282 hex!["d464908266c878acbf181bf8fda398b3aa3fd2d05508013e414aaece4cf0d702"]
284 .unchecked_into(),
285 hex!["02fdf30222d2cb88f2376d558d3de9cb83f9fde3aa4b2dd40c93e3104e3488bcd2"]
287 .unchecked_into(),
288 ),
289 (
290 hex!["56e0f73c563d49ee4a3971c393e17c44eaa313dabad7fcf297dc3271d803f303"].into(),
292 hex!["2c58e5e1d5aef77774480cead4f6876b1a1a6261170166995184d7f86140572b"].into(),
294 hex!["6ed45cb7af613be5d88a2622921e18d147225165f24538af03b93f2a03ce6e13"]
296 .unchecked_into(),
297 hex!["b0f8d2b9e4e1eafd4dab6358e0b9d5380d78af27c094e69ae9d6d30ca300fd86"]
299 .unchecked_into(),
300 hex!["1055100a283968271a0781450b389b9093231be809be1e48a305ebad2a90497e"]
302 .unchecked_into(),
303 hex!["3cea4ab74bab4adf176cf05a6e18c1599a7bc217d4c6c217275bfbe3b037a527"]
305 .unchecked_into(),
306 hex!["169faa81aebfe74533518bda28567f2e2664014c8905aa07ea003336afda5a58"]
308 .unchecked_into(),
309 hex!["03429d0d20f6ac5ca8b349f04d014f7b5b864acf382a744104d5d9a51108156c0f"]
311 .unchecked_into(),
312 ),
313 (
314 hex!["deb804ed2ed2bb696a3dd4ed7de4cd5c496528a2b204051c6ace385bacd66a3a"].into(),
316 hex!["366da6a748afedb31f07902f2de36ab265beccee37762d3ae1f237de234d9c36"].into(),
318 hex!["1089bc0cd60237d061872925e81d36c9d9205d250d5d8b542c8e08a8ecf1b911"]
320 .unchecked_into(),
321 hex!["1c309a70b4e274314b84c9a0a1f973c9c4fc084df5479ef686c54b1ae4950424"]
323 .unchecked_into(),
324 hex!["2ee4d78f328db178c54f205ac809da12e291a33bcbd4f29f081ce7e74bdc5044"]
326 .unchecked_into(),
327 hex!["d88e40e3c2c7a7c5abf96ffdd8f7b7bec8798cc277bc97e255881871ab73b529"]
329 .unchecked_into(),
330 hex!["4cb3863271b70daa38612acd5dae4f5afcb7c165fa277629e5150d2214df322a"]
332 .unchecked_into(),
333 hex!["03be5ec86d10a94db89c9b7a396d3c7742e3bec5f85159d4cf308cef505966ddf5"]
335 .unchecked_into(),
336 ),
337 ]);
338
339 const ENDOWMENT: u128 = 1_000_000 * WND;
340 const STASH: u128 = 100 * WND;
341
342 build_struct_json_patch!(RuntimeGenesisConfig {
343 balances: BalancesConfig {
344 balances: endowed_accounts
345 .iter()
346 .map(|k: &AccountId| (k.clone(), ENDOWMENT))
347 .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
348 .collect::<Vec<_>>(),
349 },
350 session: SessionConfig {
351 keys: initial_authorities
352 .iter()
353 .map(|x| {
354 (
355 x.0.clone(),
356 x.0.clone(),
357 westend_session_keys(
358 x.2.clone(),
359 x.3.clone(),
360 x.4.clone(),
361 x.5.clone(),
362 x.6.clone(),
363 x.7.clone(),
364 ),
365 )
366 })
367 .collect::<Vec<_>>(),
368 },
369 staking: StakingConfig {
370 validator_count: 50,
371 minimum_validator_count: 4,
372 stakers: initial_authorities
373 .iter()
374 .map(|x| (x.0.clone(), x.0.clone(), STASH, StakerStatus::<AccountId>::Validator))
375 .collect::<Vec<_>>(),
376 invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect::<Vec<_>>(),
377 force_era: Forcing::ForceNone,
378 slash_reward_fraction: Perbill::from_percent(10),
379 },
380 babe: BabeConfig { epoch_config: BABE_GENESIS_EPOCH_CONFIG },
381 sudo: SudoConfig { key: Some(endowed_accounts[0].clone()) },
382 configuration: ConfigurationConfig { config: default_parachains_host_configuration() },
383 registrar: RegistrarConfig { next_free_para_id: polkadot_primitives::LOWEST_PUBLIC_ID },
384 })
385}
386
387fn westend_development_config_genesis() -> serde_json::Value {
389 westend_testnet_genesis(
390 Vec::from([get_authority_keys_from_seed("Alice")]),
391 Sr25519Keyring::Alice.to_account_id(),
392 None,
393 )
394}
395
396fn westend_local_testnet_genesis() -> serde_json::Value {
398 westend_testnet_genesis(
399 Vec::from([get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Bob")]),
400 Sr25519Keyring::Alice.to_account_id(),
401 None,
402 )
403}
404
405pub fn get_preset(id: &PresetId) -> Option<Vec<u8>> {
407 let patch = match id.as_ref() {
408 sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET => westend_local_testnet_genesis(),
409 sp_genesis_builder::DEV_RUNTIME_PRESET => westend_development_config_genesis(),
410 "staging_testnet" => westend_staging_testnet_config_genesis(),
411 _ => return None,
412 };
413 Some(
414 serde_json::to_string(&patch)
415 .expect("serialization to json is expected to work. qed.")
416 .into_bytes(),
417 )
418}
419
420pub fn preset_names() -> Vec<PresetId> {
422 vec![
423 PresetId::from(sp_genesis_builder::LOCAL_TESTNET_RUNTIME_PRESET),
424 PresetId::from(sp_genesis_builder::DEV_RUNTIME_PRESET),
425 PresetId::from("staging_testnet"),
426 ]
427}