pallet-referenda: make the pallet instanceable (#11089)

Signed-off-by: koushiro <koushiro.cqx@gmail.com>
This commit is contained in:
Qinxuan Chen
2022-03-25 00:36:58 +08:00
committed by GitHub
parent a4041add8a
commit 44e71d8d7e
3 changed files with 160 additions and 141 deletions
+8 -6
View File
@@ -59,7 +59,7 @@ impl From<BeginDecidingBranch> for ServiceBranch {
impl ServiceBranch { impl ServiceBranch {
/// Return the weight of the `nudge` function when it takes the branch denoted by `self`. /// Return the weight of the `nudge` function when it takes the branch denoted by `self`.
pub fn weight_of_nudge<T: Config>(self) -> frame_support::weights::Weight { pub fn weight_of_nudge<T: Config<I>, I: 'static>(self) -> frame_support::weights::Weight {
use ServiceBranch::*; use ServiceBranch::*;
match self { match self {
NoDeposit => T::WeightInfo::nudge_referendum_no_deposit(), NoDeposit => T::WeightInfo::nudge_referendum_no_deposit(),
@@ -81,7 +81,7 @@ impl ServiceBranch {
} }
/// Return the maximum possible weight of the `nudge` function. /// Return the maximum possible weight of the `nudge` function.
pub fn max_weight_of_nudge<T: Config>() -> frame_support::weights::Weight { pub fn max_weight_of_nudge<T: Config<I>, I: 'static>() -> frame_support::weights::Weight {
0.max(T::WeightInfo::nudge_referendum_no_deposit()) 0.max(T::WeightInfo::nudge_referendum_no_deposit())
.max(T::WeightInfo::nudge_referendum_preparing()) .max(T::WeightInfo::nudge_referendum_preparing())
.max(T::WeightInfo::nudge_referendum_queued()) .max(T::WeightInfo::nudge_referendum_queued())
@@ -101,7 +101,9 @@ impl ServiceBranch {
/// Return the weight of the `place_decision_deposit` function when it takes the branch denoted /// Return the weight of the `place_decision_deposit` function when it takes the branch denoted
/// by `self`. /// by `self`.
pub fn weight_of_deposit<T: Config>(self) -> Option<frame_support::weights::Weight> { pub fn weight_of_deposit<T: Config<I>, I: 'static>(
self,
) -> Option<frame_support::weights::Weight> {
use ServiceBranch::*; use ServiceBranch::*;
Some(match self { Some(match self {
Preparing => T::WeightInfo::place_decision_deposit_preparing(), Preparing => T::WeightInfo::place_decision_deposit_preparing(),
@@ -124,7 +126,7 @@ impl ServiceBranch {
} }
/// Return the maximum possible weight of the `place_decision_deposit` function. /// Return the maximum possible weight of the `place_decision_deposit` function.
pub fn max_weight_of_deposit<T: Config>() -> frame_support::weights::Weight { pub fn max_weight_of_deposit<T: Config<I>, I: 'static>() -> frame_support::weights::Weight {
0.max(T::WeightInfo::place_decision_deposit_preparing()) 0.max(T::WeightInfo::place_decision_deposit_preparing())
.max(T::WeightInfo::place_decision_deposit_queued()) .max(T::WeightInfo::place_decision_deposit_queued())
.max(T::WeightInfo::place_decision_deposit_not_queued()) .max(T::WeightInfo::place_decision_deposit_not_queued())
@@ -154,7 +156,7 @@ impl From<BeginDecidingBranch> for OneFewerDecidingBranch {
impl OneFewerDecidingBranch { impl OneFewerDecidingBranch {
/// Return the weight of the `one_fewer_deciding` function when it takes the branch denoted /// Return the weight of the `one_fewer_deciding` function when it takes the branch denoted
/// by `self`. /// by `self`.
pub fn weight<T: Config>(self) -> frame_support::weights::Weight { pub fn weight<T: Config<I>, I: 'static>(self) -> frame_support::weights::Weight {
use OneFewerDecidingBranch::*; use OneFewerDecidingBranch::*;
match self { match self {
QueueEmpty => T::WeightInfo::one_fewer_deciding_queue_empty(), QueueEmpty => T::WeightInfo::one_fewer_deciding_queue_empty(),
@@ -164,7 +166,7 @@ impl OneFewerDecidingBranch {
} }
/// Return the maximum possible weight of the `one_fewer_deciding` function. /// Return the maximum possible weight of the `one_fewer_deciding` function.
pub fn max_weight<T: Config>() -> frame_support::weights::Weight { pub fn max_weight<T: Config<I>, I: 'static>() -> frame_support::weights::Weight {
0.max(T::WeightInfo::one_fewer_deciding_queue_empty()) 0.max(T::WeightInfo::one_fewer_deciding_queue_empty())
.max(T::WeightInfo::one_fewer_deciding_passing()) .max(T::WeightInfo::one_fewer_deciding_passing())
.max(T::WeightInfo::one_fewer_deciding_failing()) .max(T::WeightInfo::one_fewer_deciding_failing())
+130 -114
View File
@@ -83,15 +83,18 @@ use sp_std::{fmt::Debug, prelude::*};
mod branch; mod branch;
mod types; mod types;
pub mod weights; pub mod weights;
use branch::{BeginDecidingBranch, OneFewerDecidingBranch, ServiceBranch};
pub use pallet::*; use self::branch::{BeginDecidingBranch, OneFewerDecidingBranch, ServiceBranch};
pub use types::{ pub use self::{
BalanceOf, CallOf, Curve, DecidingStatus, DecidingStatusOf, Deposit, InsertSorted, pallet::*,
NegativeImbalanceOf, PalletsOriginOf, ReferendumIndex, ReferendumInfo, ReferendumInfoOf, types::{
ReferendumStatus, ReferendumStatusOf, ScheduleAddressOf, TallyOf, TrackIdOf, TrackInfo, BalanceOf, CallOf, Curve, DecidingStatus, DecidingStatusOf, Deposit, InsertSorted,
TrackInfoOf, TracksInfo, VotesOf, NegativeImbalanceOf, PalletsOriginOf, ReferendumIndex, ReferendumInfo, ReferendumInfoOf,
ReferendumStatus, ReferendumStatusOf, ScheduleAddressOf, TallyOf, TrackIdOf, TrackInfo,
TrackInfoOf, TracksInfo, VotesOf,
},
weights::WeightInfo,
}; };
pub use weights::WeightInfo;
#[cfg(test)] #[cfg(test)]
mod mock; mod mock;
@@ -106,25 +109,33 @@ const ASSEMBLY_ID: LockIdentifier = *b"assembly";
#[frame_support::pallet] #[frame_support::pallet]
pub mod pallet { pub mod pallet {
use super::*; use super::*;
use frame_support::{pallet_prelude::*, traits::EnsureOrigin, Parameter}; use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*; use frame_system::pallet_prelude::*;
use sp_runtime::DispatchResult;
#[pallet::pallet] #[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)] #[pallet::generate_store(pub(super) trait Store)]
#[pallet::without_storage_info] #[pallet::without_storage_info]
pub struct Pallet<T>(_); pub struct Pallet<T, I = ()>(_);
#[pallet::config] #[pallet::config]
pub trait Config: frame_system::Config + Sized { pub trait Config<I: 'static = ()>: frame_system::Config + Sized {
// System level stuff. // System level stuff.
type Call: Parameter + Dispatchable<Origin = Self::Origin> + From<Call<Self>>; type Call: Parameter + Dispatchable<Origin = Self::Origin> + From<Call<Self, I>>;
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>; type Event: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::Event>;
/// Weight information for extrinsics in this pallet. /// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo; type WeightInfo: WeightInfo;
/// The Scheduler. /// The Scheduler.
type Scheduler: ScheduleAnon<Self::BlockNumber, CallOf<Self>, PalletsOriginOf<Self>, Hash = Self::Hash> type Scheduler: ScheduleAnon<
+ ScheduleNamed<Self::BlockNumber, CallOf<Self>, PalletsOriginOf<Self>, Hash = Self::Hash>; Self::BlockNumber,
CallOf<Self, I>,
PalletsOriginOf<Self>,
Hash = Self::Hash,
> + ScheduleNamed<
Self::BlockNumber,
CallOf<Self, I>,
PalletsOriginOf<Self>,
Hash = Self::Hash,
>;
/// Currency type for this pallet. /// Currency type for this pallet.
type Currency: ReservableCurrency<Self::AccountId>; type Currency: ReservableCurrency<Self::AccountId>;
// Origins and unbalances. // Origins and unbalances.
@@ -133,7 +144,7 @@ pub mod pallet {
/// Origin from which any vote may be killed. /// Origin from which any vote may be killed.
type KillOrigin: EnsureOrigin<Self::Origin>; type KillOrigin: EnsureOrigin<Self::Origin>;
/// Handler for the unbalanced reduction when slashing a preimage deposit. /// Handler for the unbalanced reduction when slashing a preimage deposit.
type Slash: OnUnbalanced<NegativeImbalanceOf<Self>>; type Slash: OnUnbalanced<NegativeImbalanceOf<Self, I>>;
/// The counting type for votes. Usually just balance. /// The counting type for votes. Usually just balance.
type Votes: AtLeast32BitUnsigned + Copy + Parameter + Member; type Votes: AtLeast32BitUnsigned + Copy + Parameter + Member;
/// The tallying type. /// The tallying type.
@@ -142,7 +153,7 @@ pub mod pallet {
// Constants // Constants
/// The minimum amount to be used as a deposit for a public referendum proposal. /// The minimum amount to be used as a deposit for a public referendum proposal.
#[pallet::constant] #[pallet::constant]
type SubmissionDeposit: Get<BalanceOf<Self>>; type SubmissionDeposit: Get<BalanceOf<Self, I>>;
/// Maximum size of the referendum queue for a single track. /// Maximum size of the referendum queue for a single track.
#[pallet::constant] #[pallet::constant]
@@ -162,7 +173,7 @@ pub mod pallet {
// The other stuff. // The other stuff.
/// Information concerning the different referendum tracks. /// Information concerning the different referendum tracks.
type Tracks: TracksInfo< type Tracks: TracksInfo<
BalanceOf<Self>, BalanceOf<Self, I>,
Self::BlockNumber, Self::BlockNumber,
Origin = <Self::Origin as OriginTrait>::PalletsOrigin, Origin = <Self::Origin as OriginTrait>::PalletsOrigin,
>; >;
@@ -170,39 +181,40 @@ pub mod pallet {
/// The next free referendum index, aka the number of referenda started so far. /// The next free referendum index, aka the number of referenda started so far.
#[pallet::storage] #[pallet::storage]
pub type ReferendumCount<T> = StorageValue<_, ReferendumIndex, ValueQuery>; pub type ReferendumCount<T, I = ()> = StorageValue<_, ReferendumIndex, ValueQuery>;
/// Information concerning any given referendum. /// Information concerning any given referendum.
#[pallet::storage] #[pallet::storage]
pub type ReferendumInfoFor<T: Config> = pub type ReferendumInfoFor<T: Config<I>, I: 'static = ()> =
StorageMap<_, Blake2_128Concat, ReferendumIndex, ReferendumInfoOf<T>>; StorageMap<_, Blake2_128Concat, ReferendumIndex, ReferendumInfoOf<T, I>>;
/// The sorted list of referenda ready to be decided but not yet being decided, ordered by /// The sorted list of referenda ready to be decided but not yet being decided, ordered by
/// conviction-weighted approvals. /// conviction-weighted approvals.
/// ///
/// This should be empty if `DecidingCount` is less than `TrackInfo::max_deciding`. /// This should be empty if `DecidingCount` is less than `TrackInfo::max_deciding`.
#[pallet::storage] #[pallet::storage]
pub type TrackQueue<T: Config> = StorageMap< pub type TrackQueue<T: Config<I>, I: 'static = ()> = StorageMap<
_, _,
Twox64Concat, Twox64Concat,
TrackIdOf<T>, TrackIdOf<T, I>,
BoundedVec<(ReferendumIndex, T::Votes), T::MaxQueued>, BoundedVec<(ReferendumIndex, T::Votes), T::MaxQueued>,
ValueQuery, ValueQuery,
>; >;
/// The number of referenda being decided currently. /// The number of referenda being decided currently.
#[pallet::storage] #[pallet::storage]
pub type DecidingCount<T: Config> = StorageMap<_, Twox64Concat, TrackIdOf<T>, u32, ValueQuery>; pub type DecidingCount<T: Config<I>, I: 'static = ()> =
StorageMap<_, Twox64Concat, TrackIdOf<T, I>, u32, ValueQuery>;
#[pallet::event] #[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)] #[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> { pub enum Event<T: Config<I>, I: 'static = ()> {
/// A referendum has being submitted. /// A referendum has being submitted.
Submitted { Submitted {
/// Index of the referendum. /// Index of the referendum.
index: ReferendumIndex, index: ReferendumIndex,
/// The track (and by extension proposal dispatch origin) of this referendum. /// The track (and by extension proposal dispatch origin) of this referendum.
track: TrackIdOf<T>, track: TrackIdOf<T, I>,
/// The hash of the proposal up for referendum. /// The hash of the proposal up for referendum.
proposal_hash: T::Hash, proposal_hash: T::Hash,
}, },
@@ -213,7 +225,7 @@ pub mod pallet {
/// The account who placed the deposit. /// The account who placed the deposit.
who: T::AccountId, who: T::AccountId,
/// The amount placed by the account. /// The amount placed by the account.
amount: BalanceOf<T>, amount: BalanceOf<T, I>,
}, },
/// The decision deposit has been refunded. /// The decision deposit has been refunded.
DecisionDepositRefunded { DecisionDepositRefunded {
@@ -222,21 +234,21 @@ pub mod pallet {
/// The account who placed the deposit. /// The account who placed the deposit.
who: T::AccountId, who: T::AccountId,
/// The amount placed by the account. /// The amount placed by the account.
amount: BalanceOf<T>, amount: BalanceOf<T, I>,
}, },
/// A deposit has been slashaed. /// A deposit has been slashaed.
DepositSlashed { DepositSlashed {
/// The account who placed the deposit. /// The account who placed the deposit.
who: T::AccountId, who: T::AccountId,
/// The amount placed by the account. /// The amount placed by the account.
amount: BalanceOf<T>, amount: BalanceOf<T, I>,
}, },
/// A referendum has moved into the deciding phase. /// A referendum has moved into the deciding phase.
DecisionStarted { DecisionStarted {
/// Index of the referendum. /// Index of the referendum.
index: ReferendumIndex, index: ReferendumIndex,
/// The track (and by extension proposal dispatch origin) of this referendum. /// The track (and by extension proposal dispatch origin) of this referendum.
track: TrackIdOf<T>, track: TrackIdOf<T, I>,
/// The hash of the proposal up for referendum. /// The hash of the proposal up for referendum.
proposal_hash: T::Hash, proposal_hash: T::Hash,
/// The current tally of votes in this referendum. /// The current tally of votes in this referendum.
@@ -293,7 +305,7 @@ pub mod pallet {
} }
#[pallet::error] #[pallet::error]
pub enum Error<T> { pub enum Error<T, I = ()> {
/// Referendum is not ongoing. /// Referendum is not ongoing.
NotOngoing, NotOngoing,
/// Referendum's decision deposit is already paid. /// Referendum's decision deposit is already paid.
@@ -319,7 +331,7 @@ pub mod pallet {
} }
#[pallet::call] #[pallet::call]
impl<T: Config> Pallet<T> { impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Propose a referendum on a privileged action. /// Propose a referendum on a privileged action.
/// ///
/// - `origin`: must be `Signed` and the account must have `SubmissionDeposit` funds /// - `origin`: must be `Signed` and the account must have `SubmissionDeposit` funds
@@ -338,9 +350,10 @@ pub mod pallet {
) -> DispatchResult { ) -> DispatchResult {
let who = ensure_signed(origin)?; let who = ensure_signed(origin)?;
let track = T::Tracks::track_for(&proposal_origin).map_err(|_| Error::<T>::NoTrack)?; let track =
T::Tracks::track_for(&proposal_origin).map_err(|_| Error::<T, I>::NoTrack)?;
let submission_deposit = Self::take_deposit(who, T::SubmissionDeposit::get())?; let submission_deposit = Self::take_deposit(who, T::SubmissionDeposit::get())?;
let index = ReferendumCount::<T>::mutate(|x| { let index = ReferendumCount::<T, I>::mutate(|x| {
let r = *x; let r = *x;
*x += 1; *x += 1;
r r
@@ -360,9 +373,9 @@ pub mod pallet {
in_queue: false, in_queue: false,
alarm: Self::set_alarm(nudge_call, now.saturating_add(T::UndecidingTimeout::get())), alarm: Self::set_alarm(nudge_call, now.saturating_add(T::UndecidingTimeout::get())),
}; };
ReferendumInfoFor::<T>::insert(index, ReferendumInfo::Ongoing(status)); ReferendumInfoFor::<T, I>::insert(index, ReferendumInfo::Ongoing(status));
Self::deposit_event(Event::<T>::Submitted { index, track, proposal_hash }); Self::deposit_event(Event::<T, I>::Submitted { index, track, proposal_hash });
Ok(()) Ok(())
} }
@@ -374,24 +387,24 @@ pub mod pallet {
/// posted. /// posted.
/// ///
/// Emits `DecisionDepositPlaced`. /// Emits `DecisionDepositPlaced`.
#[pallet::weight(ServiceBranch::max_weight_of_deposit::<T>())] #[pallet::weight(ServiceBranch::max_weight_of_deposit::<T, I>())]
pub fn place_decision_deposit( pub fn place_decision_deposit(
origin: OriginFor<T>, origin: OriginFor<T>,
index: ReferendumIndex, index: ReferendumIndex,
) -> DispatchResultWithPostInfo { ) -> DispatchResultWithPostInfo {
let who = ensure_signed(origin)?; let who = ensure_signed(origin)?;
let mut status = Self::ensure_ongoing(index)?; let mut status = Self::ensure_ongoing(index)?;
ensure!(status.decision_deposit.is_none(), Error::<T>::HasDeposit); ensure!(status.decision_deposit.is_none(), Error::<T, I>::HasDeposit);
let track = Self::track(status.track).ok_or(Error::<T>::NoTrack)?; let track = Self::track(status.track).ok_or(Error::<T, I>::NoTrack)?;
status.decision_deposit = status.decision_deposit =
Some(Self::take_deposit(who.clone(), track.decision_deposit)?); Some(Self::take_deposit(who.clone(), track.decision_deposit)?);
let now = frame_system::Pallet::<T>::block_number(); let now = frame_system::Pallet::<T>::block_number();
let (info, _, branch) = Self::service_referendum(now, index, status); let (info, _, branch) = Self::service_referendum(now, index, status);
ReferendumInfoFor::<T>::insert(index, info); ReferendumInfoFor::<T, I>::insert(index, info);
let e = let e =
Event::<T>::DecisionDepositPlaced { index, who, amount: track.decision_deposit }; Event::<T, I>::DecisionDepositPlaced { index, who, amount: track.decision_deposit };
Self::deposit_event(e); Self::deposit_event(e);
Ok(branch.weight_of_deposit::<T>().into()) Ok(branch.weight_of_deposit::<T, I>().into())
} }
/// Refund the Decision Deposit for a closed referendum back to the depositor. /// Refund the Decision Deposit for a closed referendum back to the depositor.
@@ -407,14 +420,15 @@ pub mod pallet {
index: ReferendumIndex, index: ReferendumIndex,
) -> DispatchResult { ) -> DispatchResult {
ensure_signed_or_root(origin)?; ensure_signed_or_root(origin)?;
let mut info = ReferendumInfoFor::<T>::get(index).ok_or(Error::<T>::BadReferendum)?; let mut info =
ReferendumInfoFor::<T, I>::get(index).ok_or(Error::<T, I>::BadReferendum)?;
let deposit = info let deposit = info
.take_decision_deposit() .take_decision_deposit()
.map_err(|_| Error::<T>::Unfinished)? .map_err(|_| Error::<T, I>::Unfinished)?
.ok_or(Error::<T>::NoDeposit)?; .ok_or(Error::<T, I>::NoDeposit)?;
Self::refund_deposit(Some(deposit.clone())); Self::refund_deposit(Some(deposit.clone()));
ReferendumInfoFor::<T>::insert(index, info); ReferendumInfoFor::<T, I>::insert(index, info);
let e = Event::<T>::DecisionDepositRefunded { let e = Event::<T, I>::DecisionDepositRefunded {
index, index,
who: deposit.who, who: deposit.who,
amount: deposit.amount, amount: deposit.amount,
@@ -437,13 +451,13 @@ pub mod pallet {
let _ = T::Scheduler::cancel(last_alarm); let _ = T::Scheduler::cancel(last_alarm);
} }
Self::note_one_fewer_deciding(status.track); Self::note_one_fewer_deciding(status.track);
Self::deposit_event(Event::<T>::Cancelled { index, tally: status.tally }); Self::deposit_event(Event::<T, I>::Cancelled { index, tally: status.tally });
let info = ReferendumInfo::Cancelled( let info = ReferendumInfo::Cancelled(
frame_system::Pallet::<T>::block_number(), frame_system::Pallet::<T>::block_number(),
status.submission_deposit, status.submission_deposit,
status.decision_deposit, status.decision_deposit,
); );
ReferendumInfoFor::<T>::insert(index, info); ReferendumInfoFor::<T, I>::insert(index, info);
Ok(()) Ok(())
} }
@@ -461,11 +475,11 @@ pub mod pallet {
let _ = T::Scheduler::cancel(last_alarm); let _ = T::Scheduler::cancel(last_alarm);
} }
Self::note_one_fewer_deciding(status.track); Self::note_one_fewer_deciding(status.track);
Self::deposit_event(Event::<T>::Killed { index, tally: status.tally }); Self::deposit_event(Event::<T, I>::Killed { index, tally: status.tally });
Self::slash_deposit(Some(status.submission_deposit.clone())); Self::slash_deposit(Some(status.submission_deposit.clone()));
Self::slash_deposit(status.decision_deposit.clone()); Self::slash_deposit(status.decision_deposit.clone());
let info = ReferendumInfo::Killed(frame_system::Pallet::<T>::block_number()); let info = ReferendumInfo::Killed(frame_system::Pallet::<T>::block_number());
ReferendumInfoFor::<T>::insert(index, info); ReferendumInfoFor::<T, I>::insert(index, info);
Ok(()) Ok(())
} }
@@ -473,7 +487,7 @@ pub mod pallet {
/// ///
/// - `origin`: must be `Root`. /// - `origin`: must be `Root`.
/// - `index`: the referendum to be advanced. /// - `index`: the referendum to be advanced.
#[pallet::weight(ServiceBranch::max_weight_of_nudge::<T>())] #[pallet::weight(ServiceBranch::max_weight_of_nudge::<T, I>())]
pub fn nudge_referendum( pub fn nudge_referendum(
origin: OriginFor<T>, origin: OriginFor<T>,
index: ReferendumIndex, index: ReferendumIndex,
@@ -485,9 +499,9 @@ pub mod pallet {
status.alarm = None; status.alarm = None;
let (info, dirty, branch) = Self::service_referendum(now, index, status); let (info, dirty, branch) = Self::service_referendum(now, index, status);
if dirty { if dirty {
ReferendumInfoFor::<T>::insert(index, info); ReferendumInfoFor::<T, I>::insert(index, info);
} }
Ok(Some(branch.weight_of_nudge::<T>()).into()) Ok(Some(branch.weight_of_nudge::<T, I>()).into())
} }
/// Advance a track onto its next logical state. Only used internally. /// Advance a track onto its next logical state. Only used internally.
@@ -499,14 +513,14 @@ pub mod pallet {
/// `DecidingCount` is not yet updated. This means that we should either: /// `DecidingCount` is not yet updated. This means that we should either:
/// - begin deciding another referendum (and leave `DecidingCount` alone); or /// - begin deciding another referendum (and leave `DecidingCount` alone); or
/// - decrement `DecidingCount`. /// - decrement `DecidingCount`.
#[pallet::weight(OneFewerDecidingBranch::max_weight::<T>())] #[pallet::weight(OneFewerDecidingBranch::max_weight::<T, I>())]
pub fn one_fewer_deciding( pub fn one_fewer_deciding(
origin: OriginFor<T>, origin: OriginFor<T>,
track: TrackIdOf<T>, track: TrackIdOf<T, I>,
) -> DispatchResultWithPostInfo { ) -> DispatchResultWithPostInfo {
ensure_root(origin)?; ensure_root(origin)?;
let track_info = T::Tracks::info(track).ok_or(Error::<T>::BadTrack)?; let track_info = T::Tracks::info(track).ok_or(Error::<T, I>::BadTrack)?;
let mut track_queue = TrackQueue::<T>::get(track); let mut track_queue = TrackQueue::<T, I>::get(track);
let branch = let branch =
if let Some((index, mut status)) = Self::next_for_deciding(&mut track_queue) { if let Some((index, mut status)) = Self::next_for_deciding(&mut track_queue) {
let now = frame_system::Pallet::<T>::block_number(); let now = frame_system::Pallet::<T>::block_number();
@@ -515,23 +529,23 @@ pub mod pallet {
if let Some(set_alarm) = maybe_alarm { if let Some(set_alarm) = maybe_alarm {
Self::ensure_alarm_at(&mut status, index, set_alarm); Self::ensure_alarm_at(&mut status, index, set_alarm);
} }
ReferendumInfoFor::<T>::insert(index, ReferendumInfo::Ongoing(status)); ReferendumInfoFor::<T, I>::insert(index, ReferendumInfo::Ongoing(status));
TrackQueue::<T>::insert(track, track_queue); TrackQueue::<T, I>::insert(track, track_queue);
branch.into() branch.into()
} else { } else {
DecidingCount::<T>::mutate(track, |x| x.saturating_dec()); DecidingCount::<T, I>::mutate(track, |x| x.saturating_dec());
OneFewerDecidingBranch::QueueEmpty OneFewerDecidingBranch::QueueEmpty
}; };
Ok(Some(branch.weight::<T>()).into()) Ok(Some(branch.weight::<T, I>()).into())
} }
} }
} }
impl<T: Config> Polling<T::Tally> for Pallet<T> { impl<T: Config<I>, I: 'static> Polling<T::Tally> for Pallet<T, I> {
type Index = ReferendumIndex; type Index = ReferendumIndex;
type Votes = VotesOf<T>; type Votes = VotesOf<T, I>;
type Moment = T::BlockNumber; type Moment = T::BlockNumber;
type Class = TrackIdOf<T>; type Class = TrackIdOf<T, I>;
fn classes() -> Vec<Self::Class> { fn classes() -> Vec<Self::Class> {
T::Tracks::tracks().iter().map(|x| x.0).collect() T::Tracks::tracks().iter().map(|x| x.0).collect()
@@ -539,14 +553,14 @@ impl<T: Config> Polling<T::Tally> for Pallet<T> {
fn access_poll<R>( fn access_poll<R>(
index: Self::Index, index: Self::Index,
f: impl FnOnce(PollStatus<&mut T::Tally, T::BlockNumber, TrackIdOf<T>>) -> R, f: impl FnOnce(PollStatus<&mut T::Tally, T::BlockNumber, TrackIdOf<T, I>>) -> R,
) -> R { ) -> R {
match ReferendumInfoFor::<T>::get(index) { match ReferendumInfoFor::<T, I>::get(index) {
Some(ReferendumInfo::Ongoing(mut status)) => { Some(ReferendumInfo::Ongoing(mut status)) => {
let result = f(PollStatus::Ongoing(&mut status.tally, status.track)); let result = f(PollStatus::Ongoing(&mut status.tally, status.track));
let now = frame_system::Pallet::<T>::block_number(); let now = frame_system::Pallet::<T>::block_number();
Self::ensure_alarm_at(&mut status, index, now + One::one()); Self::ensure_alarm_at(&mut status, index, now + One::one());
ReferendumInfoFor::<T>::insert(index, ReferendumInfo::Ongoing(status)); ReferendumInfoFor::<T, I>::insert(index, ReferendumInfo::Ongoing(status));
result result
}, },
Some(ReferendumInfo::Approved(end, ..)) => f(PollStatus::Completed(end, true)), Some(ReferendumInfo::Approved(end, ..)) => f(PollStatus::Completed(end, true)),
@@ -558,15 +572,15 @@ impl<T: Config> Polling<T::Tally> for Pallet<T> {
fn try_access_poll<R>( fn try_access_poll<R>(
index: Self::Index, index: Self::Index,
f: impl FnOnce( f: impl FnOnce(
PollStatus<&mut T::Tally, T::BlockNumber, TrackIdOf<T>>, PollStatus<&mut T::Tally, T::BlockNumber, TrackIdOf<T, I>>,
) -> Result<R, DispatchError>, ) -> Result<R, DispatchError>,
) -> Result<R, DispatchError> { ) -> Result<R, DispatchError> {
match ReferendumInfoFor::<T>::get(index) { match ReferendumInfoFor::<T, I>::get(index) {
Some(ReferendumInfo::Ongoing(mut status)) => { Some(ReferendumInfo::Ongoing(mut status)) => {
let result = f(PollStatus::Ongoing(&mut status.tally, status.track))?; let result = f(PollStatus::Ongoing(&mut status.tally, status.track))?;
let now = frame_system::Pallet::<T>::block_number(); let now = frame_system::Pallet::<T>::block_number();
Self::ensure_alarm_at(&mut status, index, now + One::one()); Self::ensure_alarm_at(&mut status, index, now + One::one());
ReferendumInfoFor::<T>::insert(index, ReferendumInfo::Ongoing(status)); ReferendumInfoFor::<T, I>::insert(index, ReferendumInfo::Ongoing(status));
Ok(result) Ok(result)
}, },
Some(ReferendumInfo::Approved(end, ..)) => f(PollStatus::Completed(end, true)), Some(ReferendumInfo::Approved(end, ..)) => f(PollStatus::Completed(end, true)),
@@ -575,13 +589,13 @@ impl<T: Config> Polling<T::Tally> for Pallet<T> {
} }
} }
fn as_ongoing(index: Self::Index) -> Option<(T::Tally, TrackIdOf<T>)> { fn as_ongoing(index: Self::Index) -> Option<(T::Tally, TrackIdOf<T, I>)> {
Self::ensure_ongoing(index).ok().map(|x| (x.tally, x.track)) Self::ensure_ongoing(index).ok().map(|x| (x.tally, x.track))
} }
#[cfg(feature = "runtime-benchmarks")] #[cfg(feature = "runtime-benchmarks")]
fn create_ongoing(class: Self::Class) -> Result<Self::Index, ()> { fn create_ongoing(class: Self::Class) -> Result<Self::Index, ()> {
let index = ReferendumCount::<T>::mutate(|x| { let index = ReferendumCount::<T, I>::mutate(|x| {
let r = *x; let r = *x;
*x += 1; *x += 1;
r r
@@ -590,7 +604,7 @@ impl<T: Config> Polling<T::Tally> for Pallet<T> {
let dummy_account_id = let dummy_account_id =
codec::Decode::decode(&mut sp_runtime::traits::TrailingZeroInput::new(&b"dummy"[..])) codec::Decode::decode(&mut sp_runtime::traits::TrailingZeroInput::new(&b"dummy"[..]))
.expect("infinite length input; no invalid inputs for type; qed"); .expect("infinite length input; no invalid inputs for type; qed");
let mut status = ReferendumStatusOf::<T> { let mut status = ReferendumStatusOf::<T, I> {
track: class, track: class,
origin: frame_support::dispatch::RawOrigin::Root.into(), origin: frame_support::dispatch::RawOrigin::Root.into(),
proposal_hash: <T::Hashing as sp_runtime::traits::Hash>::hash_of(&index), proposal_hash: <T::Hashing as sp_runtime::traits::Hash>::hash_of(&index),
@@ -604,7 +618,7 @@ impl<T: Config> Polling<T::Tally> for Pallet<T> {
alarm: None, alarm: None,
}; };
Self::ensure_alarm_at(&mut status, index, sp_runtime::traits::Bounded::max_value()); Self::ensure_alarm_at(&mut status, index, sp_runtime::traits::Bounded::max_value());
ReferendumInfoFor::<T>::insert(index, ReferendumInfo::Ongoing(status)); ReferendumInfoFor::<T, I>::insert(index, ReferendumInfo::Ongoing(status));
Ok(index) Ok(index)
} }
@@ -619,7 +633,7 @@ impl<T: Config> Polling<T::Tally> for Pallet<T> {
} else { } else {
ReferendumInfo::Rejected(now, status.submission_deposit, status.decision_deposit) ReferendumInfo::Rejected(now, status.submission_deposit, status.decision_deposit)
}; };
ReferendumInfoFor::<T>::insert(index, info); ReferendumInfoFor::<T, I>::insert(index, info);
Ok(()) Ok(())
} }
@@ -633,20 +647,22 @@ impl<T: Config> Polling<T::Tally> for Pallet<T> {
} }
} }
impl<T: Config> Pallet<T> { impl<T: Config<I>, I: 'static> Pallet<T, I> {
/// Check that referendum `index` is in the `Ongoing` state and return the `ReferendumStatus` /// Check that referendum `index` is in the `Ongoing` state and return the `ReferendumStatus`
/// value, or `Err` otherwise. /// value, or `Err` otherwise.
pub fn ensure_ongoing(index: ReferendumIndex) -> Result<ReferendumStatusOf<T>, DispatchError> { pub fn ensure_ongoing(
match ReferendumInfoFor::<T>::get(index) { index: ReferendumIndex,
) -> Result<ReferendumStatusOf<T, I>, DispatchError> {
match ReferendumInfoFor::<T, I>::get(index) {
Some(ReferendumInfo::Ongoing(status)) => Ok(status), Some(ReferendumInfo::Ongoing(status)) => Ok(status),
_ => Err(Error::<T>::NotOngoing.into()), _ => Err(Error::<T, I>::NotOngoing.into()),
} }
} }
// Enqueue a proposal from a referendum which has presumably passed. // Enqueue a proposal from a referendum which has presumably passed.
fn schedule_enactment( fn schedule_enactment(
index: ReferendumIndex, index: ReferendumIndex,
track: &TrackInfoOf<T>, track: &TrackInfoOf<T, I>,
desired: DispatchTime<T::BlockNumber>, desired: DispatchTime<T::BlockNumber>,
origin: PalletsOriginOf<T>, origin: PalletsOriginOf<T>,
call_hash: T::Hash, call_hash: T::Hash,
@@ -668,9 +684,9 @@ impl<T: Config> Pallet<T> {
/// Set an alarm to dispatch `call` at block number `when`. /// Set an alarm to dispatch `call` at block number `when`.
fn set_alarm( fn set_alarm(
call: impl Into<CallOf<T>>, call: impl Into<CallOf<T, I>>,
when: T::BlockNumber, when: T::BlockNumber,
) -> Option<(T::BlockNumber, ScheduleAddressOf<T>)> { ) -> Option<(T::BlockNumber, ScheduleAddressOf<T, I>)> {
let alarm_interval = T::AlarmInterval::get().max(One::one()); let alarm_interval = T::AlarmInterval::get().max(One::one());
let when = (when + alarm_interval - One::one()) / alarm_interval * alarm_interval; let when = (when + alarm_interval - One::one()) / alarm_interval * alarm_interval;
let maybe_result = T::Scheduler::schedule( let maybe_result = T::Scheduler::schedule(
@@ -698,10 +714,10 @@ impl<T: Config> Pallet<T> {
/// ///
/// This will properly set up the `confirming` item. /// This will properly set up the `confirming` item.
fn begin_deciding( fn begin_deciding(
status: &mut ReferendumStatusOf<T>, status: &mut ReferendumStatusOf<T, I>,
index: ReferendumIndex, index: ReferendumIndex,
now: T::BlockNumber, now: T::BlockNumber,
track: &TrackInfoOf<T>, track: &TrackInfoOf<T, I>,
) -> (Option<T::BlockNumber>, BeginDecidingBranch) { ) -> (Option<T::BlockNumber>, BeginDecidingBranch) {
let is_passing = Self::is_passing( let is_passing = Self::is_passing(
&status.tally, &status.tally,
@@ -711,14 +727,14 @@ impl<T: Config> Pallet<T> {
&track.min_approval, &track.min_approval,
); );
status.in_queue = false; status.in_queue = false;
Self::deposit_event(Event::<T>::DecisionStarted { Self::deposit_event(Event::<T, I>::DecisionStarted {
index, index,
tally: status.tally.clone(), tally: status.tally.clone(),
proposal_hash: status.proposal_hash.clone(), proposal_hash: status.proposal_hash.clone(),
track: status.track.clone(), track: status.track.clone(),
}); });
let confirming = if is_passing { let confirming = if is_passing {
Self::deposit_event(Event::<T>::ConfirmStarted { index }); Self::deposit_event(Event::<T, I>::ConfirmStarted { index });
Some(now.saturating_add(track.confirm_period)) Some(now.saturating_add(track.confirm_period))
} else { } else {
None None
@@ -737,21 +753,21 @@ impl<T: Config> Pallet<T> {
/// If `None`, then it is queued and should be nudged automatically as the queue gets drained. /// If `None`, then it is queued and should be nudged automatically as the queue gets drained.
fn ready_for_deciding( fn ready_for_deciding(
now: T::BlockNumber, now: T::BlockNumber,
track: &TrackInfoOf<T>, track: &TrackInfoOf<T, I>,
index: ReferendumIndex, index: ReferendumIndex,
status: &mut ReferendumStatusOf<T>, status: &mut ReferendumStatusOf<T, I>,
) -> (Option<T::BlockNumber>, ServiceBranch) { ) -> (Option<T::BlockNumber>, ServiceBranch) {
let deciding_count = DecidingCount::<T>::get(status.track); let deciding_count = DecidingCount::<T, I>::get(status.track);
if deciding_count < track.max_deciding { if deciding_count < track.max_deciding {
// Begin deciding. // Begin deciding.
DecidingCount::<T>::insert(status.track, deciding_count.saturating_add(1)); DecidingCount::<T, I>::insert(status.track, deciding_count.saturating_add(1));
let r = Self::begin_deciding(status, index, now, track); let r = Self::begin_deciding(status, index, now, track);
(r.0, r.1.into()) (r.0, r.1.into())
} else { } else {
// Add to queue. // Add to queue.
let item = (index, status.tally.ayes()); let item = (index, status.tally.ayes());
status.in_queue = true; status.in_queue = true;
TrackQueue::<T>::mutate(status.track, |q| q.insert_sorted_by_key(item, |x| x.1)); TrackQueue::<T, I>::mutate(status.track, |q| q.insert_sorted_by_key(item, |x| x.1));
(None, ServiceBranch::Queued) (None, ServiceBranch::Queued)
} }
} }
@@ -759,8 +775,8 @@ impl<T: Config> Pallet<T> {
/// Grab the index and status for the referendum which is the highest priority of those for the /// Grab the index and status for the referendum which is the highest priority of those for the
/// given track which are ready for being decided. /// given track which are ready for being decided.
fn next_for_deciding( fn next_for_deciding(
track_queue: &mut BoundedVec<(u32, VotesOf<T>), T::MaxQueued>, track_queue: &mut BoundedVec<(u32, VotesOf<T, I>), T::MaxQueued>,
) -> Option<(ReferendumIndex, ReferendumStatusOf<T>)> { ) -> Option<(ReferendumIndex, ReferendumStatusOf<T, I>)> {
loop { loop {
let (index, _) = track_queue.pop()?; let (index, _) = track_queue.pop()?;
match Self::ensure_ongoing(index) { match Self::ensure_ongoing(index) {
@@ -773,7 +789,7 @@ impl<T: Config> Pallet<T> {
/// Schedule a call to `one_fewer_deciding` function via the dispatchable /// Schedule a call to `one_fewer_deciding` function via the dispatchable
/// `defer_one_fewer_deciding`. We could theoretically call it immediately (and it would be /// `defer_one_fewer_deciding`. We could theoretically call it immediately (and it would be
/// overall more efficient), however the weights become rather less easy to measure. /// overall more efficient), however the weights become rather less easy to measure.
fn note_one_fewer_deciding(track: TrackIdOf<T>) { fn note_one_fewer_deciding(track: TrackIdOf<T, I>) {
// Set an alarm call for the next block to nudge the track along. // Set an alarm call for the next block to nudge the track along.
let now = frame_system::Pallet::<T>::block_number(); let now = frame_system::Pallet::<T>::block_number();
let next_block = now + One::one(); let next_block = now + One::one();
@@ -801,7 +817,7 @@ impl<T: Config> Pallet<T> {
/// ///
/// Returns `false` if nothing changed. /// Returns `false` if nothing changed.
fn ensure_alarm_at( fn ensure_alarm_at(
status: &mut ReferendumStatusOf<T>, status: &mut ReferendumStatusOf<T, I>,
index: ReferendumIndex, index: ReferendumIndex,
alarm: T::BlockNumber, alarm: T::BlockNumber,
) -> bool { ) -> bool {
@@ -839,8 +855,8 @@ impl<T: Config> Pallet<T> {
fn service_referendum( fn service_referendum(
now: T::BlockNumber, now: T::BlockNumber,
index: ReferendumIndex, index: ReferendumIndex,
mut status: ReferendumStatusOf<T>, mut status: ReferendumStatusOf<T, I>,
) -> (ReferendumInfoOf<T>, bool, ServiceBranch) { ) -> (ReferendumInfoOf<T, I>, bool, ServiceBranch) {
let mut dirty = false; let mut dirty = false;
// Should it begin being decided? // Should it begin being decided?
let track = match Self::track(status.track) { let track = match Self::track(status.track) {
@@ -857,7 +873,7 @@ impl<T: Config> Pallet<T> {
if status.in_queue { if status.in_queue {
// Does our position in the queue need updating? // Does our position in the queue need updating?
let ayes = status.tally.ayes(); let ayes = status.tally.ayes();
let mut queue = TrackQueue::<T>::get(status.track); let mut queue = TrackQueue::<T, I>::get(status.track);
let maybe_old_pos = queue.iter().position(|(x, _)| *x == index); let maybe_old_pos = queue.iter().position(|(x, _)| *x == index);
let new_pos = queue.binary_search_by_key(&ayes, |x| x.1).unwrap_or_else(|x| x); let new_pos = queue.binary_search_by_key(&ayes, |x| x.1).unwrap_or_else(|x| x);
branch = if maybe_old_pos.is_none() && new_pos > 0 { branch = if maybe_old_pos.is_none() && new_pos > 0 {
@@ -872,7 +888,7 @@ impl<T: Config> Pallet<T> {
} else { } else {
ServiceBranch::NotQueued ServiceBranch::NotQueued
}; };
TrackQueue::<T>::insert(status.track, queue); TrackQueue::<T, I>::insert(status.track, queue);
} else { } else {
// Are we ready for deciding? // Are we ready for deciding?
branch = if status.decision_deposit.is_some() { branch = if status.decision_deposit.is_some() {
@@ -897,7 +913,7 @@ impl<T: Config> Pallet<T> {
if status.deciding.is_none() && now >= timeout { if status.deciding.is_none() && now >= timeout {
// Too long without being decided - end it. // Too long without being decided - end it.
Self::ensure_no_alarm(&mut status); Self::ensure_no_alarm(&mut status);
Self::deposit_event(Event::<T>::TimedOut { index, tally: status.tally }); Self::deposit_event(Event::<T, I>::TimedOut { index, tally: status.tally });
return ( return (
ReferendumInfo::TimedOut( ReferendumInfo::TimedOut(
now, now,
@@ -931,7 +947,7 @@ impl<T: Config> Pallet<T> {
status.origin, status.origin,
call_hash, call_hash,
); );
Self::deposit_event(Event::<T>::Confirmed { Self::deposit_event(Event::<T, I>::Confirmed {
index, index,
tally: status.tally, tally: status.tally,
}); });
@@ -950,7 +966,7 @@ impl<T: Config> Pallet<T> {
// Start confirming // Start confirming
dirty = true; dirty = true;
deciding.confirming = Some(now.saturating_add(track.confirm_period)); deciding.confirming = Some(now.saturating_add(track.confirm_period));
Self::deposit_event(Event::<T>::ConfirmStarted { index }); Self::deposit_event(Event::<T, I>::ConfirmStarted { index });
ServiceBranch::BeginConfirming ServiceBranch::BeginConfirming
}, },
} }
@@ -959,7 +975,7 @@ impl<T: Config> Pallet<T> {
// Failed! // Failed!
Self::ensure_no_alarm(&mut status); Self::ensure_no_alarm(&mut status);
Self::note_one_fewer_deciding(status.track); Self::note_one_fewer_deciding(status.track);
Self::deposit_event(Event::<T>::Rejected { index, tally: status.tally }); Self::deposit_event(Event::<T, I>::Rejected { index, tally: status.tally });
return ( return (
ReferendumInfo::Rejected( ReferendumInfo::Rejected(
now, now,
@@ -974,7 +990,7 @@ impl<T: Config> Pallet<T> {
// Stop confirming // Stop confirming
dirty = true; dirty = true;
deciding.confirming = None; deciding.confirming = None;
Self::deposit_event(Event::<T>::ConfirmAborted { index }); Self::deposit_event(Event::<T, I>::ConfirmAborted { index });
ServiceBranch::EndConfirming ServiceBranch::EndConfirming
} else { } else {
ServiceBranch::ContinueNotConfirming ServiceBranch::ContinueNotConfirming
@@ -993,7 +1009,7 @@ impl<T: Config> Pallet<T> {
fn decision_time( fn decision_time(
deciding: &DecidingStatusOf<T>, deciding: &DecidingStatusOf<T>,
tally: &T::Tally, tally: &T::Tally,
track: &TrackInfoOf<T>, track: &TrackInfoOf<T, I>,
) -> T::BlockNumber { ) -> T::BlockNumber {
deciding.confirming.unwrap_or_else(|| { deciding.confirming.unwrap_or_else(|| {
// Set alarm to the point where the current voting would make it pass. // Set alarm to the point where the current voting would make it pass.
@@ -1007,7 +1023,7 @@ impl<T: Config> Pallet<T> {
} }
/// Cancel the alarm in `status`, if one exists. /// Cancel the alarm in `status`, if one exists.
fn ensure_no_alarm(status: &mut ReferendumStatusOf<T>) { fn ensure_no_alarm(status: &mut ReferendumStatusOf<T, I>) {
if let Some((_, last_alarm)) = status.alarm.take() { if let Some((_, last_alarm)) = status.alarm.take() {
// Incorrect alarm - cancel it. // Incorrect alarm - cancel it.
let _ = T::Scheduler::cancel(last_alarm); let _ = T::Scheduler::cancel(last_alarm);
@@ -1017,29 +1033,29 @@ impl<T: Config> Pallet<T> {
/// Reserve a deposit and return the `Deposit` instance. /// Reserve a deposit and return the `Deposit` instance.
fn take_deposit( fn take_deposit(
who: T::AccountId, who: T::AccountId,
amount: BalanceOf<T>, amount: BalanceOf<T, I>,
) -> Result<Deposit<T::AccountId, BalanceOf<T>>, DispatchError> { ) -> Result<Deposit<T::AccountId, BalanceOf<T, I>>, DispatchError> {
T::Currency::reserve(&who, amount)?; T::Currency::reserve(&who, amount)?;
Ok(Deposit { who, amount }) Ok(Deposit { who, amount })
} }
/// Return a deposit, if `Some`. /// Return a deposit, if `Some`.
fn refund_deposit(deposit: Option<Deposit<T::AccountId, BalanceOf<T>>>) { fn refund_deposit(deposit: Option<Deposit<T::AccountId, BalanceOf<T, I>>>) {
if let Some(Deposit { who, amount }) = deposit { if let Some(Deposit { who, amount }) = deposit {
T::Currency::unreserve(&who, amount); T::Currency::unreserve(&who, amount);
} }
} }
/// Slash a deposit, if `Some`. /// Slash a deposit, if `Some`.
fn slash_deposit(deposit: Option<Deposit<T::AccountId, BalanceOf<T>>>) { fn slash_deposit(deposit: Option<Deposit<T::AccountId, BalanceOf<T, I>>>) {
if let Some(Deposit { who, amount }) = deposit { if let Some(Deposit { who, amount }) = deposit {
T::Slash::on_unbalanced(T::Currency::slash_reserved(&who, amount).0); T::Slash::on_unbalanced(T::Currency::slash_reserved(&who, amount).0);
Self::deposit_event(Event::<T>::DepositSlashed { who, amount }); Self::deposit_event(Event::<T, I>::DepositSlashed { who, amount });
} }
} }
/// Get the track info value for the track `id`. /// Get the track info value for the track `id`.
fn track(id: TrackIdOf<T>) -> Option<&'static TrackInfoOf<T>> { fn track(id: TrackIdOf<T, I>) -> Option<&'static TrackInfoOf<T, I>> {
let tracks = T::Tracks::tracks(); let tracks = T::Tracks::tracks();
let index = tracks.binary_search_by_key(&id, |x| x.0).unwrap_or_else(|x| x); let index = tracks.binary_search_by_key(&id, |x| x.0).unwrap_or_else(|x| x);
Some(&tracks[index].1) Some(&tracks[index].1)
+22 -21
View File
@@ -24,44 +24,45 @@ use scale_info::TypeInfo;
use sp_runtime::RuntimeDebug; use sp_runtime::RuntimeDebug;
use sp_std::fmt::Debug; use sp_std::fmt::Debug;
pub type BalanceOf<T> = pub type BalanceOf<T, I = ()> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance; <<T as Config<I>>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
pub type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency< pub type NegativeImbalanceOf<T, I> = <<T as Config<I>>::Currency as Currency<
<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId,
>>::NegativeImbalance; >>::NegativeImbalance;
pub type CallOf<T> = <T as Config>::Call; pub type CallOf<T, I> = <T as Config<I>>::Call;
pub type VotesOf<T> = <T as Config>::Votes; pub type VotesOf<T, I> = <T as Config<I>>::Votes;
pub type TallyOf<T> = <T as Config>::Tally; pub type TallyOf<T, I> = <T as Config<I>>::Tally;
pub type PalletsOriginOf<T> = <<T as frame_system::Config>::Origin as OriginTrait>::PalletsOrigin; pub type PalletsOriginOf<T> = <<T as frame_system::Config>::Origin as OriginTrait>::PalletsOrigin;
pub type ReferendumInfoOf<T> = ReferendumInfo< pub type ReferendumInfoOf<T, I> = ReferendumInfo<
TrackIdOf<T>, TrackIdOf<T, I>,
PalletsOriginOf<T>, PalletsOriginOf<T>,
<T as frame_system::Config>::BlockNumber, <T as frame_system::Config>::BlockNumber,
<T as frame_system::Config>::Hash, <T as frame_system::Config>::Hash,
BalanceOf<T>, BalanceOf<T, I>,
TallyOf<T>, TallyOf<T, I>,
<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId,
ScheduleAddressOf<T>, ScheduleAddressOf<T, I>,
>; >;
pub type ReferendumStatusOf<T> = ReferendumStatus< pub type ReferendumStatusOf<T, I> = ReferendumStatus<
TrackIdOf<T>, TrackIdOf<T, I>,
PalletsOriginOf<T>, PalletsOriginOf<T>,
<T as frame_system::Config>::BlockNumber, <T as frame_system::Config>::BlockNumber,
<T as frame_system::Config>::Hash, <T as frame_system::Config>::Hash,
BalanceOf<T>, BalanceOf<T, I>,
TallyOf<T>, TallyOf<T, I>,
<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId,
ScheduleAddressOf<T>, ScheduleAddressOf<T, I>,
>; >;
pub type DecidingStatusOf<T> = DecidingStatus<<T as frame_system::Config>::BlockNumber>; pub type DecidingStatusOf<T> = DecidingStatus<<T as frame_system::Config>::BlockNumber>;
pub type TrackInfoOf<T> = TrackInfo<BalanceOf<T>, <T as frame_system::Config>::BlockNumber>; pub type TrackInfoOf<T, I = ()> =
pub type TrackIdOf<T> = <<T as Config>::Tracks as TracksInfo< TrackInfo<BalanceOf<T, I>, <T as frame_system::Config>::BlockNumber>;
BalanceOf<T>, pub type TrackIdOf<T, I> = <<T as Config<I>>::Tracks as TracksInfo<
BalanceOf<T, I>,
<T as frame_system::Config>::BlockNumber, <T as frame_system::Config>::BlockNumber,
>>::Id; >>::Id;
pub type ScheduleAddressOf<T> = <<T as Config>::Scheduler as Anon< pub type ScheduleAddressOf<T, I> = <<T as Config<I>>::Scheduler as Anon<
<T as frame_system::Config>::BlockNumber, <T as frame_system::Config>::BlockNumber,
CallOf<T>, CallOf<T, I>,
PalletsOriginOf<T>, PalletsOriginOf<T>,
>>::Address; >>::Address;