lib.rs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595
  1. //! The Substrate Node Template runtime. This can be compiled with `#[no_std]`, ready for Wasm.
  2. #![cfg_attr(not(feature = "std"), no_std)]
  3. // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
  4. #![recursion_limit = "256"]
  5. // Make the WASM binary available.
  6. #[cfg(feature = "std")]
  7. include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
  8. use babe::AuthorityId as BabeId;
  9. use substrate_client::{
  10. block_builder::api::{self as block_builder_api, CheckInherentsResult, InherentData},
  11. impl_runtime_apis, runtime_api as client_api,
  12. };
  13. use grandpa::fg_primitives::{self, ScheduledChange};
  14. use grandpa::{AuthorityId as GrandpaId, AuthorityWeight as GrandpaWeight};
  15. use primitives::{crypto::key_types, OpaqueMetadata};
  16. use rstd::prelude::*;
  17. use runtime_primitives::traits::{
  18. BlakeTwo256, Block as BlockT, ConvertInto, DigestFor, NumberFor, StaticLookup, Verify,
  19. };
  20. use runtime_primitives::weights::Weight;
  21. use runtime_primitives::{
  22. create_runtime_str, generic, impl_opaque_keys, transaction_validity::TransactionValidity,
  23. AnySignature, ApplyResult,
  24. };
  25. #[cfg(feature = "std")]
  26. use version::NativeVersion;
  27. use version::RuntimeVersion;
  28. // A few exports that help ease life for downstream crates.
  29. pub use balances::Call as BalancesCall;
  30. #[cfg(any(feature = "std", test))]
  31. pub use runtime_primitives::BuildStorage;
  32. pub use runtime_primitives::{Perbill, Permill};
  33. pub use srml_support::{construct_runtime, parameter_types, StorageValue};
  34. pub use timestamp::Call as TimestampCall;
  35. /// An index to a block.
  36. pub type BlockNumber = u32;
  37. /// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
  38. pub type Signature = AnySignature;
  39. /// Some way of identifying an account on the chain. We intentionally make it equivalent
  40. /// to the public key of our transaction signing scheme.
  41. pub type AccountId = <Signature as Verify>::Signer;
  42. /// The type for looking up accounts. We don't expect more than 4 billion of them, but you
  43. /// never know...
  44. pub type AccountIndex = u32;
  45. /// Balance of an account.
  46. pub type Balance = u128;
  47. /// Index of a transaction in the chain.
  48. pub type Index = u32;
  49. /// A hash of some data used by the chain.
  50. pub type Hash = primitives::H256;
  51. /// Digest item type.
  52. pub type DigestItem = generic::DigestItem<Hash>;
  53. /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
  54. /// the specifics of the runtime. They can then be made to be agnostic over specific formats
  55. /// of data like extrinsics, allowing for them to continue syncing the network through upgrades
  56. /// to even the core datastructures.
  57. pub mod opaque {
  58. use super::*;
  59. pub use runtime_primitives::OpaqueExtrinsic as UncheckedExtrinsic;
  60. /// Opaque block header type.
  61. pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
  62. /// Opaque block type.
  63. pub type Block = generic::Block<Header, UncheckedExtrinsic>;
  64. /// Opaque block identifier type.
  65. pub type BlockId = generic::BlockId<Block>;
  66. pub type SessionHandlers = (Grandpa, Babe);
  67. impl_opaque_keys! {
  68. pub struct SessionKeys {
  69. #[id(key_types::GRANDPA)]
  70. pub grandpa: GrandpaId,
  71. #[id(key_types::BABE)]
  72. pub babe: BabeId,
  73. }
  74. }
  75. }
  76. /// This runtime version.
  77. pub const VERSION: RuntimeVersion = RuntimeVersion {
  78. spec_name: create_runtime_str!("joystream-node"),
  79. impl_name: create_runtime_str!("joystream-node"),
  80. authoring_version: 0,
  81. spec_version: 6,
  82. impl_version: 0,
  83. apis: RUNTIME_API_VERSIONS,
  84. };
  85. /// Constants for Babe.
  86. /// Since BABE is probabilistic this is the average expected block time that
  87. /// we are targetting. Blocks will be produced at a minimum duration defined
  88. /// by `SLOT_DURATION`, but some slots will not be allocated to any
  89. /// authority and hence no block will be produced. We expect to have this
  90. /// block time on average following the defined slot duration and the value
  91. /// of `c` configured for BABE (where `1 - c` represents the probability of
  92. /// a slot being empty).
  93. /// This value is only used indirectly to define the unit constants below
  94. /// that are expressed in blocks. The rest of the code should use
  95. /// `SLOT_DURATION` instead (like the timestamp module for calculating the
  96. /// minimum period).
  97. /// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
  98. pub const MILLISECS_PER_BLOCK: u64 = 6000;
  99. pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
  100. pub const EPOCH_DURATION_IN_BLOCKS: u32 = 10 * MINUTES;
  101. // These time units are defined in number of blocks.
  102. pub const MINUTES: BlockNumber = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
  103. pub const HOURS: BlockNumber = MINUTES * 60;
  104. pub const DAYS: BlockNumber = HOURS * 24;
  105. // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks.
  106. pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
  107. /// The version infromation used to identify this runtime when compiled natively.
  108. #[cfg(feature = "std")]
  109. pub fn native_version() -> NativeVersion {
  110. NativeVersion {
  111. runtime_version: VERSION,
  112. can_author_with: Default::default(),
  113. }
  114. }
  115. parameter_types! {
  116. pub const BlockHashCount: BlockNumber = 250;
  117. pub const MaximumBlockWeight: Weight = 1_000_000;
  118. pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
  119. pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
  120. pub const Version: RuntimeVersion = VERSION;
  121. }
  122. impl system::Trait for Runtime {
  123. /// The identifier used to distinguish between accounts.
  124. type AccountId = AccountId;
  125. /// The aggregated dispatch type that is available for extrinsics.
  126. type Call = Call;
  127. /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
  128. type Lookup = Indices;
  129. /// The index type for storing how many extrinsics an account has signed.
  130. type Index = Index;
  131. /// The index type for blocks.
  132. type BlockNumber = BlockNumber;
  133. /// The type for hashing blocks and tries.
  134. type Hash = Hash;
  135. /// The hashing algorithm used.
  136. type Hashing = BlakeTwo256;
  137. /// The header type.
  138. type Header = generic::Header<BlockNumber, BlakeTwo256>;
  139. /// The ubiquitous event type.
  140. type Event = Event;
  141. /// Update weight (to fee) multiplier per-block.
  142. type WeightMultiplierUpdate = ();
  143. /// The ubiquitous origin type.
  144. type Origin = Origin;
  145. /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
  146. type BlockHashCount = BlockHashCount;
  147. /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok.
  148. type MaximumBlockWeight = MaximumBlockWeight;
  149. /// Maximum size of all encoded transactions (in bytes) that are allowed in one block.
  150. type MaximumBlockLength = MaximumBlockLength;
  151. /// Portion of the block weight that is available to all normal transactions.
  152. type AvailableBlockRatio = AvailableBlockRatio;
  153. type Version = Version;
  154. }
  155. parameter_types! {
  156. pub const EpochDuration: u64 = EPOCH_DURATION_IN_BLOCKS as u64;
  157. pub const ExpectedBlockTime: u64 = MILLISECS_PER_BLOCK;
  158. }
  159. impl babe::Trait for Runtime {
  160. type EpochDuration = EpochDuration;
  161. type ExpectedBlockTime = ExpectedBlockTime;
  162. }
  163. impl grandpa::Trait for Runtime {
  164. type Event = Event;
  165. }
  166. impl indices::Trait for Runtime {
  167. /// The type for recording indexing into the account enumeration. If this ever overflows, there
  168. /// will be problems!
  169. type AccountIndex = u32;
  170. /// Use the standard means of resolving an index hint from an id.
  171. type ResolveHint = indices::SimpleResolveHint<Self::AccountId, Self::AccountIndex>;
  172. /// Determine whether an account is dead.
  173. type IsDeadAccount = Balances;
  174. /// The ubiquitous event type.
  175. type Event = Event;
  176. }
  177. parameter_types! {
  178. pub const MinimumPeriod: u64 = 5000;
  179. }
  180. impl timestamp::Trait for Runtime {
  181. /// A timestamp: milliseconds since the unix epoch.
  182. type Moment = u64;
  183. type OnTimestampSet = Babe;
  184. type MinimumPeriod = MinimumPeriod;
  185. }
  186. parameter_types! {
  187. pub const ExistentialDeposit: u128 = 0;
  188. pub const TransferFee: u128 = 0;
  189. pub const CreationFee: u128 = 0;
  190. pub const TransactionBaseFee: u128 = 1;
  191. pub const TransactionByteFee: u128 = 0;
  192. }
  193. impl balances::Trait for Runtime {
  194. /// The type for recording an account's balance.
  195. type Balance = Balance;
  196. /// What to do if an account's free balance gets zeroed.
  197. type OnFreeBalanceZero = ();
  198. /// What to do if a new account is created.
  199. type OnNewAccount = Indices;
  200. /// The ubiquitous event type.
  201. type Event = Event;
  202. type TransactionPayment = ();
  203. type DustRemoval = ();
  204. type TransferPayment = ();
  205. type ExistentialDeposit = ExistentialDeposit;
  206. type TransferFee = TransferFee;
  207. type CreationFee = CreationFee;
  208. type TransactionBaseFee = TransactionBaseFee;
  209. type TransactionByteFee = TransactionByteFee;
  210. type WeightToFee = ConvertInto;
  211. }
  212. impl sudo::Trait for Runtime {
  213. type Event = Event;
  214. type Proposal = Call;
  215. }
  216. pub mod currency;
  217. pub mod governance;
  218. use governance::{council, election, proposals};
  219. pub mod storage;
  220. use storage::{data_directory, data_object_storage_registry, data_object_type_registry, downloads};
  221. mod membership;
  222. mod memo;
  223. mod traits;
  224. pub use forum;
  225. use membership::members;
  226. mod migration;
  227. mod roles;
  228. mod service_discovery;
  229. use service_discovery::discovery;
  230. use roles::actors;
  231. /// Alias for ContentId, used in various places.
  232. pub type ContentId = primitives::H256;
  233. impl currency::GovernanceCurrency for Runtime {
  234. type Currency = balances::Module<Self>;
  235. }
  236. impl governance::proposals::Trait for Runtime {
  237. type Event = Event;
  238. type Members = Members;
  239. }
  240. impl governance::election::Trait for Runtime {
  241. type Event = Event;
  242. type CouncilElected = (Council,);
  243. type Members = Members;
  244. }
  245. impl governance::council::Trait for Runtime {
  246. type Event = Event;
  247. type CouncilTermEnded = (CouncilElection,);
  248. }
  249. impl memo::Trait for Runtime {
  250. type Event = Event;
  251. }
  252. impl storage::data_object_type_registry::Trait for Runtime {
  253. type Event = Event;
  254. type DataObjectTypeId = u64;
  255. }
  256. impl storage::data_directory::Trait for Runtime {
  257. type Event = Event;
  258. type ContentId = ContentId;
  259. type SchemaId = u64;
  260. type Members = Members;
  261. type Roles = LookupRoles;
  262. type IsActiveDataObjectType = DataObjectTypeRegistry;
  263. }
  264. impl storage::downloads::Trait for Runtime {
  265. type Event = Event;
  266. type DownloadSessionId = u64;
  267. type ContentHasStorage = DataObjectStorageRegistry;
  268. }
  269. impl storage::data_object_storage_registry::Trait for Runtime {
  270. type Event = Event;
  271. type DataObjectStorageRelationshipId = u64;
  272. type Members = Members;
  273. type Roles = LookupRoles;
  274. type ContentIdExists = DataDirectory;
  275. }
  276. fn random_index(upper_bound: usize) -> usize {
  277. let seed = <system::Module<Runtime>>::random_seed();
  278. let mut rand: u64 = 0;
  279. for offset in 0..8 {
  280. rand += (seed.as_ref()[offset] as u64) << offset;
  281. }
  282. (rand as usize) % upper_bound
  283. }
  284. pub struct LookupRoles {}
  285. impl traits::Roles<Runtime> for LookupRoles {
  286. fn is_role_account(account_id: &<Runtime as system::Trait>::AccountId) -> bool {
  287. <actors::Module<Runtime>>::is_role_account(account_id)
  288. }
  289. fn account_has_role(
  290. account_id: &<Runtime as system::Trait>::AccountId,
  291. role: actors::Role,
  292. ) -> bool {
  293. <actors::Module<Runtime>>::account_has_role(account_id, role)
  294. }
  295. fn random_account_for_role(
  296. role: actors::Role,
  297. ) -> Result<<Runtime as system::Trait>::AccountId, &'static str> {
  298. let ids = <actors::AccountIdsByRole<Runtime>>::get(role);
  299. let live_ids: Vec<<Runtime as system::Trait>::AccountId> = ids
  300. .into_iter()
  301. .filter(|id| !<discovery::Module<Runtime>>::is_account_info_expired(id))
  302. .collect();
  303. if live_ids.len() == 0 {
  304. Err("no staked account found")
  305. } else {
  306. let index = random_index(live_ids.len());
  307. Ok(live_ids[index].clone())
  308. }
  309. }
  310. }
  311. impl members::Trait for Runtime {
  312. type Event = Event;
  313. type MemberId = u64;
  314. type PaidTermId = u64;
  315. type SubscriptionId = u64;
  316. type Roles = LookupRoles;
  317. }
  318. /*
  319. * Forum module integration
  320. *
  321. * ForumUserRegistry could have been implemented directly on
  322. * the membership module, and likewise ForumUser on Profile,
  323. * however this approach is more loosley coupled.
  324. *
  325. * Further exploration required to decide what the long
  326. * run convention should be.
  327. */
  328. /// Shim registry which will proxy ForumUserRegistry behaviour to the members module
  329. pub struct ShimMembershipRegistry {}
  330. impl forum::ForumUserRegistry<AccountId> for ShimMembershipRegistry {
  331. fn get_forum_user(id: &AccountId) -> Option<forum::ForumUser<AccountId>> {
  332. if let Some(_profile) = members::Module::<Runtime>::get_profile(id) {
  333. // For now the profile is not used for anything,
  334. // but in the future we may need it to read out more
  335. // information possibly required to construct a
  336. // ForumUser.
  337. // Now convert member profile to a forum user
  338. Some(forum::ForumUser { id: id.clone() })
  339. } else {
  340. None
  341. }
  342. }
  343. }
  344. impl forum::Trait for Runtime {
  345. type Event = Event;
  346. type MembershipRegistry = ShimMembershipRegistry;
  347. }
  348. impl migration::Trait for Runtime {
  349. type Event = Event;
  350. }
  351. impl actors::Trait for Runtime {
  352. type Event = Event;
  353. type Members = Members;
  354. type OnActorRemoved = HandleActorRemoved;
  355. }
  356. pub struct HandleActorRemoved {}
  357. impl actors::ActorRemoved<Runtime> for HandleActorRemoved {
  358. fn actor_removed(actor: &<Runtime as system::Trait>::AccountId) {
  359. Discovery::remove_account_info(actor);
  360. }
  361. }
  362. impl discovery::Trait for Runtime {
  363. type Event = Event;
  364. type Roles = LookupRoles;
  365. }
  366. construct_runtime!(
  367. pub enum Runtime where
  368. Block = Block,
  369. NodeBlock = opaque::Block,
  370. UncheckedExtrinsic = UncheckedExtrinsic
  371. {
  372. System: system::{Module, Call, Storage, Config, Event},
  373. Timestamp: timestamp::{Module, Call, Storage, Inherent},
  374. Babe: babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
  375. Grandpa: grandpa::{Module, Call, Storage, Config, Event},
  376. Indices: indices::{default, Config<T>},
  377. Balances: balances,
  378. Sudo: sudo,
  379. // Joystream
  380. Proposals: proposals::{Module, Call, Storage, Event<T>, Config<T>},
  381. CouncilElection: election::{Module, Call, Storage, Event<T>, Config<T>},
  382. Council: council::{Module, Call, Storage, Event<T>, Config<T>},
  383. Memo: memo::{Module, Call, Storage, Event<T>},
  384. Members: members::{Module, Call, Storage, Event<T>, Config<T>},
  385. Forum: forum::{Module, Call, Storage, Event<T>, Config<T>},
  386. Migration: migration::{Module, Call, Storage, Event<T>},
  387. Actors: actors::{Module, Call, Storage, Event<T>, Config<T>},
  388. DataObjectTypeRegistry: data_object_type_registry::{Module, Call, Storage, Event<T>, Config<T>},
  389. DataDirectory: data_directory::{Module, Call, Storage, Event<T>},
  390. DataObjectStorageRegistry: data_object_storage_registry::{Module, Call, Storage, Event<T>, Config<T>},
  391. DownloadSessions: downloads::{Module, Call, Storage, Event<T>, Config<T>},
  392. Discovery: discovery::{Module, Call, Storage, Event<T>},
  393. }
  394. );
  395. /// The address format for describing accounts.
  396. pub type Address = <Indices as StaticLookup>::Source;
  397. /// Block header type as expected by this runtime.
  398. pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
  399. /// Block type as expected by this runtime.
  400. pub type Block = generic::Block<Header, UncheckedExtrinsic>;
  401. /// A Block signed with a Justification
  402. pub type SignedBlock = generic::SignedBlock<Block>;
  403. /// BlockId type as expected by this runtime.
  404. pub type BlockId = generic::BlockId<Block>;
  405. /// The SignedExtension to the basic transaction logic.
  406. pub type SignedExtra = (
  407. system::CheckVersion<Runtime>,
  408. system::CheckGenesis<Runtime>,
  409. system::CheckEra<Runtime>,
  410. system::CheckNonce<Runtime>,
  411. system::CheckWeight<Runtime>,
  412. balances::TakeFees<Runtime>,
  413. );
  414. /// Unchecked extrinsic type as expected by this runtime.
  415. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
  416. /// Extrinsic type that has already been checked.
  417. pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
  418. /// Executive: handles dispatch to the various modules.
  419. pub type Executive =
  420. executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
  421. impl_runtime_apis! {
  422. impl client_api::Core<Block> for Runtime {
  423. fn version() -> RuntimeVersion {
  424. VERSION
  425. }
  426. fn execute_block(block: Block) {
  427. Executive::execute_block(block)
  428. }
  429. fn initialize_block(header: &<Block as BlockT>::Header) {
  430. Executive::initialize_block(header)
  431. }
  432. }
  433. impl client_api::Metadata<Block> for Runtime {
  434. fn metadata() -> OpaqueMetadata {
  435. Runtime::metadata().into()
  436. }
  437. }
  438. impl block_builder_api::BlockBuilder<Block> for Runtime {
  439. fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyResult {
  440. Executive::apply_extrinsic(extrinsic)
  441. }
  442. fn finalize_block() -> <Block as BlockT>::Header {
  443. Executive::finalize_block()
  444. }
  445. fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
  446. data.create_extrinsics()
  447. }
  448. fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
  449. data.check_extrinsics(&block)
  450. }
  451. fn random_seed() -> <Block as BlockT>::Hash {
  452. System::random_seed()
  453. }
  454. }
  455. impl client_api::TaggedTransactionQueue<Block> for Runtime {
  456. fn validate_transaction(tx: <Block as BlockT>::Extrinsic) -> TransactionValidity {
  457. Executive::validate_transaction(tx)
  458. }
  459. }
  460. impl offchain_primitives::OffchainWorkerApi<Block> for Runtime {
  461. fn offchain_worker(number: NumberFor<Block>) {
  462. Executive::offchain_worker(number)
  463. }
  464. }
  465. impl fg_primitives::GrandpaApi<Block> for Runtime {
  466. fn grandpa_pending_change(digest: &DigestFor<Block>)
  467. -> Option<ScheduledChange<NumberFor<Block>>>
  468. {
  469. Grandpa::pending_change(digest)
  470. }
  471. fn grandpa_forced_change(digest: &DigestFor<Block>)
  472. -> Option<(NumberFor<Block>, ScheduledChange<NumberFor<Block>>)>
  473. {
  474. Grandpa::forced_change(digest)
  475. }
  476. fn grandpa_authorities() -> Vec<(GrandpaId, GrandpaWeight)> {
  477. Grandpa::grandpa_authorities()
  478. }
  479. }
  480. impl babe_primitives::BabeApi<Block> for Runtime {
  481. fn startup_data() -> babe_primitives::BabeConfiguration {
  482. // The choice of `c` parameter (where `1 - c` represents the
  483. // probability of a slot being empty), is done in accordance to the
  484. // slot duration and expected target block time, for safely
  485. // resisting network delays of maximum two seconds.
  486. // <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
  487. babe_primitives::BabeConfiguration {
  488. median_required_blocks: 1000,
  489. slot_duration: Babe::slot_duration(),
  490. c: PRIMARY_PROBABILITY,
  491. }
  492. }
  493. fn epoch() -> babe_primitives::Epoch {
  494. babe_primitives::Epoch {
  495. start_slot: Babe::epoch_start_slot(),
  496. authorities: Babe::authorities(),
  497. epoch_index: Babe::epoch_index(),
  498. randomness: Babe::randomness(),
  499. duration: EpochDuration::get(),
  500. secondary_slots: Babe::secondary_slots().0,
  501. }
  502. }
  503. }
  504. impl substrate_session::SessionKeys<Block> for Runtime {
  505. fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
  506. let seed = seed.as_ref().map(|s| rstd::str::from_utf8(&s).expect("Seed is an utf8 string"));
  507. opaque::SessionKeys::generate(seed)
  508. }
  509. }
  510. }