chore: regenerate umbrella crate, fix feature propagation
This commit is contained in:
@@ -271,7 +271,8 @@ mod benchmarks {
|
||||
#[block]
|
||||
{
|
||||
// fallback might decide to fail, that's okay..
|
||||
let maybe_err = Pezpallet::<T>::manage(origin, crate::ManagerOperation::EmergencyFallback);
|
||||
let maybe_err =
|
||||
Pezpallet::<T>::manage(origin, crate::ManagerOperation::EmergencyFallback);
|
||||
//.. but it cannot be bad origin.
|
||||
assert!(maybe_err.is_ok() || maybe_err.unwrap_err() != DispatchError::BadOrigin.into());
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
|
||||
//! # Multi-phase, multi-block, election provider pezpallet.
|
||||
//!
|
||||
//! > This pezpallet is sometimes abbreviated as `EPMB`, and `pezpallet_election_provider_multi_phase` as
|
||||
//! > This pezpallet is sometimes abbreviated as `EPMB`, and
|
||||
//! > `pezpallet_election_provider_multi_phase` as
|
||||
//! > `EPM`.
|
||||
//!
|
||||
//! ## Overall idea
|
||||
@@ -35,16 +36,16 @@
|
||||
//! with large enough blocks (in a dedicated teyrchain), the number of voters included in the NPoS
|
||||
//! system can grow significantly (yet, obviously not indefinitely).
|
||||
//!
|
||||
//! Note that this pezpallet does not consider how the recipient is processing the results. To ensure
|
||||
//! scalability, the recipient of this pezpallet's data (i.e. `pezpallet-staking`) must also be capable of
|
||||
//! pagination and multi-block processing.
|
||||
//! Note that this pezpallet does not consider how the recipient is processing the results. To
|
||||
//! ensure scalability, the recipient of this pezpallet's data (i.e. `pezpallet-staking`) must also
|
||||
//! be capable of pagination and multi-block processing.
|
||||
//!
|
||||
//! ## Companion pallets
|
||||
//!
|
||||
//! This pezpallet will only function in a sensible way if it is peered with its companion pallets.
|
||||
//!
|
||||
//! - The [`verifier`] pezpallet provides a standard implementation of the [`verifier::Verifier`]. This
|
||||
//! pezpallet is mandatory.
|
||||
//! - The [`verifier`] pezpallet provides a standard implementation of the [`verifier::Verifier`].
|
||||
//! This pezpallet is mandatory.
|
||||
//! - The [`unsigned`] module provides the implementation of unsigned submission by validators. If
|
||||
//! this pezpallet is included, then [`Config::UnsignedPhase`] will determine its duration.
|
||||
//! - The [`signed`] module provides the implementation of the signed submission by any account. If
|
||||
@@ -61,8 +62,8 @@
|
||||
//!
|
||||
//! ### Pezpallet Ordering:
|
||||
//!
|
||||
//! TODO: @kiaenigma: this needs clarification and a enforcement. Signed pezpallet should come first.
|
||||
//! Fixing this should yield removing `verifier_done` from the phase transition.
|
||||
//! TODO: @kiaenigma: this needs clarification and a enforcement. Signed pezpallet should come
|
||||
//! first. Fixing this should yield removing `verifier_done` from the phase transition.
|
||||
//!
|
||||
//! The ordering of these pallets in a runtime should be:
|
||||
//! * parent
|
||||
@@ -76,11 +77,11 @@
|
||||
//!
|
||||
//! ## Pagination
|
||||
//!
|
||||
//! Most of the external APIs of this pezpallet are paginated. All pagination follow a pattern where if
|
||||
//! `N` pages exist, the first paginated call is `function(N-1)` and the last one is `function(0)`.
|
||||
//! For example, with 3 pages, the `elect` of [`ElectionProvider`] is expected to be called as
|
||||
//! `elect(2) -> elect(1) -> elect(0)`. In essence, calling a paginated function with index 0 is
|
||||
//! always a signal of termination, meaning that no further calls will follow.
|
||||
//! Most of the external APIs of this pezpallet are paginated. All pagination follow a pattern where
|
||||
//! if `N` pages exist, the first paginated call is `function(N-1)` and the last one is
|
||||
//! `function(0)`. For example, with 3 pages, the `elect` of [`ElectionProvider`] is expected to be
|
||||
//! called as `elect(2) -> elect(1) -> elect(0)`. In essence, calling a paginated function with
|
||||
//! index 0 is always a signal of termination, meaning that no further calls will follow.
|
||||
//!
|
||||
//! The snapshot creation for voters (Nominators in staking), submission of signed pages, validation
|
||||
//! of signed solutions and exporting of pages are all paginated. Note that this pezpallet is yet to
|
||||
@@ -95,8 +96,8 @@
|
||||
//! ## Phases
|
||||
//!
|
||||
//! The operations in this pezpallet are divided intor rounds, a `u32` number stored in [`Round`].
|
||||
//! This value helps this pezpallet organize itself, and leaves the door open for lazy deletion of any
|
||||
//! stale data. A round, under the happy path, starts by receiving the call to
|
||||
//! This value helps this pezpallet organize itself, and leaves the door open for lazy deletion of
|
||||
//! any stale data. A round, under the happy path, starts by receiving the call to
|
||||
//! [`ElectionProvider::start`], and is terminated by receiving a call to
|
||||
//! [`ElectionProvider::elect`] with value 0.
|
||||
//!
|
||||
@@ -124,7 +125,8 @@
|
||||
//! * [`Config::Pages`] calls to elect are expected, but all in all the pezpallet will close a round
|
||||
//! once `elect(0)` is called.
|
||||
//!
|
||||
//! > Given this, it is rather important for the user of this pezpallet to ensure it always terminates
|
||||
//! > Given this, it is rather important for the user of this pezpallet to ensure it always
|
||||
//! > terminates
|
||||
//! > election via `elect` before requesting a new one.
|
||||
//!
|
||||
//! ## Feasible Solution (correct solution)
|
||||
@@ -149,8 +151,8 @@
|
||||
//!
|
||||
//! 1. Do nothing: [`Continue`]
|
||||
//! 2. Force us into the emergency phase: [`crate::InitiateEmergencyPhase`]. This initiates
|
||||
//! [`Phase::Emergency`], which will halt almost all operations of this pezpallet, and it can only
|
||||
//! be recovered by [`AdminOperation`], dispatched via [`Call::manage`].
|
||||
//! [`Phase::Emergency`], which will halt almost all operations of this pezpallet, and it can
|
||||
//! only be recovered by [`AdminOperation`], dispatched via [`Call::manage`].
|
||||
//! 3. compute an onchain from the give page of snapshot.
|
||||
//!
|
||||
//! Note that configuring the fallback to be onchain computation is not recommended, unless for
|
||||
@@ -182,16 +184,16 @@
|
||||
// - Naming convention is: `${singular}_page` for singular, e.g. `voter_page` for `Vec<Voter>`.
|
||||
// `paged_${plural}` for plural, e.g. `paged_voters` for `Vec<Vec<Voter>>`.
|
||||
//
|
||||
// - Since this crate has multiple `Pezpallet` and `Configs`, in each sub-pezpallet, we only reference the
|
||||
// local `Pezpallet` without a prefix and allow it to be imported via `use`. Avoid `super::Pezpallet`
|
||||
// except for the case of a modules that want to reference their local `Pezpallet` . The
|
||||
// `crate::Pezpallet` is always reserved for the parent pezpallet. Other sibling pallets must be
|
||||
// referenced with full path, e.g. `crate::Verifier::Pezpallet`. Do NOT write something like `use
|
||||
// unsigned::Pezpallet as UnsignedPallet`.
|
||||
// - Since this crate has multiple `Pezpallet` and `Configs`, in each sub-pezpallet, we only
|
||||
// reference the local `Pezpallet` without a prefix and allow it to be imported via `use`. Avoid
|
||||
// `super::Pezpallet` except for the case of a modules that want to reference their local
|
||||
// `Pezpallet` . The `crate::Pezpallet` is always reserved for the parent pezpallet. Other sibling
|
||||
// pallets must be referenced with full path, e.g. `crate::Verifier::Pezpallet`. Do NOT write
|
||||
// something like `use unsigned::Pezpallet as UnsignedPallet`.
|
||||
//
|
||||
// - Respecting private storage items with wrapper We move all implementations out of the `mod
|
||||
// pezpallet` as much as possible to ensure we NEVER access the internal storage items directly. All
|
||||
// operations should happen with the wrapper types.
|
||||
// pezpallet` as much as possible to ensure we NEVER access the internal storage items directly.
|
||||
// All operations should happen with the wrapper types.
|
||||
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
@@ -210,7 +212,6 @@ use pezframe_support::{
|
||||
DebugNoBound, Twox64Concat,
|
||||
};
|
||||
use pezframe_system::pezpallet_prelude::*;
|
||||
use scale_info::TypeInfo;
|
||||
use pezsp_arithmetic::{
|
||||
traits::{CheckedAdd, Zero},
|
||||
PerThing, UpperOf,
|
||||
@@ -221,6 +222,7 @@ use pezsp_runtime::{
|
||||
SaturatedConversion,
|
||||
};
|
||||
use pezsp_std::{borrow::ToOwned, boxed::Box, prelude::*};
|
||||
use scale_info::TypeInfo;
|
||||
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
@@ -1630,8 +1632,8 @@ impl<T: Config> ElectionProvider for Pezpallet<T> {
|
||||
.map_err(|err| {
|
||||
// if any pages returns an error, we go into the emergency phase and don't do
|
||||
// anything else anymore. This will prevent any new submissions to signed and
|
||||
// unsigned pezpallet, and thus the verifier will also be almost stuck, except for the
|
||||
// submission of emergency solutions.
|
||||
// unsigned pezpallet, and thus the verifier will also be almost stuck, except for
|
||||
// the submission of emergency solutions.
|
||||
log!(debug, "fallback also ({:?}) failed for page {:?}", err, remaining);
|
||||
err
|
||||
})
|
||||
@@ -2904,9 +2906,9 @@ mod manage_ops {
|
||||
// This scenario have multiple outcomes:
|
||||
// 1. rotate in off => almost a noop
|
||||
// 2. rotate mid signed, validation, unsigned, done, but NOT export => clear all data, move to
|
||||
// next round and be off. Note: all of the data in this pezpallet is indexed by the round index,
|
||||
// so moving to the next round will implicitly make the old data unavaioable, even if not
|
||||
// cleared out. This secnario needs further testing.
|
||||
// next round and be off. Note: all of the data in this pezpallet is indexed by the round
|
||||
// index, so moving to the next round will implicitly make the old data unavaioable, even if
|
||||
// not cleared out. This secnario needs further testing.
|
||||
// 3. rotate mid export: same as above, except staking will be out of sync and will also need
|
||||
// governance intervention.
|
||||
//
|
||||
|
||||
@@ -31,6 +31,7 @@ use crate::{
|
||||
verifier::{self as verifier_pallet, AsynchronousVerifier, Status},
|
||||
};
|
||||
use codec::{Decode, Encode, MaxEncodedLen};
|
||||
use parking_lot::RwLock;
|
||||
use pezframe_election_provider_support::{
|
||||
bounds::{ElectionBounds, ElectionBoundsBuilder},
|
||||
InstantElectionProvider, NposSolution, SequentialPhragmen,
|
||||
@@ -42,8 +43,6 @@ use pezframe_support::{
|
||||
weights::{constants, Weight},
|
||||
};
|
||||
use pezframe_system::EnsureRoot;
|
||||
use parking_lot::RwLock;
|
||||
pub use signed::*;
|
||||
use pezsp_core::{
|
||||
offchain::{
|
||||
testing::{PoolState, TestOffchainExt, TestTransactionPoolExt},
|
||||
@@ -57,6 +56,7 @@ use pezsp_runtime::{
|
||||
traits::{BlakeTwo256, IdentityLookup},
|
||||
BuildStorage, PerU16, Perbill,
|
||||
};
|
||||
pub use signed::*;
|
||||
pub use staking::*;
|
||||
use std::{sync::Arc, vec};
|
||||
|
||||
|
||||
@@ -64,7 +64,11 @@ mod benchmarks {
|
||||
if i == 0 {
|
||||
for p in 0..T::Pages::get() {
|
||||
let page = Some(Default::default());
|
||||
Pezpallet::<T>::submit_page(RawOrigin::Signed(submitter.clone()).into(), p, page)?;
|
||||
Pezpallet::<T>::submit_page(
|
||||
RawOrigin::Signed(submitter.clone()).into(),
|
||||
p,
|
||||
page,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,11 +71,11 @@ use pezframe_support::{
|
||||
BoundedVec, Twox64Concat,
|
||||
};
|
||||
use pezframe_system::{ensure_signed, pezpallet_prelude::*};
|
||||
use scale_info::TypeInfo;
|
||||
use pezsp_io::MultiRemovalResults;
|
||||
use pezsp_npos_elections::ElectionScore;
|
||||
use pezsp_runtime::{traits::Saturating, Perbill};
|
||||
use pezsp_std::prelude::*;
|
||||
use scale_info::TypeInfo;
|
||||
|
||||
/// Explore all weights
|
||||
pub use crate::weights::traits::pezpallet_election_provider_multi_block_signed::*;
|
||||
@@ -984,7 +984,9 @@ pub mod pezpallet {
|
||||
|
||||
impl<T: Config> Pezpallet<T> {
|
||||
#[cfg(any(feature = "try-runtime", test, feature = "runtime-benchmarks"))]
|
||||
pub(crate) fn do_try_state(_n: BlockNumberFor<T>) -> Result<(), pezsp_runtime::TryRuntimeError> {
|
||||
pub(crate) fn do_try_state(
|
||||
_n: BlockNumberFor<T>,
|
||||
) -> Result<(), pezsp_runtime::TryRuntimeError> {
|
||||
Submissions::<T>::sanity_check_round(Self::current_round())
|
||||
}
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
//!
|
||||
//! ## [`SolutionOf`]
|
||||
//!
|
||||
//! This type is among the most cryptic used in the EPMB pezpallet. The origins of this type go back to
|
||||
//! the fact that sending a solution, with hundreds or thousands of account-ids in it would be too
|
||||
//! large for a chain to handle. This was particularly the case in a single page solution, as
|
||||
//! This type is among the most cryptic used in the EPMB pezpallet. The origins of this type go back
|
||||
//! to the fact that sending a solution, with hundreds or thousands of account-ids in it would be
|
||||
//! too large for a chain to handle. This was particularly the case in a single page solution, as
|
||||
//! developed in `election-provider-multi-phase`. To combat this, a "compact" custom type is
|
||||
//! generated to encapsulate a solution. This type is generated by
|
||||
//! [`pezframe_election_provider_support::generate_solution_type`]. See the documentation of this macro
|
||||
//! for more information about the hacks used to reduce the size of the solution.
|
||||
//! [`pezframe_election_provider_support::generate_solution_type`]. See the documentation of this
|
||||
//! macro for more information about the hacks used to reduce the size of the solution.
|
||||
//!
|
||||
//! Consequently, the [`SolutionVoterIndexOf`] and [`SolutionTargetIndexOf`] and
|
||||
//! [`SolutionAccuracyOf`] are derived from this type.
|
||||
@@ -44,7 +44,6 @@ use pezframe_support::{
|
||||
PartialEqNoBound,
|
||||
};
|
||||
use pezframe_system::pezpallet_prelude::BlockNumberFor;
|
||||
use scale_info::TypeInfo;
|
||||
use pezsp_core::Get;
|
||||
pub use pezsp_npos_elections::{ElectionResult, ElectionScore};
|
||||
use pezsp_runtime::{
|
||||
@@ -52,6 +51,7 @@ use pezsp_runtime::{
|
||||
SaturatedConversion, Saturating,
|
||||
};
|
||||
use pezsp_std::{collections::btree_set::BTreeSet, fmt::Debug, prelude::*};
|
||||
use scale_info::TypeInfo;
|
||||
|
||||
/// The solution type used by this crate.
|
||||
pub type SolutionOf<T> = <T as MinerConfig>::Solution;
|
||||
@@ -280,8 +280,8 @@ pub enum Phase<T: crate::Config> {
|
||||
///
|
||||
/// Once this is active, no more signed or solutions will be accepted.
|
||||
Export(PageIndex),
|
||||
/// The emergency phase. This is could be enabled by one of the fallbacks, and locks the pezpallet
|
||||
/// such that only governance can change the state.
|
||||
/// The emergency phase. This is could be enabled by one of the fallbacks, and locks the
|
||||
/// pezpallet such that only governance can change the state.
|
||||
Emergency,
|
||||
}
|
||||
|
||||
|
||||
@@ -36,13 +36,13 @@ use codec::Encode;
|
||||
use pezframe_election_provider_support::{ExtendedBalance, NposSolver, Support, VoteWeight};
|
||||
use pezframe_support::{traits::Get, BoundedVec};
|
||||
use pezframe_system::pezpallet_prelude::*;
|
||||
use scale_info::TypeInfo;
|
||||
use pezsp_npos_elections::EvaluateSupport;
|
||||
use pezsp_runtime::{
|
||||
offchain::storage::{MutateStorageError, StorageValueRef},
|
||||
traits::{SaturatedConversion, Saturating, Zero},
|
||||
};
|
||||
use pezsp_std::{collections::btree_map::BTreeMap, prelude::*};
|
||||
use scale_info::TypeInfo;
|
||||
|
||||
// TODO: we should have a fuzzer for miner that ensures no matter the parameters, it generates a
|
||||
// valid solution. Esp. for the trimming.
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
//! ## The unsigned phase, and its miner.
|
||||
//!
|
||||
//! This pezpallet deals with unsigned submissions. These are backup, "possibly" multi-page submissions
|
||||
//! from validators.
|
||||
//! This pezpallet deals with unsigned submissions. These are backup, "possibly" multi-page
|
||||
//! submissions from validators.
|
||||
//!
|
||||
//! This pezpallet has two miners, described in [`unsigned::miner`].
|
||||
//!
|
||||
|
||||
@@ -188,8 +188,8 @@ mod benchmarks {
|
||||
crate::mock::ElectionStart::set(pezsp_runtime::traits::Bounded::max_value());
|
||||
crate::Pezpallet::<T>::start().unwrap();
|
||||
|
||||
// roll to signed validation, with a solution stored in the signed pezpallet, but this solution
|
||||
// is corrupt in its msp.
|
||||
// roll to signed validation, with a solution stored in the signed pezpallet, but this
|
||||
// solution is corrupt in its msp.
|
||||
let mut paged_solution = crate::Pezpallet::<T>::roll_to_signed_and_mine_full_solution();
|
||||
let page_to_corrupt = crate::Pezpallet::<T>::msp() - v;
|
||||
crate::log!(
|
||||
|
||||
@@ -191,8 +191,8 @@ pub(crate) mod pezpallet {
|
||||
/// - The number of existing keys in `QueuedSolutionBackings` must always match that of the
|
||||
/// INVALID variant.
|
||||
///
|
||||
/// Moreover, the following conditions must be met when this pezpallet is in [`Status::Nothing`],
|
||||
/// meaning that no ongoing asynchronous verification is ongoing.
|
||||
/// Moreover, the following conditions must be met when this pezpallet is in
|
||||
/// [`Status::Nothing`], meaning that no ongoing asynchronous verification is ongoing.
|
||||
///
|
||||
/// - No keys should exist in the INVALID variant.
|
||||
/// - This implies that no data should exist in `QueuedSolutionBackings`.
|
||||
@@ -202,8 +202,8 @@ pub(crate) mod pezpallet {
|
||||
/// > the number of keys in the VALID variant. In fact, an empty solution with score of [0, 0,
|
||||
/// > 0] can also be correct.
|
||||
///
|
||||
/// No additional conditions must be met when the pezpallet is in [`Status::Ongoing`]. The number
|
||||
/// of pages in
|
||||
/// No additional conditions must be met when the pezpallet is in [`Status::Ongoing`]. The
|
||||
/// number of pages in
|
||||
pub struct QueuedSolution<T: Config>(pezsp_std::marker::PhantomData<T>);
|
||||
impl<T: Config> QueuedSolution<T> {
|
||||
/// Private helper for mutating the storage group.
|
||||
@@ -275,7 +275,10 @@ pub(crate) mod pezpallet {
|
||||
/// known to be valid. At this stage, we write to the invalid variant. Once all pages are
|
||||
/// verified, a call to [`finalize_correct`] will seal the correct pages and flip the
|
||||
/// invalid/valid variants.
|
||||
pub(crate) fn set_invalid_page(page: PageIndex, supports: SupportsOfVerifier<Pezpallet<T>>) {
|
||||
pub(crate) fn set_invalid_page(
|
||||
page: PageIndex,
|
||||
supports: SupportsOfVerifier<Pezpallet<T>>,
|
||||
) {
|
||||
use pezframe_support::traits::TryCollect;
|
||||
Self::mutate_checked(|| {
|
||||
let backings: BoundedVec<_, _> = supports
|
||||
@@ -851,7 +854,9 @@ impl<T: Config> Pezpallet<T> {
|
||||
}
|
||||
|
||||
#[cfg(any(test, feature = "runtime-benchmarks", feature = "try-runtime"))]
|
||||
pub(crate) fn do_try_state(_now: BlockNumberFor<T>) -> Result<(), pezsp_runtime::TryRuntimeError> {
|
||||
pub(crate) fn do_try_state(
|
||||
_now: BlockNumberFor<T>,
|
||||
) -> Result<(), pezsp_runtime::TryRuntimeError> {
|
||||
QueuedSolution::<T>::sanity_check()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
|
||||
//! # The Verifier Pezpallet
|
||||
//!
|
||||
//! This pezpallet has no end-user functionality, and is only used internally by other pallets in the
|
||||
//! EPMB machinery to verify solutions.
|
||||
//! This pezpallet has no end-user functionality, and is only used internally by other pallets in
|
||||
//! the EPMB machinery to verify solutions.
|
||||
//!
|
||||
//! ### *Feasibility* Check
|
||||
//!
|
||||
@@ -76,9 +76,9 @@ mod tests;
|
||||
// internal imports
|
||||
pub use crate::weights::traits::pezpallet_election_provider_multi_block_verifier::*;
|
||||
|
||||
use pezframe_election_provider_support::PageIndex;
|
||||
use impls::SupportsOfVerifier;
|
||||
pub use impls::{feasibility_check_page_inner_with_snapshot, pezpallet::*, Status};
|
||||
use pezframe_election_provider_support::PageIndex;
|
||||
use pezsp_core::Get;
|
||||
use pezsp_npos_elections::ElectionScore;
|
||||
use pezsp_std::{fmt::Debug, prelude::*};
|
||||
@@ -227,8 +227,9 @@ pub enum VerificationResult {
|
||||
|
||||
/// Something that can provide candidate solutions to the verifier.
|
||||
///
|
||||
/// In reality, this can be implemented by the [`crate::signed::Pezpallet`], where signed solutions are
|
||||
/// queued and sorted based on claimed score, and they are put forth one by one, from best to worse.
|
||||
/// In reality, this can be implemented by the [`crate::signed::Pezpallet`], where signed solutions
|
||||
/// are queued and sorted based on claimed score, and they are put forth one by one, from best to
|
||||
/// worse.
|
||||
pub trait SolutionDataProvider {
|
||||
/// The opaque solution type.
|
||||
type Solution;
|
||||
|
||||
@@ -153,7 +153,9 @@ mod feasibility_check {
|
||||
paged.solution_pages[0].clone(),
|
||||
0
|
||||
),
|
||||
FeasibilityError::NposElection(pezsp_npos_elections::Error::SolutionInvalidIndex),
|
||||
FeasibilityError::NposElection(
|
||||
pezsp_npos_elections::Error::SolutionInvalidIndex
|
||||
),
|
||||
);
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user