-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Multi-phase elections solution resubmission #8290
Changes from 9 commits
62e1854
9a8c4a2
19d7251
02ad14b
f6a0fd9
59a0fb4
4612d07
c8ccbe9
7e4408f
f4b50fc
a192ba3
81ceca1
9023b61
449b799
85f715e
c6ecab8
ad3b786
bee456c
89cf445
458682b
d7dbcc0
b3e4950
0b77268
576f87c
d0f031a
681e6f0
0fac518
276a06a
ea3fc29
cc70d37
4b46a93
224d5e1
c5668e9
e9305be
fe84141
8b31773
9978693
ebcdeaa
0236288
bd7a195
1c896be
2243501
2b5d050
5eb2673
f12d59d
70b4f71
9c28048
3f1109b
af2d2c6
fc71d3d
840bad3
8eaf481
f4b52f0
6ae73c4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -192,10 +192,6 @@ | |
| //! **Score based on (byte) size**: We should always prioritize small solutions over bigger ones, if | ||
| //! there is a tie. Even more harsh should be to enforce the bound of the `reduce` algorithm. | ||
| //! | ||
| //! **Offchain resubmit**: Essentially port <https://github.com/paritytech/substrate/pull/7976> to | ||
| //! this pallet as well. The `OFFCHAIN_REPEAT` also needs to become an adjustable parameter of the | ||
| //! pallet. | ||
| //! | ||
| //! **Make the number of nominators configurable from the runtime**. Remove `sp_npos_elections` | ||
| //! dependency from staking and the compact solution type. It should be generated at runtime, there | ||
| //! it should be encoded how many votes each nominators have. Essentially translate | ||
|
|
@@ -213,7 +209,7 @@ use frame_support::{ | |
| use frame_system::{ensure_none, offchain::SendTransactionTypes}; | ||
| use sp_election_providers::{ElectionDataProvider, ElectionProvider, onchain}; | ||
| use sp_npos_elections::{ | ||
| assignment_ratio_to_staked_normalized, is_score_better, CompactSolution, ElectionScore, | ||
| assignment_ratio_to_staked_normalized, CompactSolution, ElectionScore, | ||
| EvaluateSupport, PerThing128, Supports, VoteWeight, | ||
| }; | ||
| use sp_runtime::{ | ||
|
|
@@ -291,8 +287,16 @@ pub enum Phase<Bn> { | |
| Off, | ||
| /// Signed phase is open. | ||
| Signed, | ||
| /// Unsigned phase. First element is whether it is open or not, second the starting block | ||
| /// Unsigned phase. First element is whether it is active or not, second the starting block | ||
| /// number. | ||
| /// | ||
| /// We do not yet check whether the unsigned phase is active or passive. The intent is for the | ||
| /// blockchain to be able to declare: "I believe that there exists an adequate signed solution," | ||
| /// advising validators not to bother running the unsigned offchain worker. | ||
| /// | ||
| /// As validator nodes are free to edit their OCW code, they could simply ignore this advisory | ||
| /// and always compute their own solution. However, by default, when the unsigned phase is passive, | ||
| /// the offchain workers will not bother running. | ||
gui1117 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| Unsigned((bool, Bn)), | ||
| } | ||
|
|
||
|
|
@@ -303,27 +307,27 @@ impl<Bn> Default for Phase<Bn> { | |
| } | ||
|
|
||
| impl<Bn: PartialEq + Eq> Phase<Bn> { | ||
| /// Weather the phase is signed or not. | ||
| /// Whether the phase is signed or not. | ||
| pub fn is_signed(&self) -> bool { | ||
| matches!(self, Phase::Signed) | ||
| } | ||
|
|
||
| /// Weather the phase is unsigned or not. | ||
| /// Whether the phase is unsigned or not. | ||
| pub fn is_unsigned(&self) -> bool { | ||
| matches!(self, Phase::Unsigned(_)) | ||
| } | ||
|
|
||
| /// Weather the phase is unsigned and open or not, with specific start. | ||
| /// Whether the phase is unsigned and open or not, with specific start. | ||
| pub fn is_unsigned_open_at(&self, at: Bn) -> bool { | ||
| matches!(self, Phase::Unsigned((true, real)) if *real == at) | ||
| } | ||
|
|
||
| /// Weather the phase is unsigned and open or not. | ||
| /// Whether the phase is unsigned and open or not. | ||
| pub fn is_unsigned_open(&self) -> bool { | ||
| matches!(self, Phase::Unsigned((true, _))) | ||
| } | ||
|
|
||
| /// Weather the phase is off or not. | ||
| /// Whether the phase is off or not. | ||
coriolinus marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| pub fn is_off(&self) -> bool { | ||
| matches!(self, Phase::Off) | ||
| } | ||
|
|
@@ -514,6 +518,13 @@ pub mod pallet { | |
| #[pallet::constant] | ||
| type SolutionImprovementThreshold: Get<Perbill>; | ||
|
|
||
| /// The repeat threshold of the offchain worker. | ||
| /// | ||
| /// For example, if it is 5, that means that at least 5 blocks will elapse between attempts | ||
| /// to submit the worker's solution. | ||
| #[pallet::constant] | ||
| type OffchainRepeat: Get<Self::BlockNumber>; | ||
|
|
||
| /// The priority of the unsigned transaction submitted in the unsigned-phase | ||
| type MinerTxPriority: Get<TransactionPriority>; | ||
| /// Maximum number of iteration of balancing that will be executed in the embedded miner of | ||
|
|
@@ -595,16 +606,26 @@ pub mod pallet { | |
| } | ||
| } | ||
|
|
||
| fn offchain_worker(n: T::BlockNumber) { | ||
| // We only run the OCW in the first block of the unsigned phase. | ||
| if Self::current_phase().is_unsigned_open_at(n) { | ||
| match Self::try_acquire_offchain_lock(n) { | ||
| Ok(_) => { | ||
| let outcome = Self::mine_check_and_submit().map_err(ElectionError::from); | ||
| log!(info, "miner exeuction done: {:?}", outcome); | ||
| fn offchain_worker(now: T::BlockNumber) { | ||
| let threshold = T::OffchainRepeat::get(); | ||
coriolinus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| match Self::current_phase() { | ||
| Phase::Unsigned((true, opened)) if opened == now => { | ||
| // mine a new solution, cache it, and attempt to submit it | ||
| let initial_output = Self::try_acquire_offchain_lock(now, threshold) | ||
| .and_then(|_| Self::mine_check_save_submit()); | ||
| log!(info, "initial OCW output at {:?}: {:?}", now, initial_output); | ||
| } | ||
| Phase::Unsigned((true, opened)) if opened < now => { | ||
| if !<QueuedSolution<T>>::exists() { | ||
|
||
| // as long as there is no feasible solution, keep trying to submit ours | ||
coriolinus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // | ||
coriolinus marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // the offchain_lock prevents us from spamming submissions too often. | ||
| let resubmit_output = Self::try_acquire_offchain_lock(now, threshold) | ||
| .and_then(|_| Self::restore_or_compute_then_submit()); | ||
| log!(info, "resubmit OCW output at {:?}: {:?}", now, resubmit_output); | ||
| } | ||
| Err(why) => log!(warn, "denied offchain worker: {:?}", why), | ||
| } | ||
| _ => {} | ||
| } | ||
| } | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.