1234567891011121314151617use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};18use sc_service::ChainType;19use sp_core::{sr25519, Pair, Public};20use sp_runtime::traits::{IdentifyAccount, Verify};21use std::collections::BTreeMap;2223use serde::{Deserialize, Serialize};24use serde_json::map::Map;2526use up_common::types::opaque::*;27use up_common::constants::GENESIS_CANDIDACY_BOND;2829#[cfg(feature = "unique-runtime")]30pub use unique_runtime as default_runtime;3132#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]33pub use quartz_runtime as default_runtime;3435#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]36pub use opal_runtime as default_runtime;373839#[cfg(feature = "unique-runtime")]40pub type UniqueChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;414243#[cfg(feature = "quartz-runtime")]44pub type QuartzChainSpec = sc_service::GenericChainSpec<quartz_runtime::GenesisConfig, Extensions>;454647pub type OpalChainSpec = sc_service::GenericChainSpec<opal_runtime::GenesisConfig, Extensions>;4849#[cfg(feature = "unique-runtime")]50pub type DefaultChainSpec = UniqueChainSpec;5152#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]53pub type DefaultChainSpec = QuartzChainSpec;5455#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]56pub type DefaultChainSpec = OpalChainSpec;5758pub enum RuntimeId {59 #[cfg(feature = "unique-runtime")]60 Unique,6162 #[cfg(feature = "quartz-runtime")]63 Quartz,6465 Opal,66 Unknown(String),67}6869#[cfg(not(feature = "unique-runtime"))]7071const PARA_ID: u32 = 2095;7273#[cfg(feature = "unique-runtime")]7475const PARA_ID: u32 = 2037;7677pub trait RuntimeIdentification {78 fn runtime_id(&self) -> RuntimeId;79}8081impl RuntimeIdentification for Box<dyn sc_service::ChainSpec> {82 fn runtime_id(&self) -> RuntimeId {83 #[cfg(feature = "unique-runtime")]84 if self.id().starts_with("unique") || self.id().starts_with("unq") {85 return RuntimeId::Unique;86 }8788 #[cfg(feature = "quartz-runtime")]89 if self.id().starts_with("quartz") || self.id().starts_with("qtz") {90 return RuntimeId::Quartz;91 }9293 if self.id().starts_with("opal")94 || self.id().starts_with("sapphire")95 || self.id() == "dev"96 || self.id() == "local_testnet"97 {98 return RuntimeId::Opal;99 }100101 RuntimeId::Unknown(self.id().into())102 }103}104105pub enum ServiceId {106 Prod,107 Dev,108}109110pub trait ServiceIdentification {111 fn service_id(&self) -> ServiceId;112}113114impl ServiceIdentification for Box<dyn sc_service::ChainSpec> {115 fn service_id(&self) -> ServiceId {116 if self.id().ends_with("dev") {117 ServiceId::Dev118 } else {119 ServiceId::Prod120 }121 }122}123124125pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {126 TPublic::Pair::from_string(&format!("//{}", seed), None)127 .expect("static values are valid; qed")128 .public()129}130131132#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]133#[serde(deny_unknown_fields)]134pub struct Extensions {135 136 pub relay_chain: String,137 138 pub para_id: u32,139}140141impl Extensions {142 143 pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {144 sc_chain_spec::get_extension(chain_spec.extensions())145 }146}147148type AccountPublic = <Signature as Verify>::Signer;149150151pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId152where153 AccountPublic: From<<TPublic::Pair as Pair>::Public>,154{155 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()156}157158#[cfg(not(any(feature = "unique-runtime", feature = "quartz-runtime")))]159macro_rules! testnet_genesis {160 (161 $runtime:path,162 $root_key:expr,163 $initial_invulnerables:expr,164 $endowed_accounts:expr,165 $id:expr166 ) => {{167 use $runtime::*;168169 GenesisConfig {170 system: SystemConfig {171 code: WASM_BINARY172 .expect("WASM binary was not build, please build it!")173 .to_vec(),174 },175 balances: BalancesConfig {176 balances: $endowed_accounts177 .iter()178 .cloned()179 180 .map(|k| (k, 1 << 100))181 .collect(),182 },183 treasury: Default::default(),184 tokens: TokensConfig { balances: vec![] },185 sudo: SudoConfig {186 key: Some($root_key),187 },188 vesting: VestingConfig { vesting: vec![] },189 parachain_info: ParachainInfoConfig {190 parachain_id: $id.into(),191 },192 parachain_system: Default::default(),193 collator_selection: CollatorSelectionConfig {194 invulnerables: $initial_invulnerables195 .iter()196 .cloned()197 .map(|(acc, _)| acc)198 .collect(),199 candidacy_bond: GENESIS_CANDIDACY_BOND,200 ..Default::default()201 },202 session: SessionConfig {203 keys: $initial_invulnerables204 .into_iter()205 .map(|(acc, aura)| {206 (207 acc.clone(), 208 acc, 209 SessionKeys { aura }, 210 )211 })212 .collect(),213 },214 aura: Default::default(),215 aura_ext: Default::default(),216 evm: EVMConfig {217 accounts: BTreeMap::new(),218 },219 ethereum: EthereumConfig {},220 }221 }};222}223224#[cfg(any(feature = "unique-runtime", feature = "quartz-runtime"))]225macro_rules! testnet_genesis {226 (227 $runtime:path,228 $root_key:expr,229 $initial_invulnerables:expr,230 $endowed_accounts:expr,231 $id:expr232 ) => {{233 use $runtime::*;234235 GenesisConfig {236 system: SystemConfig {237 code: WASM_BINARY238 .expect("WASM binary was not build, please build it!")239 .to_vec(),240 },241 balances: BalancesConfig {242 balances: $endowed_accounts243 .iter()244 .cloned()245 246 .map(|k| (k, 1 << 100))247 .collect(),248 },249 treasury: Default::default(),250 tokens: TokensConfig { balances: vec![] },251 sudo: SudoConfig {252 key: Some($root_key),253 },254 vesting: VestingConfig { vesting: vec![] },255 parachain_info: ParachainInfoConfig {256 parachain_id: $id.into(),257 },258 parachain_system: Default::default(),259 aura: AuraConfig {260 authorities: $initial_invulnerables261 .into_iter()262 .map(|(_, aura)| aura)263 .collect(),264 },265 aura_ext: Default::default(),266 evm: EVMConfig {267 accounts: BTreeMap::new(),268 },269 ethereum: EthereumConfig {},270 }271 }};272}273274pub fn development_config() -> DefaultChainSpec {275 let mut properties = Map::new();276 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());277 properties.insert("tokenDecimals".into(), 18.into());278 properties.insert(279 "ss58Format".into(),280 default_runtime::SS58Prefix::get().into(),281 );282283 DefaultChainSpec::from_genesis(284 285 format!(286 "{}{}",287 default_runtime::RUNTIME_NAME.to_uppercase(),288 if cfg!(feature = "unique-runtime") {289 ""290 } else {291 " by UNIQUE"292 }293 )294 .as_str(),295 296 format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),297 ChainType::Local,298 move || {299 testnet_genesis!(300 default_runtime,301 302 get_account_id_from_seed::<sr25519::Public>("Alice"),303 vec![304 (305 get_account_id_from_seed::<sr25519::Public>("Alice"),306 get_from_seed::<AuraId>("Alice"),307 ),308 (309 get_account_id_from_seed::<sr25519::Public>("Bob"),310 get_from_seed::<AuraId>("Bob"),311 ),312 ],313 314 vec![315 get_account_id_from_seed::<sr25519::Public>("Alice"),316 get_account_id_from_seed::<sr25519::Public>("Bob"),317 get_account_id_from_seed::<sr25519::Public>("Charlie"),318 get_account_id_from_seed::<sr25519::Public>("Dave"),319 get_account_id_from_seed::<sr25519::Public>("Eve"),320 get_account_id_from_seed::<sr25519::Public>("Ferdie"),321 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),322 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),323 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),324 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),325 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),326 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),327 ],328 PARA_ID329 )330 },331 332 vec![],333 334 None,335 336 None,337 None,338 339 Some(properties),340 341 Extensions {342 relay_chain: "rococo-dev".into(),343 para_id: PARA_ID,344 },345 )346}347348pub fn local_testnet_config() -> DefaultChainSpec {349 let mut properties = Map::new();350 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());351 properties.insert("tokenDecimals".into(), 18.into());352 properties.insert(353 "ss58Format".into(),354 default_runtime::SS58Prefix::get().into(),355 );356357 DefaultChainSpec::from_genesis(358 359 format!(360 "{}{}",361 default_runtime::RUNTIME_NAME.to_uppercase(),362 if cfg!(feature = "unique-runtime") {363 ""364 } else {365 " by UNIQUE"366 }367 )368 .as_str(),369 370 format!("{}_local", default_runtime::RUNTIME_NAME).as_str(),371 ChainType::Local,372 move || {373 testnet_genesis!(374 default_runtime,375 376 get_account_id_from_seed::<sr25519::Public>("Alice"),377 vec![378 (379 get_account_id_from_seed::<sr25519::Public>("Alice"),380 get_from_seed::<AuraId>("Alice"),381 ),382 (383 get_account_id_from_seed::<sr25519::Public>("Bob"),384 get_from_seed::<AuraId>("Bob"),385 ),386 ],387 388 vec![389 get_account_id_from_seed::<sr25519::Public>("Alice"),390 get_account_id_from_seed::<sr25519::Public>("Bob"),391 get_account_id_from_seed::<sr25519::Public>("Charlie"),392 get_account_id_from_seed::<sr25519::Public>("Dave"),393 get_account_id_from_seed::<sr25519::Public>("Eve"),394 get_account_id_from_seed::<sr25519::Public>("Ferdie"),395 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),396 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),397 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),398 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),399 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),400 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),401 ],402 PARA_ID403 )404 },405 406 vec![],407 408 None,409 410 None,411 None,412 413 Some(properties),414 415 Extensions {416 relay_chain: "westend-local".into(),417 para_id: PARA_ID,418 },419 )420}