mod.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  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 pallet_im_online::sr25519::AuthorityId as ImOnlineId;
  18. use serde_json as json;
  19. use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
  20. use sp_consensus_babe::AuthorityId as BabeId;
  21. use sp_core::{sr25519, Pair, Public};
  22. use sp_finality_grandpa::AuthorityId as GrandpaId;
  23. use sp_runtime::traits::{IdentifyAccount, Verify};
  24. use sp_runtime::Perbill;
  25. use node_runtime::{
  26. membership, AuthorityDiscoveryConfig, BabeConfig, Balance, BalancesConfig,
  27. ContentWorkingGroupConfig, CouncilConfig, CouncilElectionConfig, DataDirectoryConfig,
  28. DataObjectStorageRegistryConfig, DataObjectTypeRegistryConfig, ElectionParameters, ForumConfig,
  29. GrandpaConfig, ImOnlineConfig, MembersConfig, Moment, ProposalsCodexConfig, SessionConfig,
  30. SessionKeys, Signature, StakerStatus, StakingConfig, StorageWorkingGroupConfig, SudoConfig,
  31. SystemConfig, VersionedStoreConfig, VersionedStorePermissionsConfig, DAYS, WASM_BINARY,
  32. };
  33. // Exported to be used by chain-spec-builder
  34. pub use node_runtime::{AccountId, GenesisConfig};
  35. pub mod content_config;
  36. pub mod forum_config;
  37. pub mod initial_members;
  38. pub mod proposals_config;
  39. type AccountPublic = <Signature as Verify>::Signer;
  40. /// Specialized `ChainSpec`. This is a specialization of the general Substrate ChainSpec type.
  41. pub type ChainSpec = sc_service::GenericChainSpec<GenesisConfig>;
  42. use sc_chain_spec::ChainType;
  43. /// The chain specification option. This is expected to come in from the CLI and
  44. /// is little more than one of a number of alternatives which can easily be converted
  45. /// from a string (`--chain=...`) into a `ChainSpec`.
  46. #[derive(Clone, Debug)]
  47. pub enum Alternative {
  48. /// Whatever the current runtime is, with just Alice as an auth.
  49. Development,
  50. /// Whatever the current runtime is, with simple Alice/Bob auths.
  51. LocalTestnet,
  52. }
  53. /// Helper function to generate a crypto pair from seed
  54. pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
  55. TPublic::Pair::from_string(&format!("//{}", seed), None)
  56. .expect("static values are valid; qed")
  57. .public()
  58. }
  59. /// Helper function to generate an account ID from seed
  60. pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId
  61. where
  62. AccountPublic: From<<TPublic::Pair as Pair>::Public>,
  63. {
  64. AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()
  65. }
  66. /// Helper function to generate stash, controller and session key from seed
  67. pub fn get_authority_keys_from_seed(
  68. seed: &str,
  69. ) -> (
  70. AccountId,
  71. AccountId,
  72. GrandpaId,
  73. BabeId,
  74. ImOnlineId,
  75. AuthorityDiscoveryId,
  76. ) {
  77. (
  78. get_account_id_from_seed::<sr25519::Public>(&format!("{}//stash", seed)),
  79. get_account_id_from_seed::<sr25519::Public>(seed),
  80. get_from_seed::<GrandpaId>(seed),
  81. get_from_seed::<BabeId>(seed),
  82. get_from_seed::<ImOnlineId>(seed),
  83. get_from_seed::<AuthorityDiscoveryId>(seed),
  84. )
  85. }
  86. fn session_keys(
  87. grandpa: GrandpaId,
  88. babe: BabeId,
  89. im_online: ImOnlineId,
  90. authority_discovery: AuthorityDiscoveryId,
  91. ) -> SessionKeys {
  92. SessionKeys {
  93. grandpa,
  94. babe,
  95. im_online,
  96. authority_discovery,
  97. }
  98. }
  99. impl Alternative {
  100. /// Get an actual chain config from one of the alternatives.
  101. pub(crate) fn load(self) -> Result<ChainSpec, String> {
  102. Ok(match self {
  103. Alternative::Development => ChainSpec::from_genesis(
  104. "Development",
  105. "dev",
  106. ChainType::Development,
  107. || {
  108. testnet_genesis(
  109. vec![get_authority_keys_from_seed("Alice")],
  110. get_account_id_from_seed::<sr25519::Public>("Alice"),
  111. vec![
  112. get_account_id_from_seed::<sr25519::Public>("Alice"),
  113. get_account_id_from_seed::<sr25519::Public>("Bob"),
  114. get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
  115. get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
  116. ],
  117. proposals_config::development(),
  118. initial_members::none(),
  119. forum_config::empty(get_account_id_from_seed::<sr25519::Public>("Alice")),
  120. content_config::empty_versioned_store_config(),
  121. content_config::empty_versioned_store_permissions_config(),
  122. content_config::empty_data_directory_config(),
  123. content_config::empty_content_working_group_config(),
  124. )
  125. },
  126. Vec::new(),
  127. None,
  128. None,
  129. Some(chain_spec_properties()),
  130. None,
  131. ),
  132. Alternative::LocalTestnet => ChainSpec::from_genesis(
  133. "Local Testnet",
  134. "local_testnet",
  135. ChainType::Local,
  136. || {
  137. testnet_genesis(
  138. vec![
  139. get_authority_keys_from_seed("Alice"),
  140. get_authority_keys_from_seed("Bob"),
  141. ],
  142. get_account_id_from_seed::<sr25519::Public>("Alice"),
  143. vec![
  144. get_account_id_from_seed::<sr25519::Public>("Alice"),
  145. get_account_id_from_seed::<sr25519::Public>("Bob"),
  146. get_account_id_from_seed::<sr25519::Public>("Charlie"),
  147. get_account_id_from_seed::<sr25519::Public>("Dave"),
  148. get_account_id_from_seed::<sr25519::Public>("Eve"),
  149. get_account_id_from_seed::<sr25519::Public>("Ferdie"),
  150. get_account_id_from_seed::<sr25519::Public>("Alice//stash"),
  151. get_account_id_from_seed::<sr25519::Public>("Bob//stash"),
  152. get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),
  153. get_account_id_from_seed::<sr25519::Public>("Dave//stash"),
  154. get_account_id_from_seed::<sr25519::Public>("Eve//stash"),
  155. get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),
  156. ],
  157. proposals_config::development(),
  158. initial_members::none(),
  159. forum_config::empty(get_account_id_from_seed::<sr25519::Public>("Alice")),
  160. content_config::empty_versioned_store_config(),
  161. content_config::empty_versioned_store_permissions_config(),
  162. content_config::empty_data_directory_config(),
  163. content_config::empty_content_working_group_config(),
  164. )
  165. },
  166. Vec::new(),
  167. None,
  168. None,
  169. Some(chain_spec_properties()),
  170. None,
  171. ),
  172. })
  173. }
  174. }
  175. pub fn chain_spec_properties() -> json::map::Map<String, json::Value> {
  176. let mut properties: json::map::Map<String, json::Value> = json::map::Map::new();
  177. properties.insert(
  178. String::from("tokenDecimals"),
  179. json::Value::Number(json::Number::from(0)),
  180. );
  181. properties.insert(
  182. String::from("tokenSymbol"),
  183. json::Value::String(String::from("JOY")),
  184. );
  185. properties
  186. }
  187. #[allow(clippy::too_many_arguments)]
  188. pub fn testnet_genesis(
  189. initial_authorities: Vec<(
  190. AccountId,
  191. AccountId,
  192. GrandpaId,
  193. BabeId,
  194. ImOnlineId,
  195. AuthorityDiscoveryId,
  196. )>,
  197. root_key: AccountId,
  198. endowed_accounts: Vec<AccountId>,
  199. cpcp: node_runtime::ProposalsConfigParameters,
  200. members: Vec<membership::genesis::Member<u64, AccountId, Moment>>,
  201. forum_config: ForumConfig,
  202. versioned_store_config: VersionedStoreConfig,
  203. versioned_store_permissions_config: VersionedStorePermissionsConfig,
  204. data_directory_config: DataDirectoryConfig,
  205. content_working_group_config: ContentWorkingGroupConfig,
  206. ) -> GenesisConfig {
  207. const CENTS: Balance = 1;
  208. const DOLLARS: Balance = 100 * CENTS;
  209. const STASH: Balance = 20 * DOLLARS;
  210. const ENDOWMENT: Balance = 100_000 * DOLLARS;
  211. let default_text_constraint = node_runtime::working_group::default_text_constraint();
  212. GenesisConfig {
  213. system: Some(SystemConfig {
  214. code: WASM_BINARY.to_vec(),
  215. changes_trie_config: Default::default(),
  216. }),
  217. pallet_balances: Some(BalancesConfig {
  218. balances: endowed_accounts
  219. .iter()
  220. .cloned()
  221. .map(|k| (k, ENDOWMENT))
  222. .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
  223. .collect(),
  224. }),
  225. pallet_staking: Some(StakingConfig {
  226. validator_count: 20,
  227. minimum_validator_count: 1,
  228. stakers: initial_authorities
  229. .iter()
  230. .map(|x| (x.0.clone(), x.1.clone(), STASH, StakerStatus::Validator))
  231. .collect(),
  232. invulnerables: initial_authorities.iter().map(|x| x.0.clone()).collect(),
  233. slash_reward_fraction: Perbill::from_percent(10),
  234. ..Default::default()
  235. }),
  236. pallet_sudo: Some(SudoConfig { key: root_key }),
  237. pallet_babe: Some(BabeConfig {
  238. authorities: vec![],
  239. }),
  240. pallet_im_online: Some(ImOnlineConfig { keys: vec![] }),
  241. pallet_authority_discovery: Some(AuthorityDiscoveryConfig { keys: vec![] }),
  242. pallet_grandpa: Some(GrandpaConfig {
  243. authorities: vec![],
  244. }),
  245. pallet_session: Some(SessionConfig {
  246. keys: initial_authorities
  247. .iter()
  248. .map(|x| {
  249. (
  250. x.0.clone(),
  251. x.0.clone(),
  252. session_keys(x.2.clone(), x.3.clone(), x.4.clone(), x.5.clone()),
  253. )
  254. })
  255. .collect::<Vec<_>>(),
  256. }),
  257. council: Some(CouncilConfig {
  258. active_council: vec![],
  259. term_ends_at: 1,
  260. }),
  261. election: Some(CouncilElectionConfig {
  262. auto_start: true,
  263. election_parameters: ElectionParameters {
  264. announcing_period: 3 * DAYS,
  265. voting_period: 1 * DAYS,
  266. revealing_period: 1 * DAYS,
  267. council_size: 12,
  268. candidacy_limit: 25,
  269. min_council_stake: 10 * DOLLARS,
  270. new_term_duration: 14 * DAYS,
  271. min_voting_stake: 1 * DOLLARS,
  272. },
  273. }),
  274. membership: Some(MembersConfig {
  275. default_paid_membership_fee: 100u128,
  276. members,
  277. }),
  278. forum: Some(forum_config),
  279. data_directory: Some(data_directory_config),
  280. data_object_type_registry: Some(DataObjectTypeRegistryConfig {
  281. first_data_object_type_id: 1,
  282. }),
  283. data_object_storage_registry: Some(DataObjectStorageRegistryConfig {
  284. first_relationship_id: 1,
  285. }),
  286. working_group_Instance2: Some(StorageWorkingGroupConfig {
  287. phantom: Default::default(),
  288. storage_working_group_mint_capacity: 0,
  289. opening_human_readable_text_constraint: default_text_constraint,
  290. worker_application_human_readable_text_constraint: default_text_constraint,
  291. worker_exit_rationale_text_constraint: default_text_constraint,
  292. }),
  293. versioned_store: Some(versioned_store_config),
  294. versioned_store_permissions: Some(versioned_store_permissions_config),
  295. content_wg: Some(content_working_group_config),
  296. proposals_codex: Some(ProposalsCodexConfig {
  297. set_validator_count_proposal_voting_period: cpcp
  298. .set_validator_count_proposal_voting_period,
  299. set_validator_count_proposal_grace_period: cpcp
  300. .set_validator_count_proposal_grace_period,
  301. runtime_upgrade_proposal_voting_period: cpcp.runtime_upgrade_proposal_voting_period,
  302. runtime_upgrade_proposal_grace_period: cpcp.runtime_upgrade_proposal_grace_period,
  303. text_proposal_voting_period: cpcp.text_proposal_voting_period,
  304. text_proposal_grace_period: cpcp.text_proposal_grace_period,
  305. set_election_parameters_proposal_voting_period: cpcp
  306. .set_election_parameters_proposal_voting_period,
  307. set_election_parameters_proposal_grace_period: cpcp
  308. .set_election_parameters_proposal_grace_period,
  309. set_content_working_group_mint_capacity_proposal_voting_period: cpcp
  310. .set_content_working_group_mint_capacity_proposal_voting_period,
  311. set_content_working_group_mint_capacity_proposal_grace_period: cpcp
  312. .set_content_working_group_mint_capacity_proposal_grace_period,
  313. set_lead_proposal_voting_period: cpcp.set_lead_proposal_voting_period,
  314. set_lead_proposal_grace_period: cpcp.set_lead_proposal_grace_period,
  315. spending_proposal_voting_period: cpcp.spending_proposal_voting_period,
  316. spending_proposal_grace_period: cpcp.spending_proposal_grace_period,
  317. add_working_group_opening_proposal_voting_period: cpcp
  318. .add_working_group_opening_proposal_voting_period,
  319. add_working_group_opening_proposal_grace_period: cpcp
  320. .add_working_group_opening_proposal_grace_period,
  321. begin_review_working_group_leader_applications_proposal_voting_period: cpcp
  322. .begin_review_working_group_leader_applications_proposal_voting_period,
  323. begin_review_working_group_leader_applications_proposal_grace_period: cpcp
  324. .begin_review_working_group_leader_applications_proposal_grace_period,
  325. fill_working_group_leader_opening_proposal_voting_period: cpcp
  326. .fill_working_group_leader_opening_proposal_voting_period,
  327. fill_working_group_leader_opening_proposal_grace_period: cpcp
  328. .fill_working_group_leader_opening_proposal_grace_period,
  329. set_working_group_mint_capacity_proposal_voting_period: cpcp
  330. .set_content_working_group_mint_capacity_proposal_voting_period,
  331. set_working_group_mint_capacity_proposal_grace_period: cpcp
  332. .set_content_working_group_mint_capacity_proposal_grace_period,
  333. decrease_working_group_leader_stake_proposal_voting_period: cpcp
  334. .decrease_working_group_leader_stake_proposal_voting_period,
  335. decrease_working_group_leader_stake_proposal_grace_period: cpcp
  336. .decrease_working_group_leader_stake_proposal_grace_period,
  337. slash_working_group_leader_stake_proposal_voting_period: cpcp
  338. .slash_working_group_leader_stake_proposal_voting_period,
  339. slash_working_group_leader_stake_proposal_grace_period: cpcp
  340. .slash_working_group_leader_stake_proposal_grace_period,
  341. set_working_group_leader_reward_proposal_voting_period: cpcp
  342. .set_working_group_leader_reward_proposal_voting_period,
  343. set_working_group_leader_reward_proposal_grace_period: cpcp
  344. .set_working_group_leader_reward_proposal_grace_period,
  345. terminate_working_group_leader_role_proposal_voting_period: cpcp
  346. .terminate_working_group_leader_role_proposal_voting_period,
  347. terminate_working_group_leader_role_proposal_grace_period: cpcp
  348. .terminate_working_group_leader_role_proposal_grace_period,
  349. }),
  350. }
  351. }
  352. // Tests are commented out until we find a solution to why
  353. // building dependencies for the tests are taking so long on Travis CI
  354. // #[cfg(test)]
  355. // pub(crate) mod tests {
  356. // use super::*;
  357. // use crate::service::{new_full, new_light};
  358. // use sc_service_test;
  359. // fn local_testnet_genesis_instant_single() -> GenesisConfig {
  360. // testnet_genesis(
  361. // vec![get_authority_keys_from_seed("Alice")],
  362. // get_account_id_from_seed::<sr25519::Public>("Alice"),
  363. // vec![get_authority_keys_from_seed("Alice").0],
  364. // crate::proposals_config::development(),
  365. // )
  366. // }
  367. // /// Local testnet config (single validator - Alice)
  368. // pub fn integration_test_config_with_single_authority() -> ChainSpec {
  369. // ChainSpec::from_genesis(
  370. // "Integration Test",
  371. // "test",
  372. // ChainType::Development,
  373. // local_testnet_genesis_instant_single,
  374. // vec![],
  375. // None,
  376. // None,
  377. // None,
  378. // Default::default(),
  379. // )
  380. // }
  381. // fn local_testnet_genesis() -> GenesisConfig {
  382. // testnet_genesis(
  383. // vec![
  384. // get_authority_keys_from_seed("Alice"),
  385. // get_authority_keys_from_seed("Bob"),
  386. // ],
  387. // get_account_id_from_seed::<sr25519::Public>("Alice"),
  388. // vec![
  389. // get_authority_keys_from_seed("Alice").0,
  390. // get_authority_keys_from_seed("Bob").0,
  391. // ],
  392. // crate::proposals_config::development(),
  393. // )
  394. // }
  395. // /// Local testnet config (multivalidator Alice + Bob)
  396. // pub fn integration_test_config_with_two_authorities() -> ChainSpec {
  397. // ChainSpec::from_genesis(
  398. // "Integration Test",
  399. // "test",
  400. // ChainType::Development,
  401. // local_testnet_genesis,
  402. // vec![],
  403. // None,
  404. // None,
  405. // None,
  406. // Default::default(),
  407. // )
  408. // }
  409. // #[test]
  410. // #[ignore]
  411. // fn test_connectivity() {
  412. // sc_service_test::connectivity(
  413. // integration_test_config_with_two_authorities(),
  414. // |config| new_full(config),
  415. // |config| new_light(config),
  416. // );
  417. // }
  418. // }