lib.rs 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. //! The Joystream Substrate Node runtime.
  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. //Substrate internal issues.
  6. #![allow(clippy::large_enum_variant)]
  7. #![allow(clippy::unnecessary_mut_passed)]
  8. // Make the WASM binary available.
  9. // This is required only by the node build.
  10. // A dummy wasm_binary.rs will be built for the IDE.
  11. #[cfg(feature = "std")]
  12. include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
  13. mod integration;
  14. mod migration;
  15. #[cfg(test)]
  16. mod tests; // Runtime integration tests
  17. use frame_support::inherent::{CheckInherentsResult, InherentData};
  18. use frame_support::traits::KeyOwnerProofSystem;
  19. use frame_support::weights::{IdentityFee, Weight};
  20. use frame_support::{
  21. construct_runtime, parameter_types, traits::Randomness, StorageMap, StorageValue,
  22. };
  23. use pallet_grandpa::fg_primitives;
  24. use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
  25. use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
  26. use pallet_session::historical as pallet_session_historical;
  27. use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
  28. use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
  29. use sp_api::impl_runtime_apis;
  30. use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
  31. use sp_core::crypto::KeyTypeId;
  32. use sp_core::OpaqueMetadata;
  33. use sp_runtime::curve::PiecewiseLinear;
  34. use sp_runtime::traits::{
  35. BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, StaticLookup, Verify,
  36. };
  37. use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity};
  38. use sp_runtime::{
  39. create_runtime_str, generic, impl_opaque_keys, ApplyExtrinsicResult, FixedPointNumber,
  40. MultiSignature, Perbill, Perquintill,
  41. };
  42. use sp_std::boxed::Box;
  43. use sp_std::vec::Vec;
  44. #[cfg(feature = "std")]
  45. use sp_version::NativeVersion;
  46. use sp_version::RuntimeVersion;
  47. use system::EnsureRoot;
  48. use integration::proposals::{CouncilManager, ExtrinsicProposalEncoder, MembershipOriginValidator};
  49. use content_working_group as content_wg;
  50. use governance::{council, election};
  51. use storage::{data_directory, data_object_storage_registry, data_object_type_registry};
  52. /// Priority for a transaction. Additive. Higher is better.
  53. pub type TransactionPriority = u64;
  54. /// Alias for ContentId, used in various places.
  55. pub type ContentId = sp_core::H256;
  56. /// An index to a block.
  57. pub type BlockNumber = u32;
  58. /// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
  59. pub type Signature = MultiSignature;
  60. /// Some way of identifying an account on the chain. We intentionally make it equivalent
  61. /// to the public key of our transaction signing scheme.
  62. pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
  63. /// The type for looking up accounts. We don't expect more than 4 billion of them, but you
  64. /// never know...
  65. pub type AccountIndex = u32;
  66. /// Balance of an account.
  67. pub type Balance = u128;
  68. /// Index of a transaction in the chain.
  69. pub type Index = u32;
  70. /// A hash of some data used by the chain.
  71. pub type Hash = sp_core::H256;
  72. /// Digest item type.
  73. pub type DigestItem = generic::DigestItem<Hash>;
  74. /// Moment type
  75. pub type Moment = u64;
  76. /// Credential type
  77. pub type Credential = u64;
  78. /// Represents a thread identifier for both Forum and Proposals Discussion
  79. ///
  80. /// Note: Both modules expose type names ThreadId and PostId (which are defined on their Trait) and
  81. /// used in state storage and dispatchable method's argument types,
  82. /// and are therefore part of the public API/metadata of the runtime.
  83. /// In the currenlty version the polkadot-js/api that is used and is compatible with the runtime,
  84. /// the type registry has flat namespace and its not possible
  85. /// to register identically named types from different modules, separately. And so we MUST configure
  86. /// the underlying types to be identicaly to avoid issues with encoding/decoding these types on the client side.
  87. pub type ThreadId = u64;
  88. /// Represents a post identifier for both Forum and Proposals Discussion
  89. ///
  90. /// See the Note about ThreadId
  91. pub type PostId = u64;
  92. /// Represent an actor in membership group, which is the same in the working groups.
  93. pub type ActorId = u64;
  94. /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
  95. /// the specifics of the runtime. They can then be made to be agnostic over specific formats
  96. /// of data like extrinsics, allowing for them to continue syncing the network through upgrades
  97. /// to even the core datastructures.
  98. pub mod opaque {
  99. use super::*;
  100. pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
  101. pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
  102. pub type Block = generic::Block<Header, UncheckedExtrinsic>;
  103. pub type BlockId = generic::BlockId<Block>;
  104. pub type SessionHandlers = (Grandpa, Babe, ImOnline);
  105. impl_opaque_keys! {
  106. pub struct SessionKeys {
  107. pub grandpa: Grandpa,
  108. pub babe: Babe,
  109. pub im_online: ImOnline,
  110. }
  111. }
  112. }
  113. /// This runtime version.
  114. pub const VERSION: RuntimeVersion = RuntimeVersion {
  115. spec_name: create_runtime_str!("joystream-node"),
  116. impl_name: create_runtime_str!("joystream-node"),
  117. authoring_version: 6,
  118. spec_version: 20,
  119. impl_version: 0,
  120. apis: RUNTIME_API_VERSIONS,
  121. transaction_version: 0, //TODO ??
  122. };
  123. /// Constants for Babe.
  124. /// Since BABE is probabilistic this is the average expected block time that
  125. /// we are targetting. Blocks will be produced at a minimum duration defined
  126. /// by `SLOT_DURATION`, but some slots will not be allocated to any
  127. /// authority and hence no block will be produced. We expect to have this
  128. /// block time on average following the defined slot duration and the value
  129. /// of `c` configured for BABE (where `1 - c` represents the probability of
  130. /// a slot being empty).
  131. /// This value is only used indirectly to define the unit constants below
  132. /// that are expressed in blocks. The rest of the code should use
  133. /// `SLOT_DURATION` instead (like the timestamp module for calculating the
  134. /// minimum period).
  135. /// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
  136. pub const MILLISECS_PER_BLOCK: Moment = 6000;
  137. pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000;
  138. pub const SLOT_DURATION: Moment = 6000;
  139. pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES;
  140. pub const EPOCH_DURATION_IN_SLOTS: u64 = {
  141. const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64;
  142. (EPOCH_DURATION_IN_BLOCKS as f64 * SLOT_FILL_RATE) as u64
  143. };
  144. // These time units are defined in number of blocks.
  145. pub const MINUTES: BlockNumber = 60 / (SECS_PER_BLOCK as BlockNumber);
  146. pub const HOURS: BlockNumber = MINUTES * 60;
  147. pub const DAYS: BlockNumber = HOURS * 24;
  148. // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks.
  149. pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
  150. /// The version information used to identify this runtime when compiled natively.
  151. #[cfg(feature = "std")]
  152. pub fn native_version() -> NativeVersion {
  153. NativeVersion {
  154. runtime_version: VERSION,
  155. can_author_with: Default::default(),
  156. }
  157. }
  158. parameter_types! {
  159. pub const BlockHashCount: BlockNumber = 250;
  160. /// We allow for 2 seconds of compute with a 6 second average block time.
  161. pub const MaximumBlockWeight: Weight = 2 * frame_support::weights::constants::WEIGHT_PER_SECOND;
  162. pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
  163. pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
  164. pub const Version: RuntimeVersion = VERSION;
  165. }
  166. impl system::Trait for Runtime {
  167. /// The identifier used to distinguish between accounts.
  168. type AccountId = AccountId;
  169. /// The aggregated dispatch type that is available for extrinsics.
  170. type Call = Call;
  171. /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
  172. type Lookup = Indices;
  173. /// The index type for storing how many extrinsics an account has signed.
  174. type Index = Index;
  175. /// The index type for blocks.
  176. type BlockNumber = BlockNumber;
  177. /// The type for hashing blocks and tries.
  178. type Hash = Hash;
  179. /// The hashing algorithm used.
  180. type Hashing = BlakeTwo256;
  181. /// The header type.
  182. type Header = generic::Header<BlockNumber, BlakeTwo256>;
  183. /// The ubiquitous event type.
  184. type Event = Event;
  185. /// The ubiquitous origin type.
  186. type Origin = Origin;
  187. /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
  188. type BlockHashCount = BlockHashCount;
  189. /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok.
  190. type MaximumBlockWeight = MaximumBlockWeight;
  191. /// Maximum size of all encoded transactions (in bytes) that are allowed in one block.
  192. type MaximumBlockLength = MaximumBlockLength;
  193. /// Portion of the block weight that is available to all normal transactions.
  194. type AvailableBlockRatio = AvailableBlockRatio;
  195. type Version = Version;
  196. //TODO
  197. type BaseCallFilter = ();
  198. type DbWeight = ();
  199. type BlockExecutionWeight = ();
  200. type ExtrinsicBaseWeight = ();
  201. type MaximumExtrinsicWeight = ();
  202. type ModuleToIndex = ();
  203. type AccountData = pallet_balances::AccountData<Balance>;
  204. type OnNewAccount = ();
  205. type OnKilledAccount = ();
  206. }
  207. /*
  208. type BaseCallFilter = ();
  209. type Origin = Origin;
  210. type Call = Call;
  211. type Index = Index;
  212. type BlockNumber = BlockNumber;
  213. type Hash = Hash;
  214. type Hashing = BlakeTwo256;
  215. type AccountId = AccountId;
  216. type Lookup = Indices;
  217. type Header = generic::Header<BlockNumber, BlakeTwo256>;
  218. type Event = Event;
  219. type BlockHashCount = BlockHashCount;
  220. type MaximumBlockWeight = MaximumBlockWeight;
  221. type DbWeight = RocksDbWeight;
  222. type BlockExecutionWeight = BlockExecutionWeight;
  223. type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
  224. type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
  225. type MaximumBlockLength = MaximumBlockLength;
  226. type AvailableBlockRatio = AvailableBlockRatio;
  227. type Version = Version;
  228. type ModuleToIndex = ModuleToIndex;
  229. type AccountData = pallet_balances::AccountData<Balance>;
  230. type OnNewAccount = ();
  231. type OnKilledAccount = ();
  232. */
  233. parameter_types! {
  234. pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
  235. pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
  236. }
  237. impl pallet_babe::Trait for Runtime {
  238. type EpochDuration = EpochDuration;
  239. type ExpectedBlockTime = ExpectedBlockTime;
  240. type EpochChangeTrigger = pallet_babe::ExternalTrigger;
  241. }
  242. impl pallet_grandpa::Trait for Runtime {
  243. type Event = Event;
  244. //toDO
  245. type Call = Call;
  246. type KeyOwnerProofSystem = ();
  247. type KeyOwnerProof =
  248. <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
  249. type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
  250. KeyTypeId,
  251. GrandpaId,
  252. )>>::IdentificationTuple;
  253. type HandleEquivocation = ();
  254. }
  255. /*
  256. type KeyOwnerProofSystem = Historical;
  257. type KeyOwnerProof =
  258. <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
  259. type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
  260. KeyTypeId,
  261. GrandpaId,
  262. )>>::IdentificationTuple;
  263. type HandleEquivocation = pallet_grandpa::EquivocationHandler<
  264. Self::KeyOwnerIdentification,
  265. node_primitives::report::ReporterAppCrypto,
  266. Runtime,
  267. Offences,
  268. >;
  269. */
  270. impl<C> system::offchain::SendTransactionTypes<C> for Runtime
  271. where
  272. Call: From<C>,
  273. {
  274. type Extrinsic = UncheckedExtrinsic;
  275. type OverarchingCall = Call;
  276. }
  277. impl pallet_indices::Trait for Runtime {
  278. /// The type for recording indexing into the account enumeration. If this ever overflows, there
  279. /// will be problems!
  280. type AccountIndex = u32;
  281. /// Use the standard means of resolving an index hint from an id.
  282. //type ResolveHint = pallet_indices::SimpleResolveHint<Self::AccountId, Self::AccountIndex>;
  283. type Currency = Balances;
  284. //toDO
  285. type Deposit = ();
  286. type Event = Event;
  287. }
  288. parameter_types! {
  289. pub const MinimumPeriod: Moment = SLOT_DURATION / 2;
  290. }
  291. impl timestamp::Trait for Runtime {
  292. type Moment = Moment;
  293. type OnTimestampSet = Babe;
  294. type MinimumPeriod = MinimumPeriod;
  295. }
  296. parameter_types! {
  297. pub const ExistentialDeposit: u128 = 0;
  298. pub const TransferFee: u128 = 0;
  299. pub const CreationFee: u128 = 0;
  300. pub const InitialMembersBalance: u32 = 2000;
  301. }
  302. impl pallet_balances::Trait for Runtime {
  303. /// The type for recording an account's balance.
  304. type Balance = Balance;
  305. // /// What to do if an account's free balance gets zeroed.
  306. // type OnFreeBalanceZero = (Staking, Session);
  307. // /// What to do if a new account is created.
  308. // type OnNewAccount = (); // Indices; // disable use of Indices feature
  309. // /// The ubiquitous event type.
  310. type Event = Event;
  311. type DustRemoval = ();
  312. //type TransferPayment = ();
  313. type ExistentialDeposit = ExistentialDeposit;
  314. // type TransferFee = TransferFee;
  315. // type CreationFee = CreationFee;
  316. type AccountStore = System;
  317. }
  318. parameter_types! {
  319. pub const TransactionByteFee: Balance = 1; // TODO: adjust fee
  320. pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
  321. pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000);
  322. pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128);
  323. }
  324. impl pallet_transaction_payment::Trait for Runtime {
  325. type Currency = Balances;
  326. type OnTransactionPayment = ();
  327. type TransactionByteFee = TransactionByteFee;
  328. type WeightToFee = IdentityFee<Balance>; // TODO: adjust weight
  329. type FeeMultiplierUpdate =
  330. TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
  331. }
  332. impl pallet_sudo::Trait for Runtime {
  333. type Event = Event;
  334. type Call = Call;
  335. }
  336. parameter_types! {
  337. pub const UncleGenerations: BlockNumber = 5;
  338. }
  339. impl pallet_authorship::Trait for Runtime {
  340. type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
  341. type UncleGenerations = UncleGenerations;
  342. type FilterUncle = ();
  343. type EventHandler = Staking;
  344. }
  345. type SessionHandlers = (Grandpa, Babe, ImOnline);
  346. impl_opaque_keys! {
  347. pub struct SessionKeys {
  348. pub grandpa: Grandpa,
  349. pub babe: Babe,
  350. pub im_online: ImOnline,
  351. }
  352. }
  353. // NOTE: `SessionHandler` and `SessionKeys` are co-dependent: One key will be used for each handler.
  354. // The number and order of items in `SessionHandler` *MUST* be the same number and order of keys in
  355. // `SessionKeys`.
  356. // TODO: Introduce some structure to tie these together to make it a bit less of a footgun. This
  357. // should be easy, since OneSessionHandler trait provides the `Key` as an associated type. #2858
  358. parameter_types! {
  359. pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
  360. }
  361. impl pallet_session::Trait for Runtime {
  362. type Event = Event;
  363. type ValidatorId = AccountId;
  364. type ValidatorIdOf = pallet_staking::StashOf<Self>;
  365. type ShouldEndSession = Babe;
  366. type NextSessionRotation = Babe;
  367. type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
  368. type SessionHandler = SessionHandlers;
  369. type Keys = SessionKeys;
  370. type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
  371. }
  372. impl pallet_session::historical::Trait for Runtime {
  373. type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
  374. type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
  375. }
  376. pallet_staking_reward_curve::build! {
  377. const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
  378. min_inflation: 0_025_000,
  379. max_inflation: 0_300_000,
  380. ideal_stake: 0_300_000,
  381. falloff: 0_050_000,
  382. max_piece_count: 100,
  383. test_precision: 0_005_000,
  384. );
  385. }
  386. parameter_types! {
  387. pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _;
  388. pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
  389. /// We prioritize im-online heartbeats over election solution submission.
  390. pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
  391. }
  392. parameter_types! {
  393. pub const SessionsPerEra: sp_staking::SessionIndex = 6;
  394. pub const BondingDuration: pallet_staking::EraIndex = 24;
  395. pub const SlashDeferDuration: pallet_staking::EraIndex = 6; // 1/4 the bonding duration.
  396. pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
  397. pub const MaxNominatorRewardedPerValidator: u32 = 64;
  398. pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;
  399. pub const MaxIterations: u32 = 10;
  400. // 0.05%. The higher the value, the more strict solution acceptance becomes.
  401. pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
  402. }
  403. impl pallet_staking::Trait for Runtime {
  404. type Currency = Balances;
  405. type UnixTime = Timestamp;
  406. type CurrencyToVote = common::currency::CurrencyToVoteHandler;
  407. type RewardRemainder = (); // Could be Treasury.
  408. type Event = Event;
  409. type Slash = (); // Where to send the slashed funds. Could be Treasury.
  410. type Reward = (); // Rewards are minted from the void.
  411. type SessionsPerEra = SessionsPerEra;
  412. type BondingDuration = BondingDuration;
  413. type SlashDeferDuration = SlashDeferDuration;
  414. type SlashCancelOrigin = EnsureRoot<AccountId>; // Requires sudo. Parity recommends: a super-majority of the council can cancel the slash.
  415. type SessionInterface = Self;
  416. type RewardCurve = RewardCurve;
  417. type NextNewSession = Session;
  418. type ElectionLookahead = MaxIterations;
  419. type Call = Call;
  420. type MaxIterations = MaxIterations;
  421. type MinSolutionScoreBump = MinSolutionScoreBump;
  422. type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
  423. type UnsignedPriority = StakingUnsignedPriority;
  424. }
  425. //type SubmitTransaction = TransactionSubmitter<ImOnlineId, Runtime, UncheckedExtrinsic>;
  426. impl pallet_im_online::Trait for Runtime {
  427. type AuthorityId = ImOnlineId;
  428. type Event = Event;
  429. type SessionDuration = SessionDuration;
  430. type ReportUnresponsiveness = Offences;
  431. type UnsignedPriority = ImOnlineUnsignedPriority;
  432. }
  433. impl pallet_offences::Trait for Runtime {
  434. type Event = Event;
  435. type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
  436. type OnOffenceHandler = Staking;
  437. type WeightSoftLimit = (); //OffencesWeightSoftLimit;
  438. }
  439. impl pallet_authority_discovery::Trait for Runtime {}
  440. parameter_types! {
  441. pub const WindowSize: BlockNumber = 101;
  442. pub const ReportLatency: BlockNumber = 1000;
  443. }
  444. impl pallet_finality_tracker::Trait for Runtime {
  445. type OnFinalizationStalled = Grandpa;
  446. type WindowSize = WindowSize;
  447. type ReportLatency = ReportLatency;
  448. }
  449. impl versioned_store::Trait for Runtime {
  450. type Event = Event;
  451. }
  452. impl versioned_store_permissions::Trait for Runtime {
  453. type Credential = Credential;
  454. type CredentialChecker = (
  455. integration::content_working_group::ContentWorkingGroupCredentials,
  456. SudoKeyHasAllCredentials,
  457. );
  458. type CreateClassPermissionsChecker = ContentLeadOrSudoKeyCanCreateClasses;
  459. }
  460. // Credential Checker that gives the sudo key holder all credentials
  461. pub struct SudoKeyHasAllCredentials {}
  462. impl versioned_store_permissions::CredentialChecker<Runtime> for SudoKeyHasAllCredentials {
  463. fn account_has_credential(
  464. account: &AccountId,
  465. _credential: <Runtime as versioned_store_permissions::Trait>::Credential,
  466. ) -> bool {
  467. <pallet_sudo::Module<Runtime>>::key() == *account
  468. }
  469. }
  470. // Allow sudo key holder permission to create classes
  471. pub struct SudoKeyCanCreateClasses {}
  472. impl versioned_store_permissions::CreateClassPermissionsChecker<Runtime>
  473. for SudoKeyCanCreateClasses
  474. {
  475. fn account_can_create_class_permissions(account: &AccountId) -> bool {
  476. <pallet_sudo::Module<Runtime>>::key() == *account
  477. }
  478. }
  479. pub struct ContentLeadOrSudoKeyCanCreateClasses {}
  480. impl versioned_store_permissions::CreateClassPermissionsChecker<Runtime>
  481. for ContentLeadOrSudoKeyCanCreateClasses
  482. {
  483. fn account_can_create_class_permissions(account: &AccountId) -> bool {
  484. ContentLeadCanCreateClasses::account_can_create_class_permissions(account)
  485. || SudoKeyCanCreateClasses::account_can_create_class_permissions(account)
  486. }
  487. }
  488. // Allow content working group lead to create classes in content directory
  489. pub struct ContentLeadCanCreateClasses {}
  490. impl versioned_store_permissions::CreateClassPermissionsChecker<Runtime>
  491. for ContentLeadCanCreateClasses
  492. {
  493. fn account_can_create_class_permissions(account: &AccountId) -> bool {
  494. // get current lead id
  495. let maybe_current_lead_id = content_wg::CurrentLeadId::<Runtime>::get();
  496. if let Some(lead_id) = maybe_current_lead_id {
  497. let lead = content_wg::LeadById::<Runtime>::get(lead_id);
  498. lead.role_account == *account
  499. } else {
  500. false
  501. }
  502. }
  503. }
  504. impl hiring::Trait for Runtime {
  505. type OpeningId = u64;
  506. type ApplicationId = u64;
  507. type ApplicationDeactivatedHandler = (); // TODO - what needs to happen?
  508. type StakeHandlerProvider = hiring::Module<Self>;
  509. }
  510. impl minting::Trait for Runtime {
  511. type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
  512. type MintId = u64;
  513. }
  514. impl recurring_rewards::Trait for Runtime {
  515. type PayoutStatusHandler = (); // TODO - deal with successful and failed payouts
  516. type RecipientId = u64;
  517. type RewardRelationshipId = u64;
  518. }
  519. parameter_types! {
  520. pub const StakePoolId: [u8; 8] = *b"joystake";
  521. }
  522. impl stake::Trait for Runtime {
  523. type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
  524. type StakePoolId = StakePoolId;
  525. type StakingEventsHandler = (
  526. crate::integration::content_working_group::ContentWorkingGroupStakingEventHandler,
  527. (
  528. crate::integration::proposals::StakingEventsHandler<Self>,
  529. crate::integration::working_group::StakingEventsHandler<Self>,
  530. ),
  531. );
  532. type StakeId = u64;
  533. type SlashId = u64;
  534. }
  535. impl content_wg::Trait for Runtime {
  536. type Event = Event;
  537. }
  538. impl common::currency::GovernanceCurrency for Runtime {
  539. type Currency = pallet_balances::Module<Self>;
  540. }
  541. impl governance::election::Trait for Runtime {
  542. type Event = Event;
  543. type CouncilElected = (Council, integration::proposals::CouncilElectedHandler);
  544. }
  545. impl governance::council::Trait for Runtime {
  546. type Event = Event;
  547. type CouncilTermEnded = (CouncilElection,);
  548. }
  549. impl memo::Trait for Runtime {
  550. type Event = Event;
  551. }
  552. parameter_types! {
  553. pub const MaxObjectsPerInjection: u32 = 100;
  554. }
  555. impl storage::data_object_type_registry::Trait for Runtime {
  556. type Event = Event;
  557. type DataObjectTypeId = u64;
  558. }
  559. impl storage::data_directory::Trait for Runtime {
  560. type Event = Event;
  561. type ContentId = ContentId;
  562. type StorageProviderHelper = integration::storage::StorageProviderHelper;
  563. type IsActiveDataObjectType = DataObjectTypeRegistry;
  564. type MemberOriginValidator = MembershipOriginValidator<Self>;
  565. type MaxObjectsPerInjection = MaxObjectsPerInjection;
  566. }
  567. impl storage::data_object_storage_registry::Trait for Runtime {
  568. type Event = Event;
  569. type DataObjectStorageRelationshipId = u64;
  570. type ContentIdExists = DataDirectory;
  571. }
  572. impl membership::Trait for Runtime {
  573. type Event = Event;
  574. type MemberId = u64;
  575. type PaidTermId = u64;
  576. type SubscriptionId = u64;
  577. type ActorId = ActorId;
  578. }
  579. /*
  580. * Forum module integration
  581. *
  582. * ForumUserRegistry could have been implemented directly on
  583. * the membership module, and likewise ForumUser on Profile,
  584. * however this approach is more loosely coupled.
  585. *
  586. * Further exploration required to decide what the long
  587. * run convention should be.
  588. */
  589. /// Shim registry which will proxy ForumUserRegistry behaviour to the members module
  590. pub struct ShimMembershipRegistry {}
  591. impl forum::ForumUserRegistry<AccountId> for ShimMembershipRegistry {
  592. fn get_forum_user(id: &AccountId) -> Option<forum::ForumUser<AccountId>> {
  593. if membership::Module::<Runtime>::is_member_account(id) {
  594. // For now we don't retreive the members profile since it is not used for anything,
  595. // but in the future we may need it to read out more
  596. // information possibly required to construct a
  597. // ForumUser.
  598. // Now convert member profile to a forum user
  599. Some(forum::ForumUser { id: id.clone() })
  600. } else {
  601. None
  602. }
  603. }
  604. }
  605. impl forum::Trait for Runtime {
  606. type Event = Event;
  607. type MembershipRegistry = ShimMembershipRegistry;
  608. type ThreadId = ThreadId;
  609. type PostId = PostId;
  610. }
  611. impl migration::Trait for Runtime {
  612. type Event = Event;
  613. }
  614. // The storage working group instance alias.
  615. pub type StorageWorkingGroupInstance = working_group::Instance2;
  616. parameter_types! {
  617. pub const MaxWorkerNumberLimit: u32 = 100;
  618. }
  619. impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
  620. type Event = Event;
  621. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  622. }
  623. impl service_discovery::Trait for Runtime {
  624. type Event = Event;
  625. }
  626. parameter_types! {
  627. pub const ProposalCancellationFee: u64 = 10000;
  628. pub const ProposalRejectionFee: u64 = 5000;
  629. pub const ProposalTitleMaxLength: u32 = 40;
  630. pub const ProposalDescriptionMaxLength: u32 = 3000;
  631. pub const ProposalMaxActiveProposalLimit: u32 = 5;
  632. }
  633. impl proposals_engine::Trait for Runtime {
  634. type Event = Event;
  635. type ProposerOriginValidator = MembershipOriginValidator<Self>;
  636. type VoterOriginValidator = CouncilManager<Self>;
  637. type TotalVotersCounter = CouncilManager<Self>;
  638. type ProposalId = u32;
  639. type StakeHandlerProvider = proposals_engine::DefaultStakeHandlerProvider;
  640. type CancellationFee = ProposalCancellationFee;
  641. type RejectionFee = ProposalRejectionFee;
  642. type TitleMaxLength = ProposalTitleMaxLength;
  643. type DescriptionMaxLength = ProposalDescriptionMaxLength;
  644. type MaxActiveProposalLimit = ProposalMaxActiveProposalLimit;
  645. type DispatchableCallCode = Call;
  646. }
  647. impl Default for Call {
  648. fn default() -> Self {
  649. panic!("shouldn't call default for Call");
  650. }
  651. }
  652. parameter_types! {
  653. pub const ProposalMaxPostEditionNumber: u32 = 0; // post update is disabled
  654. pub const ProposalMaxThreadInARowNumber: u32 = 100_000; // will not be used
  655. pub const ProposalThreadTitleLengthLimit: u32 = 40;
  656. pub const ProposalPostLengthLimit: u32 = 1000;
  657. }
  658. impl proposals_discussion::Trait for Runtime {
  659. type Event = Event;
  660. type PostAuthorOriginValidator = MembershipOriginValidator<Self>;
  661. type ThreadId = ThreadId;
  662. type PostId = PostId;
  663. type MaxPostEditionNumber = ProposalMaxPostEditionNumber;
  664. type ThreadTitleLengthLimit = ProposalThreadTitleLengthLimit;
  665. type PostLengthLimit = ProposalPostLengthLimit;
  666. type MaxThreadInARowNumber = ProposalMaxThreadInARowNumber;
  667. }
  668. parameter_types! {
  669. pub const TextProposalMaxLength: u32 = 5_000;
  670. pub const RuntimeUpgradeWasmProposalMaxLength: u32 = 2_000_000;
  671. }
  672. impl proposals_codex::Trait for Runtime {
  673. type MembershipOriginValidator = MembershipOriginValidator<Self>;
  674. type TextProposalMaxLength = TextProposalMaxLength;
  675. type RuntimeUpgradeWasmProposalMaxLength = RuntimeUpgradeWasmProposalMaxLength;
  676. type ProposalEncoder = ExtrinsicProposalEncoder;
  677. }
  678. construct_runtime!(
  679. pub enum Runtime where
  680. Block = Block,
  681. NodeBlock = opaque::Block,
  682. UncheckedExtrinsic = UncheckedExtrinsic
  683. {
  684. // Substrate
  685. System: system::{Module, Call, Storage, Config, Event<T>},
  686. Babe: pallet_babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
  687. Timestamp: timestamp::{Module, Call, Storage, Inherent},
  688. Authorship: pallet_authorship::{Module, Call, Storage, Inherent},
  689. Indices: pallet_indices::{Module, Call, Storage, Config<T>, Event<T>},
  690. Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
  691. TransactionPayment: pallet_transaction_payment::{Module, Storage},
  692. Staking: pallet_staking::{Module, Call, Config<T>, Storage, Event<T>, ValidateUnsigned},
  693. Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
  694. Historical: pallet_session_historical::{Module},
  695. FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent},
  696. Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},
  697. ImOnline: pallet_im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
  698. AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config},
  699. Offences: pallet_offences::{Module, Call, Storage, Event},
  700. RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
  701. Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},
  702. // Joystream
  703. Migration: migration::{Module, Call, Storage, Event<T>, Config},
  704. CouncilElection: election::{Module, Call, Storage, Event<T>, Config<T>},
  705. Council: council::{Module, Call, Storage, Event<T>, Config<T>},
  706. Memo: memo::{Module, Call, Storage, Event<T>},
  707. Members: membership::{Module, Call, Storage, Event<T>, Config<T>},
  708. Forum: forum::{Module, Call, Storage, Event<T>, Config<T>},
  709. VersionedStore: versioned_store::{Module, Call, Storage, Event<T>, Config},
  710. VersionedStorePermissions: versioned_store_permissions::{Module, Call, Storage},
  711. Stake: stake::{Module, Call, Storage},
  712. Minting: minting::{Module, Call, Storage},
  713. RecurringRewards: recurring_rewards::{Module, Call, Storage},
  714. Hiring: hiring::{Module, Call, Storage},
  715. ContentWorkingGroup: content_wg::{Module, Call, Storage, Event<T>, Config<T>},
  716. // --- Storage
  717. DataObjectTypeRegistry: data_object_type_registry::{Module, Call, Storage, Event<T>, Config<T>},
  718. DataDirectory: data_directory::{Module, Call, Storage, Event<T>},
  719. DataObjectStorageRegistry: data_object_storage_registry::{Module, Call, Storage, Event<T>, Config<T>},
  720. Discovery: service_discovery::{Module, Call, Storage, Event<T>},
  721. // --- Proposals
  722. ProposalsEngine: proposals_engine::{Module, Call, Storage, Event<T>},
  723. ProposalsDiscussion: proposals_discussion::{Module, Call, Storage, Event<T>},
  724. ProposalsCodex: proposals_codex::{Module, Call, Storage, Config<T>},
  725. // --- Working groups
  726. // reserved for the future use: ForumWorkingGroup: working_group::<Instance1>::{Module, Call, Storage, Event<T>},
  727. StorageWorkingGroup: working_group::<Instance2>::{Module, Call, Storage, Config<T>, Event<T>},
  728. }
  729. );
  730. /// The address format for describing accounts.
  731. pub type Address = <Indices as StaticLookup>::Source;
  732. /// Block header type as expected by this runtime.
  733. pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
  734. /// Block type as expected by this runtime.
  735. pub type Block = generic::Block<Header, UncheckedExtrinsic>;
  736. /// A Block signed with a Justification
  737. pub type SignedBlock = generic::SignedBlock<Block>;
  738. /// BlockId type as expected by this runtime.
  739. pub type BlockId = generic::BlockId<Block>;
  740. /// The SignedExtension to the basic transaction logic.
  741. pub type SignedExtra = (
  742. system::CheckSpecVersion<Runtime>,
  743. system::CheckTxVersion<Runtime>,
  744. system::CheckGenesis<Runtime>,
  745. system::CheckEra<Runtime>,
  746. system::CheckNonce<Runtime>,
  747. system::CheckWeight<Runtime>,
  748. pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
  749. pallet_grandpa::ValidateEquivocationReport<Runtime>,
  750. );
  751. /// Unchecked extrinsic type as expected by this runtime.
  752. pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
  753. /// Extrinsic type that has already been checked.
  754. pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
  755. /// Executive: handles dispatch to the various modules.
  756. pub type Executive =
  757. frame_executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
  758. impl_runtime_apis! {
  759. impl sp_api::Core<Block> for Runtime {
  760. fn version() -> RuntimeVersion {
  761. VERSION
  762. }
  763. fn execute_block(block: Block) {
  764. Executive::execute_block(block)
  765. }
  766. fn initialize_block(header: &<Block as BlockT>::Header) {
  767. Executive::initialize_block(header)
  768. }
  769. }
  770. impl sp_api::Metadata<Block> for Runtime {
  771. fn metadata() -> OpaqueMetadata {
  772. Runtime::metadata().into()
  773. }
  774. }
  775. impl sp_block_builder::BlockBuilder<Block> for Runtime {
  776. fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
  777. Executive::apply_extrinsic(extrinsic)
  778. }
  779. fn finalize_block() -> <Block as BlockT>::Header {
  780. Executive::finalize_block()
  781. }
  782. fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
  783. data.create_extrinsics()
  784. }
  785. fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
  786. data.check_extrinsics(&block)
  787. }
  788. fn random_seed() -> <Block as BlockT>::Hash {
  789. RandomnessCollectiveFlip::random_seed()
  790. }
  791. }
  792. impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
  793. fn validate_transaction(
  794. source: TransactionSource,
  795. tx: <Block as BlockT>::Extrinsic,
  796. ) -> TransactionValidity {
  797. Executive::validate_transaction(source, tx)
  798. }
  799. }
  800. impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
  801. fn offchain_worker(header: &<Block as BlockT>::Header) {
  802. Executive::offchain_worker(header)
  803. }
  804. }
  805. impl fg_primitives::GrandpaApi<Block> for Runtime {
  806. fn grandpa_authorities() -> GrandpaAuthorityList {
  807. Grandpa::grandpa_authorities()
  808. }
  809. fn submit_report_equivocation_extrinsic(
  810. equivocation_proof: fg_primitives::EquivocationProof<
  811. <Block as BlockT>::Hash,
  812. NumberFor<Block>,
  813. >,
  814. key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
  815. ) -> Option<()> {
  816. let key_owner_proof = key_owner_proof.decode()?;
  817. Grandpa::submit_report_equivocation_extrinsic(
  818. equivocation_proof,
  819. key_owner_proof,
  820. )
  821. }
  822. fn generate_key_ownership_proof(
  823. _set_id: fg_primitives::SetId,
  824. authority_id: GrandpaId,
  825. ) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
  826. use codec::Encode;
  827. Historical::prove((fg_primitives::KEY_TYPE, authority_id))
  828. .map(|p| p.encode())
  829. .map(fg_primitives::OpaqueKeyOwnershipProof::new)
  830. }
  831. }
  832. impl sp_consensus_babe::BabeApi<Block> for Runtime {
  833. fn configuration() -> sp_consensus_babe::BabeGenesisConfiguration {
  834. // The choice of `c` parameter (where `1 - c` represents the
  835. // probability of a slot being empty), is done in accordance to the
  836. // slot duration and expected target block time, for safely
  837. // resisting network delays of maximum two seconds.
  838. // <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
  839. sp_consensus_babe::BabeGenesisConfiguration {
  840. slot_duration: Babe::slot_duration(),
  841. epoch_length: EpochDuration::get(),
  842. c: PRIMARY_PROBABILITY,
  843. genesis_authorities: Babe::authorities(),
  844. randomness: Babe::randomness(),
  845. allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots,
  846. }
  847. }
  848. fn current_epoch_start() -> sp_consensus_babe::SlotNumber {
  849. Babe::current_epoch_start()
  850. }
  851. }
  852. impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
  853. fn authorities() -> Vec<AuthorityDiscoveryId> {
  854. AuthorityDiscovery::authorities()
  855. }
  856. }
  857. impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
  858. fn account_nonce(account: AccountId) -> Index {
  859. System::account_nonce(account)
  860. }
  861. }
  862. impl sp_session::SessionKeys<Block> for Runtime {
  863. fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
  864. SessionKeys::generate(seed)
  865. }
  866. fn decode_session_keys(
  867. encoded: Vec<u8>,
  868. ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
  869. SessionKeys::decode_into_raw_public_keys(&encoded)
  870. }
  871. }
  872. impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
  873. Block,
  874. Balance,
  875. UncheckedExtrinsic,
  876. > for Runtime {
  877. fn query_info(uxt: UncheckedExtrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
  878. TransactionPayment::query_info(uxt, len)
  879. }
  880. }
  881. }