ContentDirectoryWorkingGroup
The working groups solves the problems of how to administrate the write access permissions to the content directory state.
The working group has two types of participants. A lead, which is inducted by root. The lead is involved in two activities. First, hiring and managing the second participant type, namely curators. Second, creating and managing the actor groups, called permission groups, for the content directory. These groups are defined by some criteria for what accounts belong to them at any given time, and in particular they may defined to include the account(s) of one of the following
These permission groups are presumed to be used with the permission module and the version store module. Both leads and curators are possibly staked and rewarded. The staking is managed by the staking module, and the rewards are managed by the recurring rewards module. All rewards in the group flow from a single group mint.
I used in concert with a range of other modules described in the next section.
RecurringReward
moduleHiring
moduleMembership
moduleVersionedStorePermissions
module
trait Trait : RecurringReward::Trait + Hiring::Trait + Membership::Trait VersionedStorePermissions::Trait {
// Type of identifier for permissions groups.
type PermissionGroupId : INTEGER_TRAIT_CONSTRAINTS;
}
// Type of identifier for lead.
type LeadId = Trait::RoleActorId;
// Type of identifier for curators.
type CuratorId = Trait::RoleActorId;
// Type of identifier for publishers.
type PublisherId = Trait::MemberId;
enum LeadRoleState {
Active,
Exited {
initiated_at_block_number: T::BlockNumber,
}
}
// Working group lead: curator lead
// For now this role is not staked or inducted through an structured process, like the hiring module,
// hence information about this is missing. Recurring rewards is included, somewhat arbitrarily!
struct Lead<T: Trait> {
// Account used to authenticate in this role,
role_account: T::AccountId,
// Whether the role has recurring reward, and if so an identifier for this.
reward_relationship: Option<T::RewardRelationshipId>,
// When was inducted
// TODO: Add richer information about circumstances of induction
inducted: T::BlockNumber,
//
stage: LeadRoleState
}
enum CuratorExitInitiationOrigin {
Lead,
Curator
}
enum CuratorRoleStage<T: Trait> {
Active,
Exited {
origin: CuratorExitInitiationOrigin,
initiated_at_block_number: T::BlockNumber,
rationale_text: Vec<u8>
}
}
struct CuratorInduction<T: Trait> {
// Lead responsible
lead: LeadId,
// Application through which curator was inducted
application: T::ApplicationId,
// When induction occurred
at_block: T::BlockNumber
}
// Working group participant: curator
// This role can be staked, have reward and be inducted through the hiring module.
struct Curator<T: Trait> {
// Account used to authenticate in this role,
role_account: T::AccountId,
// Whether the role has recurring reward, and if so an identifier for this.
reward_relationship: Option<T::RewardRelationshipId>,
// Whether participant is staked, and if so, the identifier for this staking in the staking module.
stake: Option<T::StakeId>,
//
stage: CuratorRoleStage<T>,
//
induction: CuratorInduction<T>
}
// The type of permission groups supported
enum PermissionGroupType<T: Trait> {
CurrentLead,
Curator(T::CuratorId),
Member(T::MemberId),
Publisher(T::PublisherId),
AnyCurator,
AnyMember,
AnyPublisher
}
// Represents a group as understood by the VersionedStorePermissions module
struct PermissionGroup<T: Trait> {
// ..
type: PermissionGroupType<T>,
// ..
is_active: bool,
// ..
created: T::BlockNumber,
// ..
description: Vec<u8>
}
// Policy governing any curator opening which can be made by lead.
struct OpeningPolicy<T: Trait> {
/**
* // Whether there should be a number of active curators which would block the
* // creation of new openings, and if so what value.
* active_curator_count_blocking_new_openings: Option<u16>,
*/
// Maximum length of review period of applications
max_review_period_length: BlockNumber,
// Staking policy for application
application_staking_policy: Option<T::StakingPolicy>,
// Staking policy for role itself
role_staking_policy: Option<T::StakingPolicy>
}
mint: T::TokenMintId
: The mint currently funding the rewards for this module.current_lead: Option<T::LeadId>
: The current lead.leadById: linked_map T::LeadId => Lead<T>
: Maps identifier to corresponding lead.nextLeadId: T::LeadId
: Next identifier for new current lead.openings_policy: Option<OpeningPolicy<T>>
: The constraints lead must respect when creating a new curator opening. Lack of policy is interpreted as blocking any new openings at all.openings: linked_map T::OpeningId => ()
: set of identifiers for all openings originated from this group.curatorById: linked_map T::CuratorId => Curator<T>
: Maps identifier to corresponding curator.nextCuratorId: T::CuratorId
: Next identifier for new curator.permissionGroupById: linked_map T::PermissionGroupId => PermissionGroup<T>
: Maps identifier to corresponding permission group.nextPermissionGroupId: T::PermissionGroupId
: Next identifier for new permission group.maxPermissionGroupDescriptionLength: u16
: Upper bound for character length of description
field of any new or updated PermissionGroup
maxCuratorExitRationaleTextLength: u16
: Upper bound for character length of the rationale_text
field of any new CuratorRoleStage
.LeadSet
LeadUnset
OpeningPolicySet
LeadRewardUpdated
LeadRoleAccountUpdated
LeadRewardAccountUpdated
PermissionGroupAdded
PermissionGroupUpdated
CuratorOpeningAdded
AcceptedCuratorApplications
BeganCuratorApplicationReview
CuratorOpeningFilled
CuratorSlashed
TerminatedCurator
AppliedOnCuratorOpening
CuratorRewardUpdated
CuratorRoleAccountUpdated
CuratorRewardAccountUpdated
CuratorExited
Module implements VersionedStorePermissions::GroupMembershipChecker
, and sets GroupMembershipChecker::GroupdId
to T::PermissionGroupId
.
update_lead_role_account
Can only be called by Signed origin, and caller must pass test on membership module of key_can_sign_for_role
for the current_lead
.
Updates role_account
of current_lead
to given new value.
Emits LeadRoleAccountUpdated
.
update_lead_reward_account
Can only be called by Signed origin, and caller must match role_account
of set current_lead
. Also, reward_relationship
must be set on current_lead
.
Updates account
on reward_relationship
to given new value.
Emits LeadRewardAccountUpdated
.
add_permission_group
Can only be called by Signed origin, and caller must match role_account
of set current_lead
.
Creates and adds new permission group.
Emits PermissionGroupAdded
.
update_permission_group
Can only be called by Signed origin, and caller must match role_account
of set current_lead
.
Updates a given permission group, based on its identifier. Field created
is not mutable.
Emits PermissionGroupUpdated
.
add_curator_opening
Can only be called by Signed origin, and caller must match role_account
of set current_lead
.
Also requires that openings_policy
is set, and if so, a new application is added to the Hiring
module using relevant parameter values from this policy. The new opening identifier is added to openings
.
Emits CuratorOpeningAdded
.
accept_curator_applications
Can only be called by Signed origin, and caller must match role_account
of set current_lead
.
Given opening identifier must be in openings
. If so, begin_accepting_applications
is called on the corresponding opening the Opening
module.
Emits AcceptedCuratorApplications
begin_curator_applicant_review
Can only be called by Signed origin, and caller must match role_account
of set current_lead
. Given opening identifier must be in openings
. If so, begin_review
is called on the corresponding opening the Opening
module.
Emits BeganCuratorApplicationReview
fill_curator_opening
Can only be called by Signed origin, and caller must match role_account
of set current_lead
. Given opening identifier must be in openings
. Checks with the Membership
module that all hires still can step into the role as curator at this time. If so, fill_opening
is called on the corresponding opening the Opening
module.
All hired curators are turned into new Curator
instances, with identifiers based on nextCuratorId
, and added to curatorsById
.
Emits CuratorOpeningFilled
and CuratorAdded
for each curator hired.
update_curator_reward
Can only be called by Signed origin, and caller must match role_account
of set current_lead
. Updates reward_relationship
on given curator.
Emits CuratorRewardUpdated
.
slash_curator
Can only be called by Signed origin, and caller must match role_account
of set current_lead
.
Also requires that stake
is set on given curator, if so, initiate_slashing
is called on the Stake
module on the stake for this curator.
Emits CuratorSlashed
.
terminate_curator
Can only be called by Signed origin, and caller must match role_account
of set current_lead
.
Also requires that given curator is found in curatorsById
in the Active
stage. If so, the stage is updated Exited
, with suitable other parameters, and any reward_relationship
set is disabled. Lastly, unstaking is initiated if present.
Emits TerminatedCurator
.
apply_on_curator_opening
Can only be called by Signed origin, and caller must pass test on Membership
module of whether they can occupy a curator role at this time. Next, provided parameters must match staking and other requirements of opening. If so, add_application
is on Hiring
module. Return value is returned.
Emits AppliedOnCuratorOpening
.
update_curator_role_account
Can only be called by Signed origin, and account must match role_account
of provided curator identifier. Also requires that given curator is found in curatorsById
in the Active
stage.
Updates role_account
on given curator.
Emits CuratorRoleAccountUpdated
.
update_curator_reward_account
Can only be called by Signed origin, and account must match role_account
of provided curator identifier. Also requires that given curator is found in curatorsById
in the Active
stage. Also, given curator must also have reward_relationship
set.
Updates account
on given curator reward_relationship
.
Emits CuratorRewardAccountUpdated
.
exit_curator_role
Can only be called by Signed origin, and account must match role_account
of provided curator identifier. Also requires that given curator is found in curatorsById
in the Active
stage. If so, the stage is updated Exited
, with suitable other parameters, and any reward_relationship
set is disabled. Lastly, unstaking is initiated if present.
Emits CuratorExited
.
set_lead
Can only be called by Root origin, and requires that current_lead
is not set. Membership module is consulted as to whether the given signing account can be setup as the curator lead with id nextLeadId
, if no, then method terminates. Otherwise continues as follows.
A new recipient and reward relationship is added to the reward module, and a new current_lead
instance is created with corresponding values and id nextLeadId
, added to leadById
undert this id, and current_lead
i also set to this key. Lastly, nextLeadId
is incremented.
Emits event LeadSet
. Returns nothing.
unset_lead
Can only be called by Root origin, and requires that current_lead
is set. Membership module is informed to unregister the lead as playing the role of a curator lead. If reward_relationship
is set on lead, then disable it to any further rewards. Lastly set exited
to the current block number.
Emits event LeadUnset
. Returns nothing.
set_opening_policy
Can only be called by Root origin. Updates opening_policy
.
Emits event OpeningPolicySet
. Returns nothing.
update_lead_reward
Can only be called by Root origin, and requires that current_lead
is set. The lead must also have reward_relationship
set. If so, then amount_per_payout
, next_payment_in_block
and payout_interval
of the reward relationship can be updated.
Emits event LeadRewardUpdated
. Returns nothing.
account_is_in_group
Takes group id and looks up permissionGroupById
, lack of match results in false
being returned. A match is then used to evaluate the given account as follows
CurrentLead
: Account matches role_account
of current_lead
which is set.Curator(id)
: ..Member(id)
: ..Publisher(id)
: .AnyCurator
: ..AnyMember
: ..AnyPublisher
: ..