Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 1c434cd

Browse files
kianenigmashawntabrizigui1117Parity Benchmarking Bot
authored
Decouple Staking and Election - Part 2 Unsigned Phase (#7909)
* Base features and traits. * pallet and unsigned phase * Undo bad formattings. * some formatting cleanup. * Small self-cleanup. * Make it all build * self-review * Some doc tests. * Some changes from other PR * Fix session test * Update Cargo.lock * Update frame/election-provider-multi-phase/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Some review comments * Rename + make encode/decode * Do an assert as well, just in case. * Fix build * Update frame/election-provider-multi-phase/src/unsigned.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Las comment * fix staking fuzzer. * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_election_provider_multi_phase --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/election-provider-multi-phase/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Add one last layer of feasibility check as well. * Last fixes to benchmarks * Some more docs. * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_election_provider_multi_phase --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/election-provider-multi-phase/src/weights.rs --template=./.maintain/frame-weight-template.hbs * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_election_provider_multi_phase --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/election-provider-multi-phase/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Some nits * cargo run --release --features=runtime-benchmarks --manifest-path=bin/node/cli/Cargo.toml -- benchmark --chain=dev --steps=50 --repeat=20 --pallet=pallet_staking --extrinsic=* --execution=wasm --wasm-execution=compiled --heap-pages=4096 --output=./frame/staking/src/weights.rs --template=./.maintain/frame-weight-template.hbs * Fix doc * Mkae ci green Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Parity Benchmarking Bot <admin@parity.io>
1 parent 27e1f89 commit 1c434cd

34 files changed

Lines changed: 4092 additions & 231 deletions

File tree

Cargo.lock

Lines changed: 33 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ members = [
7575
"frame/democracy",
7676
"frame/try-runtime",
7777
"frame/elections",
78+
"frame/election-provider-multi-phase",
7879
"frame/example",
7980
"frame/example-offchain-worker",
8081
"frame/example-parallel",

bin/node/runtime/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ pallet-contracts-primitives = { version = "2.0.0", default-features = false, pat
5656
pallet-contracts-rpc-runtime-api = { version = "0.8.0", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" }
5757
pallet-democracy = { version = "3.0.0", default-features = false, path = "../../../frame/democracy" }
5858
pallet-elections-phragmen = { version = "3.0.0", default-features = false, path = "../../../frame/elections-phragmen" }
59+
pallet-election-provider-multi-phase = { version = "3.0.0", default-features = false, path = "../../../frame/election-provider-multi-phase" }
5960
pallet-grandpa = { version = "3.0.0", default-features = false, path = "../../../frame/grandpa" }
6061
pallet-im-online = { version = "3.0.0", default-features = false, path = "../../../frame/im-online" }
6162
pallet-indices = { version = "3.0.0", default-features = false, path = "../../../frame/indices" }
@@ -141,6 +142,7 @@ std = [
141142
"frame-benchmarking/std",
142143
"frame-system-rpc-runtime-api/std",
143144
"frame-system/std",
145+
"pallet-election-provider-multi-phase/std",
144146
"pallet-timestamp/std",
145147
"pallet-tips/std",
146148
"pallet-transaction-payment-rpc-runtime-api/std",
@@ -157,6 +159,7 @@ runtime-benchmarks = [
157159
"frame-benchmarking",
158160
"frame-support/runtime-benchmarks",
159161
"frame-system/runtime-benchmarks",
162+
"pallet-election-provider-multi-phase/runtime-benchmarks",
160163
"sp-runtime/runtime-benchmarks",
161164
"pallet-assets/runtime-benchmarks",
162165
"pallet-babe/runtime-benchmarks",

bin/node/runtime/src/constants.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ pub mod time {
3535
use node_primitives::{Moment, BlockNumber};
3636

3737
/// Since BABE is probabilistic this is the average expected block time that
38-
/// we are targetting. Blocks will be produced at a minimum duration defined
38+
/// we are targeting. Blocks will be produced at a minimum duration defined
3939
/// by `SLOT_DURATION`, but some slots will not be allocated to any
4040
/// authority and hence no block will be produced. We expect to have this
4141
/// block time on average following the defined slot duration and the value

bin/node/runtime/src/lib.rs

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ use frame_support::{
2828
construct_runtime, parameter_types, debug, RuntimeDebug,
2929
weights::{
3030
Weight, IdentityFee,
31-
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, DispatchClass,
31+
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
32+
DispatchClass,
3233
},
3334
traits::{
3435
Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness, LockIdentifier,
@@ -50,14 +51,14 @@ pub use node_primitives::{AccountId, Signature};
5051
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
5152
use sp_api::impl_runtime_apis;
5253
use sp_runtime::{
53-
Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult,
54-
impl_opaque_keys, generic, create_runtime_str, ModuleId, FixedPointNumber,
54+
Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic,
55+
create_runtime_str, ModuleId, FixedPointNumber,
5556
};
5657
use sp_runtime::curve::PiecewiseLinear;
5758
use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority};
5859
use sp_runtime::traits::{
59-
self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion,
60-
ConvertInto, OpaqueKeys, NumberFor,
60+
self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys,
61+
NumberFor,
6162
};
6263
use sp_version::RuntimeVersion;
6364
#[cfg(any(feature = "std", test))]
@@ -145,7 +146,7 @@ impl OnUnbalanced<NegativeImbalance> for DealWithFees {
145146
}
146147
}
147148

148-
/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
149+
/// We assume that ~10% of the block weight is consumed by `on_initialize` handlers.
149150
/// This is used to limit the maximal weight of a single extrinsic.
150151
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
151152
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
@@ -490,18 +491,56 @@ impl pallet_staking::Config for Runtime {
490491
type SessionInterface = Self;
491492
type RewardCurve = RewardCurve;
492493
type NextNewSession = Session;
494+
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
493495
type ElectionLookahead = ElectionLookahead;
494496
type Call = Call;
495497
type MaxIterations = MaxIterations;
496498
type MinSolutionScoreBump = MinSolutionScoreBump;
497-
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
498499
type UnsignedPriority = StakingUnsignedPriority;
499500
// The unsigned solution weight targeted by the OCW. We set it to the maximum possible value of
500501
// a single extrinsic.
501502
type OffchainSolutionWeightLimit = OffchainSolutionWeightLimit;
503+
type ElectionProvider = ElectionProviderMultiPhase;
502504
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
503505
}
504506

507+
parameter_types! {
508+
// phase durations. 1/4 of the last session for each.
509+
pub const SignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4;
510+
pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4;
511+
512+
// fallback: no need to do on-chain phragmen initially.
513+
pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
514+
pallet_election_provider_multi_phase::FallbackStrategy::Nothing;
515+
516+
pub SolutionImprovementThreshold: Perbill = Perbill::from_rational_approximation(1u32, 10_000);
517+
518+
// miner configs
519+
pub const MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64;
520+
pub const MinerMaxIterations: u32 = 10;
521+
pub MinerMaxWeight: Weight = RuntimeBlockWeights::get()
522+
.get(DispatchClass::Normal)
523+
.max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed")
524+
.saturating_sub(BlockExecutionWeight::get());
525+
}
526+
527+
impl pallet_election_provider_multi_phase::Config for Runtime {
528+
type Event = Event;
529+
type Currency = Balances;
530+
type SignedPhase = SignedPhase;
531+
type UnsignedPhase = UnsignedPhase;
532+
type SolutionImprovementThreshold = MinSolutionScoreBump;
533+
type MinerMaxIterations = MinerMaxIterations;
534+
type MinerMaxWeight = MinerMaxWeight;
535+
type MinerTxPriority = MultiPhaseUnsignedPriority;
536+
type DataProvider = Staking;
537+
type OnChainAccuracy = Perbill;
538+
type CompactSolution = pallet_staking::CompactAssignments;
539+
type Fallback = Fallback;
540+
type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight<Runtime>;
541+
type BenchmarkingConfig = ();
542+
}
543+
505544
parameter_types! {
506545
pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
507546
pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
@@ -548,7 +587,7 @@ impl pallet_democracy::Config for Runtime {
548587
>;
549588
type BlacklistOrigin = EnsureRoot<AccountId>;
550589
// Any single technical committee member may veto a coming council proposal, however they can
551-
// only do it once and it lasts only for the cooloff period.
590+
// only do it once and it lasts only for the cool-off period.
552591
type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
553592
type CooloffPeriod = CooloffPeriod;
554593
type PreimageByteDeposit = PreimageByteDeposit;
@@ -1020,6 +1059,7 @@ construct_runtime!(
10201059
Indices: pallet_indices::{Module, Call, Storage, Config<T>, Event<T>},
10211060
Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
10221061
TransactionPayment: pallet_transaction_payment::{Module, Storage},
1062+
ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Module, Call, Storage, Event<T>, ValidateUnsigned},
10231063
Staking: pallet_staking::{Module, Call, Config<T>, Storage, Event<T>, ValidateUnsigned},
10241064
Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
10251065
Democracy: pallet_democracy::{Module, Call, Storage, Config, Event<T>},
@@ -1386,6 +1426,7 @@ impl_runtime_apis! {
13861426
add_benchmark!(params, batches, pallet_contracts, Contracts);
13871427
add_benchmark!(params, batches, pallet_democracy, Democracy);
13881428
add_benchmark!(params, batches, pallet_elections_phragmen, Elections);
1429+
add_benchmark!(params, batches, pallet_election_provider_multi_phase, ElectionProviderMultiPhase);
13891430
add_benchmark!(params, batches, pallet_grandpa, Grandpa);
13901431
add_benchmark!(params, batches, pallet_identity, Identity);
13911432
add_benchmark!(params, batches, pallet_im_online, ImOnline);

frame/babe/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,12 @@ sp-std = { version = "3.0.0", default-features = false, path = "../../primitives
3232
sp-timestamp = { version = "3.0.0", default-features = false, path = "../../primitives/timestamp" }
3333

3434
[dev-dependencies]
35-
frame-benchmarking = { version = "3.0.0", path = "../benchmarking" }
3635
pallet-balances = { version = "3.0.0", path = "../balances" }
3736
pallet-offences = { version = "3.0.0", path = "../offences" }
3837
pallet-staking = { version = "3.0.0", path = "../staking" }
3938
pallet-staking-reward-curve = { version = "3.0.0", path = "../staking/reward-curve" }
4039
sp-core = { version = "3.0.0", path = "../../primitives/core" }
40+
sp-election-providers = { version = "3.0.0", path = "../../primitives/election-providers" }
4141

4242
[features]
4343
default = ["std"]

frame/babe/src/lib.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -413,12 +413,14 @@ impl<T: Config> Module<T> {
413413
/// In other word, this is only accurate if no slots are missed. Given missed slots, the slot
414414
/// number will grow while the block number will not. Hence, the result can be interpreted as an
415415
/// upper bound.
416-
// -------------- IMPORTANT NOTE --------------
416+
//
417+
// ## IMPORTANT NOTE
418+
//
417419
// This implementation is linked to how [`should_epoch_change`] is working. This might need to
418420
// be updated accordingly, if the underlying mechanics of slot and epochs change.
419421
//
420-
// WEIGHT NOTE: This function is tied to the weight of `EstimateNextSessionRotation`. If you update
421-
// this function, you must also update the corresponding weight.
422+
// WEIGHT NOTE: This function is tied to the weight of `EstimateNextSessionRotation`. If you
423+
// update this function, you must also update the corresponding weight.
422424
pub fn next_expected_epoch_change(now: T::BlockNumber) -> Option<T::BlockNumber> {
423425
let next_slot = Self::current_epoch_start().saturating_add(T::EpochDuration::get());
424426
next_slot
@@ -754,6 +756,10 @@ impl<T: Config> OnTimestampSet<T::Moment> for Module<T> {
754756
}
755757

756758
impl<T: Config> frame_support::traits::EstimateNextSessionRotation<T::BlockNumber> for Module<T> {
759+
fn average_session_length() -> T::BlockNumber {
760+
T::EpochDuration::get().saturated_into()
761+
}
762+
757763
fn estimate_next_session_rotation(now: T::BlockNumber) -> Option<T::BlockNumber> {
758764
Self::next_expected_epoch_change(now)
759765
}

frame/babe/src/mock.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use sp_consensus_babe::{AuthorityId, AuthorityPair, Slot};
3737
use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof};
3838
use sp_staking::SessionIndex;
3939
use pallet_staking::EraIndex;
40+
use sp_election_providers::onchain;
4041
use pallet_session::historical as pallet_session_historical;
4142

4243
type DummyValidatorId = u64;
@@ -183,6 +184,13 @@ parameter_types! {
183184
pub const StakingUnsignedPriority: u64 = u64::max_value() / 2;
184185
}
185186

187+
impl onchain::Config for Test {
188+
type AccountId = <Self as frame_system::Config>::AccountId;
189+
type BlockNumber = <Self as frame_system::Config>::BlockNumber;
190+
type Accuracy = Perbill;
191+
type DataProvider = Staking;
192+
}
193+
186194
impl pallet_staking::Config for Test {
187195
type RewardRemainder = ();
188196
type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote;
@@ -205,6 +213,7 @@ impl pallet_staking::Config for Test {
205213
type MaxIterations = ();
206214
type MinSolutionScoreBump = ();
207215
type OffchainSolutionWeightLimit = ();
216+
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
208217
type WeightInfo = ();
209218
}
210219

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
[package]
2+
name = "pallet-election-provider-multi-phase"
3+
version = "3.0.0"
4+
authors = ["Parity Technologies <admin@parity.io>"]
5+
edition = "2018"
6+
license = "Apache-2.0"
7+
homepage = "https://substrate.dev"
8+
repository = "https://github.com/paritytech/substrate/"
9+
description = "PALLET two phase election providers"
10+
readme = "README.md"
11+
12+
[package.metadata.docs.rs]
13+
targets = ["x86_64-unknown-linux-gnu"]
14+
15+
[dependencies]
16+
static_assertions = "1.1.0"
17+
serde = { version = "1.0.101", optional = true }
18+
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }
19+
20+
frame-support = { version = "3.0.0", default-features = false, path = "../support" }
21+
frame-system = { version = "3.0.0", default-features = false, path = "../system" }
22+
23+
sp-io ={ version = "3.0.0", default-features = false, path = "../../primitives/io" }
24+
sp-std = { version = "3.0.0", default-features = false, path = "../../primitives/std" }
25+
sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" }
26+
sp-npos-elections = { version = "3.0.0", default-features = false, path = "../../primitives/npos-elections" }
27+
sp-arithmetic = { version = "3.0.0", default-features = false, path = "../../primitives/arithmetic" }
28+
sp-election-providers = { version = "3.0.0", default-features = false, path = "../../primitives/election-providers" }
29+
30+
# Optional imports for benchmarking
31+
frame-benchmarking = { version = "3.0.0", default-features = false, path = "../benchmarking", optional = true }
32+
rand = { version = "0.7.3", default-features = false, optional = true, features = ["alloc", "small_rng"] }
33+
34+
[dev-dependencies]
35+
paste = "1.0.3"
36+
parking_lot = "0.11.0"
37+
rand = { version = "0.7.3" }
38+
hex-literal = "0.3.1"
39+
substrate-test-utils = { version = "3.0.0", path = "../../test-utils" }
40+
sp-io = { version = "3.0.0", path = "../../primitives/io" }
41+
sp-core = { version = "3.0.0", path = "../../primitives/core" }
42+
sp-tracing = { version = "3.0.0", path = "../../primitives/tracing" }
43+
sp-election-providers = { version = "3.0.0", features = ["runtime-benchmarks"], path = "../../primitives/election-providers" }
44+
pallet-balances = { version = "3.0.0", path = "../balances" }
45+
frame-benchmarking = { path = "../benchmarking" }
46+
47+
[features]
48+
default = ["std"]
49+
std = [
50+
"serde",
51+
"codec/std",
52+
53+
"frame-support/std",
54+
"frame-system/std",
55+
56+
"sp-io/std",
57+
"sp-std/std",
58+
"sp-runtime/std",
59+
"sp-npos-elections/std",
60+
"sp-arithmetic/std",
61+
"sp-election-providers/std",
62+
]
63+
runtime-benchmarks = [
64+
"frame-benchmarking",
65+
"rand",
66+
]

0 commit comments

Comments
 (0)