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") || self.id() == "dev" || self.id() == "local_testnet" {94 return RuntimeId::Opal;95 }9697 RuntimeId::Unknown(self.id().into())98 }99}100101pub enum ServiceId {102 Prod,103 Dev,104}105106pub trait ServiceIdentification {107 fn service_id(&self) -> ServiceId;108}109110impl ServiceIdentification for Box<dyn sc_service::ChainSpec> {111 fn service_id(&self) -> ServiceId {112 if self.id().ends_with("dev") {113 ServiceId::Dev114 } else {115 ServiceId::Prod116 }117 }118}119120121pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {122 TPublic::Pair::from_string(&format!("//{}", seed), None)123 .expect("static values are valid; qed")124 .public()125}126127128#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]129#[serde(deny_unknown_fields)]130pub struct Extensions {131 132 pub relay_chain: String,133 134 pub para_id: u32,135}136137impl Extensions {138 139 pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {140 sc_chain_spec::get_extension(chain_spec.extensions())141 }142}143144type AccountPublic = <Signature as Verify>::Signer;145146147pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId148where149 AccountPublic: From<<TPublic::Pair as Pair>::Public>,150{151 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()152}153154#[cfg(not(any(feature = "unique-runtime", feature = "quartz-runtime")))]155macro_rules! testnet_genesis {156 (157 $runtime:path,158 $root_key:expr,159 $initial_invulnerables:expr,160 $endowed_accounts:expr,161 $id:expr162 ) => {{163 use $runtime::*;164165 GenesisConfig {166 system: SystemConfig {167 code: WASM_BINARY168 .expect("WASM binary was not build, please build it!")169 .to_vec(),170 },171 balances: BalancesConfig {172 balances: $endowed_accounts173 .iter()174 .cloned()175 176 .map(|k| (k, 1 << 100))177 .collect(),178 },179 treasury: Default::default(),180 tokens: TokensConfig { balances: vec![] },181 sudo: SudoConfig {182 key: Some($root_key),183 },184 vesting: VestingConfig { vesting: vec![] },185 parachain_info: ParachainInfoConfig {186 parachain_id: $id.into(),187 },188 parachain_system: Default::default(),189 collator_selection: CollatorSelectionConfig {190 invulnerables: $initial_invulnerables191 .iter()192 .cloned()193 .map(|(acc, _)| acc)194 .collect(),195 candidacy_bond: GENESIS_CANDIDACY_BOND,196 ..Default::default()197 },198 session: SessionConfig {199 keys: $initial_invulnerables200 .into_iter()201 .map(|(acc, aura)| {202 (203 acc.clone(), 204 acc, 205 SessionKeys { aura }, 206 )207 })208 .collect(),209 },210 aura: Default::default(),211 aura_ext: Default::default(),212 evm: EVMConfig {213 accounts: BTreeMap::new(),214 },215 ethereum: EthereumConfig {},216 }217 }};218}219220#[cfg(any(feature = "unique-runtime", feature = "quartz-runtime"))]221macro_rules! testnet_genesis {222 (223 $runtime:path,224 $root_key:expr,225 $initial_invulnerables:expr,226 $endowed_accounts:expr,227 $id:expr228 ) => {{229 use $runtime::*;230231 GenesisConfig {232 system: SystemConfig {233 code: WASM_BINARY234 .expect("WASM binary was not build, please build it!")235 .to_vec(),236 },237 balances: BalancesConfig {238 balances: $endowed_accounts239 .iter()240 .cloned()241 242 .map(|k| (k, 1 << 100))243 .collect(),244 },245 treasury: Default::default(),246 tokens: TokensConfig { balances: vec![] },247 sudo: SudoConfig {248 key: Some($root_key),249 },250 vesting: VestingConfig { vesting: vec![] },251 parachain_info: ParachainInfoConfig {252 parachain_id: $id.into(),253 },254 parachain_system: Default::default(),255 aura: AuraConfig {256 authorities: $initial_invulnerables257 .into_iter()258 .map(|(_, aura)| aura)259 .collect(),260 },261 aura_ext: Default::default(),262 evm: EVMConfig {263 accounts: BTreeMap::new(),264 },265 ethereum: EthereumConfig {},266 }267 }};268}269270pub fn development_config() -> DefaultChainSpec {271 let mut properties = Map::new();272 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());273 properties.insert("tokenDecimals".into(), 18.into());274 properties.insert(275 "ss58Format".into(),276 default_runtime::SS58Prefix::get().into(),277 );278279 DefaultChainSpec::from_genesis(280 281 format!(282 "{}{}",283 default_runtime::RUNTIME_NAME.to_uppercase(),284 if cfg!(feature = "unique-runtime") {285 ""286 } else {287 " by UNIQUE"288 }289 )290 .as_str(),291 292 format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),293 ChainType::Local,294 move || {295 testnet_genesis!(296 default_runtime,297 298 get_account_id_from_seed::<sr25519::Public>("Alice"),299 vec![300 (301 get_account_id_from_seed::<sr25519::Public>("Alice"),302 get_from_seed::<AuraId>("Alice"),303 ),304 (305 get_account_id_from_seed::<sr25519::Public>("Bob"),306 get_from_seed::<AuraId>("Bob"),307 ),308 ],309 310 vec![311 get_account_id_from_seed::<sr25519::Public>("Alice"),312 get_account_id_from_seed::<sr25519::Public>("Bob"),313 get_account_id_from_seed::<sr25519::Public>("Charlie"),314 get_account_id_from_seed::<sr25519::Public>("Dave"),315 get_account_id_from_seed::<sr25519::Public>("Eve"),316 get_account_id_from_seed::<sr25519::Public>("Ferdie"),317 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),318 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),319 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),320 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),321 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),322 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),323 ],324 PARA_ID325 )326 },327 328 vec![],329 330 None,331 332 None,333 None,334 335 Some(properties),336 337 Extensions {338 relay_chain: "rococo-dev".into(),339 para_id: PARA_ID,340 },341 )342}343344pub fn local_testnet_config() -> DefaultChainSpec {345 let mut properties = Map::new();346 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());347 properties.insert("tokenDecimals".into(), 18.into());348 properties.insert(349 "ss58Format".into(),350 default_runtime::SS58Prefix::get().into(),351 );352353 DefaultChainSpec::from_genesis(354 355 format!(356 "{}{}",357 default_runtime::RUNTIME_NAME.to_uppercase(),358 if cfg!(feature = "unique-runtime") {359 ""360 } else {361 " by UNIQUE"362 }363 )364 .as_str(),365 366 format!("{}_local", default_runtime::RUNTIME_NAME).as_str(),367 ChainType::Local,368 move || {369 testnet_genesis!(370 default_runtime,371 372 get_account_id_from_seed::<sr25519::Public>("Alice"),373 vec![374 (375 get_account_id_from_seed::<sr25519::Public>("Alice"),376 get_from_seed::<AuraId>("Alice"),377 ),378 (379 get_account_id_from_seed::<sr25519::Public>("Bob"),380 get_from_seed::<AuraId>("Bob"),381 ),382 ],383 384 vec![385 get_account_id_from_seed::<sr25519::Public>("Alice"),386 get_account_id_from_seed::<sr25519::Public>("Bob"),387 get_account_id_from_seed::<sr25519::Public>("Charlie"),388 get_account_id_from_seed::<sr25519::Public>("Dave"),389 get_account_id_from_seed::<sr25519::Public>("Eve"),390 get_account_id_from_seed::<sr25519::Public>("Ferdie"),391 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),392 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),393 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),394 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),395 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),396 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),397 ],398 PARA_ID399 )400 },401 402 vec![],403 404 None,405 406 None,407 None,408 409 Some(properties),410 411 Extensions {412 relay_chain: "westend-local".into(),413 para_id: PARA_ID,414 },415 )416}