From b21c49524ff17f2951b608fcf87a3410a689b184 Mon Sep 17 00:00:00 2001
From: Shaun Wang <spxwang@gmail.com>
Date: Thu, 17 Jun 2021 02:17:57 +1200
Subject: [PATCH] Migrate pallet-elections to pallet attribute macro (#9088)

* Migrate elections pallet to pallet attribute macro.

* Metadata fix.

* Update frame/elections/src/lib.rs

Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
---
 substrate/frame/elections/src/lib.rs  | 545 +++++++++++++++-----------
 substrate/frame/elections/src/mock.rs |   4 +-
 2 files changed, 313 insertions(+), 236 deletions(-)

diff --git a/substrate/frame/elections/src/lib.rs b/substrate/frame/elections/src/lib.rs
index 46ec62bf751..b5367139356 100644
--- a/substrate/frame/elections/src/lib.rs
+++ b/substrate/frame/elections/src/lib.rs
@@ -22,7 +22,7 @@
 //!
 //! ---
 //!
-//! Election module for stake-weighted membership selection of a collective.
+//! Election pallet for stake-weighted membership selection of a collective.
 //!
 //! The composition of a set of account IDs works according to one or more approval votes
 //! weighted by stake. There is a partial carry-over facility to give greater weight to those
@@ -33,19 +33,20 @@
 
 use sp_std::prelude::*;
 use sp_runtime::{
-	RuntimeDebug, DispatchResult, print,
+	RuntimeDebug, print,
 	traits::{Zero, One, StaticLookup, Saturating},
 };
 use frame_support::{
-	decl_storage, decl_event, ensure, decl_module, decl_error,
+	pallet_prelude::*, ensure,
 	weights::{Weight, DispatchClass},
 	traits::{
-		Currency, ExistenceRequirement, Get, LockableCurrency, LockIdentifier, BalanceStatus,
+		Currency, ExistenceRequirement, LockableCurrency, LockIdentifier, BalanceStatus,
 		OnUnbalanced, ReservableCurrency, WithdrawReasons, ChangeMembers,
 	}
 };
 use codec::{Encode, Decode};
-use frame_system::{ensure_signed, ensure_root};
+use frame_system::pallet_prelude::*;
+pub use pallet::*;
 
 mod mock;
 mod tests;
@@ -152,141 +153,250 @@ type ApprovalFlag = u32;
 /// Number of approval flags that can fit into [`ApprovalFlag`] type.
 const APPROVAL_FLAG_LEN: usize = 32;
 
-pub trait Config: frame_system::Config {
-	type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;
+#[frame_support::pallet]
+pub mod pallet {
+	use super::*;
 
-	/// Identifier for the elections pallet's lock
-	type PalletId: Get<LockIdentifier>;
+	#[pallet::pallet]
+	#[pallet::generate_store(pub(super) trait Store)]
+	pub struct Pallet<T>(_);
 
-	/// The currency that people are electing with.
-	type Currency:
-		LockableCurrency<Self::AccountId, Moment=Self::BlockNumber>
-		+ ReservableCurrency<Self::AccountId>;
+	#[pallet::config]
+	pub trait Config: frame_system::Config {
+		type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
 
-	/// Handler for the unbalanced reduction when slashing a validator.
-	type BadPresentation: OnUnbalanced<NegativeImbalanceOf<Self>>;
+		/// Identifier for the elections pallet's lock
+		#[pallet::constant]
+		type PalletId: Get<LockIdentifier>;
 
-	/// Handler for the unbalanced reduction when slashing an invalid reaping attempt.
-	type BadReaper: OnUnbalanced<NegativeImbalanceOf<Self>>;
+		/// The currency that people are electing with.
+		type Currency:
+			LockableCurrency<Self::AccountId, Moment=Self::BlockNumber>
+			+ ReservableCurrency<Self::AccountId>;
 
-	/// Handler for the unbalanced reduction when submitting a bad `voter_index`.
-	type BadVoterIndex: OnUnbalanced<NegativeImbalanceOf<Self>>;
+		/// Handler for the unbalanced reduction when slashing a validator.
+		type BadPresentation: OnUnbalanced<NegativeImbalanceOf<Self>>;
 
-	/// Handler for the unbalanced reduction when a candidate has lost (and is not a runner up)
-	type LoserCandidate: OnUnbalanced<NegativeImbalanceOf<Self>>;
+		/// Handler for the unbalanced reduction when slashing an invalid reaping attempt.
+		type BadReaper: OnUnbalanced<NegativeImbalanceOf<Self>>;
 
-	/// What to do when the members change.
-	type ChangeMembers: ChangeMembers<Self::AccountId>;
+		/// Handler for the unbalanced reduction when submitting a bad `voter_index`.
+		type BadVoterIndex: OnUnbalanced<NegativeImbalanceOf<Self>>;
 
-	/// How much should be locked up in order to submit one's candidacy. A reasonable
-	/// default value is 9.
-	type CandidacyBond: Get<BalanceOf<Self>>;
+		/// Handler for the unbalanced reduction when a candidate has lost (and is not a runner up)
+		type LoserCandidate: OnUnbalanced<NegativeImbalanceOf<Self>>;
 
-	/// How much should be locked up in order to be able to submit votes.
-	type VotingBond: Get<BalanceOf<Self>>;
+		/// What to do when the members change.
+		type ChangeMembers: ChangeMembers<Self::AccountId>;
 
-	/// The amount of fee paid upon each vote submission, unless if they submit a
-	/// _hole_ index and replace it.
-	type VotingFee: Get<BalanceOf<Self>>;
+		/// How much should be locked up in order to submit one's candidacy. A reasonable
+		/// default value is 9.
+		#[pallet::constant]
+		type CandidacyBond: Get<BalanceOf<Self>>;
 
-	/// Minimum about that can be used as the locked value for voting.
-	type MinimumVotingLock: Get<BalanceOf<Self>>;
+		/// How much should be locked up in order to be able to submit votes.
+		#[pallet::constant]
+		type VotingBond: Get<BalanceOf<Self>>;
 
-	/// The punishment, per voter, if you provide an invalid presentation. A
-	/// reasonable default value is 1.
-	type PresentSlashPerVoter: Get<BalanceOf<Self>>;
+		/// The amount of fee paid upon each vote submission, unless if they submit a
+		/// _hole_ index and replace it.
+		#[pallet::constant]
+		type VotingFee: Get<BalanceOf<Self>>;
 
-	/// How many runners-up should have their approvals persist until the next
-	/// vote. A reasonable default value is 2.
-	type CarryCount: Get<u32>;
+		/// Minimum about that can be used as the locked value for voting.
+		#[pallet::constant]
+		type MinimumVotingLock: Get<BalanceOf<Self>>;
 
-	/// How many vote indices need to go by after a target voter's last vote before
-	/// they can be reaped if their approvals are moot. A reasonable default value
-	/// is 1.
-	type InactiveGracePeriod: Get<VoteIndex>;
+		/// The punishment, per voter, if you provide an invalid presentation. A
+		/// reasonable default value is 1.
+		#[pallet::constant]
+		type PresentSlashPerVoter: Get<BalanceOf<Self>>;
 
-	/// How often (in blocks) to check for new votes. A reasonable default value
-	/// is 1000.
-	type VotingPeriod: Get<Self::BlockNumber>;
+		/// How many runners-up should have their approvals persist until the next
+		/// vote. A reasonable default value is 2.
+		#[pallet::constant]
+		type CarryCount: Get<u32>;
 
-	/// Decay factor of weight when being accumulated. It should typically be set to
-	/// __at least__ `membership_size -1` to keep the collective secure.
-	/// When set to `N`, it indicates `(1/N)^t` of staked is decayed at weight
-	/// increment step `t`. 0 will result in no weight being added at all (normal
-	/// approval voting). A reasonable default value is 24.
-	type DecayRatio: Get<u32>;
-}
+		/// How many vote indices need to go by after a target voter's last vote before
+		/// they can be reaped if their approvals are moot. A reasonable default value
+		/// is 1.
+		#[pallet::constant]
+		type InactiveGracePeriod: Get<VoteIndex>;
 
-decl_storage! {
-	trait Store for Module<T: Config> as Elections {
-		// ---- parameters
-
-		/// How long to give each top candidate to present themselves after the vote ends.
-		pub PresentationDuration get(fn presentation_duration) config(): T::BlockNumber;
-		/// How long each position is active for.
-		pub TermDuration get(fn term_duration) config(): T::BlockNumber;
-		/// Number of accounts that should constitute the collective.
-		pub DesiredSeats get(fn desired_seats) config(): u32;
-
-		// ---- permanent state (always relevant, changes only at the finalization of voting)
-
-		///  The current membership. When there's a vote going on, this should still be used for
-		///  executive matters. The block number (second element in the tuple) is the block that
-		///  their position is active until (calculated by the sum of the block number when the
-		///  member was elected and their term duration).
-		pub Members get(fn members) config(): Vec<(T::AccountId, T::BlockNumber)>;
-		/// The total number of vote rounds that have happened or are in progress.
-		pub VoteCount get(fn vote_index): VoteIndex;
-
-		// ---- persistent state (always relevant, changes constantly)
-
-		// A list of votes for each voter. The votes are stored as numeric values and parsed in a
-		// bit-wise manner. In order to get a human-readable representation (`Vec<bool>`), use
-		// [`all_approvals_of`]. Furthermore, each vector of scalars is chunked with the cap of
-		// `APPROVAL_SET_SIZE`.
-		///
-		/// TWOX-NOTE: SAFE as `AccountId` is a crypto hash and `SetIndex` is not
-		/// attacker-controlled.
-		pub ApprovalsOf get(fn approvals_of):
-			map hasher(twox_64_concat) (T::AccountId, SetIndex) => Vec<ApprovalFlag>;
-		/// The vote index and list slot that the candidate `who` was registered or `None` if they
-		/// are not currently registered.
-		///
-		/// TWOX-NOTE: SAFE as `AccountId` is a crypto hash.
-		pub RegisterInfoOf get(fn candidate_reg_info):
-			map hasher(twox_64_concat) T::AccountId => Option<(VoteIndex, u32)>;
-		/// Basic information about a voter.
-		///
-		/// TWOX-NOTE: SAFE as `AccountId` is a crypto hash.
-		pub VoterInfoOf get(fn voter_info):
-			map hasher(twox_64_concat) T::AccountId => Option<VoterInfo<BalanceOf<T>>>;
-		/// The present voter list (chunked and capped at [`VOTER_SET_SIZE`]).
-		///
-		/// TWOX-NOTE: OKAY ― `SetIndex` is not user-controlled data.
-		pub Voters get(fn voters): map hasher(twox_64_concat) SetIndex => Vec<Option<T::AccountId>>;
-		/// the next free set to store a voter in. This will keep growing.
-		pub NextVoterSet get(fn next_nonfull_voter_set): SetIndex = 0;
-		/// Current number of Voters.
-		pub VoterCount get(fn voter_count): SetIndex = 0;
-		/// The present candidate list.
-		pub Candidates get(fn candidates): Vec<T::AccountId>; // has holes
-		/// Current number of active candidates
-		pub CandidateCount get(fn candidate_count): u32;
-
-		// ---- temporary state (only relevant during finalization/presentation)
-
-		/// The accounts holding the seats that will become free on the next tally.
-		pub NextFinalize get(fn next_finalize): Option<(T::BlockNumber, u32, Vec<T::AccountId>)>;
-		/// Get the leaderboard if we're in the presentation phase. The first element is the weight
-		/// of each entry; It may be the direct summed approval stakes, or a weighted version of it.
-		/// Sorted from low to high.
-		pub Leaderboard get(fn leaderboard): Option<Vec<(BalanceOf<T>, T::AccountId)> >;
+		/// How often (in blocks) to check for new votes. A reasonable default value
+		/// is 1000.
+		#[pallet::constant]
+		type VotingPeriod: Get<Self::BlockNumber>;
+
+		/// Decay factor of weight when being accumulated. It should typically be set to
+		/// __at least__ `membership_size -1` to keep the collective secure.
+		/// When set to `N`, it indicates `(1/N)^t` of staked is decayed at weight
+		/// increment step `t`. 0 will result in no weight being added at all (normal
+		/// approval voting). A reasonable default value is 24.
+		#[pallet::constant]
+		type DecayRatio: Get<u32>;
 	}
-}
 
-decl_error! {
-	/// Error for the elections module.
-	pub enum Error for Module<T: Config> {
+	#[pallet::extra_constants]
+	impl<T: Config> Pallet<T> {
+		//TODO: rename to snake case after https://github.com/paritytech/substrate/issues/8826 fixed.
+		/// The chunk size of the voter vector.
+		#[allow(non_snake_case)]
+		fn VOTER_SET_SIZE() -> u32 {
+			VOTER_SET_SIZE as u32
+		}
+
+		//TODO: rename to snake case after https://github.com/paritytech/substrate/issues/8826 fixed.
+		/// The chunk size of the approval vector.
+		#[allow(non_snake_case)]
+		fn APPROVAL_SET_SIZE() -> u32 {
+			APPROVAL_SET_SIZE as u32
+		}
+	}
+
+	// ---- permanent state (always relevant, changes only at the finalization of voting)
+
+	/// How long to give each top candidate to present themselves after the vote ends.
+	#[pallet::storage]
+	#[pallet::getter(fn presentation_duration)]
+	pub type PresentationDuration<T: Config> = StorageValue<_, T::BlockNumber, ValueQuery>;
+
+	/// How long each position is active for.
+	#[pallet::storage]
+	#[pallet::getter(fn term_duration)]
+	pub type TermDuration<T: Config> = StorageValue<_, T::BlockNumber, ValueQuery>;
+
+	/// Number of accounts that should constitute the collective.
+	#[pallet::storage]
+	#[pallet::getter(fn desired_seats)]
+	pub type DesiredSeats<T> = StorageValue<_, u32, ValueQuery>;
+
+	// ---- permanent state (always relevant, changes only at the finalization of voting)
+
+	///  The current membership. When there's a vote going on, this should still be used for
+	///  executive matters. The block number (second element in the tuple) is the block that
+	///  their position is active until (calculated by the sum of the block number when the
+	///  member was elected and their term duration).
+	#[pallet::storage]
+	#[pallet::getter(fn members)]
+	pub type Members<T: Config> = StorageValue<_, Vec<(T::AccountId, T::BlockNumber)>, ValueQuery>;
+
+	/// The total number of vote rounds that have happened or are in progress.
+	#[pallet::storage]
+	#[pallet::getter(fn vote_index)]
+	pub type VoteCount<T> = StorageValue<_, VoteIndex, ValueQuery>;
+
+	// ---- persistent state (always relevant, changes constantly)
+
+	// A list of votes for each voter. The votes are stored as numeric values and parsed in a
+	// bit-wise manner. In order to get a human-readable representation (`Vec<bool>`), use
+	// [`all_approvals_of`]. Furthermore, each vector of scalars is chunked with the cap of
+	// `APPROVAL_SET_SIZE`.
+	///
+	/// TWOX-NOTE: SAFE as `AccountId` is a crypto hash and `SetIndex` is not
+	/// attacker-controlled.
+	#[pallet::storage]
+	#[pallet::getter(fn approvals_of)]
+	pub type ApprovalsOf<T: Config> = StorageMap<
+		_,
+		Twox64Concat, (T::AccountId, SetIndex),
+		Vec<ApprovalFlag>,
+		ValueQuery,
+	>;
+
+	/// The vote index and list slot that the candidate `who` was registered or `None` if they
+	/// are not currently registered.
+	///
+	/// TWOX-NOTE: SAFE as `AccountId` is a crypto hash.
+	#[pallet::storage]
+	#[pallet::getter(fn candidate_reg_info)]
+	pub type RegisterInfoOf<T: Config> = StorageMap<_, Twox64Concat, T::AccountId, (VoteIndex, u32)>;
+
+	/// Basic information about a voter.
+	///
+	/// TWOX-NOTE: SAFE as `AccountId` is a crypto hash.
+	#[pallet::storage]
+	#[pallet::getter(fn voter_info)]
+	pub type VoterInfoOf<T: Config> = StorageMap<_, Twox64Concat, T::AccountId, VoterInfo<BalanceOf<T>>>;
+
+	/// The present voter list (chunked and capped at [`VOTER_SET_SIZE`]).
+	///
+	/// TWOX-NOTE: OKAY ― `SetIndex` is not user-controlled data.
+	#[pallet::storage]
+	#[pallet::getter(fn voters)]
+	pub type Voters<T: Config> = StorageMap<
+		_,
+		Twox64Concat, SetIndex,
+		Vec<Option<T::AccountId>>,
+		ValueQuery,
+	>;
+
+	/// the next free set to store a voter in. This will keep growing.
+	#[pallet::storage]
+	#[pallet::getter(fn next_nonfull_voter_set)]
+	pub type NextVoterSet<T> = StorageValue<_, SetIndex, ValueQuery>;
+
+	/// Current number of Voters.
+	#[pallet::storage]
+	#[pallet::getter(fn voter_count)]
+	pub type VoterCount<T> = StorageValue<_, SetIndex, ValueQuery>;
+
+	/// The present candidate list.
+	#[pallet::storage]
+	#[pallet::getter(fn candidates)]
+	pub type Candidates<T: Config> = StorageValue<_, Vec<T::AccountId>, ValueQuery>; // has holes
+
+	/// Current number of active candidates
+	#[pallet::storage]
+	#[pallet::getter(fn candidate_count)]
+	pub type CandidateCount<T> = StorageValue<_, u32, ValueQuery>;
+
+	// ---- temporary state (only relevant during finalization/presentation)
+
+	/// The accounts holding the seats that will become free on the next tally.
+	#[pallet::storage]
+	#[pallet::getter(fn next_finalize)]
+	pub type NextFinalize<T: Config> = StorageValue<_, (T::BlockNumber, u32, Vec<T::AccountId>)>;
+
+	/// Get the leaderboard if we're in the presentation phase. The first element is the weight
+	/// of each entry; It may be the direct summed approval stakes, or a weighted version of it.
+	/// Sorted from low to high.
+	#[pallet::storage]
+	#[pallet::getter(fn leaderboard)]
+	pub type Leaderboard<T: Config> = StorageValue<_, Vec<(BalanceOf<T>, T::AccountId)>>;
+
+	#[pallet::genesis_config]
+	pub struct GenesisConfig<T: Config> {
+		pub presentation_duration: T::BlockNumber,
+		pub term_duration: T::BlockNumber,
+		pub desired_seats: u32,
+		pub members: Vec<(T::AccountId, T::BlockNumber)>,
+	}
+
+	#[cfg(feature = "std")]
+	impl<T: Config> Default for GenesisConfig<T> {
+		fn default() -> Self {
+			GenesisConfig {
+				presentation_duration: Default::default(),
+				term_duration: Default::default(),
+				desired_seats: Default::default(),
+				members: Default::default(),
+			}
+		}
+	}
+
+	#[pallet::genesis_build]
+	impl<T: Config> GenesisBuild<T> for GenesisConfig<T> {
+		fn build(&self) {
+			PresentationDuration::<T>::put(self.presentation_duration);
+			TermDuration::<T>::put(self.term_duration);
+			DesiredSeats::<T>::put(self.desired_seats);
+			Members::<T>::put(&self.members);
+		}
+	}
+
+	#[pallet::error]
+	pub enum Error<T> {
 		/// Reporter must be a voter.
 		NotVoter,
 		/// Target for inactivity cleanup must be active.
@@ -342,59 +452,35 @@ decl_error! {
 		/// No approval changes during presentation period.
 		ApprovalPresentation,
 	}
-}
 
-decl_module! {
-	pub struct Module<T: Config> for enum Call where origin: T::Origin {
-		type Error = Error<T>;
-
-		/// How much should be locked up in order to submit one's candidacy. A reasonable
-		/// default value is 9.
-		const CandidacyBond: BalanceOf<T> = T::CandidacyBond::get();
-
-		/// How much should be locked up in order to be able to submit votes.
-		const VotingBond: BalanceOf<T> = T::VotingBond::get();
-
-		/// The amount of fee paid upon each vote submission, unless if they submit a
-		/// _hole_ index and replace it.
-		const VotingFee: BalanceOf<T> = T::VotingFee::get();
-
-		/// The punishment, per voter, if you provide an invalid presentation. A
-		/// reasonable default value is 1.
-		const PresentSlashPerVoter: BalanceOf<T> = T::PresentSlashPerVoter::get();
-
-		/// How many runners-up should have their approvals persist until the next
-		/// vote. A reasonable default value is 2.
-		const CarryCount: u32 = T::CarryCount::get();
-
-		/// How many vote indices need to go by after a target voter's last vote before
-		/// they can be reaped if their approvals are moot. A reasonable default value
-		/// is 1.
-		const InactiveGracePeriod: VoteIndex = T::InactiveGracePeriod::get();
-
-		/// How often (in blocks) to check for new votes. A reasonable default value
-		/// is 1000.
-		const VotingPeriod: T::BlockNumber = T::VotingPeriod::get();
-
-		/// Minimum about that can be used as the locked value for voting.
-		const MinimumVotingLock: BalanceOf<T> = T::MinimumVotingLock::get();
-
-		/// Decay factor of weight when being accumulated. It should typically be set to
-		/// __at least__ `membership_size -1` to keep the collective secure.
-		/// When set to `N`, it indicates `(1/N)^t` of staked is decayed at weight
-		/// increment step `t`. 0 will result in no weight being added at all (normal
-		/// approval voting). A reasonable default value is 24.
-		const DecayRatio: u32 = T::DecayRatio::get();
-
-		/// The chunk size of the voter vector.
-		const VOTER_SET_SIZE: u32 = VOTER_SET_SIZE as u32;
-		/// The chunk size of the approval vector.
-		const APPROVAL_SET_SIZE: u32 = APPROVAL_SET_SIZE as u32;
-
-		const PalletId: LockIdentifier = T::PalletId::get();
+	#[pallet::hooks]
+	impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
+		fn on_initialize(n: T::BlockNumber) -> Weight {
+			if let Err(e) = Self::end_block(n) {
+				print("Guru meditation");
+				print(e);
+			}
+			0
+		}
+	}
 
-		fn deposit_event() = default;
+	#[pallet::event]
+	#[pallet::generate_deposit(pub(super) fn deposit_event)]
+	#[pallet::metadata(T::AccountId = "AccountId", Vec<T::AccountId> = "Vec<AccountId>")]
+	pub enum Event<T: Config> {
+		/// Reaped \[voter, reaper\].
+		VoterReaped(T::AccountId, T::AccountId),
+		/// Slashed \[reaper\].
+		BadReaperSlashed(T::AccountId),
+		/// A tally (for approval votes of \[seats\]) has started.
+		TallyStarted(u32),
+		/// A tally (for approval votes of seat(s)) has ended (with one or more new members).
+		/// \[incoming, outgoing\]
+		TallyFinalized(Vec<T::AccountId>, Vec<T::AccountId>),
+	}
 
+	#[pallet::call]
+	impl<T: Config> Pallet<T> {
 		/// Set candidate approvals. Approval slots stay valid as long as candidates in those slots
 		/// are registered.
 		///
@@ -419,13 +505,13 @@ decl_module! {
 		/// - Two extra DB entries, one DB change.
 		/// - Argument `votes` is limited in length to number of candidates.
 		/// # </weight>
-		#[weight = 2_500_000_000]
-		fn set_approvals(
-			origin,
+		#[pallet::weight(2_500_000_000)]
+		pub fn set_approvals(
+			origin: OriginFor<T>,
 			votes: Vec<bool>,
-			#[compact] index: VoteIndex,
+			#[pallet::compact] index: VoteIndex,
 			hint: SetIndex,
-			#[compact] value: BalanceOf<T>,
+			#[pallet::compact] value: BalanceOf<T>,
 		) -> DispatchResult {
 			let who = ensure_signed(origin)?;
 			Self::do_set_approvals(who, votes, index, hint, value)
@@ -443,14 +529,14 @@ decl_module! {
 		/// - O(1).
 		/// - Two fewer DB entries, one DB change.
 		/// # </weight>
-		#[weight = 2_500_000_000]
-		fn reap_inactive_voter(
-			origin,
-			#[compact] reporter_index: u32,
+		#[pallet::weight(2_500_000_000)]
+		pub fn reap_inactive_voter(
+			origin: OriginFor<T>,
+			#[pallet::compact] reporter_index: u32,
 			who: <T::Lookup as StaticLookup>::Source,
-			#[compact] who_index: u32,
-			#[compact] assumed_vote_index: VoteIndex,
-		) {
+			#[pallet::compact] who_index: u32,
+			#[pallet::compact] assumed_vote_index: VoteIndex,
+		) -> DispatchResult {
 			let reporter = ensure_signed(origin)?;
 			let who = T::Lookup::lookup(who)?;
 
@@ -499,12 +585,13 @@ decl_module! {
 				// This only fails if `reporter` doesn't exist, which it clearly must do since its
 				// the origin. Still, it's no more harmful to propagate any error at this point.
 				T::Currency::repatriate_reserved(&who, &reporter, T::VotingBond::get(), BalanceStatus::Free)?;
-				Self::deposit_event(RawEvent::VoterReaped(who, reporter));
+				Self::deposit_event(Event::<T>::VoterReaped(who, reporter));
 			} else {
 				let imbalance = T::Currency::slash_reserved(&reporter, T::VotingBond::get()).0;
 				T::BadReaper::on_unbalanced(imbalance);
-				Self::deposit_event(RawEvent::BadReaperSlashed(reporter));
+				Self::deposit_event(Event::<T>::BadReaperSlashed(reporter));
 			}
+			Ok(())
 		}
 
 		/// Remove a voter. All votes are cancelled and the voter deposit is returned.
@@ -517,8 +604,8 @@ decl_module! {
 		/// - O(1).
 		/// - Two fewer DB entries, one DB change.
 		/// # </weight>
-		#[weight = 1_250_000_000]
-		fn retract_voter(origin, #[compact] index: u32) {
+		#[pallet::weight(1_250_000_000)]
+		pub fn retract_voter(origin: OriginFor<T>, #[pallet::compact] index: u32) -> DispatchResult {
 			let who = ensure_signed(origin)?;
 
 			ensure!(!Self::presentation_active(), Error::<T>::CannotRetractPresenting);
@@ -530,6 +617,7 @@ decl_module! {
 			Self::remove_voter(&who, index);
 			T::Currency::unreserve(&who, T::VotingBond::get());
 			T::Currency::remove_lock(T::PalletId::get(), &who);
+			Ok(())
 		}
 
 		/// Submit oneself for candidacy.
@@ -545,8 +633,8 @@ decl_module! {
 		/// - Independent of input.
 		/// - Three DB changes.
 		/// # </weight>
-		#[weight = 2_500_000_000]
-		fn submit_candidacy(origin, #[compact] slot: u32) {
+		#[pallet::weight(2_500_000_000)]
+		pub fn submit_candidacy(origin: OriginFor<T>, #[pallet::compact] slot: u32) -> DispatchResult {
 			let who = ensure_signed(origin)?;
 
 			ensure!(!Self::is_a_candidate(&who), Error::<T>::DuplicatedCandidate);
@@ -570,7 +658,8 @@ decl_module! {
 				candidates[slot] = who;
 			}
 			<Candidates<T>>::put(candidates);
-			CandidateCount::put(count as u32 + 1);
+			CandidateCount::<T>::put(count as u32 + 1);
+			Ok(())
 		}
 
 		/// Claim that `candidate` is one of the top `carry_count + desired_seats` candidates. Only
@@ -582,12 +671,12 @@ decl_module! {
 		/// - O(voters) compute.
 		/// - One DB change.
 		/// # </weight>
-		#[weight = 10_000_000_000]
-		fn present_winner(
-			origin,
+		#[pallet::weight(10_000_000_000)]
+		pub fn present_winner(
+			origin: OriginFor<T>,
 			candidate: <T::Lookup as StaticLookup>::Source,
-			#[compact] total: BalanceOf<T>,
-			#[compact] index: VoteIndex,
+			#[pallet::compact] total: BalanceOf<T>,
+			#[pallet::compact] index: VoteIndex,
 		) -> DispatchResult {
 			let who = ensure_signed(origin)?;
 			ensure!(
@@ -656,18 +745,19 @@ decl_module! {
 		/// Set the desired member count; if lower than the current count, then seats will not be up
 		/// election when they expire. If more, then a new vote will be started if one is not
 		/// already in progress.
-		#[weight = (0, DispatchClass::Operational)]
-		fn set_desired_seats(origin, #[compact] count: u32) {
+		#[pallet::weight((0, DispatchClass::Operational))]
+		pub fn set_desired_seats(origin: OriginFor<T>, #[pallet::compact] count: u32) -> DispatchResult {
 			ensure_root(origin)?;
-			DesiredSeats::put(count);
+			DesiredSeats::<T>::put(count);
+			Ok(())
 		}
 
 		/// Remove a particular member from the set. This is effective immediately.
 		///
 		/// Note: A tally should happen instantly (if not already in a presentation
 		/// period) to fill the seat if removal means that the desired members are not met.
-		#[weight = (0, DispatchClass::Operational)]
-		fn remove_member(origin, who: <T::Lookup as StaticLookup>::Source) {
+		#[pallet::weight((0, DispatchClass::Operational))]
+		pub fn remove_member(origin: OriginFor<T>, who: <T::Lookup as StaticLookup>::Source) -> DispatchResult {
 			ensure_root(origin)?;
 			let who = T::Lookup::lookup(who)?;
 			let new_set: Vec<(T::AccountId, T::BlockNumber)> = Self::members()
@@ -677,49 +767,36 @@ decl_module! {
 			<Members<T>>::put(&new_set);
 			let new_set = new_set.into_iter().map(|x| x.0).collect::<Vec<_>>();
 			T::ChangeMembers::change_members(&[], &[who], new_set);
+			Ok(())
 		}
 
 		/// Set the presentation duration. If there is currently a vote being presented for, will
 		/// invoke `finalize_vote`.
-		#[weight = (0, DispatchClass::Operational)]
-		fn set_presentation_duration(origin, #[compact] count: T::BlockNumber) {
+		#[pallet::weight((0, DispatchClass::Operational))]
+		pub fn set_presentation_duration(
+			origin: OriginFor<T>,
+			#[pallet::compact] count: T::BlockNumber,
+		) -> DispatchResult {
 			ensure_root(origin)?;
 			<PresentationDuration<T>>::put(count);
+			Ok(())
 		}
 
 		/// Set the presentation duration. If there is current a vote being presented for, will
 		/// invoke `finalize_vote`.
-		#[weight = (0, DispatchClass::Operational)]
-		fn set_term_duration(origin, #[compact] count: T::BlockNumber) {
+		#[pallet::weight((0, DispatchClass::Operational))]
+		pub fn set_term_duration(
+			origin: OriginFor<T>,
+			#[pallet::compact] count: T::BlockNumber,
+		) -> DispatchResult {
 			ensure_root(origin)?;
 			<TermDuration<T>>::put(count);
-		}
-
-		fn on_initialize(n: T::BlockNumber) -> Weight {
-			if let Err(e) = Self::end_block(n) {
-				print("Guru meditation");
-				print(e);
-			}
-			0
+			Ok(())
 		}
 	}
 }
 
-decl_event!(
-	pub enum Event<T> where <T as frame_system::Config>::AccountId {
-		/// Reaped \[voter, reaper\].
-		VoterReaped(AccountId, AccountId),
-		/// Slashed \[reaper\].
-		BadReaperSlashed(AccountId),
-		/// A tally (for approval votes of \[seats\]) has started.
-		TallyStarted(u32),
-		/// A tally (for approval votes of seat(s)) has ended (with one or more new members).
-		/// \[incoming, outgoing\]
-		TallyFinalized(Vec<AccountId>, Vec<AccountId>),
-	}
-);
-
-impl<T: Config> Module<T> {
+impl<T: Config> Pallet<T> {
 	// exposed immutables.
 
 	/// True if we're currently in a presentation period.
@@ -800,7 +877,7 @@ impl<T: Config> Module<T> {
 		let mut set = Self::voters(set_index);
 		set[vec_index] = None;
 		<Voters<T>>::insert(set_index, set);
-		VoterCount::mutate(|c| *c = *c - 1);
+		VoterCount::<T>::mutate(|c| *c = *c - 1);
 		Self::remove_all_approvals_of(voter);
 		<VoterInfoOf<T>>::remove(voter);
 	}
@@ -879,14 +956,14 @@ impl<T: Config> Module<T> {
 						locked_balance -= T::VotingFee::get();
 					}
 					if set_len + 1 == VOTER_SET_SIZE {
-						NextVoterSet::put(next + 1);
+						NextVoterSet::<T>::put(next + 1);
 					}
 					<Voters<T>>::append(next, Some(who.clone()));
 				}
 			}
 
 			T::Currency::reserve(&who, T::VotingBond::get())?;
-			VoterCount::mutate(|c| *c = *c + 1);
+			VoterCount::<T>::mutate(|c| *c = *c + 1);
 		}
 
 		T::Currency::set_lock(
@@ -928,7 +1005,7 @@ impl<T: Config> Module<T> {
 			let leaderboard_size = empty_seats + T::CarryCount::get() as usize;
 			<Leaderboard<T>>::put(vec![(BalanceOf::<T>::zero(), T::AccountId::default()); leaderboard_size]);
 
-			Self::deposit_event(RawEvent::TallyStarted(empty_seats as u32));
+			Self::deposit_event(Event::<T>::TallyStarted(empty_seats as u32));
 		}
 	}
 
@@ -1017,11 +1094,11 @@ impl<T: Config> Module<T> {
 				new_candidates.truncate(last_index + 1);
 			}
 
-		Self::deposit_event(RawEvent::TallyFinalized(incoming, outgoing));
+		Self::deposit_event(Event::<T>::TallyFinalized(incoming, outgoing));
 
 		<Candidates<T>>::put(new_candidates);
-		CandidateCount::put(count);
-		VoteCount::put(Self::vote_index() + 1);
+		CandidateCount::<T>::put(count);
+		VoteCount::<T>::put(Self::vote_index() + 1);
 		Ok(())
 	}
 
diff --git a/substrate/frame/elections/src/mock.rs b/substrate/frame/elections/src/mock.rs
index bb67622eb7e..7eef7f49099 100644
--- a/substrate/frame/elections/src/mock.rs
+++ b/substrate/frame/elections/src/mock.rs
@@ -20,7 +20,7 @@
 #![cfg(test)]
 
 use frame_support::{
-	StorageValue, StorageMap, parameter_types, assert_ok,
+	parameter_types, assert_ok,
 	traits::{ChangeMembers, Currency, LockIdentifier},
 };
 use sp_core::H256;
@@ -266,7 +266,7 @@ pub(crate) fn new_test_ext_with_candidate_holes() -> sp_io::TestExternalities {
 	let mut t = ExtBuilder::default().build();
 	t.execute_with(|| {
 		<elections::Candidates<Test>>::put(vec![0, 0, 1]);
-		elections::CandidateCount::put(1);
+		elections::CandidateCount::<Test>::put(1);
 		<elections::RegisterInfoOf<Test>>::insert(1, (0, 2));
 	});
 	t
-- 
GitLab