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_LICENSE_BOND, SESSION_LENGTH};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 desired_collators: 10,200 license_bond: GENESIS_LICENSE_BOND,201 kick_threshold: SESSION_LENGTH,202 },203 session: SessionConfig {204 keys: $initial_invulnerables205 .into_iter()206 .map(|(acc, aura)| {207 (208 acc.clone(), 209 acc, 210 SessionKeys { aura }, 211 )212 })213 .collect(),214 },215 aura: Default::default(),216 aura_ext: Default::default(),217 evm: EVMConfig {218 accounts: BTreeMap::new(),219 },220 ethereum: EthereumConfig {},221 }222 }};223}224225#[cfg(any(feature = "unique-runtime", feature = "quartz-runtime"))]226macro_rules! testnet_genesis {227 (228 $runtime:path,229 $root_key:expr,230 $initial_invulnerables:expr,231 $endowed_accounts:expr,232 $id:expr233 ) => {{234 use $runtime::*;235236 GenesisConfig {237 system: SystemConfig {238 code: WASM_BINARY239 .expect("WASM binary was not build, please build it!")240 .to_vec(),241 },242 balances: BalancesConfig {243 balances: $endowed_accounts244 .iter()245 .cloned()246 247 .map(|k| (k, 1 << 100))248 .collect(),249 },250 treasury: Default::default(),251 tokens: TokensConfig { balances: vec![] },252 sudo: SudoConfig {253 key: Some($root_key),254 },255 vesting: VestingConfig { vesting: vec![] },256 parachain_info: ParachainInfoConfig {257 parachain_id: $id.into(),258 },259 parachain_system: Default::default(),260 aura: AuraConfig {261 authorities: $initial_invulnerables262 .into_iter()263 .map(|(_, aura)| aura)264 .collect(),265 },266 aura_ext: Default::default(),267 evm: EVMConfig {268 accounts: BTreeMap::new(),269 },270 ethereum: EthereumConfig {},271 }272 }};273}274275pub fn development_config() -> DefaultChainSpec {276 let mut properties = Map::new();277 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());278 properties.insert("tokenDecimals".into(), 18.into());279 properties.insert(280 "ss58Format".into(),281 default_runtime::SS58Prefix::get().into(),282 );283284 DefaultChainSpec::from_genesis(285 286 format!(287 "{}{}",288 default_runtime::RUNTIME_NAME.to_uppercase(),289 if cfg!(feature = "unique-runtime") {290 ""291 } else {292 " by UNIQUE"293 }294 )295 .as_str(),296 297 format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),298 ChainType::Local,299 move || {300 testnet_genesis!(301 default_runtime,302 303 get_account_id_from_seed::<sr25519::Public>("Alice"),304 vec![305 (306 get_account_id_from_seed::<sr25519::Public>("Alice"),307 get_from_seed::<AuraId>("Alice"),308 ),309 (310 get_account_id_from_seed::<sr25519::Public>("Bob"),311 get_from_seed::<AuraId>("Bob"),312 ),313 ],314 315 vec![316 get_account_id_from_seed::<sr25519::Public>("Alice"),317 get_account_id_from_seed::<sr25519::Public>("Bob"),318 get_account_id_from_seed::<sr25519::Public>("Charlie"),319 get_account_id_from_seed::<sr25519::Public>("Dave"),320 get_account_id_from_seed::<sr25519::Public>("Eve"),321 get_account_id_from_seed::<sr25519::Public>("Ferdie"),322 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),323 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),324 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),325 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),326 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),327 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),328 ],329 PARA_ID330 )331 },332 333 vec![],334 335 None,336 337 None,338 None,339 340 Some(properties),341 342 Extensions {343 relay_chain: "rococo-dev".into(),344 para_id: PARA_ID,345 },346 )347}348349pub fn local_testnet_config() -> DefaultChainSpec {350 let mut properties = Map::new();351 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());352 properties.insert("tokenDecimals".into(), 18.into());353 properties.insert(354 "ss58Format".into(),355 default_runtime::SS58Prefix::get().into(),356 );357358 DefaultChainSpec::from_genesis(359 360 format!(361 "{}{}",362 default_runtime::RUNTIME_NAME.to_uppercase(),363 if cfg!(feature = "unique-runtime") {364 ""365 } else {366 " by UNIQUE"367 }368 )369 .as_str(),370 371 format!("{}_local", default_runtime::RUNTIME_NAME).as_str(),372 ChainType::Local,373 move || {374 testnet_genesis!(375 default_runtime,376 377 get_account_id_from_seed::<sr25519::Public>("Alice"),378 vec![379 (380 get_account_id_from_seed::<sr25519::Public>("Alice"),381 get_from_seed::<AuraId>("Alice"),382 ),383 (384 get_account_id_from_seed::<sr25519::Public>("Bob"),385 get_from_seed::<AuraId>("Bob"),386 ),387 ],388 389 vec![390 get_account_id_from_seed::<sr25519::Public>("Alice"),391 get_account_id_from_seed::<sr25519::Public>("Bob"),392 get_account_id_from_seed::<sr25519::Public>("Charlie"),393 get_account_id_from_seed::<sr25519::Public>("Dave"),394 get_account_id_from_seed::<sr25519::Public>("Eve"),395 get_account_id_from_seed::<sr25519::Public>("Ferdie"),396 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),397 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),398 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),399 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),400 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),401 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),402 ],403 PARA_ID404 )405 },406 407 vec![],408 409 None,410 411 None,412 None,413 414 Some(properties),415 416 Extensions {417 relay_chain: "westend-local".into(),418 para_id: PARA_ID,419 },420 )421}