1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018 |
- //! The Joystream Substrate Node runtime.
- #![cfg_attr(not(feature = "std"), no_std)]
- // `construct_runtime!` does a lot of recursion and requires us to increase the limit to 256.
- #![recursion_limit = "256"]
- //Substrate internal issues.
- #![allow(clippy::large_enum_variant)]
- #![allow(clippy::unnecessary_mut_passed)]
- // Make the WASM binary available.
- // This is required only by the node build.
- // A dummy wasm_binary.rs will be built for the IDE.
- #[cfg(feature = "std")]
- include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
- mod integration;
- mod migration;
- #[cfg(test)]
- mod tests; // Runtime integration tests
- use frame_support::inherent::{CheckInherentsResult, InherentData};
- use frame_support::traits::KeyOwnerProofSystem;
- use frame_support::weights::{IdentityFee, Weight};
- use frame_support::{
- construct_runtime, parameter_types, traits::Randomness, StorageMap, StorageValue,
- };
- use pallet_grandpa::fg_primitives;
- use pallet_grandpa::{AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
- use pallet_im_online::sr25519::AuthorityId as ImOnlineId;
- use pallet_session::historical as pallet_session_historical;
- use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
- use pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo;
- use sp_api::impl_runtime_apis;
- use sp_authority_discovery::AuthorityId as AuthorityDiscoveryId;
- use sp_core::crypto::KeyTypeId;
- use sp_core::OpaqueMetadata;
- use sp_runtime::curve::PiecewiseLinear;
- use sp_runtime::traits::{
- BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, StaticLookup, Verify,
- };
- use sp_runtime::transaction_validity::{TransactionSource, TransactionValidity};
- use sp_runtime::{
- create_runtime_str, generic, impl_opaque_keys, ApplyExtrinsicResult, FixedPointNumber,
- MultiSignature, Perbill, Perquintill,
- };
- use sp_std::boxed::Box;
- use sp_std::vec::Vec;
- #[cfg(feature = "std")]
- use sp_version::NativeVersion;
- use sp_version::RuntimeVersion;
- use system::EnsureRoot;
- use integration::proposals::{CouncilManager, ExtrinsicProposalEncoder, MembershipOriginValidator};
- use content_working_group as content_wg;
- use governance::{council, election};
- use storage::{data_directory, data_object_storage_registry, data_object_type_registry};
- /// Priority for a transaction. Additive. Higher is better.
- pub type TransactionPriority = u64;
- /// Alias for ContentId, used in various places.
- pub type ContentId = sp_core::H256;
- /// An index to a block.
- pub type BlockNumber = u32;
- /// Alias to 512-bit hash when used in the context of a transaction signature on the chain.
- pub type Signature = MultiSignature;
- /// Some way of identifying an account on the chain. We intentionally make it equivalent
- /// to the public key of our transaction signing scheme.
- pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
- /// The type for looking up accounts. We don't expect more than 4 billion of them, but you
- /// never know...
- pub type AccountIndex = u32;
- /// Balance of an account.
- pub type Balance = u128;
- /// Index of a transaction in the chain.
- pub type Index = u32;
- /// A hash of some data used by the chain.
- pub type Hash = sp_core::H256;
- /// Digest item type.
- pub type DigestItem = generic::DigestItem<Hash>;
- /// Moment type
- pub type Moment = u64;
- /// Credential type
- pub type Credential = u64;
- /// Represents a thread identifier for both Forum and Proposals Discussion
- ///
- /// Note: Both modules expose type names ThreadId and PostId (which are defined on their Trait) and
- /// used in state storage and dispatchable method's argument types,
- /// and are therefore part of the public API/metadata of the runtime.
- /// In the currenlty version the polkadot-js/api that is used and is compatible with the runtime,
- /// the type registry has flat namespace and its not possible
- /// to register identically named types from different modules, separately. And so we MUST configure
- /// the underlying types to be identicaly to avoid issues with encoding/decoding these types on the client side.
- pub type ThreadId = u64;
- /// Represents a post identifier for both Forum and Proposals Discussion
- ///
- /// See the Note about ThreadId
- pub type PostId = u64;
- /// Represent an actor in membership group, which is the same in the working groups.
- pub type ActorId = u64;
- /// Opaque types. These are used by the CLI to instantiate machinery that don't need to know
- /// the specifics of the runtime. They can then be made to be agnostic over specific formats
- /// of data like extrinsics, allowing for them to continue syncing the network through upgrades
- /// to even the core datastructures.
- pub mod opaque {
- use super::*;
- pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
- pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
- pub type Block = generic::Block<Header, UncheckedExtrinsic>;
- pub type BlockId = generic::BlockId<Block>;
- pub type SessionHandlers = (Grandpa, Babe, ImOnline);
- impl_opaque_keys! {
- pub struct SessionKeys {
- pub grandpa: Grandpa,
- pub babe: Babe,
- pub im_online: ImOnline,
- }
- }
- }
- /// This runtime version.
- pub const VERSION: RuntimeVersion = RuntimeVersion {
- spec_name: create_runtime_str!("joystream-node"),
- impl_name: create_runtime_str!("joystream-node"),
- authoring_version: 6,
- spec_version: 20,
- impl_version: 0,
- apis: RUNTIME_API_VERSIONS,
- transaction_version: 0, //TODO ??
- };
- /// Constants for Babe.
- /// Since BABE is probabilistic this is the average expected block time that
- /// we are targetting. Blocks will be produced at a minimum duration defined
- /// by `SLOT_DURATION`, but some slots will not be allocated to any
- /// authority and hence no block will be produced. We expect to have this
- /// block time on average following the defined slot duration and the value
- /// of `c` configured for BABE (where `1 - c` represents the probability of
- /// a slot being empty).
- /// This value is only used indirectly to define the unit constants below
- /// that are expressed in blocks. The rest of the code should use
- /// `SLOT_DURATION` instead (like the timestamp module for calculating the
- /// minimum period).
- /// <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
- pub const MILLISECS_PER_BLOCK: Moment = 6000;
- pub const SECS_PER_BLOCK: Moment = MILLISECS_PER_BLOCK / 1000;
- pub const SLOT_DURATION: Moment = 6000;
- pub const EPOCH_DURATION_IN_BLOCKS: BlockNumber = 10 * MINUTES;
- pub const EPOCH_DURATION_IN_SLOTS: u64 = {
- const SLOT_FILL_RATE: f64 = MILLISECS_PER_BLOCK as f64 / SLOT_DURATION as f64;
- (EPOCH_DURATION_IN_BLOCKS as f64 * SLOT_FILL_RATE) as u64
- };
- // These time units are defined in number of blocks.
- pub const MINUTES: BlockNumber = 60 / (SECS_PER_BLOCK as BlockNumber);
- pub const HOURS: BlockNumber = MINUTES * 60;
- pub const DAYS: BlockNumber = HOURS * 24;
- // 1 in 4 blocks (on average, not counting collisions) will be primary babe blocks.
- pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
- /// The version information used to identify this runtime when compiled natively.
- #[cfg(feature = "std")]
- pub fn native_version() -> NativeVersion {
- NativeVersion {
- runtime_version: VERSION,
- can_author_with: Default::default(),
- }
- }
- parameter_types! {
- pub const BlockHashCount: BlockNumber = 250;
- /// We allow for 2 seconds of compute with a 6 second average block time.
- pub const MaximumBlockWeight: Weight = 2 * frame_support::weights::constants::WEIGHT_PER_SECOND;
- pub const AvailableBlockRatio: Perbill = Perbill::from_percent(75);
- pub const MaximumBlockLength: u32 = 5 * 1024 * 1024;
- pub const Version: RuntimeVersion = VERSION;
- }
- impl system::Trait for Runtime {
- /// The identifier used to distinguish between accounts.
- type AccountId = AccountId;
- /// The aggregated dispatch type that is available for extrinsics.
- type Call = Call;
- /// The lookup mechanism to get account ID from whatever is passed in dispatchers.
- type Lookup = Indices;
- /// The index type for storing how many extrinsics an account has signed.
- type Index = Index;
- /// The index type for blocks.
- type BlockNumber = BlockNumber;
- /// The type for hashing blocks and tries.
- type Hash = Hash;
- /// The hashing algorithm used.
- type Hashing = BlakeTwo256;
- /// The header type.
- type Header = generic::Header<BlockNumber, BlakeTwo256>;
- /// The ubiquitous event type.
- type Event = Event;
- /// The ubiquitous origin type.
- type Origin = Origin;
- /// Maximum number of block number to block hash mappings to keep (oldest pruned first).
- type BlockHashCount = BlockHashCount;
- /// Maximum weight of each block. With a default weight system of 1byte == 1weight, 4mb is ok.
- type MaximumBlockWeight = MaximumBlockWeight;
- /// Maximum size of all encoded transactions (in bytes) that are allowed in one block.
- type MaximumBlockLength = MaximumBlockLength;
- /// Portion of the block weight that is available to all normal transactions.
- type AvailableBlockRatio = AvailableBlockRatio;
- type Version = Version;
- //TODO
- type BaseCallFilter = ();
- type DbWeight = ();
- type BlockExecutionWeight = ();
- type ExtrinsicBaseWeight = ();
- type MaximumExtrinsicWeight = ();
- type ModuleToIndex = ();
- type AccountData = pallet_balances::AccountData<Balance>;
- type OnNewAccount = ();
- type OnKilledAccount = ();
- }
- /*
- type BaseCallFilter = ();
- type Origin = Origin;
- type Call = Call;
- type Index = Index;
- type BlockNumber = BlockNumber;
- type Hash = Hash;
- type Hashing = BlakeTwo256;
- type AccountId = AccountId;
- type Lookup = Indices;
- type Header = generic::Header<BlockNumber, BlakeTwo256>;
- type Event = Event;
- type BlockHashCount = BlockHashCount;
- type MaximumBlockWeight = MaximumBlockWeight;
- type DbWeight = RocksDbWeight;
- type BlockExecutionWeight = BlockExecutionWeight;
- type ExtrinsicBaseWeight = ExtrinsicBaseWeight;
- type MaximumExtrinsicWeight = MaximumExtrinsicWeight;
- type MaximumBlockLength = MaximumBlockLength;
- type AvailableBlockRatio = AvailableBlockRatio;
- type Version = Version;
- type ModuleToIndex = ModuleToIndex;
- type AccountData = pallet_balances::AccountData<Balance>;
- type OnNewAccount = ();
- type OnKilledAccount = ();
- */
- parameter_types! {
- pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
- pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
- }
- impl pallet_babe::Trait for Runtime {
- type EpochDuration = EpochDuration;
- type ExpectedBlockTime = ExpectedBlockTime;
- type EpochChangeTrigger = pallet_babe::ExternalTrigger;
- }
- impl pallet_grandpa::Trait for Runtime {
- type Event = Event;
- //toDO
- type Call = Call;
- type KeyOwnerProofSystem = ();
- type KeyOwnerProof =
- <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
- type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
- KeyTypeId,
- GrandpaId,
- )>>::IdentificationTuple;
- type HandleEquivocation = ();
- }
- /*
- type KeyOwnerProofSystem = Historical;
- type KeyOwnerProof =
- <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
- type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
- KeyTypeId,
- GrandpaId,
- )>>::IdentificationTuple;
- type HandleEquivocation = pallet_grandpa::EquivocationHandler<
- Self::KeyOwnerIdentification,
- node_primitives::report::ReporterAppCrypto,
- Runtime,
- Offences,
- >;
- */
- impl<C> system::offchain::SendTransactionTypes<C> for Runtime
- where
- Call: From<C>,
- {
- type Extrinsic = UncheckedExtrinsic;
- type OverarchingCall = Call;
- }
- impl pallet_indices::Trait for Runtime {
- /// The type for recording indexing into the account enumeration. If this ever overflows, there
- /// will be problems!
- type AccountIndex = u32;
- /// Use the standard means of resolving an index hint from an id.
- //type ResolveHint = pallet_indices::SimpleResolveHint<Self::AccountId, Self::AccountIndex>;
- type Currency = Balances;
- //toDO
- type Deposit = ();
- type Event = Event;
- }
- parameter_types! {
- pub const MinimumPeriod: Moment = SLOT_DURATION / 2;
- }
- impl timestamp::Trait for Runtime {
- type Moment = Moment;
- type OnTimestampSet = Babe;
- type MinimumPeriod = MinimumPeriod;
- }
- parameter_types! {
- pub const ExistentialDeposit: u128 = 0;
- pub const TransferFee: u128 = 0;
- pub const CreationFee: u128 = 0;
- pub const InitialMembersBalance: u32 = 2000;
- }
- impl pallet_balances::Trait for Runtime {
- /// The type for recording an account's balance.
- type Balance = Balance;
- // /// What to do if an account's free balance gets zeroed.
- // type OnFreeBalanceZero = (Staking, Session);
- // /// What to do if a new account is created.
- // type OnNewAccount = (); // Indices; // disable use of Indices feature
- // /// The ubiquitous event type.
- type Event = Event;
- type DustRemoval = ();
- //type TransferPayment = ();
- type ExistentialDeposit = ExistentialDeposit;
- // type TransferFee = TransferFee;
- // type CreationFee = CreationFee;
- type AccountStore = System;
- }
- parameter_types! {
- pub const TransactionByteFee: Balance = 1; // TODO: adjust fee
- pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
- pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000);
- pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128);
- }
- impl pallet_transaction_payment::Trait for Runtime {
- type Currency = Balances;
- type OnTransactionPayment = ();
- type TransactionByteFee = TransactionByteFee;
- type WeightToFee = IdentityFee<Balance>; // TODO: adjust weight
- type FeeMultiplierUpdate =
- TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
- }
- impl pallet_sudo::Trait for Runtime {
- type Event = Event;
- type Call = Call;
- }
- parameter_types! {
- pub const UncleGenerations: BlockNumber = 5;
- }
- impl pallet_authorship::Trait for Runtime {
- type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
- type UncleGenerations = UncleGenerations;
- type FilterUncle = ();
- type EventHandler = Staking;
- }
- type SessionHandlers = (Grandpa, Babe, ImOnline);
- impl_opaque_keys! {
- pub struct SessionKeys {
- pub grandpa: Grandpa,
- pub babe: Babe,
- pub im_online: ImOnline,
- }
- }
- // NOTE: `SessionHandler` and `SessionKeys` are co-dependent: One key will be used for each handler.
- // The number and order of items in `SessionHandler` *MUST* be the same number and order of keys in
- // `SessionKeys`.
- // TODO: Introduce some structure to tie these together to make it a bit less of a footgun. This
- // should be easy, since OneSessionHandler trait provides the `Key` as an associated type. #2858
- parameter_types! {
- pub const DisabledValidatorsThreshold: Perbill = Perbill::from_percent(17);
- }
- impl pallet_session::Trait for Runtime {
- type Event = Event;
- type ValidatorId = AccountId;
- type ValidatorIdOf = pallet_staking::StashOf<Self>;
- type ShouldEndSession = Babe;
- type NextSessionRotation = Babe;
- type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
- type SessionHandler = SessionHandlers;
- type Keys = SessionKeys;
- type DisabledValidatorsThreshold = DisabledValidatorsThreshold;
- }
- impl pallet_session::historical::Trait for Runtime {
- type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
- type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
- }
- pallet_staking_reward_curve::build! {
- const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
- min_inflation: 0_025_000,
- max_inflation: 0_300_000,
- ideal_stake: 0_300_000,
- falloff: 0_050_000,
- max_piece_count: 100,
- test_precision: 0_005_000,
- );
- }
- parameter_types! {
- pub const SessionDuration: BlockNumber = EPOCH_DURATION_IN_SLOTS as _;
- pub const ImOnlineUnsignedPriority: TransactionPriority = TransactionPriority::max_value();
- /// We prioritize im-online heartbeats over election solution submission.
- pub const StakingUnsignedPriority: TransactionPriority = TransactionPriority::max_value() / 2;
- }
- parameter_types! {
- pub const SessionsPerEra: sp_staking::SessionIndex = 6;
- pub const BondingDuration: pallet_staking::EraIndex = 24;
- pub const SlashDeferDuration: pallet_staking::EraIndex = 6; // 1/4 the bonding duration.
- pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
- pub const MaxNominatorRewardedPerValidator: u32 = 64;
- pub const ElectionLookahead: BlockNumber = EPOCH_DURATION_IN_BLOCKS / 4;
- pub const MaxIterations: u32 = 10;
- // 0.05%. The higher the value, the more strict solution acceptance becomes.
- pub MinSolutionScoreBump: Perbill = Perbill::from_rational_approximation(5u32, 10_000);
- }
- impl pallet_staking::Trait for Runtime {
- type Currency = Balances;
- type UnixTime = Timestamp;
- type CurrencyToVote = common::currency::CurrencyToVoteHandler;
- type RewardRemainder = (); // Could be Treasury.
- type Event = Event;
- type Slash = (); // Where to send the slashed funds. Could be Treasury.
- type Reward = (); // Rewards are minted from the void.
- type SessionsPerEra = SessionsPerEra;
- type BondingDuration = BondingDuration;
- type SlashDeferDuration = SlashDeferDuration;
- type SlashCancelOrigin = EnsureRoot<AccountId>; // Requires sudo. Parity recommends: a super-majority of the council can cancel the slash.
- type SessionInterface = Self;
- type RewardCurve = RewardCurve;
- type NextNewSession = Session;
- type ElectionLookahead = MaxIterations;
- type Call = Call;
- type MaxIterations = MaxIterations;
- type MinSolutionScoreBump = MinSolutionScoreBump;
- type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
- type UnsignedPriority = StakingUnsignedPriority;
- }
- //type SubmitTransaction = TransactionSubmitter<ImOnlineId, Runtime, UncheckedExtrinsic>;
- impl pallet_im_online::Trait for Runtime {
- type AuthorityId = ImOnlineId;
- type Event = Event;
- type SessionDuration = SessionDuration;
- type ReportUnresponsiveness = Offences;
- type UnsignedPriority = ImOnlineUnsignedPriority;
- }
- impl pallet_offences::Trait for Runtime {
- type Event = Event;
- type IdentificationTuple = pallet_session::historical::IdentificationTuple<Self>;
- type OnOffenceHandler = Staking;
- type WeightSoftLimit = (); //OffencesWeightSoftLimit;
- }
- impl pallet_authority_discovery::Trait for Runtime {}
- parameter_types! {
- pub const WindowSize: BlockNumber = 101;
- pub const ReportLatency: BlockNumber = 1000;
- }
- impl pallet_finality_tracker::Trait for Runtime {
- type OnFinalizationStalled = Grandpa;
- type WindowSize = WindowSize;
- type ReportLatency = ReportLatency;
- }
- impl versioned_store::Trait for Runtime {
- type Event = Event;
- }
- impl versioned_store_permissions::Trait for Runtime {
- type Credential = Credential;
- type CredentialChecker = (
- integration::content_working_group::ContentWorkingGroupCredentials,
- SudoKeyHasAllCredentials,
- );
- type CreateClassPermissionsChecker = ContentLeadOrSudoKeyCanCreateClasses;
- }
- // Credential Checker that gives the sudo key holder all credentials
- pub struct SudoKeyHasAllCredentials {}
- impl versioned_store_permissions::CredentialChecker<Runtime> for SudoKeyHasAllCredentials {
- fn account_has_credential(
- account: &AccountId,
- _credential: <Runtime as versioned_store_permissions::Trait>::Credential,
- ) -> bool {
- <pallet_sudo::Module<Runtime>>::key() == *account
- }
- }
- // Allow sudo key holder permission to create classes
- pub struct SudoKeyCanCreateClasses {}
- impl versioned_store_permissions::CreateClassPermissionsChecker<Runtime>
- for SudoKeyCanCreateClasses
- {
- fn account_can_create_class_permissions(account: &AccountId) -> bool {
- <pallet_sudo::Module<Runtime>>::key() == *account
- }
- }
- pub struct ContentLeadOrSudoKeyCanCreateClasses {}
- impl versioned_store_permissions::CreateClassPermissionsChecker<Runtime>
- for ContentLeadOrSudoKeyCanCreateClasses
- {
- fn account_can_create_class_permissions(account: &AccountId) -> bool {
- ContentLeadCanCreateClasses::account_can_create_class_permissions(account)
- || SudoKeyCanCreateClasses::account_can_create_class_permissions(account)
- }
- }
- // Allow content working group lead to create classes in content directory
- pub struct ContentLeadCanCreateClasses {}
- impl versioned_store_permissions::CreateClassPermissionsChecker<Runtime>
- for ContentLeadCanCreateClasses
- {
- fn account_can_create_class_permissions(account: &AccountId) -> bool {
- // get current lead id
- let maybe_current_lead_id = content_wg::CurrentLeadId::<Runtime>::get();
- if let Some(lead_id) = maybe_current_lead_id {
- let lead = content_wg::LeadById::<Runtime>::get(lead_id);
- lead.role_account == *account
- } else {
- false
- }
- }
- }
- impl hiring::Trait for Runtime {
- type OpeningId = u64;
- type ApplicationId = u64;
- type ApplicationDeactivatedHandler = (); // TODO - what needs to happen?
- type StakeHandlerProvider = hiring::Module<Self>;
- }
- impl minting::Trait for Runtime {
- type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
- type MintId = u64;
- }
- impl recurring_rewards::Trait for Runtime {
- type PayoutStatusHandler = (); // TODO - deal with successful and failed payouts
- type RecipientId = u64;
- type RewardRelationshipId = u64;
- }
- parameter_types! {
- pub const StakePoolId: [u8; 8] = *b"joystake";
- }
- impl stake::Trait for Runtime {
- type Currency = <Self as common::currency::GovernanceCurrency>::Currency;
- type StakePoolId = StakePoolId;
- type StakingEventsHandler = (
- crate::integration::content_working_group::ContentWorkingGroupStakingEventHandler,
- (
- crate::integration::proposals::StakingEventsHandler<Self>,
- crate::integration::working_group::StakingEventsHandler<Self>,
- ),
- );
- type StakeId = u64;
- type SlashId = u64;
- }
- impl content_wg::Trait for Runtime {
- type Event = Event;
- }
- impl common::currency::GovernanceCurrency for Runtime {
- type Currency = pallet_balances::Module<Self>;
- }
- impl governance::election::Trait for Runtime {
- type Event = Event;
- type CouncilElected = (Council, integration::proposals::CouncilElectedHandler);
- }
- impl governance::council::Trait for Runtime {
- type Event = Event;
- type CouncilTermEnded = (CouncilElection,);
- }
- impl memo::Trait for Runtime {
- type Event = Event;
- }
- parameter_types! {
- pub const MaxObjectsPerInjection: u32 = 100;
- }
- impl storage::data_object_type_registry::Trait for Runtime {
- type Event = Event;
- type DataObjectTypeId = u64;
- }
- impl storage::data_directory::Trait for Runtime {
- type Event = Event;
- type ContentId = ContentId;
- type StorageProviderHelper = integration::storage::StorageProviderHelper;
- type IsActiveDataObjectType = DataObjectTypeRegistry;
- type MemberOriginValidator = MembershipOriginValidator<Self>;
- type MaxObjectsPerInjection = MaxObjectsPerInjection;
- }
- impl storage::data_object_storage_registry::Trait for Runtime {
- type Event = Event;
- type DataObjectStorageRelationshipId = u64;
- type ContentIdExists = DataDirectory;
- }
- impl membership::Trait for Runtime {
- type Event = Event;
- type MemberId = u64;
- type PaidTermId = u64;
- type SubscriptionId = u64;
- type ActorId = ActorId;
- }
- /*
- * Forum module integration
- *
- * ForumUserRegistry could have been implemented directly on
- * the membership module, and likewise ForumUser on Profile,
- * however this approach is more loosely coupled.
- *
- * Further exploration required to decide what the long
- * run convention should be.
- */
- /// Shim registry which will proxy ForumUserRegistry behaviour to the members module
- pub struct ShimMembershipRegistry {}
- impl forum::ForumUserRegistry<AccountId> for ShimMembershipRegistry {
- fn get_forum_user(id: &AccountId) -> Option<forum::ForumUser<AccountId>> {
- if membership::Module::<Runtime>::is_member_account(id) {
- // For now we don't retreive the members profile since it is not used for anything,
- // but in the future we may need it to read out more
- // information possibly required to construct a
- // ForumUser.
- // Now convert member profile to a forum user
- Some(forum::ForumUser { id: id.clone() })
- } else {
- None
- }
- }
- }
- impl forum::Trait for Runtime {
- type Event = Event;
- type MembershipRegistry = ShimMembershipRegistry;
- type ThreadId = ThreadId;
- type PostId = PostId;
- }
- impl migration::Trait for Runtime {
- type Event = Event;
- }
- // The storage working group instance alias.
- pub type StorageWorkingGroupInstance = working_group::Instance2;
- parameter_types! {
- pub const MaxWorkerNumberLimit: u32 = 100;
- }
- impl working_group::Trait<StorageWorkingGroupInstance> for Runtime {
- type Event = Event;
- type MaxWorkerNumberLimit = MaxWorkerNumberLimit;
- }
- impl service_discovery::Trait for Runtime {
- type Event = Event;
- }
- parameter_types! {
- pub const ProposalCancellationFee: u64 = 10000;
- pub const ProposalRejectionFee: u64 = 5000;
- pub const ProposalTitleMaxLength: u32 = 40;
- pub const ProposalDescriptionMaxLength: u32 = 3000;
- pub const ProposalMaxActiveProposalLimit: u32 = 5;
- }
- impl proposals_engine::Trait for Runtime {
- type Event = Event;
- type ProposerOriginValidator = MembershipOriginValidator<Self>;
- type VoterOriginValidator = CouncilManager<Self>;
- type TotalVotersCounter = CouncilManager<Self>;
- type ProposalId = u32;
- type StakeHandlerProvider = proposals_engine::DefaultStakeHandlerProvider;
- type CancellationFee = ProposalCancellationFee;
- type RejectionFee = ProposalRejectionFee;
- type TitleMaxLength = ProposalTitleMaxLength;
- type DescriptionMaxLength = ProposalDescriptionMaxLength;
- type MaxActiveProposalLimit = ProposalMaxActiveProposalLimit;
- type DispatchableCallCode = Call;
- }
- impl Default for Call {
- fn default() -> Self {
- panic!("shouldn't call default for Call");
- }
- }
- parameter_types! {
- pub const ProposalMaxPostEditionNumber: u32 = 0; // post update is disabled
- pub const ProposalMaxThreadInARowNumber: u32 = 100_000; // will not be used
- pub const ProposalThreadTitleLengthLimit: u32 = 40;
- pub const ProposalPostLengthLimit: u32 = 1000;
- }
- impl proposals_discussion::Trait for Runtime {
- type Event = Event;
- type PostAuthorOriginValidator = MembershipOriginValidator<Self>;
- type ThreadId = ThreadId;
- type PostId = PostId;
- type MaxPostEditionNumber = ProposalMaxPostEditionNumber;
- type ThreadTitleLengthLimit = ProposalThreadTitleLengthLimit;
- type PostLengthLimit = ProposalPostLengthLimit;
- type MaxThreadInARowNumber = ProposalMaxThreadInARowNumber;
- }
- parameter_types! {
- pub const TextProposalMaxLength: u32 = 5_000;
- pub const RuntimeUpgradeWasmProposalMaxLength: u32 = 2_000_000;
- }
- impl proposals_codex::Trait for Runtime {
- type MembershipOriginValidator = MembershipOriginValidator<Self>;
- type TextProposalMaxLength = TextProposalMaxLength;
- type RuntimeUpgradeWasmProposalMaxLength = RuntimeUpgradeWasmProposalMaxLength;
- type ProposalEncoder = ExtrinsicProposalEncoder;
- }
- construct_runtime!(
- pub enum Runtime where
- Block = Block,
- NodeBlock = opaque::Block,
- UncheckedExtrinsic = UncheckedExtrinsic
- {
- // Substrate
- System: system::{Module, Call, Storage, Config, Event<T>},
- Babe: pallet_babe::{Module, Call, Storage, Config, Inherent(Timestamp)},
- Timestamp: timestamp::{Module, Call, Storage, Inherent},
- Authorship: pallet_authorship::{Module, Call, Storage, Inherent},
- Indices: pallet_indices::{Module, Call, Storage, Config<T>, Event<T>},
- Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
- TransactionPayment: pallet_transaction_payment::{Module, Storage},
- Staking: pallet_staking::{Module, Call, Config<T>, Storage, Event<T>, ValidateUnsigned},
- Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
- Historical: pallet_session_historical::{Module},
- FinalityTracker: pallet_finality_tracker::{Module, Call, Inherent},
- Grandpa: pallet_grandpa::{Module, Call, Storage, Config, Event},
- ImOnline: pallet_im_online::{Module, Call, Storage, Event<T>, ValidateUnsigned, Config<T>},
- AuthorityDiscovery: pallet_authority_discovery::{Module, Call, Config},
- Offences: pallet_offences::{Module, Call, Storage, Event},
- RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
- Sudo: pallet_sudo::{Module, Call, Config<T>, Storage, Event<T>},
- // Joystream
- Migration: migration::{Module, Call, Storage, Event<T>, Config},
- CouncilElection: election::{Module, Call, Storage, Event<T>, Config<T>},
- Council: council::{Module, Call, Storage, Event<T>, Config<T>},
- Memo: memo::{Module, Call, Storage, Event<T>},
- Members: membership::{Module, Call, Storage, Event<T>, Config<T>},
- Forum: forum::{Module, Call, Storage, Event<T>, Config<T>},
- VersionedStore: versioned_store::{Module, Call, Storage, Event<T>, Config},
- VersionedStorePermissions: versioned_store_permissions::{Module, Call, Storage},
- Stake: stake::{Module, Call, Storage},
- Minting: minting::{Module, Call, Storage},
- RecurringRewards: recurring_rewards::{Module, Call, Storage},
- Hiring: hiring::{Module, Call, Storage},
- ContentWorkingGroup: content_wg::{Module, Call, Storage, Event<T>, Config<T>},
- // --- Storage
- DataObjectTypeRegistry: data_object_type_registry::{Module, Call, Storage, Event<T>, Config<T>},
- DataDirectory: data_directory::{Module, Call, Storage, Event<T>},
- DataObjectStorageRegistry: data_object_storage_registry::{Module, Call, Storage, Event<T>, Config<T>},
- Discovery: service_discovery::{Module, Call, Storage, Event<T>},
- // --- Proposals
- ProposalsEngine: proposals_engine::{Module, Call, Storage, Event<T>},
- ProposalsDiscussion: proposals_discussion::{Module, Call, Storage, Event<T>},
- ProposalsCodex: proposals_codex::{Module, Call, Storage, Config<T>},
- // --- Working groups
- // reserved for the future use: ForumWorkingGroup: working_group::<Instance1>::{Module, Call, Storage, Event<T>},
- StorageWorkingGroup: working_group::<Instance2>::{Module, Call, Storage, Config<T>, Event<T>},
- }
- );
- /// The address format for describing accounts.
- pub type Address = <Indices as StaticLookup>::Source;
- /// Block header type as expected by this runtime.
- pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
- /// Block type as expected by this runtime.
- pub type Block = generic::Block<Header, UncheckedExtrinsic>;
- /// A Block signed with a Justification
- pub type SignedBlock = generic::SignedBlock<Block>;
- /// BlockId type as expected by this runtime.
- pub type BlockId = generic::BlockId<Block>;
- /// The SignedExtension to the basic transaction logic.
- pub type SignedExtra = (
- system::CheckSpecVersion<Runtime>,
- system::CheckTxVersion<Runtime>,
- system::CheckGenesis<Runtime>,
- system::CheckEra<Runtime>,
- system::CheckNonce<Runtime>,
- system::CheckWeight<Runtime>,
- pallet_transaction_payment::ChargeTransactionPayment<Runtime>,
- pallet_grandpa::ValidateEquivocationReport<Runtime>,
- );
- /// Unchecked extrinsic type as expected by this runtime.
- pub type UncheckedExtrinsic = generic::UncheckedExtrinsic<Address, Call, Signature, SignedExtra>;
- /// Extrinsic type that has already been checked.
- pub type CheckedExtrinsic = generic::CheckedExtrinsic<AccountId, Call, SignedExtra>;
- /// Executive: handles dispatch to the various modules.
- pub type Executive =
- frame_executive::Executive<Runtime, Block, system::ChainContext<Runtime>, Runtime, AllModules>;
- impl_runtime_apis! {
- impl sp_api::Core<Block> for Runtime {
- fn version() -> RuntimeVersion {
- VERSION
- }
- fn execute_block(block: Block) {
- Executive::execute_block(block)
- }
- fn initialize_block(header: &<Block as BlockT>::Header) {
- Executive::initialize_block(header)
- }
- }
- impl sp_api::Metadata<Block> for Runtime {
- fn metadata() -> OpaqueMetadata {
- Runtime::metadata().into()
- }
- }
- impl sp_block_builder::BlockBuilder<Block> for Runtime {
- fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
- Executive::apply_extrinsic(extrinsic)
- }
- fn finalize_block() -> <Block as BlockT>::Header {
- Executive::finalize_block()
- }
- fn inherent_extrinsics(data: InherentData) -> Vec<<Block as BlockT>::Extrinsic> {
- data.create_extrinsics()
- }
- fn check_inherents(block: Block, data: InherentData) -> CheckInherentsResult {
- data.check_extrinsics(&block)
- }
- fn random_seed() -> <Block as BlockT>::Hash {
- RandomnessCollectiveFlip::random_seed()
- }
- }
- impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
- fn validate_transaction(
- source: TransactionSource,
- tx: <Block as BlockT>::Extrinsic,
- ) -> TransactionValidity {
- Executive::validate_transaction(source, tx)
- }
- }
- impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
- fn offchain_worker(header: &<Block as BlockT>::Header) {
- Executive::offchain_worker(header)
- }
- }
- impl fg_primitives::GrandpaApi<Block> for Runtime {
- fn grandpa_authorities() -> GrandpaAuthorityList {
- Grandpa::grandpa_authorities()
- }
- fn submit_report_equivocation_extrinsic(
- equivocation_proof: fg_primitives::EquivocationProof<
- <Block as BlockT>::Hash,
- NumberFor<Block>,
- >,
- key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
- ) -> Option<()> {
- let key_owner_proof = key_owner_proof.decode()?;
- Grandpa::submit_report_equivocation_extrinsic(
- equivocation_proof,
- key_owner_proof,
- )
- }
- fn generate_key_ownership_proof(
- _set_id: fg_primitives::SetId,
- authority_id: GrandpaId,
- ) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
- use codec::Encode;
- Historical::prove((fg_primitives::KEY_TYPE, authority_id))
- .map(|p| p.encode())
- .map(fg_primitives::OpaqueKeyOwnershipProof::new)
- }
- }
- impl sp_consensus_babe::BabeApi<Block> for Runtime {
- fn configuration() -> sp_consensus_babe::BabeGenesisConfiguration {
- // The choice of `c` parameter (where `1 - c` represents the
- // probability of a slot being empty), is done in accordance to the
- // slot duration and expected target block time, for safely
- // resisting network delays of maximum two seconds.
- // <https://research.web3.foundation/en/latest/polkadot/BABE/Babe/#6-practical-results>
- sp_consensus_babe::BabeGenesisConfiguration {
- slot_duration: Babe::slot_duration(),
- epoch_length: EpochDuration::get(),
- c: PRIMARY_PROBABILITY,
- genesis_authorities: Babe::authorities(),
- randomness: Babe::randomness(),
- allowed_slots: sp_consensus_babe::AllowedSlots::PrimaryAndSecondaryPlainSlots,
- }
- }
- fn current_epoch_start() -> sp_consensus_babe::SlotNumber {
- Babe::current_epoch_start()
- }
- }
- impl sp_authority_discovery::AuthorityDiscoveryApi<Block> for Runtime {
- fn authorities() -> Vec<AuthorityDiscoveryId> {
- AuthorityDiscovery::authorities()
- }
- }
- impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Index> for Runtime {
- fn account_nonce(account: AccountId) -> Index {
- System::account_nonce(account)
- }
- }
- impl sp_session::SessionKeys<Block> for Runtime {
- fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
- SessionKeys::generate(seed)
- }
- fn decode_session_keys(
- encoded: Vec<u8>,
- ) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
- SessionKeys::decode_into_raw_public_keys(&encoded)
- }
- }
- impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<
- Block,
- Balance,
- UncheckedExtrinsic,
- > for Runtime {
- fn query_info(uxt: UncheckedExtrinsic, len: u32) -> RuntimeDispatchInfo<Balance> {
- TransactionPayment::query_info(uxt, len)
- }
- }
- }
|