lib.rs 30 KB

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