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::*;2728#[cfg(feature = "unique-runtime")]29pub use unique_runtime as default_runtime;3031#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]32pub use quartz_runtime as default_runtime;3334#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]35pub use opal_runtime as default_runtime;363738#[cfg(feature = "unique-runtime")]39pub type UniqueChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;404142#[cfg(feature = "quartz-runtime")]43pub type QuartzChainSpec = sc_service::GenericChainSpec<quartz_runtime::GenesisConfig, Extensions>;444546pub type OpalChainSpec = sc_service::GenericChainSpec<opal_runtime::GenesisConfig, Extensions>;4748#[cfg(feature = "unique-runtime")]49pub type DefaultChainSpec = UniqueChainSpec;5051#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]52pub type DefaultChainSpec = QuartzChainSpec;5354#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]55pub type DefaultChainSpec = OpalChainSpec;5657pub enum RuntimeId {58 #[cfg(feature = "unique-runtime")]59 Unique,6061 #[cfg(feature = "quartz-runtime")]62 Quartz,6364 Opal,65 Unknown(String),66}6768#[cfg(not(feature = "unique-runtime"))]6970const PARA_ID: u32 = 2095;7172#[cfg(feature = "unique-runtime")]7374const PARA_ID: u32 = 2037;7576pub trait RuntimeIdentification {77 fn runtime_id(&self) -> RuntimeId;78}7980impl RuntimeIdentification for Box<dyn sc_service::ChainSpec> {81 fn runtime_id(&self) -> RuntimeId {82 #[cfg(feature = "unique-runtime")]83 if self.id().starts_with("unique") || self.id().starts_with("unq") {84 return RuntimeId::Unique;85 }8687 #[cfg(feature = "quartz-runtime")]88 if self.id().starts_with("quartz") || self.id().starts_with("qtz") {89 return RuntimeId::Quartz;90 }9192 if self.id().starts_with("opal")93 || self.id().starts_with("sapphire")94 || self.id() == "dev"95 || self.id() == "local_testnet"96 {97 return RuntimeId::Opal;98 }99100 RuntimeId::Unknown(self.id().into())101 }102}103104pub enum ServiceId {105 Prod,106 Dev,107}108109pub trait ServiceIdentification {110 fn service_id(&self) -> ServiceId;111}112113impl ServiceIdentification for Box<dyn sc_service::ChainSpec> {114 fn service_id(&self) -> ServiceId {115 if self.id().ends_with("dev") {116 ServiceId::Dev117 } else {118 ServiceId::Prod119 }120 }121}122123124pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {125 TPublic::Pair::from_string(&format!("//{}", seed), None)126 .expect("static values are valid; qed")127 .public()128}129130131#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]132#[serde(deny_unknown_fields)]133pub struct Extensions {134 135 pub relay_chain: String,136 137 pub para_id: u32,138}139140impl Extensions {141 142 pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {143 sc_chain_spec::get_extension(chain_spec.extensions())144 }145}146147type AccountPublic = <Signature as Verify>::Signer;148149150pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId151where152 AccountPublic: From<<TPublic::Pair as Pair>::Public>,153{154 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()155}156157#[cfg(not(any(feature = "unique-runtime", feature = "quartz-runtime")))]158macro_rules! testnet_genesis {159 (160 $runtime:path,161 $root_key:expr,162 $initial_invulnerables:expr,163 $endowed_accounts:expr,164 $id:expr165 ) => {{166 use $runtime::*;167168 GenesisConfig {169 system: SystemConfig {170 code: WASM_BINARY171 .expect("WASM binary was not build, please build it!")172 .to_vec(),173 },174 balances: BalancesConfig {175 balances: $endowed_accounts176 .iter()177 .cloned()178 179 .map(|k| (k, 1 << 100))180 .collect(),181 },182 treasury: Default::default(),183 tokens: TokensConfig { balances: vec![] },184 sudo: SudoConfig {185 key: Some($root_key),186 },187 vesting: VestingConfig { vesting: vec![] },188 parachain_info: ParachainInfoConfig {189 parachain_id: $id.into(),190 },191 parachain_system: Default::default(),192 collator_selection: CollatorSelectionConfig {193 invulnerables: $initial_invulnerables194 .iter()195 .cloned()196 .map(|(acc, _)| acc)197 .collect(),198 },199 session: SessionConfig {200 keys: $initial_invulnerables201 .into_iter()202 .map(|(acc, aura)| {203 (204 acc.clone(), 205 acc, 206 SessionKeys { aura }, 207 )208 })209 .collect(),210 },211 aura: Default::default(),212 aura_ext: Default::default(),213 evm: EVMConfig {214 accounts: BTreeMap::new(),215 },216 ethereum: EthereumConfig {},217 }218 }};219}220221#[cfg(any(feature = "unique-runtime", feature = "quartz-runtime"))]222macro_rules! testnet_genesis {223 (224 $runtime:path,225 $root_key:expr,226 $initial_invulnerables:expr,227 $endowed_accounts:expr,228 $id:expr229 ) => {{230 use $runtime::*;231232 GenesisConfig {233 system: SystemConfig {234 code: WASM_BINARY235 .expect("WASM binary was not build, please build it!")236 .to_vec(),237 },238 balances: BalancesConfig {239 balances: $endowed_accounts240 .iter()241 .cloned()242 243 .map(|k| (k, 1 << 100))244 .collect(),245 },246 treasury: Default::default(),247 tokens: TokensConfig { balances: vec![] },248 sudo: SudoConfig {249 key: Some($root_key),250 },251 vesting: VestingConfig { vesting: vec![] },252 parachain_info: ParachainInfoConfig {253 parachain_id: $id.into(),254 },255 parachain_system: Default::default(),256 aura: AuraConfig {257 authorities: $initial_invulnerables258 .into_iter()259 .map(|(_, aura)| aura)260 .collect(),261 },262 aura_ext: Default::default(),263 evm: EVMConfig {264 accounts: BTreeMap::new(),265 },266 ethereum: EthereumConfig {},267 }268 }};269}270271pub fn development_config() -> DefaultChainSpec {272 let mut properties = Map::new();273 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());274 properties.insert("tokenDecimals".into(), 18.into());275 properties.insert(276 "ss58Format".into(),277 default_runtime::SS58Prefix::get().into(),278 );279280 DefaultChainSpec::from_genesis(281 282 format!(283 "{}{}",284 default_runtime::RUNTIME_NAME.to_uppercase(),285 if cfg!(feature = "unique-runtime") {286 ""287 } else {288 " by UNIQUE"289 }290 )291 .as_str(),292 293 format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),294 ChainType::Local,295 move || {296 testnet_genesis!(297 default_runtime,298 299 get_account_id_from_seed::<sr25519::Public>("Alice"),300 vec![301 (302 get_account_id_from_seed::<sr25519::Public>("Alice"),303 get_from_seed::<AuraId>("Alice"),304 ),305 (306 get_account_id_from_seed::<sr25519::Public>("Bob"),307 get_from_seed::<AuraId>("Bob"),308 ),309 ],310 311 vec![312 get_account_id_from_seed::<sr25519::Public>("Alice"),313 get_account_id_from_seed::<sr25519::Public>("Bob"),314 get_account_id_from_seed::<sr25519::Public>("Charlie"),315 get_account_id_from_seed::<sr25519::Public>("Dave"),316 get_account_id_from_seed::<sr25519::Public>("Eve"),317 get_account_id_from_seed::<sr25519::Public>("Ferdie"),318 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),319 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),320 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),321 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),322 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),323 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),324 ],325 PARA_ID326 )327 },328 329 vec![],330 331 None,332 333 None,334 None,335 336 Some(properties),337 338 Extensions {339 relay_chain: "rococo-dev".into(),340 para_id: PARA_ID,341 },342 )343}344345pub fn local_testnet_config() -> DefaultChainSpec {346 let mut properties = Map::new();347 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());348 properties.insert("tokenDecimals".into(), 18.into());349 properties.insert(350 "ss58Format".into(),351 default_runtime::SS58Prefix::get().into(),352 );353354 DefaultChainSpec::from_genesis(355 356 format!(357 "{}{}",358 default_runtime::RUNTIME_NAME.to_uppercase(),359 if cfg!(feature = "unique-runtime") {360 ""361 } else {362 " by UNIQUE"363 }364 )365 .as_str(),366 367 format!("{}_local", default_runtime::RUNTIME_NAME).as_str(),368 ChainType::Local,369 move || {370 testnet_genesis!(371 default_runtime,372 373 get_account_id_from_seed::<sr25519::Public>("Alice"),374 vec![375 (376 get_account_id_from_seed::<sr25519::Public>("Alice"),377 get_from_seed::<AuraId>("Alice"),378 ),379 (380 get_account_id_from_seed::<sr25519::Public>("Bob"),381 get_from_seed::<AuraId>("Bob"),382 ),383 ],384 385 vec![386 get_account_id_from_seed::<sr25519::Public>("Alice"),387 get_account_id_from_seed::<sr25519::Public>("Bob"),388 get_account_id_from_seed::<sr25519::Public>("Charlie"),389 get_account_id_from_seed::<sr25519::Public>("Dave"),390 get_account_id_from_seed::<sr25519::Public>("Eve"),391 get_account_id_from_seed::<sr25519::Public>("Ferdie"),392 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),393 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),394 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),395 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),396 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),397 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),398 ],399 PARA_ID400 )401 },402 403 vec![],404 405 None,406 407 None,408 None,409 410 Some(properties),411 412 Extensions {413 relay_chain: "westend-local".into(),414 para_id: PARA_ID,415 },416 )417}