lib.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  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 constants;
  14. mod integration;
  15. pub mod primitives;
  16. mod proposals_configuration;
  17. mod runtime_api;
  18. #[cfg(test)]
  19. mod tests;
  20. /// Weights for pallets used in the runtime.
  21. mod weights; // Runtime integration tests
  22. #[macro_use]
  23. extern crate lazy_static; // for proposals_configuration module
  24. use frame_support::traits::{KeyOwnerProofSystem, LockIdentifier};
  25. use frame_support::weights::{
  26. constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight},
  27. Weight,
  28. };
  29. use frame_support::{construct_runtime, parameter_types};
  30. use frame_system::EnsureRoot;
  31. use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
  32. use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
  33. use pallet_session::historical as pallet_session_historical;
  34. use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
  35. use sp_core::crypto::KeyTypeId;
  36. use sp_runtime::curve::PiecewiseLinear;
  37. use sp_runtime::traits::{BlakeTwo256, Block as BlockT, IdentityLookup, OpaqueKeys, Saturating};
  38. use sp_runtime::{create_runtime_str, generic, impl_opaque_keys, Perbill};
  39. use sp_std::boxed::Box;
  40. use sp_std::vec::Vec;
  41. #[cfg(feature = "std")]
  42. use sp_version::NativeVersion;
  43. use sp_version::RuntimeVersion;
  44. pub use constants::*;
  45. pub use primitives::*;
  46. pub use proposals_configuration::*;
  47. pub use runtime_api::*;
  48. use integration::proposals::{CouncilManager, ExtrinsicProposalEncoder, MembershipOriginValidator};
  49. use governance::{council, election};
  50. use storage::data_object_storage_registry;
  51. // Node dependencies
  52. pub use common;
  53. pub use content_directory;
  54. pub use content_directory::{
  55. HashedTextMaxLength, InputValidationLengthConstraint, MaxNumber, TextMaxLength, VecMaxLength,
  56. };
  57. pub use forum;
  58. pub use governance::election_params::ElectionParameters;
  59. pub use membership;
  60. #[cfg(any(feature = "std", test))]
  61. pub use pallet_balances::Call as BalancesCall;
  62. pub use pallet_staking::StakerStatus;
  63. pub use proposals_engine::ProposalParameters;
  64. pub use storage::{data_directory, data_object_type_registry};
  65. pub use working_group;
  66. #[cfg(feature = "std")]
  67. /// Wasm binary unwrapped. If built with `BUILD_DUMMY_WASM_BINARY`, the function panics.
  68. pub fn wasm_binary_unwrap() -> &'static [u8] {
  69. WASM_BINARY.expect(
  70. "Development wasm binary is not available. This means the client is \
  71. built with `BUILD_DUMMY_WASM_BINARY` flag and it is only usable for \
  72. production chains. Please rebuild with the flag disabled.",
  73. )
  74. }
  75. /// This runtime version.
  76. pub const VERSION: RuntimeVersion = RuntimeVersion {
  77. spec_name: create_runtime_str!("joystream-node"),
  78. impl_name: create_runtime_str!("joystream-node"),
  79. authoring_version: 7,
  80. spec_version: 8,
  81. impl_version: 0,
  82. apis: crate::runtime_api::EXPORTED_RUNTIME_API_VERSIONS,
  83. transaction_version: 1,
  84. };
  85. /// The version information used to identify this runtime when compiled natively.
  86. #[cfg(feature = "std")]
  87. pub fn native_version() -> NativeVersion {
  88. NativeVersion {
  89. runtime_version: VERSION,
  90. can_author_with: Default::default(),
  91. }
  92. }
  93. parameter_types! {
  94. pub const BlockHashCount: BlockNumber = 250;
  95. /// We allow for 2 seconds of compute with a 6 second average block time.
  96. pub const MaximumBlockWeight: Weight = 2 * frame_support::weights::constants::WEIGHT_PER_SECOND;
  97. pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
  98. pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
  99. pub const Version: RuntimeVersion = VERSION;
  100. /// Assume 10% of weight for average on_initialize calls.
  101. pub MaximumExtrinsicWeight: Weight =
  102. AvailableBlockRatio::get().saturating_sub(AVERAGE_ON_INITIALIZE_WEIGHT)
  103. * MaximumBlockWeight::get();
  104. }
  105. const AVERAGE_ON_INITIALIZE_WEIGHT: Perbill = Perbill::from_percent(10);
  106. // TODO: adjust weight
  107. impl frame_system::Trait for Runtime {
  108. type BaseCallFilter = ();
  109. type Origin = Origin;
  110. type Call = Call;
  111. type Index = Index;
  112. type BlockNumber = BlockNumber;
  113. type Hash = Hash;
  114. type Hashing = BlakeTwo256;
  115. type AccountId = AccountId;
  116. type Lookup = IdentityLookup<AccountId>;
  117. type Header = generic::Header<BlockNumber, BlakeTwo256>;
  118. type Event = Event;
  119. type BlockHashCount = BlockHashCount;
  120. type MaximumBlockWeight = MaximumBlockWeight;
  121. type DbWeight = RocksDbWeight;
  122. type BlockExecutionWeight = BlockExecutionWeight;
  123. type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
  124. type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
  125. type MaximumBlockLength = MaximumBlockLength;
  126. type AvailableBlockRatio = AvailableBlockRatio;
  127. type Version = Version;
  128. type PalletInfo = PalletInfo;
  129. type AccountData = pallet_balances::AccountData<Balance>;
  130. type OnNewAccount = ();
  131. type OnKilledAccount = ();
  132. type SystemWeightInfo = weights::frame_system::WeightInfo;
  133. }
  134. impl pallet_utility::Trait for Runtime {
  135. type Event = Event;
  136. type Call = Call;
  137. type WeightInfo = weights::pallet_utility::WeightInfo;
  138. }
  139. parameter_types! {
  140. pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
  141. pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
  142. }
  143. impl pallet_babe::Trait for Runtime {
  144. type EpochDuration = EpochDuration;
  145. type ExpectedBlockTime = ExpectedBlockTime;
  146. type EpochChangeTrigger = pallet_babe::ExternalTrigger;
  147. type KeyOwnerProofSystem = Historical;
  148. type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
  149. KeyTypeId,
  150. pallet_babe::AuthorityId,
  151. )>>::Proof;
  152. type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
  153. KeyTypeId,
  154. pallet_babe::AuthorityId,
  155. )>>::IdentificationTuple;
  156. type HandleEquivocation =
  157. pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
  158. type WeightInfo = ();
  159. }
  160. impl pallet_grandpa::Trait for Runtime {
  161. type Event = Event;
  162. type Call = Call;
  163. type KeyOwnerProof =
  164. <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
  165. type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
  166. KeyTypeId,
  167. GrandpaId,
  168. )>>::IdentificationTuple;
  169. type KeyOwnerProofSystem = Historical;
  170. type HandleEquivocation =
  171. pallet_grandpa::EquivocationHandler<Self::KeyOwnerIdentification, Offences>;
  172. type WeightInfo = ();
  173. }
  174. impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
  175. where
  176. Call: From<LocalCall>,
  177. {
  178. fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
  179. call: Call,
  180. public: <Signature as sp_runtime::traits::Verify>::Signer,
  181. account: AccountId,
  182. nonce: Index,
  183. ) -> Option<(
  184. Call,
  185. <UncheckedExtrinsic as sp_runtime::traits::Extrinsic>::SignaturePayload,
  186. )> {
  187. integration::transactions::create_transaction::<C>(call, public, account, nonce)
  188. }
  189. }
  190. impl frame_system::offchain::SigningTypes for Runtime {
  191. type Public = <Signature as sp_runtime::traits::Verify>::Signer;
  192. type Signature = Signature;
  193. }
  194. impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
  195. where
  196. Call: From<C>,
  197. {
  198. type Extrinsic = UncheckedExtrinsic;
  199. type OverarchingCall = Call;
  200. }
  201. parameter_types! {
  202. pub const MinimumPeriod: Moment = SLOT_DURATION / 2;
  203. }
  204. impl pallet_timestamp::Trait for Runtime {
  205. type Moment = Moment;
  206. type OnTimestampSet = Babe;
  207. type MinimumPeriod = MinimumPeriod;
  208. type WeightInfo = weights::pallet_timestamp::WeightInfo;
  209. }
  210. parameter_types! {
  211. pub const ExistentialDeposit: u128 = 0;
  212. pub const TransferFee: u128 = 0;
  213. pub const CreationFee: u128 = 0;
  214. pub const InitialMembersBalance: u32 = 2000;
  215. pub const MaxLocks: u32 = 50;
  216. }
  217. impl pallet_balances::Trait for Runtime {
  218. type Balance = Balance;
  219. type DustRemoval = ();
  220. type Event = Event;
  221. type ExistentialDeposit = ExistentialDeposit;
  222. type AccountStore = System;
  223. type WeightInfo = weights::pallet_balances::WeightInfo;
  224. type MaxLocks = MaxLocks;
  225. }
  226. parameter_types! {
  227. pub const TransactionByteFee: Balance = 0; // TODO: adjust fee
  228. }
  229. impl pallet_transaction_payment::Trait for Runtime {
  230. type Currency = Balances;
  231. type OnTransactionPayment = ();
  232. type TransactionByteFee = TransactionByteFee;
  233. type WeightToFee = integration::transactions::NoWeights; // TODO: adjust weight
  234. type FeeMultiplierUpdate = (); // TODO: adjust fee
  235. }
  236. impl pallet_sudo::Trait for Runtime {
  237. type Event = Event;
  238. type Call = Call;
  239. }
  240. parameter_types! {
  241. pub const UncleGenerations: BlockNumber = 0;
  242. }
  243. impl pallet_authorship::Trait for Runtime {
  244. type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
  245. type UncleGenerations = UncleGenerations;
  246. type FilterUncle = ();
  247. type EventHandler = (Staking, ImOnline);
  248. }
  249. impl_opaque_keys! {
  250. pub struct SessionKeys {
  251. pub grandpa: Grandpa,
  252. pub babe: Babe,
  253. pub im_online: ImOnline,
  254. pub authority_discovery: AuthorityDiscovery,
  255. }
  256. }
  257. // NOTE: `SessionHandler` and `SessionKeys` are co-dependent: One key will be used for each handler.
  258. // The number and order of items in `SessionHandler` *MUST* be the same number and order of keys in
  259. // `SessionKeys`.
  260. // TODO: Introduce some structure to tie these together to make it a bit less of a footgun. This
  261. // should be easy, since OneSessionHandler trait provides the `Key` as an associated type. #2858
  262. parameter_types! {
  263. pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
  264. }
  265. impl pallet_session::Trait for Runtime {
  266. type Event = Event;
  267. type ValidatorId = AccountId;
  268. type ValidatorIdOf = pallet_staking::StashOf<Self>;
  269. type ShouldEndSession = Babe;
  270. type NextSessionRotation = Babe;
  271. type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
  272. type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
  273. type Keys = SessionKeys;
  274. type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
  275. type WeightInfo = weights::pallet_session::WeightInfo;
  276. }
  277. impl pallet_session::historical::Trait for Runtime {
  278. type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
  279. type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
  280. }
  281. pallet_staking_reward_curve::build! {
  282. const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
  283. min_inflation: 0_050_000,
  284. max_inflation: 0_750_000,
  285. ideal_stake: 0_250_000,
  286. falloff: 0_050_000,
  287. max_piece_count: 100,
  288. test_precision: 0_005_000,
  289. );
  290. }
  291. parameter_types! {
  292. pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _;
  293. pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
  294. /// We prioritize im-online heartbeats over election solution submission.
  295. pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
  296. }
  297. parameter_types! {
  298. pub const SessionsPerEra: sp_staking::SessionIndex = 6;
  299. pub const BondingDuration: pallet_staking::EraIndex = BONDING_DURATION;
  300. pub const SlashDeferDuration: pallet_staking::EraIndex = BONDING_DURATION - 1; // 'slightly less' than the bonding duration.
  301. pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
  302. pub const MaxNominatorRewardedPerValidator: u32 = 64;
  303. pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;
  304. pub const MaxIterations: u32 = 10;
  305. // 0.05%. The higher the value, the more strict solution acceptance becomes.
  306. pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
  307. }
  308. impl pallet_staking::Trait for Runtime {
  309. type Currency = Balances;
  310. type UnixTime = Timestamp;
  311. type CurrencyToVote = common::currency::CurrencyToVoteHandler;
  312. type RewardRemainder = (); // Could be Treasury.
  313. type Event = Event;
  314. type Slash = (); // Where to send the slashed funds. Could be Treasury.
  315. type Reward = (); // Rewards are minted from the void.
  316. type SessionsPerEra = SessionsPerEra;
  317. type BondingDuration = BondingDuration;
  318. type SlashDeferDuration = SlashDeferDuration;
  319. type SlashCancelOrigin = EnsureRoot<AccountId>; // Requires sudo. Parity recommends: a super-majority of the council can cancel the slash.
  320. type SessionInterface = Self;
  321. type RewardCurve = RewardCurve;
  322. type NextNewSession = Session;
  323. type ElectionLookahead = ElectionLookahead;
  324. type Call = Call;
  325. type MaxIterations = MaxIterations;
  326. type MinSolutionScoreBump = MinSolutionScoreBump;
  327. type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
  328. type UnsignedPriority = StakingUnsignedPriority;
  329. type WeightInfo = weights::pallet_staking::WeightInfo;
  330. }
  331. impl pallet_im_online::Trait for Runtime {
  332. type AuthorityId = ImOnlineId;
  333. type Event = Event;
  334. type SessionDuration = SessionDuration;
  335. type ReportUnresponsiveness = Offences;
  336. type UnsignedPriority = ImOnlineUnsignedPriority;
  337. type WeightInfo = weights::pallet_im_online::WeightInfo;
  338. }
  339. parameter_types! {
  340. pub OffencesWeightSoftLimit: Weight = Perbill::from_percent(60) * MaximumBlockWeight::get();
  341. }
  342. impl pallet_offences::Trait for Runtime {
  343. type Event = Event;
  344. type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
  345. type OnOffenceHandler = Staking;
  346. type WeightSoftLimit = OffencesWeightSoftLimit;
  347. }
  348. impl pallet_authority_discovery::Trait for Runtime {}
  349. parameter_types! {
  350. pub const WindowSize: BlockNumber = 101;
  351. pub const ReportLatency: BlockNumber = 1000;
  352. }
  353. impl pallet_finality_tracker::Trait for Runtime {
  354. type OnFinalizationStalled = ();
  355. type WindowSize = WindowSize;
  356. type ReportLatency = ReportLatency;
  357. }
  358. type EntityId = <Runtime as content_directory::Trait>::EntityId;
  359. parameter_types! {
  360. pub const PropertyNameLengthConstraint: InputValidationLengthConstraint = InputValidationLengthConstraint::new(1, 49);
  361. pub const PropertyDescriptionLengthConstraint: InputValidationLengthConstraint = InputValidationLengthConstraint::new(1, 500);
  362. pub const ClassNameLengthConstraint: InputValidationLengthConstraint = InputValidationLengthConstraint::new(1, 49);
  363. pub const ClassDescriptionLengthConstraint: InputValidationLengthConstraint = InputValidationLengthConstraint::new(1, 500);
  364. pub const MaxNumberOfClasses: MaxNumber = 100;
  365. pub const MaxNumberOfMaintainersPerClass: MaxNumber = 10;
  366. pub const MaxNumberOfSchemasPerClass: MaxNumber = 20;
  367. pub const MaxNumberOfPropertiesPerSchema: MaxNumber = 40;
  368. pub const MaxNumberOfEntitiesPerClass: MaxNumber = 400;
  369. pub const MaxNumberOfCuratorsPerGroup: MaxNumber = 50;
  370. pub const MaxNumberOfOperationsDuringAtomicBatching: MaxNumber = 500;
  371. pub const VecMaxLengthConstraint: VecMaxLength = 200;
  372. pub const TextMaxLengthConstraint: TextMaxLength = 5000;
  373. pub const HashedTextMaxLengthConstraint: HashedTextMaxLength = Some(25000);
  374. pub const IndividualEntitiesCreationLimit: EntityId = 50;
  375. }
  376. impl content_directory::Trait for Runtime {
  377. type Event = Event;
  378. type Nonce = u64;
  379. type ClassId = u64;
  380. type EntityId = u64;
  381. type PropertyNameLengthConstraint = PropertyNameLengthConstraint;
  382. type PropertyDescriptionLengthConstraint = PropertyDescriptionLengthConstraint;
  383. type ClassNameLengthConstraint = ClassNameLengthConstraint;
  384. type ClassDescriptionLengthConstraint = ClassDescriptionLengthConstraint;
  385. type MaxNumberOfClasses = MaxNumberOfClasses;
  386. type MaxNumberOfMaintainersPerClass = MaxNumberOfMaintainersPerClass;
  387. type MaxNumberOfSchemasPerClass = MaxNumberOfSchemasPerClass;
  388. type MaxNumberOfPropertiesPerSchema = MaxNumberOfPropertiesPerSchema;
  389. type MaxNumberOfEntitiesPerClass = MaxNumberOfEntitiesPerClass;
  390. type MaxNumberOfCuratorsPerGroup = MaxNumberOfCuratorsPerGroup;
  391. type MaxNumberOfOperationsDuringAtomicBatching = MaxNumberOfOperationsDuringAtomicBatching;
  392. type VecMaxLengthConstraint = VecMaxLengthConstraint;
  393. type TextMaxLengthConstraint = TextMaxLengthConstraint;
  394. type HashedTextMaxLengthConstraint = HashedTextMaxLengthConstraint;
  395. type IndividualEntitiesCreationLimit = IndividualEntitiesCreationLimit;
  396. }
  397. impl minting::Trait for Runtime {
  398. type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
  399. type MintId = u64;
  400. }
  401. impl recurring_rewards::Trait for Runtime {
  402. type PayoutStatusHandler = (); // TODO - deal with successful and failed payouts
  403. type RecipientId = u64;
  404. type RewardRelationshipId = u64;
  405. }
  406. parameter_types! {
  407. pub const StakePoolId: [u8; 8] = *b"joystake";
  408. }
  409. impl stake::Trait for Runtime {
  410. type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
  411. type StakePoolId = StakePoolId;
  412. type StakingEventsHandler = ();
  413. type StakeId = u64;
  414. type SlashId = u64;
  415. }
  416. impl common::currency::GovernanceCurrency for Runtime {
  417. type Currency = pallet_balances::Module<Self>;
  418. }
  419. impl governance::election::Trait for Runtime {
  420. type Event = Event;
  421. type CouncilElected = (Council, integration::proposals::CouncilElectedHandler);
  422. }
  423. impl governance::council::Trait for Runtime {
  424. type Event = Event;
  425. type CouncilTermEnded = (CouncilElection,);
  426. }
  427. impl memo::Trait for Runtime {
  428. type Event = Event;
  429. }
  430. parameter_types! {
  431. pub const MaxObjectsPerInjection: u32 = 100;
  432. }
  433. impl storage::data_object_type_registry::Trait for Runtime {
  434. type Event = Event;
  435. type DataObjectTypeId = u64;
  436. }
  437. impl storage::data_directory::Trait for Runtime {
  438. type Event = Event;
  439. type ContentId = ContentId;
  440. type StorageProviderHelper = integration::storage::StorageProviderHelper;
  441. type IsActiveDataObjectType = DataObjectTypeRegistry;
  442. type MemberOriginValidator = MembershipOriginValidator<Self>;
  443. type MaxObjectsPerInjection = MaxObjectsPerInjection;
  444. }
  445. impl storage::data_object_storage_registry::Trait for Runtime {
  446. type Event = Event;
  447. type DataObjectStorageRelationshipId = u64;
  448. type ContentIdExists = DataDirectory;
  449. }
  450. impl membership::Trait for Runtime {
  451. type Event = Event;
  452. type MemberId = MemberId;
  453. type PaidTermId = u64;
  454. type SubscriptionId = u64;
  455. type ActorId = ActorId;
  456. }
  457. parameter_types! {
  458. pub const MaxCategoryDepth: u64 = 5;
  459. pub const MaxSubcategories: u64 = 20;
  460. pub const MaxThreadsInCategory: u64 = 20;
  461. pub const MaxPostsInThread: u64 = 20;
  462. pub const MaxModeratorsForCategory: u64 = 20;
  463. pub const MaxCategories: u64 = 20;
  464. pub const MaxPollAlternativesNumber: u64 = 20;
  465. }
  466. pub struct MapLimits;
  467. impl forum::StorageLimits for MapLimits {
  468. type MaxSubcategories = MaxSubcategories;
  469. type MaxThreadsInCategory = MaxThreadsInCategory;
  470. type MaxPostsInThread = MaxPostsInThread;
  471. type MaxModeratorsForCategory = MaxModeratorsForCategory;
  472. type MaxCategories = MaxCategories;
  473. type MaxPollAlternativesNumber = MaxPollAlternativesNumber;
  474. }
  475. // Alias for forum working group
  476. type ForumGroup<T> = working_group::Module<T, ForumWorkingGroupInstance>;
  477. impl forum::Trait for Runtime {
  478. type Event = Event;
  479. //type MembershipRegistry = ShimMembershipRegistry;
  480. type ThreadId = ThreadId;
  481. type PostId = PostId;
  482. type ForumUserId = ForumUserId;
  483. type ModeratorId = ModeratorId;
  484. type CategoryId = u64;
  485. type PostReactionId = u64;
  486. type MaxCategoryDepth = MaxCategoryDepth;
  487. type MapLimits = MapLimits;
  488. fn is_lead(_account_id: &AccountId) -> bool {
  489. // get current lead id
  490. let maybe_current_lead_id = ForumGroup::<Runtime>::current_lead();
  491. if let Some(ref current_lead_id) = maybe_current_lead_id {
  492. if let Ok(worker) = working_group::ensure_worker_exists::<
  493. Runtime,
  494. ForumWorkingGroupInstance,
  495. >(current_lead_id)
  496. {
  497. *_account_id == worker.role_account_id
  498. } else {
  499. false
  500. }
  501. } else {
  502. false
  503. }
  504. }
  505. fn is_forum_member(_account_id: &Self::AccountId, _forum_user_id: &Self::ForumUserId) -> bool {
  506. membership::Module::<Runtime>::ensure_is_controller_account_for_member(
  507. _forum_user_id,
  508. _account_id,
  509. )
  510. .is_ok()
  511. }
  512. fn is_moderator(_account_id: &Self::AccountId, _moderator_id: &Self::ModeratorId) -> bool {
  513. if let Ok(worker) =
  514. working_group::ensure_worker_exists::<Runtime, ForumWorkingGroupInstance>(_moderator_id)
  515. {
  516. *_account_id == worker.role_account_id
  517. } else {
  518. false
  519. }
  520. }
  521. fn calculate_hash(text: &[u8]) -> Self::Hash {
  522. Self::Hash::from_slice(text)
  523. }
  524. }
  525. // The forum working group instance alias.
  526. pub type ForumWorkingGroupInstance = working_group::Instance1;
  527. // The storage working group instance alias.
  528. pub type StorageWorkingGroupInstance = working_group::Instance2;
  529. // The content directory working group instance alias.
  530. pub type ContentDirectoryWorkingGroupInstance = working_group::Instance3;
  531. parameter_types! {
  532. pub const MaxWorkerNumberLimit: u32 = 100;
  533. pub const MinUnstakingPeriodLimit: u32 = 43200;
  534. pub const ForumWorkingGroupRewardPeriod: u32 = 14400 + 10;
  535. pub const StorageWorkingGroupRewardPeriod: u32 = 14400 + 20;
  536. pub const ContentWorkingGroupRewardPeriod: u32 = 14400 + 30;
  537. pub const StorageWorkingGroupLockId: LockIdentifier = [6; 8];
  538. pub const ContentWorkingGroupLockId: LockIdentifier = [7; 8];
  539. pub const ForumGroupLockId: LockIdentifier = [8; 8];
  540. }
  541. impl working_group::Trait<ForumWorkingGroupInstance> for Runtime {
  542. type Event = Event;
  543. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  544. type StakingHandler = staking_handler::StakingManager<Self, ForumGroupLockId>;
  545. type MemberOriginValidator = MembershipOriginValidator<Self>;
  546. type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
  547. type RewardPeriod = ForumWorkingGroupRewardPeriod;
  548. }
  549. impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
  550. type Event = Event;
  551. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  552. type StakingHandler = staking_handler::StakingManager<Self, StorageWorkingGroupLockId>;
  553. type MemberOriginValidator = MembershipOriginValidator<Self>;
  554. type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
  555. type RewardPeriod = StorageWorkingGroupRewardPeriod;
  556. }
  557. impl working_group::Trait<ContentDirectoryWorkingGroupInstance> for Runtime {
  558. type Event = Event;
  559. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  560. type StakingHandler = staking_handler::StakingManager<Self, ContentWorkingGroupLockId>;
  561. type MemberOriginValidator = MembershipOriginValidator<Self>;
  562. type MinUnstakingPeriodLimit = MinUnstakingPeriodLimit;
  563. type RewardPeriod = ContentWorkingGroupRewardPeriod;
  564. }
  565. impl service_discovery::Trait for Runtime {
  566. type Event = Event;
  567. }
  568. parameter_types! {
  569. pub const ProposalCancellationFee: u64 = 10000;
  570. pub const ProposalRejectionFee: u64 = 5000;
  571. pub const ProposalTitleMaxLength: u32 = 40;
  572. pub const ProposalDescriptionMaxLength: u32 = 3000;
  573. pub const ProposalMaxActiveProposalLimit: u32 = 5;
  574. pub const ProposalsLockId: LockIdentifier = [5; 8];
  575. }
  576. impl proposals_engine::Trait for Runtime {
  577. type Event = Event;
  578. type ProposerOriginValidator = MembershipOriginValidator<Self>;
  579. type VoterOriginValidator = CouncilManager<Self>;
  580. type TotalVotersCounter = CouncilManager<Self>;
  581. type ProposalId = u32;
  582. type StakingHandler = staking_handler::StakingManager<Self, ProposalsLockId>;
  583. type CancellationFee = ProposalCancellationFee;
  584. type RejectionFee = ProposalRejectionFee;
  585. type TitleMaxLength = ProposalTitleMaxLength;
  586. type DescriptionMaxLength = ProposalDescriptionMaxLength;
  587. type MaxActiveProposalLimit = ProposalMaxActiveProposalLimit;
  588. type DispatchableCallCode = Call;
  589. type ProposalObserver = ProposalsCodex;
  590. type WeightInfo = weights::proposals_engine::WeightInfo;
  591. }
  592. impl Default for Call {
  593. fn default() -> Self {
  594. panic!("shouldn't call default for Call");
  595. }
  596. }
  597. parameter_types! {
  598. pub const MaxWhiteListSize: u32 = 20;
  599. }
  600. impl proposals_discussion::Trait for Runtime {
  601. type Event = Event;
  602. type AuthorOriginValidator = MembershipOriginValidator<Self>;
  603. type CouncilOriginValidator = CouncilManager<Self>;
  604. type ThreadId = ThreadId;
  605. type PostId = PostId;
  606. type MaxWhiteListSize = MaxWhiteListSize;
  607. type WeightInfo = weights::proposals_discussion::WeightInfo;
  608. }
  609. parameter_types! {
  610. pub const TextProposalMaxLength: u32 = 5_000;
  611. pub const RuntimeUpgradeWasmProposalMaxLength: u32 = 3_000_000;
  612. }
  613. impl proposals_codex::Trait for Runtime {
  614. type TextProposalMaxLength = TextProposalMaxLength;
  615. type RuntimeUpgradeWasmProposalMaxLength = RuntimeUpgradeWasmProposalMaxLength;
  616. type MembershipOriginValidator = MembershipOriginValidator<Self>;
  617. type ProposalEncoder = ExtrinsicProposalEncoder;
  618. type SetValidatorCountProposalParameters = SetValidatorCountProposalParameters;
  619. type RuntimeUpgradeProposalParameters = RuntimeUpgradeProposalParameters;
  620. type TextProposalParameters = TextProposalParameters;
  621. type SpendingProposalParameters = SpendingProposalParameters;
  622. type AddWorkingGroupOpeningProposalParameters = AddWorkingGroupOpeningProposalParameters;
  623. type BeginReviewWorkingGroupApplicationsProposalParameters =
  624. BeginReviewWorkingGroupApplicationsProposalParameters;
  625. type FillWorkingGroupOpeningProposalParameters = FillWorkingGroupOpeningProposalParameters;
  626. type SetWorkingGroupBudgetCapacityProposalParameters =
  627. SetWorkingGroupBudgetCapacityProposalParameters;
  628. type DecreaseWorkingGroupLeaderStakeProposalParameters =
  629. DecreaseWorkingGroupLeaderStakeProposalParameters;
  630. type SlashWorkingGroupLeaderStakeProposalParameters =
  631. SlashWorkingGroupLeaderStakeProposalParameters;
  632. type SetWorkingGroupLeaderRewardProposalParameters =
  633. SetWorkingGroupLeaderRewardProposalParameters;
  634. type TerminateWorkingGroupLeaderRoleProposalParameters =
  635. TerminateWorkingGroupLeaderRoleProposalParameters;
  636. type AmendConstitutionProposalParameters = AmendConstitutionProposalParameters;
  637. }
  638. impl constitution::Trait for Runtime {
  639. type Event = Event;
  640. }
  641. parameter_types! {
  642. pub const TombstoneDeposit: Balance = 1; // TODO: adjust fee
  643. pub const RentByteFee: Balance = 1; // TODO: adjust fee
  644. pub const RentDepositOffset: Balance = 0; // no rent deposit
  645. pub const SurchargeReward: Balance = 0; // no reward
  646. }
  647. /// Forum identifiers for user, moderator and category
  648. pub type ForumUserId = u64;
  649. pub type ModeratorId = u64;
  650. pub type CategoryId = u64;
  651. /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
  652. /// the specifics of the runtime. They can then be made to be agnostic over specific formats
  653. /// of data like extrinsics, allowing for them to continue syncing the network through upgrades
  654. /// to even the core datastructures.
  655. pub mod opaque {
  656. use super::*;
  657. pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
  658. /// Opaque block header type.
  659. pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
  660. /// Opaque block type.
  661. pub type Block = generic::Block<Header, UncheckedExtrinsic>;
  662. /// Opaque block identifier type.
  663. pub type BlockId = generic::BlockId<Block>;
  664. }
  665. construct_runtime!(
  666. pub enum Runtime where
  667. Block = Block,
  668. NodeBlock = opaque::Block,
  669. UncheckedExtrinsic = UncheckedExtrinsic
  670. {
  671. // Substrate
  672. System: frame_system::{Module, Call, Storage, Config, Event<T>},
  673. Utility: pallet_utility::{Module, Call, Event},
  674. Babe: pallet_babe::{Module, Call, Storage, Config, Inherent, ValidateUnsigned},
  675. Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
  676. Authorship: pallet_authorship::{Module, Call, Storage, Inherent},
  677. Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
  678. TransactionPayment: pallet_transaction_payment::{Module, Storage},
  679. Staking: pallet_staking::{Module, Call, Config<T>, Storage, Event<T>, ValidateUnsigned},
  680. Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
  681. Historical: pallet_session_historical::{Module},
  682. FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent},
  683. Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},
  684. ImOnline: pallet_im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
  685. AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config},
  686. Offences: pallet_offences::{Module, Call, Storage, Event},
  687. RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
  688. Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},
  689. // Joystream
  690. CouncilElection: election::{Module, Call, Storage, Event<T>, Config<T>},
  691. Council: council::{Module, Call, Storage, Event<T>, Config<T>},
  692. Memo: memo::{Module, Call, Storage, Event<T>},
  693. Members: membership::{Module, Call, Storage, Event<T>, Config<T>},
  694. Forum: forum::{Module, Call, Storage, Event<T>, Config<T>},
  695. Stake: stake::{Module, Call, Storage},
  696. Minting: minting::{Module, Call, Storage},
  697. RecurringRewards: recurring_rewards::{Module, Call, Storage},
  698. ContentDirectory: content_directory::{Module, Call, Storage, Event<T>, Config<T>},
  699. Constitution: constitution::{Module, Call, Storage, Event},
  700. // --- Storage
  701. DataObjectTypeRegistry: data_object_type_registry::{Module, Call, Storage, Event<T>, Config<T>},
  702. DataDirectory: data_directory::{Module, Call, Storage, Event<T>},
  703. DataObjectStorageRegistry: data_object_storage_registry::{Module, Call, Storage, Event<T>, Config<T>},
  704. Discovery: service_discovery::{Module, Call, Storage, Event<T>},
  705. // --- Proposals
  706. ProposalsEngine: proposals_engine::{Module, Call, Storage, Event<T>},
  707. ProposalsDiscussion: proposals_discussion::{Module, Call, Storage, Event<T>},
  708. ProposalsCodex: proposals_codex::{Module, Call, Storage},
  709. // --- Working groups
  710. ForumWorkingGroup: working_group::<Instance1>::{Module, Call, Storage, Event<T>},
  711. StorageWorkingGroup: working_group::<Instance2>::{Module, Call, Storage, Event<T>},
  712. ContentDirectoryWorkingGroup: working_group::<Instance3>::{Module, Call, Storage, Event<T>},
  713. }
  714. );