chain_spec.rs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. // Copyright 2019 Joystream Contributors
  2. // This file is part of Joystream node.
  3. // Joystream node is free software: you can redistribute it and/or modify
  4. // it under the terms of the GNU General Public License as published by
  5. // the Free Software Foundation, either version 3 of the License, or
  6. // (at your option) any later version.
  7. // Joystream node is distributed in the hope that it will be useful,
  8. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. // GNU General Public License for more details.
  11. // You should have received a copy of the GNU General Public License
  12. // along with Joystream node. If not, see <http://www.gnu.org/licenses/>.
  13. // Clippy linter warning.
  14. // Disable it because we use such syntax for a code readability.
  15. // Example: voting_period: 1 * DAY
  16. #![allow(clippy::identity_op)]
  17. use node_runtime::{
  18. versioned_store::InputValidationLengthConstraint as VsInputValidation,
  19. AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig, ContentWorkingGroupConfig,
  20. CouncilConfig, CouncilElectionConfig, DataObjectStorageRegistryConfig,
  21. DataObjectTypeRegistryConfig, ElectionParameters, GrandpaConfig, ImOnlineConfig, IndicesConfig,
  22. MembersConfig, MigrationConfig, Perbill, ProposalsCodexConfig, SessionConfig, SessionKeys,
  23. Signature, StakerStatus, StakingConfig, StorageWorkingGroupConfig, SudoConfig, SystemConfig,
  24. VersionedStoreConfig, DAYS, WASM_BINARY,
  25. };
  26. pub use node_runtime::{AccountId, GenesisConfig};
  27. use primitives::{sr25519, Pair, Public};
  28. use runtime_primitives::traits::{IdentifyAccount, Verify};
  29. use babe_primitives::AuthorityId as BabeId;
  30. use grandpa_primitives::AuthorityId as GrandpaId;
  31. use im_online::sr25519::AuthorityId as ImOnlineId;
  32. use serde_json as json;
  33. type AccountPublic = <Signature as Verify>::Signer;
  34. /// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
  35. pub type ChainSpec = substrate_service::ChainSpec<GenesisConfig>;
  36. use node_runtime::common::constraints::InputValidationLengthConstraint;
  37. /// The chain specification option. This is expected to come in from the CLI and
  38. /// is little more than one of a number of alternatives which can easily be converted
  39. /// from a string (`--chain=...`) into a `ChainSpec`.
  40. #[derive(Clone, Debug)]
  41. pub enum Alternative {
  42. /// Whatever the current runtime is, with just Alice as an auth.
  43. Development,
  44. /// Whatever the current runtime is, with simple Alice/Bob auths.
  45. LocalTestnet,
  46. }
  47. /// Helper function to generate a crypto pair from seed
  48. pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
  49. TPublic::Pair::from_string(&format!("//{}", seed), None)
  50. .expect("static values are valid; qed")
  51. .public()
  52. }
  53. /// Helper function to generate an account ID from seed
  54. pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
  55. where
  56. AccountPublic: From<<TPublic::Pair as Pair>::Public>,
  57. {
  58. AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
  59. }
  60. /// Helper function to generate stash, controller and session key from seed
  61. pub fn get_authority_keys_from_seed(
  62. seed: &str,
  63. ) -> (AccountId, AccountId, GrandpaId, BabeId, ImOnlineId) {
  64. (
  65. get_account_id_from_seed::<sr25519::Public>(&format!("{}//stash", seed)),
  66. get_account_id_from_seed::<sr25519::Public>(seed),
  67. get_from_seed::<GrandpaId>(seed),
  68. get_from_seed::<BabeId>(seed),
  69. get_from_seed::<ImOnlineId>(seed),
  70. )
  71. }
  72. fn session_keys(grandpa: GrandpaId, babe: BabeId, im_online: ImOnlineId) -> SessionKeys {
  73. SessionKeys {
  74. grandpa,
  75. babe,
  76. im_online,
  77. }
  78. }
  79. impl Alternative {
  80. /// Get an actual chain config from one of the alternatives.
  81. pub(crate) fn load(self) -> Result<ChainSpec, String> {
  82. Ok(match self {
  83. Alternative::Development => ChainSpec::from_genesis(
  84. "Development",
  85. "dev",
  86. || {
  87. testnet_genesis(
  88. vec![get_authority_keys_from_seed("Alice")],
  89. get_account_id_from_seed::<sr25519::Public>("Alice"),
  90. vec![
  91. get_account_id_from_seed::<sr25519::Public>("Alice"),
  92. get_account_id_from_seed::<sr25519::Public>("Bob"),
  93. get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
  94. get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
  95. ],
  96. crate::proposals_config::development(),
  97. )
  98. },
  99. vec![],
  100. None,
  101. None,
  102. Some(chain_spec_properties()),
  103. None,
  104. ),
  105. Alternative::LocalTestnet => ChainSpec::from_genesis(
  106. "Local Testnet",
  107. "local_testnet",
  108. || {
  109. testnet_genesis(
  110. vec![
  111. get_authority_keys_from_seed("Alice"),
  112. get_authority_keys_from_seed("Bob"),
  113. ],
  114. get_account_id_from_seed::<sr25519::Public>("Alice"),
  115. vec![
  116. get_account_id_from_seed::<sr25519::Public>("Alice"),
  117. get_account_id_from_seed::<sr25519::Public>("Bob"),
  118. get_account_id_from_seed::<sr25519::Public>("Charlie"),
  119. get_account_id_from_seed::<sr25519::Public>("Dave"),
  120. get_account_id_from_seed::<sr25519::Public>("Eve"),
  121. get_account_id_from_seed::<sr25519::Public>("Ferdie"),
  122. get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
  123. get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
  124. get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
  125. get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
  126. get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
  127. get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
  128. ],
  129. crate::proposals_config::development(),
  130. )
  131. },
  132. vec![],
  133. None,
  134. None,
  135. Some(chain_spec_properties()),
  136. None,
  137. ),
  138. })
  139. }
  140. pub(crate) fn from(s: &str) -> Option<Self> {
  141. match s {
  142. "dev" => Some(Alternative::Development),
  143. "local" => Some(Alternative::LocalTestnet),
  144. _ => None,
  145. }
  146. }
  147. }
  148. fn new_vs_validation(min: u16, max_min_diff: u16) -> VsInputValidation {
  149. VsInputValidation { min, max_min_diff }
  150. }
  151. pub fn chain_spec_properties() -> json::map::Map<String, json::Value> {
  152. let mut properties: json::map::Map<String, json::Value> = json::map::Map::new();
  153. properties.insert(
  154. String::from("tokenDecimals"),
  155. json::Value::Number(json::Number::from(0)),
  156. );
  157. properties.insert(
  158. String::from("tokenSymbol"),
  159. json::Value::String(String::from("JOY")),
  160. );
  161. properties
  162. }
  163. pub fn testnet_genesis(
  164. initial_authorities: Vec<(AccountId, AccountId, GrandpaId, BabeId, ImOnlineId)>,
  165. root_key: AccountId,
  166. endowed_accounts: Vec<AccountId>,
  167. cpcp: node_runtime::ProposalsConfigParameters,
  168. ) -> GenesisConfig {
  169. const CENTS: Balance = 1;
  170. const DOLLARS: Balance = 100 * CENTS;
  171. const STASH: Balance = 20 * DOLLARS;
  172. const ENDOWMENT: Balance = 100_000 * DOLLARS;
  173. let default_text_constraint = node_runtime::working_group::default_text_constraint();
  174. GenesisConfig {
  175. system: Some(SystemConfig {
  176. code: WASM_BINARY.to_vec(),
  177. changes_trie_config: Default::default(),
  178. }),
  179. balances: Some(BalancesConfig {
  180. balances: endowed_accounts
  181. .iter()
  182. .cloned()
  183. .map(|k| (k, ENDOWMENT))
  184. .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
  185. .collect(),
  186. vesting: vec![],
  187. }),
  188. indices: Some(IndicesConfig { ids: vec![] }),
  189. session: Some(SessionConfig {
  190. keys: initial_authorities
  191. .iter()
  192. .map(|x| {
  193. (
  194. x.0.clone(),
  195. session_keys(x.2.clone(), x.3.clone(), x.4.clone()),
  196. )
  197. })
  198. .collect::<Vec<_>>(),
  199. }),
  200. staking: Some(StakingConfig {
  201. current_era: 0,
  202. validator_count: 20,
  203. minimum_validator_count: 1,
  204. stakers: initial_authorities
  205. .iter()
  206. .map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator))
  207. .collect(),
  208. invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
  209. slash_reward_fraction: Perbill::from_percent(10),
  210. ..Default::default()
  211. }),
  212. sudo: Some(SudoConfig { key: root_key }),
  213. babe: Some(BabeConfig {
  214. authorities: vec![],
  215. }),
  216. im_online: Some(ImOnlineConfig { keys: vec![] }),
  217. authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![] }),
  218. grandpa: Some(GrandpaConfig {
  219. authorities: vec![],
  220. }),
  221. council: Some(CouncilConfig {
  222. active_council: vec![],
  223. term_ends_at: 1,
  224. }),
  225. election: Some(CouncilElectionConfig {
  226. auto_start: true,
  227. election_parameters: ElectionParameters {
  228. announcing_period: 3 * DAYS,
  229. voting_period: 1 * DAYS,
  230. revealing_period: 1 * DAYS,
  231. council_size: 12,
  232. candidacy_limit: 25,
  233. min_council_stake: 10 * DOLLARS,
  234. new_term_duration: 14 * DAYS,
  235. min_voting_stake: 1 * DOLLARS,
  236. },
  237. }),
  238. members: Some(MembersConfig {
  239. default_paid_membership_fee: 100u128,
  240. members: vec![],
  241. }),
  242. forum: Some(crate::forum_config::from_serialized::create(
  243. endowed_accounts[0].clone(),
  244. )),
  245. data_object_type_registry: Some(DataObjectTypeRegistryConfig {
  246. first_data_object_type_id: 1,
  247. }),
  248. data_object_storage_registry: Some(DataObjectStorageRegistryConfig {
  249. first_relationship_id: 1,
  250. }),
  251. working_group_Instance2: Some(StorageWorkingGroupConfig {
  252. phantom: Default::default(),
  253. storage_working_group_mint_capacity: 0,
  254. opening_human_readable_text_constraint: default_text_constraint,
  255. worker_application_human_readable_text_constraint: default_text_constraint,
  256. worker_exit_rationale_text_constraint: default_text_constraint,
  257. }),
  258. versioned_store: Some(VersionedStoreConfig {
  259. class_by_id: vec![],
  260. entity_by_id: vec![],
  261. next_class_id: 1,
  262. next_entity_id: 1,
  263. property_name_constraint: new_vs_validation(1, 99),
  264. property_description_constraint: new_vs_validation(1, 999),
  265. class_name_constraint: new_vs_validation(1, 99),
  266. class_description_constraint: new_vs_validation(1, 999),
  267. }),
  268. content_wg: Some(ContentWorkingGroupConfig {
  269. mint_capacity: 100_000,
  270. curator_opening_by_id: vec![],
  271. next_curator_opening_id: 0,
  272. curator_application_by_id: vec![],
  273. next_curator_application_id: 0,
  274. channel_by_id: vec![],
  275. next_channel_id: 1,
  276. channel_id_by_handle: vec![],
  277. curator_by_id: vec![],
  278. next_curator_id: 0,
  279. principal_by_id: vec![],
  280. next_principal_id: 0,
  281. channel_creation_enabled: true, // there is no extrinsic to change it so enabling at genesis
  282. unstaker_by_stake_id: vec![],
  283. channel_handle_constraint: InputValidationLengthConstraint::new(5, 20),
  284. channel_description_constraint: InputValidationLengthConstraint::new(1, 1024),
  285. opening_human_readable_text: InputValidationLengthConstraint::new(1, 2048),
  286. curator_application_human_readable_text: InputValidationLengthConstraint::new(1, 2048),
  287. curator_exit_rationale_text: InputValidationLengthConstraint::new(1, 2048),
  288. channel_avatar_constraint: InputValidationLengthConstraint::new(5, 1024),
  289. channel_banner_constraint: InputValidationLengthConstraint::new(5, 1024),
  290. channel_title_constraint: InputValidationLengthConstraint::new(5, 1024),
  291. }),
  292. migration: Some(MigrationConfig {}),
  293. proposals_codex: Some(ProposalsCodexConfig {
  294. set_validator_count_proposal_voting_period: cpcp
  295. .set_validator_count_proposal_voting_period,
  296. set_validator_count_proposal_grace_period: cpcp
  297. .set_validator_count_proposal_grace_period,
  298. runtime_upgrade_proposal_voting_period: cpcp.runtime_upgrade_proposal_voting_period,
  299. runtime_upgrade_proposal_grace_period: cpcp.runtime_upgrade_proposal_grace_period,
  300. text_proposal_voting_period: cpcp.text_proposal_voting_period,
  301. text_proposal_grace_period: cpcp.text_proposal_grace_period,
  302. set_election_parameters_proposal_voting_period: cpcp
  303. .set_election_parameters_proposal_voting_period,
  304. set_election_parameters_proposal_grace_period: cpcp
  305. .set_election_parameters_proposal_grace_period,
  306. set_content_working_group_mint_capacity_proposal_voting_period: cpcp
  307. .set_content_working_group_mint_capacity_proposal_voting_period,
  308. set_content_working_group_mint_capacity_proposal_grace_period: cpcp
  309. .set_content_working_group_mint_capacity_proposal_grace_period,
  310. set_lead_proposal_voting_period: cpcp.set_lead_proposal_voting_period,
  311. set_lead_proposal_grace_period: cpcp.set_lead_proposal_grace_period,
  312. spending_proposal_voting_period: cpcp.spending_proposal_voting_period,
  313. spending_proposal_grace_period: cpcp.spending_proposal_grace_period,
  314. add_working_group_opening_proposal_voting_period: cpcp
  315. .add_working_group_opening_proposal_voting_period,
  316. add_working_group_opening_proposal_grace_period: cpcp
  317. .add_working_group_opening_proposal_grace_period,
  318. begin_review_working_group_leader_applications_proposal_voting_period: cpcp
  319. .begin_review_working_group_leader_applications_proposal_voting_period,
  320. begin_review_working_group_leader_applications_proposal_grace_period: cpcp
  321. .begin_review_working_group_leader_applications_proposal_grace_period,
  322. fill_working_group_leader_opening_proposal_voting_period: cpcp
  323. .fill_working_group_leader_opening_proposal_voting_period,
  324. fill_working_group_leader_opening_proposal_grace_period: cpcp
  325. .fill_working_group_leader_opening_proposal_grace_period,
  326. set_working_group_mint_capacity_proposal_voting_period: cpcp
  327. .set_content_working_group_mint_capacity_proposal_voting_period,
  328. set_working_group_mint_capacity_proposal_grace_period: cpcp
  329. .set_content_working_group_mint_capacity_proposal_grace_period,
  330. decrease_working_group_leader_stake_proposal_voting_period: cpcp
  331. .decrease_working_group_leader_stake_proposal_voting_period,
  332. decrease_working_group_leader_stake_proposal_grace_period: cpcp
  333. .decrease_working_group_leader_stake_proposal_grace_period,
  334. slash_working_group_leader_stake_proposal_voting_period: cpcp
  335. .slash_working_group_leader_stake_proposal_voting_period,
  336. slash_working_group_leader_stake_proposal_grace_period: cpcp
  337. .slash_working_group_leader_stake_proposal_grace_period,
  338. set_working_group_leader_reward_proposal_voting_period: cpcp
  339. .set_working_group_leader_reward_proposal_voting_period,
  340. set_working_group_leader_reward_proposal_grace_period: cpcp
  341. .set_working_group_leader_reward_proposal_grace_period,
  342. terminate_working_group_leader_role_proposal_voting_period: cpcp
  343. .terminate_working_group_leader_role_proposal_voting_period,
  344. terminate_working_group_leader_role_proposal_grace_period: cpcp
  345. .terminate_working_group_leader_role_proposal_grace_period,
  346. }),
  347. }
  348. }