Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ authors = ['Joystream']
build = 'build.rs'
edition = '2018'
name = 'joystream-node'
version = '2.1.4'
version = '2.1.5'
default-run = "joystream-node"

[[bin]]
Expand Down
187 changes: 94 additions & 93 deletions runtime-modules/content-working-group/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1910,103 +1910,23 @@ decl_module! {
);
}

/*
* Root origin routines for managing lead.
*/


/// Introduce a lead when one is not currently set.
pub fn set_lead(origin, member: T::MemberId, role_account: T::AccountId) {

/// Replace the current lead. First unsets the active lead if there is one.
/// If a value is provided for new_lead it will then set that new lead.
/// It is responsibility of the caller to ensure the new lead can be set
/// to avoid the lead role being vacant at the end of the call.
pub fn replace_lead(origin, new_lead: Option<(T::MemberId, T::AccountId)>) {
// Ensure root is origin
ensure_root(origin)?;

// Ensure there is no current lead
ensure!(
<CurrentLeadId<T>>::get().is_none(),
MSG_CURRENT_LEAD_ALREADY_SET
);

// Ensure that member can actually become lead
let new_lead_id = <NextLeadId<T>>::get();

let new_lead_role =
role_types::ActorInRole::new(role_types::Role::CuratorLead, new_lead_id);

let _profile = <members::Module<T>>::can_register_role_on_member(
&member,
&role_types::ActorInRole::new(role_types::Role::CuratorLead, new_lead_id),
)?;

//
// == MUTATION SAFE ==
//

// Construct lead
let new_lead = Lead {
role_account: role_account.clone(),
reward_relationship: None,
inducted: <system::Module<T>>::block_number(),
stage: LeadRoleState::Active,
};

// Store lead
<LeadById<T>>::insert(new_lead_id, new_lead);

// Update current lead
<CurrentLeadId<T>>::put(new_lead_id); // Some(new_lead_id)

// Update next lead counter
<NextLeadId<T>>::mutate(|id| *id += <LeadId<T> as One>::one());

// Register in role
let registered_role =
<members::Module<T>>::register_role_on_member(member, &new_lead_role).is_ok();

assert!(registered_role);

// Trigger event
Self::deposit_event(RawEvent::LeadSet(new_lead_id));
}

/// Evict the currently unset lead
pub fn unset_lead(origin) {

// Ensure root is origin
ensure_root(origin)?;

// Ensure there is a lead set
let (lead_id,lead) = Self::ensure_lead_is_set()?;

//
// == MUTATION SAFE ==
//

// Unregister from role in membership model
let current_lead_role = role_types::ActorInRole{
role: role_types::Role::CuratorLead,
actor_id: lead_id
};

let unregistered_role = <members::Module<T>>::unregister_role(current_lead_role).is_ok();

assert!(unregistered_role);

// Update lead stage as exited
let current_block = <system::Module<T>>::block_number();

let new_lead = Lead{
stage: LeadRoleState::Exited(ExitedLeadRole { initiated_at_block_number: current_block}),
..lead
};

<LeadById<T>>::insert(lead_id, new_lead);

// Update current lead
<CurrentLeadId<T>>::take(); // None
// Unset current lead first
if Self::ensure_lead_is_set().is_ok() {
Self::unset_lead()?;
}

// Trigger event
Self::deposit_event(RawEvent::LeadUnset(lead_id));
// Try to set new lead
if let Some((member_id, role_account)) = new_lead {
Self::set_lead(member_id, role_account)?;
}
}

/// Add an opening for a curator role.
Expand Down Expand Up @@ -2122,6 +2042,87 @@ impl<T: Trait> versioned_store_permissions::CredentialChecker<T> for Module<T> {
}

impl<T: Trait> Module<T> {
/// Introduce a lead when one is not currently set.
fn set_lead(member: T::MemberId, role_account: T::AccountId) -> dispatch::Result {
// Ensure there is no current lead
ensure!(
<CurrentLeadId<T>>::get().is_none(),
MSG_CURRENT_LEAD_ALREADY_SET
);

let new_lead_id = <NextLeadId<T>>::get();

let new_lead_role =
role_types::ActorInRole::new(role_types::Role::CuratorLead, new_lead_id);

//
// == MUTATION SAFE ==
//

// Register in role - will fail if member cannot become lead
members::Module::<T>::register_role_on_member(member, &new_lead_role)?;

// Construct lead
let new_lead = Lead {
role_account: role_account.clone(),
reward_relationship: None,
inducted: <system::Module<T>>::block_number(),
stage: LeadRoleState::Active,
};

// Store lead
<LeadById<T>>::insert(new_lead_id, new_lead);

// Update current lead
<CurrentLeadId<T>>::put(new_lead_id); // Some(new_lead_id)

// Update next lead counter
<NextLeadId<T>>::mutate(|id| *id += <LeadId<T> as One>::one());

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably, assert() can be replaced with "?" function invocation. Code reordering is required.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thats a good point, I think this is the new convention we decided on. However here I avoided changing the implementation of set_lead and unset_lead I just relocated them and converted them from being dispatchables to be private methods on the Module.

I can update it not much extra work.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in e4f57a2

// Trigger event
Self::deposit_event(RawEvent::LeadSet(new_lead_id));

Ok(())
}

/// Evict the currently set lead
fn unset_lead() -> dispatch::Result {
// Ensure there is a lead set
let (lead_id, lead) = Self::ensure_lead_is_set()?;

//
// == MUTATION SAFE ==
//

// Unregister from role in membership model
let current_lead_role = role_types::ActorInRole {
role: role_types::Role::CuratorLead,
actor_id: lead_id,
};

<members::Module<T>>::unregister_role(current_lead_role)?;

// Update lead stage as exited
let current_block = <system::Module<T>>::block_number();

let new_lead = Lead {
stage: LeadRoleState::Exited(ExitedLeadRole {
initiated_at_block_number: current_block,
}),
..lead
};

<LeadById<T>>::insert(lead_id, new_lead);

// Update current lead
<CurrentLeadId<T>>::take(); // None

// Trigger event
Self::deposit_event(RawEvent::LeadUnset(lead_id));

Ok(())
}

fn ensure_member_has_no_active_application_on_opening(
curator_applications: CuratorApplicationIdSet<T>,
member_id: T::MemberId,
Expand Down
12 changes: 7 additions & 5 deletions runtime-modules/content-working-group/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,7 +1160,10 @@ struct SetLeadFixture {

impl SetLeadFixture {
fn call(&self) -> Result<(), &'static str> {
ContentWorkingGroup::set_lead(self.origin.clone(), self.member_id, self.new_role_account)
ContentWorkingGroup::replace_lead(
self.origin.clone(),
Some((self.member_id, self.new_role_account)),
)
}

pub fn call_and_assert_success(&self) {
Expand Down Expand Up @@ -1221,7 +1224,7 @@ struct UnsetLeadFixture {

impl UnsetLeadFixture {
fn call(&self) -> Result<(), &'static str> {
ContentWorkingGroup::unset_lead(self.origin.clone())
ContentWorkingGroup::replace_lead(self.origin.clone(), None)
}

pub fn call_and_assert_success(&self) {
Expand Down Expand Up @@ -2121,10 +2124,9 @@ pub fn set_lead(

// Set lead
assert_eq!(
ContentWorkingGroup::set_lead(
ContentWorkingGroup::replace_lead(
mock::Origin::system(system::RawOrigin::Root),
member_id,
new_role_account
Some((member_id, new_role_account))
)
.unwrap(),
()
Expand Down
2 changes: 1 addition & 1 deletion runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ edition = '2018'
name = 'joystream-node-runtime'
# Follow convention: https://github.com/Joystream/substrate-runtime-joystream/issues/1
# {Authoring}.{Spec}.{Impl} of the RuntimeVersion
version = '6.10.0'
version = '6.11.0'

[features]
default = ['std']
Expand Down
2 changes: 1 addition & 1 deletion runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("joystream-node"),
impl_name: create_runtime_str!("joystream-node"),
authoring_version: 6,
spec_version: 10,
spec_version: 11,
impl_version: 0,
apis: RUNTIME_API_VERSIONS,
};
Expand Down