Create trait for NPoS election algorithms (#9664)

* build the template, hand it over to zeke now.

* Tests working

* save wip

* Some updates

* Some cleanup

* mo cleanin

* Link to issue

* Apply suggestions from code review

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Apply suggestions from code review

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Bound accuracy for prepare_election_result

* Use npos_election::Error for phragmms

* save

* Apply suggestions from code review

* Simplify test to use Balancing::set

* Cargo.lock after build

* Revert "Cargo.lock after build"

This reverts commit 7d726c8efa687c09e4f377196b106eb9e9760487.

* Try reduce cargo.lock diff

* Update bin/node/runtime/src/lib.rs

* Comment

* Apply suggestions from code review

* Set balancing directly

* Document som pub items

* Update frame/election-provider-multi-phase/src/unsigned.rs

* Apply suggestions from code review

Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>

* Improve some comments

* Revert accidental change to random file

* tiney

* revert

Co-authored-by: kianenigma <kian@parity.io>
Co-authored-by: Kian Paimani <5588131+kianenigma@users.noreply.github.com>
This commit is contained in:
Zeke Mostov
2021-09-09 12:46:24 -07:00
committed by GitHub
parent d1c281461d
commit 6bfcfeed4c
10 changed files with 203 additions and 105 deletions
@@ -485,13 +485,13 @@ pub struct SolutionOrSnapshotSize {
/// Internal errors of the pallet.
///
/// Note that this is different from [`pallet::Error`].
#[derive(Debug, Eq, PartialEq)]
#[derive(frame_support::DebugNoBound, frame_support::PartialEqNoBound)]
#[cfg_attr(feature = "runtime-benchmarks", derive(strum_macros::IntoStaticStr))]
pub enum ElectionError {
pub enum ElectionError<T: Config> {
/// An error happened in the feasibility check sub-system.
Feasibility(FeasibilityError),
/// An error in the miner (offchain) sub-system.
Miner(unsigned::MinerError),
Miner(unsigned::MinerError<T>),
/// An error in the on-chain fallback.
OnChainFallback(onchain::Error),
/// An error happened in the data provider.
@@ -500,20 +500,20 @@ pub enum ElectionError {
NoFallbackConfigured,
}
impl From<onchain::Error> for ElectionError {
impl<T: Config> From<onchain::Error> for ElectionError<T> {
fn from(e: onchain::Error) -> Self {
ElectionError::OnChainFallback(e)
}
}
impl From<FeasibilityError> for ElectionError {
impl<T: Config> From<FeasibilityError> for ElectionError<T> {
fn from(e: FeasibilityError) -> Self {
ElectionError::Feasibility(e)
}
}
impl From<unsigned::MinerError> for ElectionError {
fn from(e: unsigned::MinerError) -> Self {
impl<T: Config> From<unsigned::MinerError<T>> for ElectionError<T> {
fn from(e: unsigned::MinerError<T>) -> Self {
ElectionError::Miner(e)
}
}
@@ -555,6 +555,7 @@ pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_election_provider_support::NposSolver;
use frame_support::{pallet_prelude::*, traits::EstimateCallFee};
use frame_system::pallet_prelude::*;
@@ -592,10 +593,6 @@ pub mod pallet {
/// The priority of the unsigned transaction submitted in the unsigned-phase
#[pallet::constant]
type MinerTxPriority: Get<TransactionPriority>;
/// Maximum number of iteration of balancing that will be executed in the embedded miner of
/// the pallet.
#[pallet::constant]
type MinerMaxIterations: Get<u32>;
/// Maximum weight that the miner should consume.
///
@@ -668,6 +665,9 @@ pub mod pallet {
/// Configuration for the fallback
type Fallback: Get<FallbackStrategy>;
/// OCW election solution miner algorithm implementation.
type Solver: NposSolver<AccountId = Self::AccountId>;
/// Origin that can control this pallet. Note that any action taken by this origin (such)
/// as providing an emergency solution is not checked. Thus, it must be a trusted origin.
type ForceOrigin: EnsureOrigin<Self::Origin>;
@@ -1298,7 +1298,7 @@ impl<T: Config> Pallet<T> {
///
/// Extracted for easier weight calculation.
fn create_snapshot_external(
) -> Result<(Vec<T::AccountId>, Vec<crate::unsigned::Voter<T>>, u32), ElectionError> {
) -> Result<(Vec<T::AccountId>, Vec<crate::unsigned::Voter<T>>, u32), ElectionError<T>> {
let target_limit = <SolutionTargetIndexOf<T>>::max_value().saturated_into::<usize>();
let voter_limit = <SolutionVoterIndexOf<T>>::max_value().saturated_into::<usize>();
@@ -1328,7 +1328,7 @@ impl<T: Config> Pallet<T> {
///
/// This is a *self-weighing* function, it will register its own extra weight as
/// [`DispatchClass::Mandatory`] with the system pallet.
pub fn create_snapshot() -> Result<(), ElectionError> {
pub fn create_snapshot() -> Result<(), ElectionError<T>> {
// this is self-weighing itself..
let (targets, voters, desired_targets) = Self::create_snapshot_external()?;
@@ -1471,7 +1471,7 @@ impl<T: Config> Pallet<T> {
}
/// On-chain fallback of election.
fn onchain_fallback() -> Result<Supports<T::AccountId>, ElectionError> {
fn onchain_fallback() -> Result<Supports<T::AccountId>, ElectionError<T>> {
<onchain::OnChainSequentialPhragmen<OnChainConfig<T>> as ElectionProvider<
T::AccountId,
T::BlockNumber,
@@ -1479,7 +1479,7 @@ impl<T: Config> Pallet<T> {
.map_err(Into::into)
}
fn do_elect() -> Result<Supports<T::AccountId>, ElectionError> {
fn do_elect() -> Result<Supports<T::AccountId>, ElectionError<T>> {
// We have to unconditionally try finalizing the signed phase here. There are only two
// possibilities:
//
@@ -1530,7 +1530,7 @@ impl<T: Config> Pallet<T> {
}
impl<T: Config> ElectionProvider<T::AccountId, T::BlockNumber> for Pallet<T> {
type Error = ElectionError;
type Error = ElectionError<T>;
type DataProvider = T::DataProvider;
fn elect() -> Result<Supports<T::AccountId>, Self::Error> {
@@ -2013,7 +2013,10 @@ mod tests {
roll_to(15);
assert_eq!(MultiPhase::current_phase(), Phase::Signed);
let (solution, _) = MultiPhase::mine_solution(2).unwrap();
// set the solution balancing to get the desired score.
crate::mock::Balancing::set(Some((2, 0)));
let (solution, _) = MultiPhase::mine_solution::<<Runtime as Config>::Solver>().unwrap();
// Default solution has a score of [50, 100, 5000].
assert_eq!(solution.score, [50, 100, 5000]);