-
Notifications
You must be signed in to change notification settings - Fork 2.7k
WIP Make ChangeMembers trait fallible #5985
Changes from 3 commits
4aac2f0
3a9fabb
880d4bb
787c0ef
542088e
a5fc3ac
b547837
eae912d
eed63fe
bfe5153
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -390,7 +390,7 @@ impl<T: Trait<I>, I: Instance> Module<T, I> { | |
| /// Fetches the `MemberCount` highest scoring members from | ||
| /// `Pool` and puts them into `Members`. | ||
| /// | ||
| /// The `notify` parameter is used to deduct which associated | ||
| /// The `notify` parameter is used to decide which associated | ||
| /// type function to invoke at the end of the method. | ||
| fn refresh_members( | ||
| pool: PoolT<T, I>, | ||
|
|
@@ -407,16 +407,20 @@ impl<T: Trait<I>, I: Instance> Module<T, I> { | |
| new_members.sort(); | ||
|
|
||
| let old_members = <Members<T, I>>::get(); | ||
| // TODO: What to do in case of error? | ||
|
||
| let _ = T::MembershipChanged::ensure_can_change_members(&new_members, &old_members); | ||
| <Members<T, I>>::put(&new_members); | ||
|
|
||
| match notify { | ||
| ChangeReceiver::MembershipInitialized => | ||
| T::MembershipInitialized::initialize_members(&new_members), | ||
| ChangeReceiver::MembershipChanged => | ||
| T::MembershipChanged::set_members_sorted( | ||
| ChangeReceiver::MembershipChanged => { | ||
| // TODO: Is this safe? | ||
|
||
| let _ = T::MembershipChanged::set_members_sorted( | ||
apopiak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| &new_members[..], | ||
| &old_members[..], | ||
| ), | ||
| ); | ||
| }, | ||
| } | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -934,36 +934,68 @@ impl WithdrawReasons { | |
| } | ||
| } | ||
|
|
||
| /// Trait for type that can handle incremental changes to a set of account IDs. | ||
| pub trait ChangeMembers<AccountId: Clone + Ord> { | ||
| /// Trait for types that can handle incremental changes to a set of account IDs. | ||
| /// | ||
| /// Allows member changes according to the "verify first, write last" maxime by | ||
| /// providing the `ensure_can_change_members` function for checking as well as the | ||
| /// actual writing logic. | ||
| pub trait ChangeMembers<AccountId: Clone + Ord, MembersCount = usize> { | ||
|
|
||
| /// Returns whether changing the members will execute without errors. | ||
| /// | ||
| /// Defaults to a noop. Implement this if `change_members_sorted` could fail. | ||
apopiak marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// | ||
| /// If this returns `Err`, calls to `change_members`, `change_members_sorted` and | ||
| /// `set_members_sorted` are not guaranteed to have the desired effect. | ||
| fn ensure_can_change_members(_new: &[AccountId], _old: &[AccountId]) -> DispatchResult { | ||
shawntabrizi marked this conversation as resolved.
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't have much to say agains the core of the change itself, but enforcing this trait, which by itself has nothing to do with dispatches, to return a I guess we might use the same approach for other traits in
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is a good point, thanks. |
||
| Ok(()) | ||
| } | ||
|
|
||
| /// A number of members `incoming` just joined the set and replaced some `outgoing` ones. The | ||
| /// new set is given by `new`, and need not be sorted. | ||
| /// | ||
| /// This resets any previous value of prime. | ||
| fn change_members(incoming: &[AccountId], outgoing: &[AccountId], mut new: Vec<AccountId>) { | ||
| /// | ||
| /// Returns the actual number of members set. This may differ from `new.len()` | ||
| /// if there are errors. Use `ensure_can_change_members` to check for those beforehand. | ||
| fn change_members( | ||
| incoming: &[AccountId], | ||
| outgoing: &[AccountId], | ||
| mut new: Vec<AccountId> | ||
| ) -> MembersCount { | ||
| new.sort_unstable(); | ||
| Self::change_members_sorted(incoming, outgoing, &new[..]); | ||
| Self::change_members_sorted(incoming, outgoing, &new[..]) | ||
| } | ||
|
|
||
| /// A number of members `_incoming` just joined the set and replaced some `_outgoing` ones. The | ||
| /// new set is thus given by `sorted_new` and **must be sorted**. | ||
| /// | ||
| /// NOTE: This is the only function that needs to be implemented in `ChangeMembers`. | ||
| /// NOTE: This is the only function that needs to be implemented in `ChangeMembers`, but make | ||
| /// sure that `ensure_can_change_members` is implemented correctly. | ||
| /// | ||
| /// This resets any previous value of prime. | ||
| /// | ||
| /// Returns the actual number of members set. This may differ from `sorted_new.len()` | ||
| /// if there are errors. Use `ensure_can_change_members` to check for those beforehand. | ||
| fn change_members_sorted( | ||
| incoming: &[AccountId], | ||
| outgoing: &[AccountId], | ||
| sorted_new: &[AccountId], | ||
| ); | ||
| ) -> MembersCount; | ||
|
|
||
| /// Set the new members; they **must already be sorted**. This will compute the diff and use it to | ||
| /// call `change_members_sorted`. | ||
| /// | ||
| /// This resets any previous value of prime. | ||
| fn set_members_sorted(new_members: &[AccountId], old_members: &[AccountId]) { | ||
| /// | ||
| /// Returns the actual number of members set. This may differ from `new_members.len()` | ||
| /// if there are errors. Use `ensure_can_change_members` to check for those beforehand. | ||
| fn set_members_sorted( | ||
| new_members: &[AccountId], | ||
| old_members: &[AccountId] | ||
| ) -> MembersCount { | ||
| let (incoming, outgoing) = Self::compute_members_diff(new_members, old_members); | ||
| Self::change_members_sorted(&incoming[..], &outgoing[..], &new_members); | ||
| Self::change_members_sorted(&incoming[..], &outgoing[..], &new_members) | ||
| } | ||
|
|
||
| /// Set the new members; they **must already be sorted**. This will compute the diff and use it to | ||
|
|
@@ -1003,13 +1035,15 @@ pub trait ChangeMembers<AccountId: Clone + Ord> { | |
| } | ||
|
|
||
| /// Set the prime member. | ||
| /// | ||
| /// Defaults to a noop. | ||
| fn set_prime(_prime: Option<AccountId>) {} | ||
| } | ||
|
|
||
| impl<T: Clone + Ord> ChangeMembers<T> for () { | ||
| fn change_members(_: &[T], _: &[T], _: Vec<T>) {} | ||
| fn change_members_sorted(_: &[T], _: &[T], _: &[T]) {} | ||
| fn set_members_sorted(_: &[T], _: &[T]) {} | ||
| fn change_members(_: &[T], _: &[T], new: Vec<T>) -> usize { new.len() } | ||
| fn change_members_sorted(_: &[T], _: &[T], new: &[T]) -> usize { new.len() } | ||
| fn set_members_sorted(new: &[T], _: &[T]) -> usize { new.len() } | ||
| fn set_prime(_: Option<T>) {} | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.