lib.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  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: 9,
  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. }
  377. impl content::Trait for Runtime {
  378. type Event = Event;
  379. type ChannelOwnershipPaymentEscrowId = ChannelOwnershipPaymentEscrowId;
  380. type ChannelCategoryId = ChannelCategoryId;
  381. type VideoId = VideoId;
  382. type VideoCategoryId = VideoCategoryId;
  383. type PlaylistId = PlaylistId;
  384. type PersonId = PersonId;
  385. type SeriesId = SeriesId;
  386. type ChannelOwnershipTransferRequestId = ChannelOwnershipTransferRequestId;
  387. type MaxNumberOfCuratorsPerGroup = MaxNumberOfCuratorsPerGroup;
  388. }
  389. impl hiring::Trait for Runtime {
  390. type OpeningId = u64;
  391. type ApplicationId = u64;
  392. type ApplicationDeactivatedHandler = (); // TODO - what needs to happen?
  393. type StakeHandlerProvider = hiring::Module<Self>;
  394. }
  395. impl minting::Trait for Runtime {
  396. type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
  397. type MintId = u64;
  398. }
  399. impl recurring_rewards::Trait for Runtime {
  400. type PayoutStatusHandler = (); // TODO - deal with successful and failed payouts
  401. type RecipientId = u64;
  402. type RewardRelationshipId = u64;
  403. }
  404. parameter_types! {
  405. pub const StakePoolId: [u8; 8] = *b"joystake";
  406. }
  407. #[allow(clippy::type_complexity)]
  408. impl stake::Trait for Runtime {
  409. type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
  410. type StakePoolId = StakePoolId;
  411. type StakingEventsHandler = (
  412. (
  413. (
  414. crate::integration::proposals::StakingEventsHandler<Self>,
  415. crate::integration::working_group::ContentDirectoryWgStakingEventsHandler<Self>,
  416. ),
  417. (
  418. crate::integration::working_group::StorageWgStakingEventsHandler<Self>,
  419. crate::integration::working_group::OperationsWgStakingEventsHandlerAlpha<Self>,
  420. ),
  421. ),
  422. (
  423. (
  424. crate::integration::working_group::OperationsWgStakingEventsHandlerBeta<Self>,
  425. crate::integration::working_group::OperationsWgStakingEventsHandlerGamma<Self>,
  426. ),
  427. (
  428. crate::integration::working_group::GatewayWgStakingEventsHandler<Self>,
  429. crate::integration::working_group::DistributionWgStakingEventsHandler<Self>,
  430. ),
  431. ),
  432. );
  433. type StakeId = u64;
  434. type SlashId = u64;
  435. }
  436. impl common::currency::GovernanceCurrency for Runtime {
  437. type Currency = pallet_balances::Module<Self>;
  438. }
  439. impl common::MembershipTypes for Runtime {
  440. type MemberId = MemberId;
  441. type ActorId = ActorId;
  442. }
  443. impl common::StorageOwnership for Runtime {
  444. type ChannelId = ChannelId;
  445. type ContentId = ContentId;
  446. type DataObjectTypeId = DataObjectTypeId;
  447. }
  448. impl governance::election::Trait for Runtime {
  449. type Event = Event;
  450. type CouncilElected = (Council, integration::proposals::CouncilElectedHandler);
  451. }
  452. impl governance::council::Trait for Runtime {
  453. type Event = Event;
  454. type CouncilTermEnded = (CouncilElection,);
  455. }
  456. impl memo::Trait for Runtime {
  457. type Event = Event;
  458. }
  459. parameter_types! {
  460. pub const ScreenedMemberMaxInitialBalance: u128 = 5000;
  461. }
  462. impl membership::Trait for Runtime {
  463. type Event = Event;
  464. type PaidTermId = u64;
  465. type SubscriptionId = u64;
  466. type ScreenedMemberMaxInitialBalance = ScreenedMemberMaxInitialBalance;
  467. }
  468. impl forum::Trait for Runtime {
  469. type Event = Event;
  470. type MembershipRegistry = integration::forum::ShimMembershipRegistry;
  471. type ThreadId = ThreadId;
  472. type PostId = PostId;
  473. }
  474. // The storage working group instance alias.
  475. pub type StorageWorkingGroupInstance = working_group::Instance2;
  476. // The content working group instance alias.
  477. pub type ContentWorkingGroupInstance = working_group::Instance3;
  478. // The distribution working group instance alias.
  479. pub type DistributionWorkingGroupInstance = working_group::Instance6;
  480. // The gateway working group instance alias.
  481. pub type GatewayWorkingGroupInstance = working_group::Instance5;
  482. // The operation working group alpha instance alias.
  483. pub type OperationsWorkingGroupInstanceAlpha = working_group::Instance4;
  484. // The operation working group beta instance alias .
  485. pub type OperationsWorkingGroupInstanceBeta = working_group::Instance7;
  486. // The operation working group gamma instance alias .
  487. pub type OperationsWorkingGroupInstanceGamma = working_group::Instance8;
  488. parameter_types! {
  489. pub const MaxWorkerNumberLimit: u32 = 100;
  490. }
  491. impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
  492. type Event = Event;
  493. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  494. }
  495. impl working_group::Trait<ContentWorkingGroupInstance> for Runtime {
  496. type Event = Event;
  497. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  498. }
  499. impl working_group::Trait<DistributionWorkingGroupInstance> for Runtime {
  500. type Event = Event;
  501. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  502. }
  503. impl working_group::Trait<OperationsWorkingGroupInstanceAlpha> for Runtime {
  504. type Event = Event;
  505. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  506. }
  507. impl working_group::Trait<GatewayWorkingGroupInstance> for Runtime {
  508. type Event = Event;
  509. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  510. }
  511. impl working_group::Trait<OperationsWorkingGroupInstanceBeta> for Runtime {
  512. type Event = Event;
  513. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  514. }
  515. impl working_group::Trait<OperationsWorkingGroupInstanceGamma> for Runtime {
  516. type Event = Event;
  517. type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
  518. }
  519. parameter_types! {
  520. pub const ProposalCancellationFee: u64 = 10000;
  521. pub const ProposalRejectionFee: u64 = 5000;
  522. pub const ProposalTitleMaxLength: u32 = 40;
  523. pub const ProposalDescriptionMaxLength: u32 = 3000;
  524. pub const ProposalMaxActiveProposalLimit: u32 = 20;
  525. }
  526. impl proposals_engine::Trait for Runtime {
  527. type Event = Event;
  528. type ProposerOriginValidator = MembershipOriginValidator<Self>;
  529. type VoterOriginValidator = CouncilManager<Self>;
  530. type TotalVotersCounter = CouncilManager<Self>;
  531. type ProposalId = u32;
  532. type StakeHandlerProvider = proposals_engine::DefaultStakeHandlerProvider;
  533. type CancellationFee = ProposalCancellationFee;
  534. type RejectionFee = ProposalRejectionFee;
  535. type TitleMaxLength = ProposalTitleMaxLength;
  536. type DescriptionMaxLength = ProposalDescriptionMaxLength;
  537. type MaxActiveProposalLimit = ProposalMaxActiveProposalLimit;
  538. type DispatchableCallCode = Call;
  539. }
  540. impl Default for Call {
  541. fn default() -> Self {
  542. panic!("shouldn't call default for Call");
  543. }
  544. }
  545. parameter_types! {
  546. pub const ProposalMaxPostEditionNumber: u32 = 0; // post update is disabled
  547. pub const ProposalMaxThreadInARowNumber: u32 = 100_000; // will not be used
  548. pub const ProposalThreadTitleLengthLimit: u32 = 40;
  549. pub const ProposalPostLengthLimit: u32 = 1000;
  550. }
  551. impl proposals_discussion::Trait for Runtime {
  552. type Event = Event;
  553. type PostAuthorOriginValidator = MembershipOriginValidator<Self>;
  554. type ThreadId = ThreadId;
  555. type PostId = PostId;
  556. type MaxPostEditionNumber = ProposalMaxPostEditionNumber;
  557. type ThreadTitleLengthLimit = ProposalThreadTitleLengthLimit;
  558. type PostLengthLimit = ProposalPostLengthLimit;
  559. type MaxThreadInARowNumber = ProposalMaxThreadInARowNumber;
  560. }
  561. parameter_types! {
  562. pub const TextProposalMaxLength: u32 = 5_000;
  563. pub const RuntimeUpgradeWasmProposalMaxLength: u32 = 3_000_000;
  564. }
  565. impl proposals_codex::Trait for Runtime {
  566. type MembershipOriginValidator = MembershipOriginValidator<Self>;
  567. type TextProposalMaxLength = TextProposalMaxLength;
  568. type RuntimeUpgradeWasmProposalMaxLength = RuntimeUpgradeWasmProposalMaxLength;
  569. type ProposalEncoder = ExtrinsicProposalEncoder;
  570. }
  571. parameter_types! {
  572. pub const TombstoneDeposit: Balance = 1; // TODO: adjust fee
  573. pub const RentByteFee: Balance = 1; // TODO: adjust fee
  574. pub const RentDepositOffset: Balance = 0; // no rent deposit
  575. pub const SurchargeReward: Balance = 0; // no reward
  576. }
  577. parameter_types! {
  578. pub const MaxDistributionBucketNumberPerFamily: u64 = 20; //TODO: adjust value
  579. pub const MaxDistributionBucketFamilyNumber: u64 = 20; //TODO: adjust value
  580. pub const MaxNumberOfDataObjectsPerBag: u64 = 1000; //TODO: adjust value
  581. pub const DataObjectDeletionPrize: Balance = 10; //TODO: adjust value
  582. pub const BlacklistSizeLimit: u64 = 10000; //TODO: adjust value
  583. pub const MaxRandomIterationNumber: u64 = 30; //TODO: adjust value
  584. pub const MaxNumberOfPendingInvitationsPerDistributionBucket: u64 = 30; //TODO: adjust value
  585. pub const StorageModuleId: ModuleId = ModuleId(*b"mstorage"); // module storage
  586. pub const StorageBucketsPerBagValueConstraint: storage::StorageBucketsPerBagValueConstraint =
  587. storage::StorageBucketsPerBagValueConstraint {min: 3, max_min_diff: 7}; //TODO: adjust value
  588. pub const DefaultMemberDynamicBagNumberOfStorageBuckets: u64 = 4; //TODO: adjust value
  589. pub const DefaultChannelDynamicBagNumberOfStorageBuckets: u64 = 4; //TODO: adjust value
  590. pub const DistributionBucketsPerBagValueConstraint: storage::DistributionBucketsPerBagValueConstraint =
  591. storage::DistributionBucketsPerBagValueConstraint {min: 3, max_min_diff: 7}; //TODO: adjust value
  592. pub const MaxDataObjectSize: u64 = 10 * 1024 * 1024 * 1024; // 10 GB
  593. }
  594. impl storage::Trait for Runtime {
  595. type Event = Event;
  596. type DataObjectId = DataObjectId;
  597. type StorageBucketId = StorageBucketId;
  598. type DistributionBucketId = DistributionBucketId;
  599. type DistributionBucketFamilyId = DistributionBucketFamilyId;
  600. type ChannelId = ChannelId;
  601. type MaxNumberOfDataObjectsPerBag = MaxNumberOfDataObjectsPerBag;
  602. type DataObjectDeletionPrize = DataObjectDeletionPrize;
  603. type BlacklistSizeLimit = BlacklistSizeLimit;
  604. type ModuleId = StorageModuleId;
  605. type MemberOriginValidator = MembershipOriginValidator<Self>;
  606. type StorageBucketsPerBagValueConstraint = StorageBucketsPerBagValueConstraint;
  607. type DefaultMemberDynamicBagNumberOfStorageBuckets =
  608. DefaultMemberDynamicBagNumberOfStorageBuckets;
  609. type DefaultChannelDynamicBagNumberOfStorageBuckets =
  610. DefaultChannelDynamicBagNumberOfStorageBuckets;
  611. type Randomness = RandomnessCollectiveFlip;
  612. type MaxRandomIterationNumber = MaxRandomIterationNumber;
  613. type MaxDistributionBucketFamilyNumber = MaxDistributionBucketFamilyNumber;
  614. type MaxDistributionBucketNumberPerFamily = MaxDistributionBucketNumberPerFamily;
  615. type DistributionBucketsPerBagValueConstraint = DistributionBucketsPerBagValueConstraint;
  616. type DistributionBucketOperatorId = DistributionBucketOperatorId;
  617. type MaxNumberOfPendingInvitationsPerDistributionBucket =
  618. MaxNumberOfPendingInvitationsPerDistributionBucket;
  619. type MaxDataObjectSize = MaxDataObjectSize;
  620. type ContentId = ContentId;
  621. fn ensure_storage_working_group_leader_origin(origin: Self::Origin) -> DispatchResult {
  622. StorageWorkingGroup::ensure_origin_is_active_leader(origin)
  623. }
  624. fn ensure_storage_worker_origin(origin: Self::Origin, worker_id: ActorId) -> DispatchResult {
  625. StorageWorkingGroup::ensure_worker_signed(origin, &worker_id).map(|_| ())
  626. }
  627. fn ensure_storage_worker_exists(worker_id: &ActorId) -> DispatchResult {
  628. StorageWorkingGroup::ensure_worker_exists(&worker_id)
  629. .map(|_| ())
  630. .map_err(|err| err.into())
  631. }
  632. fn ensure_distribution_working_group_leader_origin(origin: Self::Origin) -> DispatchResult {
  633. DistributionWorkingGroup::ensure_origin_is_active_leader(origin)
  634. }
  635. fn ensure_distribution_worker_origin(
  636. origin: Self::Origin,
  637. worker_id: ActorId,
  638. ) -> DispatchResult {
  639. DistributionWorkingGroup::ensure_worker_signed(origin, &worker_id).map(|_| ())
  640. }
  641. fn ensure_distribution_worker_exists(worker_id: &ActorId) -> DispatchResult {
  642. DistributionWorkingGroup::ensure_worker_exists(&worker_id)
  643. .map(|_| ())
  644. .map_err(|err| err.into())
  645. }
  646. }
  647. /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
  648. /// the specifics of the runtime. They can then be made to be agnostic over specific formats
  649. /// of data like extrinsics, allowing for them to continue syncing the network through upgrades
  650. /// to even the core datastructures.
  651. pub mod opaque {
  652. use super::*;
  653. pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
  654. /// Opaque block header type.
  655. pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
  656. /// Opaque block type.
  657. pub type Block = generic::Block<Header, UncheckedExtrinsic>;
  658. /// Opaque block identifier type.
  659. pub type BlockId = generic::BlockId<Block>;
  660. }
  661. construct_runtime!(
  662. pub enum Runtime where
  663. Block = Block,
  664. NodeBlock = opaque::Block,
  665. UncheckedExtrinsic = UncheckedExtrinsic
  666. {
  667. // Substrate
  668. System: frame_system::{Module, Call, Storage, Config, Event<T>},
  669. Utility: substrate_utility::{Module, Call, Event},
  670. Babe: pallet_babe::{Module, Call, Storage, Config, Inherent, ValidateUnsigned},
  671. Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
  672. Authorship: pallet_authorship::{Module, Call, Storage, Inherent},
  673. Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
  674. TransactionPayment: pallet_transaction_payment::{Module, Storage},
  675. Staking: pallet_staking::{Module, Call, Config<T>, Storage, Event<T>, ValidateUnsigned},
  676. Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
  677. Historical: pallet_session_historical::{Module},
  678. FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent},
  679. Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},
  680. ImOnline: pallet_im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
  681. AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config},
  682. Offences: pallet_offences::{Module, Call, Storage, Event},
  683. RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
  684. Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},
  685. // Joystream
  686. CouncilElection: election::{Module, Call, Storage, Event<T>, Config<T>},
  687. Council: council::{Module, Call, Storage, Event<T>, Config<T>},
  688. Memo: memo::{Module, Call, Storage, Event<T>},
  689. Members: membership::{Module, Call, Storage, Event<T>, Config<T>},
  690. Forum: forum::{Module, Call, Storage, Event<T>, Config<T>},
  691. Stake: stake::{Module, Call, Storage},
  692. Minting: minting::{Module, Call, Storage},
  693. RecurringRewards: recurring_rewards::{Module, Call, Storage},
  694. Hiring: hiring::{Module, Call, Storage},
  695. Content: content::{Module, Call, Storage, Event<T>, Config<T>},
  696. // --- Proposals
  697. ProposalsEngine: proposals_engine::{Module, Call, Storage, Event<T>},
  698. ProposalsDiscussion: proposals_discussion::{Module, Call, Storage, Event<T>},
  699. ProposalsCodex: proposals_codex::{Module, Call, Storage, Config<T>},
  700. Storage: storage::{Module, Call, Storage, Event<T>},
  701. // --- Working groups
  702. // reserved for the future use: ForumWorkingGroup: working_group::<Instance1>::{Module, Call, Storage, Config<T>, Event<T>},
  703. StorageWorkingGroup: working_group::<Instance2>::{Module, Call, Storage, Config<T>, Event<T>},
  704. ContentWorkingGroup: working_group::<Instance3>::{Module, Call, Storage, Config<T>, Event<T>},
  705. OperationsWorkingGroupAlpha: working_group::<Instance4>::{Module, Call, Storage, Config<T>, Event<T>},
  706. GatewayWorkingGroup: working_group::<Instance5>::{Module, Call, Storage, Config<T>, Event<T>},
  707. DistributionWorkingGroup: working_group::<Instance6>::{Module, Call, Storage, Config<T>, Event<T>},
  708. OperationsWorkingGroupBeta: working_group::<Instance7>::{Module, Call, Storage, Config<T>, Event<T>},
  709. OperationsWorkingGroupGamma: working_group::<Instance8>::{Module, Call, Storage, Config<T>, Event<T>},
  710. }
  711. );