mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 03:31:05 +00:00
better way to resolve Phase::Emergency via governance (#10663)
* better way to resolve Phase::Emergency via governance * Update frame/election-provider-multi-phase/src/lib.rs Co-authored-by: Zeke Mostov <z.mostov@gmail.com> * review grumbles * Update frame/election-provider-support/src/onchain.rs Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> * revert usize -> u32 Co-authored-by: Zeke Mostov <z.mostov@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com>
This commit is contained in:
@@ -319,6 +319,22 @@ pub trait ElectionProvider {
|
||||
fn elect() -> Result<Supports<Self::AccountId>, Self::Error>;
|
||||
}
|
||||
|
||||
/// A sub-trait of the [`ElectionProvider`] for cases where we need to be sure an election needs to
|
||||
/// happen instantly, not asynchronously.
|
||||
///
|
||||
/// The same `DataProvider` is assumed to be used.
|
||||
///
|
||||
/// Consequently, allows for control over the amount of data that is being fetched from the
|
||||
/// [`ElectionProvider::DataProvider`].
|
||||
pub trait InstantElectionProvider: ElectionProvider {
|
||||
/// Elect a new set of winners, instantly, with the given given limits set on the
|
||||
/// `DataProvider`.
|
||||
fn instant_elect(
|
||||
maybe_max_voters: Option<usize>,
|
||||
maybe_max_targets: Option<usize>,
|
||||
) -> Result<Supports<Self::AccountId>, Self::Error>;
|
||||
}
|
||||
|
||||
/// An election provider to be used only for testing.
|
||||
#[cfg(feature = "std")]
|
||||
pub struct NoElection<X>(sp_std::marker::PhantomData<X>);
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
//! An implementation of [`ElectionProvider`] that does an on-chain sequential phragmen.
|
||||
|
||||
use crate::{ElectionDataProvider, ElectionProvider};
|
||||
use crate::{ElectionDataProvider, ElectionProvider, InstantElectionProvider};
|
||||
use frame_support::{traits::Get, weights::DispatchClass};
|
||||
use sp_npos_elections::*;
|
||||
use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData, prelude::*};
|
||||
@@ -47,8 +47,14 @@ impl From<sp_npos_elections::Error> for Error {
|
||||
/// implementation ignores the additional data of the election data provider and gives no insight on
|
||||
/// how much weight was consumed.
|
||||
///
|
||||
/// Finally, this implementation does not impose any limits on the number of voters and targets that
|
||||
/// are provided.
|
||||
/// Finally, the [`ElectionProvider`] implementation of this type does not impose any limits on the
|
||||
/// number of voters and targets that are fetched. This could potentially make this unsuitable for
|
||||
/// execution onchain. On the other hand, the [`InstantElectionProvider`] implementation does limit
|
||||
/// these inputs.
|
||||
///
|
||||
/// It is advisable to use the former ([`ElectionProvider::elect`]) only at genesis, or for testing,
|
||||
/// the latter [`InstantElectionProvider::instant_elect`] for onchain operations, with thoughtful
|
||||
/// bounds.
|
||||
pub struct OnChainSequentialPhragmen<T: Config>(PhantomData<T>);
|
||||
|
||||
/// Configuration trait of [`OnChainSequentialPhragmen`].
|
||||
@@ -68,16 +74,17 @@ pub trait Config: frame_system::Config {
|
||||
>;
|
||||
}
|
||||
|
||||
impl<T: Config> ElectionProvider for OnChainSequentialPhragmen<T> {
|
||||
type AccountId = T::AccountId;
|
||||
type BlockNumber = T::BlockNumber;
|
||||
type Error = Error;
|
||||
type DataProvider = T::DataProvider;
|
||||
|
||||
fn elect() -> Result<Supports<T::AccountId>, Self::Error> {
|
||||
let voters = Self::DataProvider::voters(None).map_err(Error::DataProvider)?;
|
||||
let targets = Self::DataProvider::targets(None).map_err(Error::DataProvider)?;
|
||||
let desired_targets = Self::DataProvider::desired_targets().map_err(Error::DataProvider)?;
|
||||
impl<T: Config> OnChainSequentialPhragmen<T> {
|
||||
fn elect_with(
|
||||
maybe_max_voters: Option<usize>,
|
||||
maybe_max_targets: Option<usize>,
|
||||
) -> Result<Supports<T::AccountId>, Error> {
|
||||
let voters = <Self as ElectionProvider>::DataProvider::voters(maybe_max_voters)
|
||||
.map_err(Error::DataProvider)?;
|
||||
let targets = <Self as ElectionProvider>::DataProvider::targets(maybe_max_targets)
|
||||
.map_err(Error::DataProvider)?;
|
||||
let desired_targets = <Self as ElectionProvider>::DataProvider::desired_targets()
|
||||
.map_err(Error::DataProvider)?;
|
||||
|
||||
let stake_map: BTreeMap<T::AccountId, VoteWeight> = voters
|
||||
.iter()
|
||||
@@ -102,6 +109,26 @@ impl<T: Config> ElectionProvider for OnChainSequentialPhragmen<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> ElectionProvider for OnChainSequentialPhragmen<T> {
|
||||
type AccountId = T::AccountId;
|
||||
type BlockNumber = T::BlockNumber;
|
||||
type Error = Error;
|
||||
type DataProvider = T::DataProvider;
|
||||
|
||||
fn elect() -> Result<Supports<T::AccountId>, Self::Error> {
|
||||
Self::elect_with(None, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> InstantElectionProvider for OnChainSequentialPhragmen<T> {
|
||||
fn instant_elect(
|
||||
maybe_max_voters: Option<usize>,
|
||||
maybe_max_targets: Option<usize>,
|
||||
) -> Result<Supports<Self::AccountId>, Self::Error> {
|
||||
Self::elect_with(maybe_max_voters, maybe_max_targets)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user