Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FRAME] Make core-fellowship and salary work for swapped members #3156

Merged
merged 16 commits into from
Jan 31, 2024

Conversation

ggwpez
Copy link
Member

@ggwpez ggwpez commented Jan 31, 2024

Fixup for #2587 to make the core-fellowship crate work with swapped members.

Adds a MemberSwappedHandler to the ranked-collective pallet that are implemented by core-fellowship+salary.
There is are exhaustive tests here and here to check that adding member 1 is equivalent to adding member 0 and then swapping.

Integration

The only change of config is in the ranked-collective pallet. Simply add all pallets that depend on it as RankedMembers provider:

impl pallet_ranked_collective::Config for Runtime {
+	type MemberSwappedHandler = (CoreFellowship, Salary);
+	#[cfg(feature = "runtime-benchmarks")]
+	type BenchmarkSetup = (CoreFellowship, Salary);

@ggwpez ggwpez requested a review from a team as a code owner January 31, 2024 10:44
@ggwpez ggwpez added the T2-pallets This PR/Issue is related to a particular pallet. label Jan 31, 2024
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
substrate/frame/core-fellowship/src/lib.rs Outdated Show resolved Hide resolved
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
MemberEvidence::<T, I>::insert(new, we);
}

Self::deposit_event(Event::<T, I>::Swapped { who: old.clone(), new_who: new.clone() });
Copy link
Contributor

Choose a reason for hiding this comment

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

I am itching for a try-state check that ensures members that are kept in Config::Members are the same as the set that is kept here. Something like:

diff --git a/substrate/frame/core-fellowship/src/lib.rs b/substrate/frame/core-fellowship/src/lib.rs
index a0a45c7c59..1db600deb0 100644
--- a/substrate/frame/core-fellowship/src/lib.rs
+++ b/substrate/frame/core-fellowship/src/lib.rs
@@ -547,6 +547,17 @@ pub mod pallet {
 				Self::deposit_event(e);
 			}
 		}
+
+		/// Invariants:
+		///
+		/// - All members tracked in this pallet under [`Members`] and [`MemberEvidence`] must have
+		///   be part of [`Config::Members`].
+		#[cfg(feature = "try-runtime")]
+		fn do_try_state() {
+			let external_members = T::Members::all().collect::<Vec<_>>();
+			let internal_members = todo!();
+			// convert to set, then compare.
+		}
 	}
 
 	impl<T: Config<I>, I: 'static> GetSalary<RankOf<T, I>, T::AccountId, T::Balance> for Pallet<T, I> {
diff --git a/substrate/frame/ranked-collective/src/lib.rs b/substrate/frame/ranked-collective/src/lib.rs
index 88631884c5..92dc44e16f 100644
--- a/substrate/frame/ranked-collective/src/lib.rs
+++ b/substrate/frame/ranked-collective/src/lib.rs
@@ -838,5 +838,10 @@ pub mod pallet {
 		fn demote(who: &Self::AccountId) -> DispatchResult {
 			Self::do_demote_member(who.clone(), None)
 		}
+
+		#[cfg(feature = "try-runtime")]
+		fn all() -> Vec<T::AccountId> {
+			Members::<T, I>::iter().map(|(who, _)| who).collect()
+		}
 	}
 }
diff --git a/substrate/frame/support/src/traits/members.rs b/substrate/frame/support/src/traits/members.rs
index d667eaa7e9..edd627257c 100644
--- a/substrate/frame/support/src/traits/members.rs
+++ b/substrate/frame/support/src/traits/members.rs
@@ -295,6 +295,9 @@ pub trait RankedMembers {
 	/// Demote a member to the next lower rank; demoting beyond the `min_rank` removes the
 	/// member entirely.
 	fn demote(who: &Self::AccountId) -> DispatchResult;
+
+	#[cfg(feature = "try-runtime")]
+	fn all() -> Vec<T::AccountId>;
 }
 
 /// Trait for type that can handle the initialization of account IDs at genesis.

Copy link
Member Author

Choose a reason for hiding this comment

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

Will do as follow up

Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
@ggwpez ggwpez changed the title [FRAME] Make core-fellowship work for swapped members [FRAME] Make core-fellowship ans salary work for swapped members Jan 31, 2024
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Signed-off-by: Oliver Tale-Yazdi <[email protected]>
#[impl_trait_for_tuples::impl_for_tuples(8)]
pub trait BenchmarkSetup<AccountId> {
/// Ensure that this member is registered correctly.
fn ensure_member(acc: &AccountId);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I'd rename this to something like register_as_member or similar because you're not really running checks and returning the validity, you're doing setup 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.

Yea true. But will do it as follow up to not retrigger the CI now to not prevent the merge.

@ggwpez ggwpez added this pull request to the merge queue Jan 31, 2024
Copy link
Contributor

@kianenigma kianenigma left a comment

Choose a reason for hiding this comment

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

I think the salary pallet's modification is yet another reason to consider multi-pallet try-state checks to make sure these pallets with interdependency remain in sync.

Although, try-state would only go as far as catching the issues in production, I am not sure what we can do at the code level.

Merged via the queue into master with commit 07e5500 Jan 31, 2024
128 checks passed
@ggwpez ggwpez deleted the oty-swap-core-fellow branch January 31, 2024 17:11
@ggwpez
Copy link
Member Author

ggwpez commented Jan 31, 2024

Although, try-state would only go as far as catching the issues in production, I am not sure what we can do at the code level.

Fuzzing maybe? And calling the try-state at the end of the tests.

bkontur added a commit to bkontur/runtimes that referenced this pull request Feb 19, 2024
@ggwpez ggwpez changed the title [FRAME] Make core-fellowship ans salary work for swapped members [FRAME] Make core-fellowship and salary work for swapped members Feb 29, 2024
bgallois pushed a commit to duniter/duniter-polkadot-sdk that referenced this pull request Mar 25, 2024
…aritytech#3156)

Fixup for paritytech#2587 to make
the `core-fellowship` crate work with swapped members.

Adds a `MemberSwappedHandler` to the `ranked-collective` pallet that are
implemented by `core-fellowship+salary`.
There is are exhaustive tests
[here](https://github.com/paritytech/polkadot-sdk/blob/72aa7ac17a0e5b16faab5d2992aa2db2e01b05d0/substrate/frame/core-fellowship/src/tests/integration.rs#L338)
and
[here](https://github.com/paritytech/polkadot-sdk/blob/ab3cdb05a5ebc1ff841f8dda67edef0ea40bbba5/substrate/frame/salary/src/tests/integration.rs#L224)
to check that adding member `1` is equivalent to adding member `0` and
then swapping.

---------

Signed-off-by: Oliver Tale-Yazdi <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T2-pallets This PR/Issue is related to a particular pallet.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants