Expand description
§Multi-phase, multi-block, election provider pallet.
This pallet is sometimes abbreviated as
EPMB
, andpallet_election_provider_multi_phase
asEPM
.
§Overall idea
pallet_election_provider_multi_phase
provides the basic ability for NPoS solutions to be
computed offchain (essentially anywhere) and submitted back to the chain as signed or unsigned
transaction, with sensible configurations and fail-safe mechanisms to ensure system safety.
Nonetheless, it has a limited capacity in terms of number of voters it can process in a single
block.
This pallet takes EPM
system, keeps most of its ideas and core premises, and extends it to
support paginated, multi-block operations. The final goal of this pallet is to scale linearly
with the number of blocks allocated to the elections. Moreover, the amount of work that it does
in one block should be bounded and measurable, making it suitable for a parachain. In principle,
with large enough blocks (in a dedicated parachain), the number of voters included in the NPoS
system can grow significantly (yet, obviously not indefinitely).
Note that this pallet does not consider how the recipient is processing the results. To ensure
scalability, the recipient of this pallet’s data (i.e. pallet-staking
) must also be capable of
pagination and multi-block processing.
§Companion pallets
This pallet will only function in a sensible way if it is peered with its companion pallets.
- The
verifier
pallet provides a standard implementation of theverifier::Verifier
. This pallet is mandatory. - The
unsigned
module provides the implementation of unsigned submission by validators. If this pallet is included, thenConfig::UnsignedPhase
will determine its duration. - The
signed
module provides the implementation of the signed submission by any account. If this pallet is included, the combinedConfig::SignedPhase
andConfig::SignedValidationPhase
will determine its duration
These pallets are in fact hierarchical. This particular one is the top level one. It contains the shared information that all child pallets use. All child pallets depend on the top level pallet ONLY, but not the other way around. For those cases, traits are used.
As in, notice that crate::verifier::Config
relies on crate::Config
, but for the
reverse, we rely on crate::verifier::Verifier
trait, which is indeed part of
crate::Config
. This is merely an implementation opinion.
§Pallet Ordering:
TODO: @kiaenigma: this needs clarification and a enforcement. Signed pallet 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
- verifier
- signed
- unsigned
This is critical for the phase transition to work.
This should be manually checked, there is not automated way to test it.
§Pagination
Most of the external APIs of this pallet 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 pallet is yet to support paginated target (Validators in staking) snapshotting.
§Terminology Note: msp
and lsp
Stand for most significant page (n-1) and least significant page (0).
See [ElectionProvider::msp
] and [ElectionProvider::lsp
], and their usage.
§Phases
The operations in this pallet are divided intor rounds, a u32
number stored in Round
.
This value helps this pallet 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.
The timeline of pallet is overall as follows:
< Off >
0 ------------ 12 13 14 15 ----------- 20 ---------25 ------- 30
| | | | |
Snapshot Signed SignedValidation Unsigned Elect
- Duration of
Snapshot
is determined byConfig::Pages
+ 1.- Whereby in the first page we take the “Targets” snapshot, and in the subsequent pages we take the voter snapshot.
- For example, with
Pages = 4
:Snapshot(4)
->Targets(all)
Snapshot(3)
->Voters(3)
Snapshot(2)
->Voters(2)
Snapshot(1)
->Voters(1)
Snapshot(0)
->Voters(0)
- Duration of
Signed
,SignedValidation
andUnsigned
are determined byConfig::SignedPhase
,Config::SignedValidationPhase
andConfig::UnsignedPhase
respectively. Config::Pages
calls to elect are expected, but all in all the pallet will close a round onceelect(0)
is called.
Given this, it is rather important for the user of this pallet to ensure it always terminates election via
elect
before requesting a new one.
§Feasible Solution (correct solution)
All submissions must undergo a feasibility check. Signed solutions are checked one by one at the end of the signed phase, and the unsigned solutions are checked on the spot. A feasible solution is as follows:
- all of the used indices must be correct.
- present exactly correct number of winners.
- any assignment is checked to match with
PagedVoterSnapshot
. - the claimed score is valid, based on the fixed point arithmetic accuracy.
More about this in verifier
, who is responsible for doing all of the above.
§Fallback and Emergency
If at any page, [ElectionProvider::elect
] fails, a call with the same page-index is dispatched
to Config::Fallback
. Config::Fallback
is itself (yet) another implementation of
[ElectionProvider
], and can decide to do anything, but a few reasonable options are provided
here:
- Do nothing:
Continue
- Force us into the emergency phase:
crate::InitiateEmergencyPhase
. This initiatesPhase::Emergency
, which will halt almost all operations of this pallet, and it can only be recovered byAdminOperation
, dispatched viaCall::manage
. - compute an onchain from the give page of snapshot.
Note that configuring the fallback to be onchain computation is not recommended, unless for test-nets for a number of reasons:
- The solution score of fallback is never checked to match the “minimum” score. That being said, the computation happens onchain so we can trust it.
- The onchain fallback runs on the same number of voters and targets that reside on a single page of a snapshot, which will very likely be too much for actual onchain computation. Yet, we don’t have another choice as we cannot request another smaller snapshot from the data provider mid-election without more bookkeeping on the staking side.
If onchain solution is to be seriously considered, an improvement to this pallet should
re-request a smaller set of voters from T::DataProvider
in a stateless manner.
§Signed Phase
Signed phase is when an offchain miner, aka, polkadot-staking-miner
should operate upon. See
signed
for more information.
§Unsigned Phase
Unsigned phase is a built-in fallback in which validators may submit a single page election,
taking into account only the [ElectionProvider::msp
] (most significant page). See
crate::unsigned
for more information.
Re-exports§
pub use weights::traits::pallet_election_provider_multi_block::WeightInfo;
pub use pallet::*;
pub use types::*;
Modules§
- benchmarking
- helpers
- Some helper functions/macros for this crate.
- pallet
- The
pallet
module in each FRAME pallet hosts the most important items needed to construct this pallet. - signed
- The signed pallet The signed phase of the multi-block election system.
- types
- Common types of the pallet Common types and traits of the EPMB pallet group.
- unsigned
- The unsigned pallet
- verifier
- The verifier pallet
- weights
- The weight module WeightInfo for the election provider multi-block pallet group.
Macros§
- log
- Emit a log specific to this pallet, setting the target to
crate::LOG_PREFIX
- miner_
log - Emit a log from within the offchain miner.
- sublog
- Emit a log within a submodule of the pallet
Structs§
- Clean
Round - An implementation of
OnRoundRotation
that immediately deletes all the data in all the pallets, once the round is over. - Continue
- A fallback implementation that silently continues into the next page.
- GetDone
- A
Get
impl forPhase::Done
- GetSigned
- A
Get
impl forPhase::Signed(T::SignedPhase::get())
- IfSolution
Queued Else - A easy means to configure
Config::AreWeDone
. - Initiate
Emergency Phase - A fallback implementation that transitions the pallet to the emergency phase.
Enums§
- Admin
Operation - Different operations that the
Config::AdminOrigin
can perform on the pallet. - Election
Error - Internal errors of the pallet. This is used in the implementation of [
ElectionProvider
].
Constants§
- LOG_
PREFIX - The common logging prefix of all pallets in this crate.
Traits§
- OnRound
Rotation - Trait to notify other sub-systems that a round has ended.
Type Aliases§
- Proceed
Regardless Of - A shorthand for
IfSolutionQueuedElse
that proceeds regardless of the solution being queued. - Revert
ToSigned IfNot Queued Of - A shorthand for
IfSolutionQueuedElse
that proceeds toPhase::Done
if the solution is queued. Otherwise, it proceeds toPhase::Signed
.