lib.rs 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  1. // Ensure we're `no_std` when compiling for Wasm.
  2. #![cfg_attr(not(feature = "std"), no_std)]
  3. #[cfg(feature = "std")]
  4. use serde::{Deserialize, Serialize};
  5. use codec::{Codec, Decode, Encode};
  6. //use rstd::collections::btree_map::BTreeMap;
  7. use rstd::collections::btree_set::BTreeSet;
  8. use rstd::prelude::*;
  9. use srml_support::traits::Currency;
  10. use srml_support::{
  11. decl_module, decl_storage, decl_event, ensure, StorageMap, StorageValue, Parameter
  12. };
  13. use runtime_primitives::traits::{Member, One, SimpleArithmetic, MaybeSerialize};
  14. use minting;
  15. use recurringrewards;
  16. use stake;
  17. use hiring;
  18. use versioned_store_permissions;
  19. use super::super::membership::members as membership;
  20. /// Module configuration trait for this Substrate module.
  21. pub trait Trait: system::Trait + minting::Trait + recurringrewards::Trait + stake::Trait + hiring::Trait + versioned_store_permissions::Trait + membership::Trait + Sized {
  22. /// The event type.
  23. type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
  24. /// Type for identifier for lead.
  25. type LeadId: Parameter
  26. + Member
  27. + SimpleArithmetic
  28. + Codec
  29. + Default
  30. + Copy
  31. + MaybeSerialize
  32. + PartialEq;
  33. /// Type for identifier for curators.
  34. type CuratorId: Parameter
  35. + Member
  36. + SimpleArithmetic
  37. + Codec
  38. + Default
  39. + Copy
  40. + MaybeSerialize
  41. + PartialEq
  42. + Ord;
  43. /// Type for identifier for channels.
  44. type ChannelId: Parameter
  45. + Member
  46. + SimpleArithmetic
  47. + Codec
  48. + Default
  49. + Copy
  50. + MaybeSerialize
  51. + PartialEq;
  52. }
  53. /// Type for identifier for dynamic version store credential.
  54. pub type DynamicCredentialId<T: Trait> = T::PrincipalId;
  55. /// Balance type of runtime
  56. pub type BalanceOf<T> =
  57. <<T as stake::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::Balance;
  58. /// Negative imbalance of runtime.
  59. pub type NegativeImbalance<T> =
  60. <<T as stake::Trait>::Currency as Currency<<T as system::Trait>::AccountId>>::NegativeImbalance;
  61. /// The exit stage of a lead involvement in the working group.
  62. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  63. pub struct ExitedLeadRole<BlockNumber> {
  64. /// When exit was initiated.
  65. pub initiated_at_block_number: BlockNumber
  66. }
  67. /// The stage of the involvement of a lead in the working group.
  68. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  69. pub enum LeadRoleState<BlockNumber> {
  70. /// Currently active.
  71. Active,
  72. /// No longer active, for some reason
  73. Exited(ExitedLeadRole<BlockNumber>)
  74. }
  75. /// Must be default constructible because it indirectly is a value in a storage map.
  76. /// ***SHOULD NEVER ACTUALLY GET CALLED, IS REQUIRED TO DUE BAD STORAGE MODEL IN SUBSTRATE***
  77. impl<BlockNumber> Default for LeadRoleState<BlockNumber> {
  78. fn default() -> Self {
  79. LeadRoleState::Active
  80. }
  81. }
  82. /// Working group lead: curator lead
  83. /// For now this role is not staked or inducted through an structured process, like the hiring module,
  84. /// hence information about this is missing. Recurring rewards is included, somewhat arbitrarily!
  85. #[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Clone, PartialOrd)]
  86. pub struct Lead<AccountId, RewardRelationshipId, BlockNumber> {
  87. /// Account used to authenticate in this role,
  88. pub role_account: AccountId,
  89. /// Whether the role has recurring reward, and if so an identifier for this.
  90. pub reward_relationship: Option<RewardRelationshipId>,
  91. /// When was inducted
  92. /// TODO: Add richer information about circumstances of induction, like referencing a council proposal?
  93. pub inducted: BlockNumber,
  94. /// The stage of the involvement of this lead in the working group.
  95. pub stage: LeadRoleState<BlockNumber>
  96. }
  97. /// Origin of exit initiation on behalf of a curator.'
  98. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  99. pub enum CuratorExitInitiationOrigin {
  100. /// Lead is origin.
  101. Lead,
  102. /// The curator exiting is the origin.
  103. Curator
  104. }
  105. /// The exit stage of a curators involvement in the working group.
  106. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  107. pub struct ExitedCuratorRoleStage<BlockNumber> {
  108. /// Origin for exit.
  109. pub origin: CuratorExitInitiationOrigin,
  110. /// When exit was initiated.
  111. pub initiated_at_block_number: BlockNumber,
  112. /// Explainer for why exit was initited.
  113. pub rationale_text: Vec<u8>
  114. }
  115. /// The stage of the involvement of a curator in the working group.
  116. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  117. pub enum CuratorRoleStage<BlockNumber> {
  118. /// Currently active.
  119. Active,
  120. /// No longer active, for some reason
  121. Exited(ExitedCuratorRoleStage<BlockNumber>)
  122. }
  123. /// Must be default constructible because it indirectly is a value in a storage map.
  124. /// ***SHOULD NEVER ACTUALLY GET CALLED, IS REQUIRED TO DUE BAD STORAGE MODEL IN SUBSTRATE***
  125. impl<BlockNumber> Default for CuratorRoleStage<BlockNumber> {
  126. fn default() -> Self {
  127. CuratorRoleStage::Active
  128. }
  129. }
  130. /// The induction of a curator in the working group.
  131. #[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Clone, PartialOrd)]
  132. pub struct CuratorInduction<LeadId, ApplicationId, BlockNumber> {
  133. /// Lead responsible
  134. pub lead: LeadId,
  135. /// Application through which curator was inducted
  136. pub application: ApplicationId,
  137. /// When induction occurred
  138. pub at_block: BlockNumber
  139. }
  140. /// Working group participant: curator
  141. /// This role can be staked, have reward and be inducted through the hiring module.
  142. #[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Clone, PartialOrd)]
  143. pub struct Curator<AccountId, RewardRelationshipId, StakeId, BlockNumber, LeadId, ApplicationId> {
  144. /// Account used to authenticate in this role,
  145. pub role_account: AccountId,
  146. /// Whether the role has recurring reward, and if so an identifier for this.
  147. pub reward_relationship: Option<RewardRelationshipId>,
  148. /// Whether participant is staked, and if so, the identifier for this staking in the staking module.
  149. pub stake: Option<StakeId>,
  150. /// The stage of this curator in the working group.
  151. pub stage: CuratorRoleStage<BlockNumber>,
  152. /// How the curator was inducted into the working group.
  153. pub induction: CuratorInduction<LeadId, ApplicationId, BlockNumber>,
  154. /// Whether this curator can unilaterally alter the curation status of a channel.
  155. pub can_update_channel_curation_status: bool
  156. }
  157. /// Type of channel content.
  158. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  159. pub enum ChannelContentType {
  160. Video,
  161. Music,
  162. Ebook
  163. }
  164. /// Must be default constructible because it indirectly is a value in a storage map.
  165. /// ***SHOULD NEVER ACTUALLY GET CALLED, IS REQUIRED TO DUE BAD STORAGE MODEL IN SUBSTRATE***
  166. impl Default for ChannelContentType {
  167. fn default() -> Self {
  168. ChannelContentType::Video
  169. }
  170. }
  171. /// Status of channel, as set by the owner.
  172. /// Is only meant to affect visibility, mutation of channel and child content
  173. /// is unaffected on runtime.
  174. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  175. pub enum ChannelPublishingStatus {
  176. /// Compliant UIs should render.
  177. Published,
  178. /// Compliant UIs should not render it or any child content.
  179. NotPublished
  180. }
  181. /// Must be default constructible because it indirectly is a value in a storage map.
  182. /// ***SHOULD NEVER ACTUALLY GET CALLED, IS REQUIRED TO DUE BAD STORAGE MODEL IN SUBSTRATE***
  183. impl Default for ChannelPublishingStatus {
  184. fn default() -> Self {
  185. ChannelPublishingStatus::Published
  186. }
  187. }
  188. /// Status of channel, as set by curators.
  189. /// Is only meant to affect visibility currently, but in the future
  190. /// it will also gate publication of new child content,
  191. /// editing properties, revenue flows, etc.
  192. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  193. pub enum ChannelCurationStatus {
  194. Normal,
  195. Censored
  196. }
  197. /// Must be default constructible because it indirectly is a value in a storage map.
  198. /// ***SHOULD NEVER ACTUALLY GET CALLED, IS REQUIRED TO DUE BAD STORAGE MODEL IN SUBSTRATE***
  199. impl Default for ChannelCurationStatus {
  200. fn default() -> Self {
  201. ChannelCurationStatus::Normal
  202. }
  203. }
  204. /// A channel for publishing content.
  205. #[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Clone, PartialOrd)]
  206. pub struct Channel<MemberId, AccountId, BlockNumber> {
  207. /// Unique human readble channel handle.
  208. pub handle: Vec<u8>,
  209. /// Whether channel has been verified, in the normal Web2.0 platform sense of being authenticated.
  210. pub verified: bool,
  211. /// Human readable description of channel purpose and scope.
  212. pub description: Vec<u8>,
  213. /// The type of channel.
  214. pub content: ChannelContentType,
  215. /// Member who owns channel.
  216. pub owner: MemberId,
  217. /// Account used to authenticate as owner.
  218. /// Can be updated through membership role key.
  219. pub role_account: AccountId,
  220. /// Publication status of channel.
  221. pub publishing_status: ChannelPublishingStatus,
  222. /// Curation status of channel.
  223. pub curation_status: ChannelCurationStatus,
  224. /// When channel was established.
  225. pub created: BlockNumber
  226. }
  227. /// The types of built in credential holders.
  228. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  229. pub enum BuiltInCredentialHolder {
  230. /// Cyrrent working group lead.
  231. Lead,
  232. /// Any active urator in the working group.
  233. AnyCurator,
  234. /// Any active member in the membership registry.
  235. AnyMember
  236. }
  237. /// Holder of dynamic credential.
  238. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  239. pub enum DynamicCredentialHolder<CuratorId: Ord, ChannelId> {
  240. /// Sets of curators.
  241. Curators(BTreeSet<CuratorId>),
  242. /// Owner of a channel.
  243. ChannelOwner(ChannelId),
  244. }
  245. /// Must be default constructible because it indirectly is a value in a storage map.
  246. /// ***SHOULD NEVER ACTUALLY GET CALLED, IS REQUIRED TO DUE BAD STORAGE MODEL IN SUBSTRATE***
  247. impl<CuratorId: Ord, ChannelId> Default for DynamicCredentialHolder<CuratorId, ChannelId> {
  248. fn default() -> Self {
  249. DynamicCredentialHolder::Curators(BTreeSet::new())
  250. }
  251. }
  252. /// Represents credential for authenticating as "the current lead".
  253. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  254. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd, Default)]
  255. pub struct LeadCredential {
  256. /// Whether it is currently possible to authenticate with this credential.
  257. pub is_active: bool
  258. }
  259. /// Represents credential for authenticating as "any curator".
  260. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  261. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd, Default)]
  262. pub struct AnyCuratorCredential {
  263. /// Whether it is currently possible to authenticate with this credential.
  264. pub is_active: bool
  265. }
  266. /// Represents credential for authenticating as "any member".
  267. #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
  268. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd, Default)]
  269. pub struct AnyMemberCredential {
  270. /// Whether it is currently possible to authenticate with this credential.
  271. pub is_active: bool
  272. }
  273. /// Represents credential to be referenced from the version store.
  274. /// It is dynamic in the sense that these can be created on the fly.
  275. #[derive(Encode, Decode, Default, Debug, Eq, PartialEq, Clone, PartialOrd)]
  276. pub struct DynamicCredential<CuratorId: Ord, ChannelId, BlockNumber> {
  277. /// Who holds this credential, meaning they can successfully authenticate with this credential.
  278. pub holder: DynamicCredentialHolder<CuratorId, ChannelId>,
  279. /// Whether it is currently possible to authenticate with this credential.
  280. pub is_active: bool,
  281. /// When it was created.
  282. pub created: BlockNumber,
  283. /// Human readable description of credential.
  284. pub description: Vec<u8>
  285. }
  286. /// Policy governing any curator opening which can be made by lead.
  287. /// Be aware that all limits are forward looking in constrainign future extrinsics or method calls.
  288. /// Updating them has no side-effects beyond changing the limit.
  289. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  290. pub struct OpeningPolicy<BlockNumber, StakingPolicy> {
  291. /// Limits the total number of curators which can be active, or possibly active through an active opening.
  292. /// The contribution of an active opening is counted by looking at the rationing policy of the opening.
  293. /// A limit of N is counted as there being N actual active curators, as a worst case bound.
  294. /// The absence of a limit is counted as "infinity", thus blocking any further openings from being created,
  295. /// and is is not possible to actually hire a number of curators that would bring the number above this parameter `curator_limit`.
  296. pub curator_limit: Option<u16>,
  297. /// Maximum length of review period of applications
  298. pub max_review_period_length: BlockNumber,
  299. /// Staking policy for application
  300. pub application_staking_policy: Option<StakingPolicy>,
  301. /// Staking policy for role itself
  302. pub role_staking_policy: Option<StakingPolicy>
  303. }
  304. /// Represents
  305. #[derive(Encode, Decode, Debug, Eq, PartialEq, Clone, PartialOrd)]
  306. pub enum WorkingGroupActor<T: Trait> {
  307. ///
  308. Lead(T::LeadId),
  309. ///
  310. Curator(T::CuratorId),
  311. }
  312. pub enum ChannelActor<T: Trait> {
  313. ///
  314. WorkingGroupActor(WorkingGroupActor<T>),
  315. ///
  316. Owner
  317. }
  318. decl_storage! {
  319. trait Store for Module<T: Trait> as ContentWorkingGroup {
  320. /// The mint currently funding the rewards for this module.
  321. pub Mint get(mint) config(): <T as minting::Trait>::MintId;
  322. /// The current lead.
  323. pub CurrentLeadId get(current_lead_id) config(): Option<T::LeadId>;
  324. /// Maps identifier to corresponding lead.
  325. pub LeadById get(lead_by_id) config(): linked_map T::LeadId => Lead<T::AccountId, T::RewardRelationshipId, T::BlockNumber>;
  326. /// Next identifier for new current lead.
  327. pub NextLeadId get(next_lead_id) config(): T::LeadId;
  328. /// Set of identifiers for all openings originated from this group.
  329. /// Using map to model a set.
  330. pub Openings get(openings) config(): linked_map T::OpeningId => ();
  331. /// Maps identifier to corresponding channel.
  332. pub ChannelById get(channel_by_id) config(): linked_map T::ChannelId => Channel<T::MemberId, T::AccountId, T::BlockNumber>;
  333. /// Identifier to be used by the next channel introduced.
  334. pub NextChannelId get(next_channel_id) config(): T::ChannelId;
  335. /// Maps (unique+immutable) channel handle to the corresponding identifier for the channel.
  336. /// Mapping is required to allow efficient (O(log N)) on-chain verification that a proposed handle is indeed unique
  337. /// at the time it is being proposed.
  338. pub ChannelIdByHandle get(channel_id_by_handle) config(): linked_map Vec<u8> => T::ChannelId;
  339. /// Maps identifier to corresponding curator.
  340. pub CuratorById get(curator_by_id) config(): linked_map T::CuratorId => Curator<T::AccountId, T::RewardRelationshipId, T::StakeId, T::BlockNumber, T::LeadId, T::ApplicationId>;
  341. /// Next identifier for new curator.
  342. pub NextCuratorId get(next_curator_id) config(): T::CuratorId;
  343. /// The constraints lead must respect when creating a new curator opening.
  344. /// Lack of policy is interpreted as blocking any new openings at all.
  345. pub OptOpeningPolicy get(opening_policy) config(): Option<OpeningPolicy<T::BlockNumber, hiring::StakingPolicy<BalanceOf<T>, T::BlockNumber>>>;
  346. /// Credentials for built in roles.
  347. pub CredentialOfLead get(credential_of_lead) config(): LeadCredential;
  348. /// The "any curator" credential.
  349. pub CredentialOfAnyCurator get(credential_of_anycurator) config(): AnyCuratorCredential;
  350. /// The "any member" credential.
  351. pub CredentialOfAnyMember get(credential_of_anymember) config(): AnyMemberCredential;
  352. /// Maps dynamic credential by
  353. pub DynamicCredentialById get(dynamic_credential_by_id) config(): linked_map DynamicCredentialId<T> => DynamicCredential<T::CuratorId, T::ChannelId, T::BlockNumber>;
  354. /// ...
  355. pub NextDynamicCredentialId get(next_dynamic_credential_id) config(): DynamicCredentialId<T>;
  356. /// Whether it is currently possible to create a channel via `create_channel` extrinsic.
  357. pub ChannelCreationEnabled get(channel_creation_enabled) config(): bool;
  358. // Input guards
  359. // TODO: use proper input constraint types
  360. /// Upper bound for character length of description field of any new or updated PermissionGroup
  361. pub MaxPermissionGroupDescriptionLength get(max_permission_group_description_length) config(): u16;
  362. /// Upper bound for character length of the rationale_text field of any new CuratorRoleStage.
  363. pub MaxCuratorExitRationaleTextLength get(max_curator_exit_rationale_text_length) config(): u16;
  364. }
  365. }
  366. /*
  367. /// Substrate module events.
  368. decl_event! {
  369. pub enum Event<T> where
  370. <T as system::Trait>::AccountId,
  371. <T as Trait>::MemberId,
  372. <T as Trait>::ActorId,
  373. {
  374. LeadSet
  375. LeadUnset
  376. OpeningPolicySet
  377. LeadRewardUpdated
  378. LeadRoleAccountUpdated
  379. LeadRewardAccountUpdated
  380. PermissionGroupAdded
  381. PermissionGroupUpdated
  382. CuratorOpeningAdded
  383. AcceptedCuratorApplications
  384. BeganCuratorApplicationReview
  385. CuratorOpeningFilled
  386. CuratorSlashed
  387. TerminatedCurator
  388. AppliedOnCuratorOpening
  389. CuratorRewardUpdated
  390. CuratorRoleAccountUpdated
  391. CuratorRewardAccountUpdated
  392. CuratorExited
  393. }
  394. }
  395. */
  396. decl_event!(
  397. pub enum Event<T>
  398. where
  399. <T as system::Trait>::AccountId,
  400. {
  401. MyOtherEvent(AccountId),
  402. }
  403. );
  404. decl_module! {
  405. pub struct Module<T: Trait> for enum Call where origin: T::Origin {
  406. fn deposit_event() = default;
  407. /*
  408. * Channel management
  409. */
  410. /// Create a new channel.
  411. pub fn create_channel(origin, handle: Vec<u8>, description: Vec<u8>, content: ChannelContentType, owner: T::MemberId, role_account: T::AccountId) {
  412. // Ensure is signed by "who".
  413. // Ensure it is currently possible to create channels (ChannelCreationEnabled).
  414. // Ensure handle is acceptable length
  415. // Ensure description is acceptable length
  416. // Ensure tx signer "who" is allowed to do this under owner id by dialing out to
  417. // membership module and asking.
  418. //
  419. // == MUTATION SAFE ==
  420. //
  421. // Get id of new channel
  422. // Construct channel
  423. // Add channel to ChannelById under id
  424. // Add id to ChannelIdByHandle under handle
  425. // Increment NextChannelId
  426. // Dial out to membership module and inform about new role as channe owner.
  427. // event?
  428. }
  429. /// An owner transfers channel ownership to a new owner.
  430. ///
  431. /// Notice that working group participants cannot do this.
  432. /// Notice that censored or unpublished channel may still be transferred.
  433. pub fn transfer_channel_ownership(origin, channel_id: T::ChannelId, new_owner: T::MemberId, new_role_account: T::AccountId) {
  434. // Ensure extrinsic is signed by "who"
  435. // Ensure channel id is valid
  436. // Ensure "who" matches role account of channel
  437. // Ensure new owner is allowed to do this under new owner id by dialing out to
  438. // membership module and asking
  439. //
  440. // == MUTATION SAFE ==
  441. //
  442. // Construct new channel with altered properties
  443. // Overwrite entry in ChannelById
  444. // Dial out to membership module and inform about removal of role as channle owner for old owner.
  445. // Dial out to membership module and inform about new role as channe owner for new owner.
  446. // event?
  447. }
  448. // perhaps curation can be done here in one go.
  449. /// Update channel curation status of a channel.
  450. ///
  451. /// Can
  452. pub fn update_channel_curation_status(origin) {
  453. // WorkingGroupActor
  454. }
  455. /*
  456. * Credential management for versioned store permissions.
  457. *
  458. * Lead credential is managed as non-dispatchable.
  459. */
  460. pub fn update_any_member_credential(origin) {
  461. }
  462. pub fn update_any_curator_credential(origin) {
  463. }
  464. pub fn create_dynamic_credential(origin) {
  465. }
  466. pub fn update_dynamic_credential(origin) {
  467. }
  468. /// ...
  469. pub fn update_channel_as_owner(origin) {
  470. }
  471. /// ...
  472. pub fn update_channel_as_curator(origin) {
  473. }
  474. /// ..
  475. pub fn create_version_store_credential(origin) {
  476. }
  477. /// ...
  478. pub fn update_lead_role_account(origin) {
  479. }
  480. /// ...
  481. pub fn update_lead_reward_account(origin) {
  482. }
  483. /// ...
  484. pub fn add_curator_opening(origin) {
  485. }
  486. /// ...
  487. pub fn accept_curator_applications(origin) {
  488. }
  489. /// ...
  490. pub fn begin_curator_applicant_review(origin) {
  491. }
  492. /// ...
  493. pub fn fill_curator_opening(origin) {
  494. }
  495. /// ...
  496. pub fn update_curator_reward(origin) {
  497. }
  498. /// ...
  499. pub fn slash_curator(origin) {
  500. }
  501. /// ...
  502. pub fn terminate_curator(origin) {
  503. }
  504. /// ...
  505. pub fn apply_on_curator_opening(origin) {
  506. }
  507. /// ...
  508. pub fn update_curator_role_account(origin) {
  509. }
  510. /// ...
  511. pub fn update_curator_reward_account(origin) {
  512. }
  513. /// ...
  514. pub fn exit_curator_role(origin) {
  515. }
  516. fn on_finalize(now: T::BlockNumber) {
  517. }
  518. }
  519. }
  520. impl<T: Trait> Module<T> {
  521. /*
  522. /// ...
  523. pub fn set_lead();
  524. /// ...
  525. pub fn unset_lead();
  526. /// ...
  527. pub fn set_opening_policy();
  528. /// ...
  529. pub fn update_lead_reward();
  530. /// ...
  531. pub fn account_is_in_group();
  532. pub fn update_lead_credential();
  533. */
  534. }
  535. /*
  536. * ======== ======== ======== ======== =======
  537. * ======== PRIVATE TYPES AND METHODS ========
  538. * ======== ======== ======== ======== =======
  539. */
  540. /// ...
  541. enum Credential<CuratorId: Ord, ChannelId, BlockNumber> {
  542. Lead(LeadCredential),
  543. AnyCurator(AnyCuratorCredential),
  544. AnyMember(AnyMemberCredential),
  545. Dynamic(DynamicCredential<CuratorId, ChannelId, BlockNumber>)
  546. }
  547. /// Holder of a credential.
  548. enum CredentialHolder<DynamicCredentialId> {
  549. /// Built in credential holder.
  550. BuiltInCredentialHolder(BuiltInCredentialHolder),
  551. /// A possible dynamic credendtial holder.
  552. CandidateDynamicCredentialId(DynamicCredentialId)
  553. }
  554. impl<T: Trait> Module<T> {
  555. /// Maps a permission module credential identifier to a credential holder.
  556. ///
  557. /// **CRITICAL**:
  558. ///
  559. /// Credential identifiers are stored in the permissions module, this means that
  560. /// the mapping in this function _must_ not disturb how it maps any id that is actually in use
  561. /// across runtime upgrades, _unless_ one is also prepared to make the corresponding migrations
  562. /// in the permissions module. Best to keep mapping stable.
  563. ///
  564. /// In practice the only way one may want augment this map is to support new
  565. /// built in credentials. In this case, the mapping has to be written and deployed while
  566. /// no new dynamic credentials are created, and a new case of the form below must be introcued
  567. /// in the match: CandidateDynamicCredentialId(credential_id - X), where X = #ChannelIds mapped so far.
  568. fn credential_id_to_holder(credential_id: T::PrincipalId) -> CredentialHolder<DynamicCredentialId<T>> {
  569. // Credential identifiers for built in credential holder types.
  570. let LEAD_CREDENTIAL_ID = T::PrincipalId::from(0);
  571. let ANY_CURATOR_CREDENTIAL_ID = T::PrincipalId::from(1);
  572. let ANY_MEMBER_CREDENTIAL_ID = T::PrincipalId::from(2);
  573. match credential_id {
  574. LEAD_CREDENTIAL_ID => CredentialHolder::BuiltInCredentialHolder(BuiltInCredentialHolder::Lead),
  575. ANY_CURATOR_CREDENTIAL_ID => CredentialHolder::BuiltInCredentialHolder(BuiltInCredentialHolder::AnyCurator),
  576. ANY_MEMBER_CREDENTIAL_ID => CredentialHolder::BuiltInCredentialHolder(BuiltInCredentialHolder::AnyMember),
  577. _ => CredentialHolder::CandidateDynamicCredentialId(credential_id - T::PrincipalId::from(3)) // will map first dynamic id to 0
  578. /*
  579. Add new built in credentials here below
  580. */
  581. }
  582. }
  583. /// .
  584. fn credential_from_id(credential_id: T::PrincipalId) -> Option<DynamicCredential<T::CuratorId, T::ChannelId, T::BlockNumber>> {
  585. //let = credential_id_to_built_in_credential_holder(credential_id);
  586. // 2.
  587. None
  588. }
  589. }