Skip to content

Commit

Permalink
Decouple Staking and Election - Part 2 Unsigned Phase (paritytech#7909)
Browse files Browse the repository at this point in the history
* 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 <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>
Co-authored-by: Guillaume Thiolliere <[email protected]>
Co-authored-by: Parity Benchmarking Bot <[email protected]>
  • Loading branch information
4 people authored Feb 23, 2021
1 parent 27e1f89 commit 1c434cd
Show file tree
Hide file tree
Showing 34 changed files with 4,092 additions and 231 deletions.
33 changes: 33 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ members = [
"frame/democracy",
"frame/try-runtime",
"frame/elections",
"frame/election-provider-multi-phase",
"frame/example",
"frame/example-offchain-worker",
"frame/example-parallel",
Expand Down
3 changes: 3 additions & 0 deletions bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ pallet-contracts-primitives = { version = "2.0.0", default-features = false, pat
pallet-contracts-rpc-runtime-api = { version = "0.8.0", default-features = false, path = "../../../frame/contracts/rpc/runtime-api/" }
pallet-democracy = { version = "3.0.0", default-features = false, path = "../../../frame/democracy" }
pallet-elections-phragmen = { version = "3.0.0", default-features = false, path = "../../../frame/elections-phragmen" }
pallet-election-provider-multi-phase = { version = "3.0.0", default-features = false, path = "../../../frame/election-provider-multi-phase" }
pallet-grandpa = { version = "3.0.0", default-features = false, path = "../../../frame/grandpa" }
pallet-im-online = { version = "3.0.0", default-features = false, path = "../../../frame/im-online" }
pallet-indices = { version = "3.0.0", default-features = false, path = "../../../frame/indices" }
Expand Down Expand Up @@ -141,6 +142,7 @@ std = [
"frame-benchmarking/std",
"frame-system-rpc-runtime-api/std",
"frame-system/std",
"pallet-election-provider-multi-phase/std",
"pallet-timestamp/std",
"pallet-tips/std",
"pallet-transaction-payment-rpc-runtime-api/std",
Expand All @@ -157,6 +159,7 @@ runtime-benchmarks = [
"frame-benchmarking",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-election-provider-multi-phase/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"pallet-assets/runtime-benchmarks",
"pallet-babe/runtime-benchmarks",
Expand Down
2 changes: 1 addition & 1 deletion bin/node/runtime/src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ pub mod time {
use node_primitives::{Moment, BlockNumber};

/// Since BABE is probabilistic this is the average expected block time that
/// we are targetting. Blocks will be produced at a minimum duration defined
/// we are targeting. Blocks will be produced at a minimum duration defined
/// by `SLOT_DURATION`, but some slots will not be allocated to any
/// authority and hence no block will be produced. We expect to have this
/// block time on average following the defined slot duration and the value
Expand Down
57 changes: 49 additions & 8 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ use frame_support::{
construct_runtime, parameter_types, debug, RuntimeDebug,
weights::{
Weight, IdentityFee,
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND}, DispatchClass,
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight, WEIGHT_PER_SECOND},
DispatchClass,
},
traits::{
Currency, Imbalance, KeyOwnerProofSystem, OnUnbalanced, Randomness, LockIdentifier,
Expand All @@ -50,14 +51,14 @@ pub use node_primitives::{AccountId, Signature};
use node_primitives::{AccountIndex, Balance, BlockNumber, Hash, Index, Moment};
use sp_api::impl_runtime_apis;
use sp_runtime::{
Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult,
impl_opaque_keys, generic, create_runtime_str, ModuleId, FixedPointNumber,
Permill, Perbill, Perquintill, Percent, ApplyExtrinsicResult, impl_opaque_keys, generic,
create_runtime_str, ModuleId, FixedPointNumber,
};
use sp_runtime::curve::PiecewiseLinear;
use sp_runtime::transaction_validity::{TransactionValidity, TransactionSource, TransactionPriority};
use sp_runtime::traits::{
self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion,
ConvertInto, OpaqueKeys, NumberFor,
self, BlakeTwo256, Block as BlockT, StaticLookup, SaturatedConversion, ConvertInto, OpaqueKeys,
NumberFor,
};
use sp_version::RuntimeVersion;
#[cfg(any(feature = "std", test))]
Expand Down Expand Up @@ -145,7 +146,7 @@ impl OnUnbalanced<NegativeImbalance> for DealWithFees {
}
}

/// We assume that ~10% of the block weight is consumed by `on_initalize` handlers.
/// We assume that ~10% of the block weight is consumed by `on_initialize` handlers.
/// This is used to limit the maximal weight of a single extrinsic.
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10);
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can be used
Expand Down Expand Up @@ -490,18 +491,56 @@ impl pallet_staking::Config for Runtime {
type SessionInterface = Self;
type RewardCurve = RewardCurve;
type NextNewSession = Session;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type ElectionLookahead = ElectionLookahead;
type Call = Call;
type MaxIterations = MaxIterations;
type MinSolutionScoreBump = MinSolutionScoreBump;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type UnsignedPriority = StakingUnsignedPriority;
// The unsigned solution weight targeted by the OCW. We set it to the maximum possible value of
// a single extrinsic.
type OffchainSolutionWeightLimit = OffchainSolutionWeightLimit;
type ElectionProvider = ElectionProviderMultiPhase;
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
}

parameter_types! {
// phase durations. 1/4 of the last session for each.
pub const SignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4;
pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4;

// fallback: no need to do on-chain phragmen initially.
pub const Fallback: pallet_election_provider_multi_phase::FallbackStrategy =
pallet_election_provider_multi_phase::FallbackStrategy::Nothing;

pub SolutionImprovementThreshold: Perbill = Perbill::from_rational_approximation(1u32, 10_000);

// miner configs
pub const MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64;
pub const MinerMaxIterations: u32 = 10;
pub MinerMaxWeight: Weight = RuntimeBlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed")
.saturating_sub(BlockExecutionWeight::get());
}

impl pallet_election_provider_multi_phase::Config for Runtime {
type Event = Event;
type Currency = Balances;
type SignedPhase = SignedPhase;
type UnsignedPhase = UnsignedPhase;
type SolutionImprovementThreshold = MinSolutionScoreBump;
type MinerMaxIterations = MinerMaxIterations;
type MinerMaxWeight = MinerMaxWeight;
type MinerTxPriority = MultiPhaseUnsignedPriority;
type DataProvider = Staking;
type OnChainAccuracy = Perbill;
type CompactSolution = pallet_staking::CompactAssignments;
type Fallback = Fallback;
type WeightInfo = pallet_election_provider_multi_phase::weights::SubstrateWeight<Runtime>;
type BenchmarkingConfig = ();
}

parameter_types! {
pub const LaunchPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
pub const VotingPeriod: BlockNumber = 28 * 24 * 60 * MINUTES;
Expand Down Expand Up @@ -548,7 +587,7 @@ impl pallet_democracy::Config for Runtime {
>;
type BlacklistOrigin = EnsureRoot<AccountId>;
// Any single technical committee member may veto a coming council proposal, however they can
// only do it once and it lasts only for the cooloff period.
// only do it once and it lasts only for the cool-off period.
type VetoOrigin = pallet_collective::EnsureMember<AccountId, TechnicalCollective>;
type CooloffPeriod = CooloffPeriod;
type PreimageByteDeposit = PreimageByteDeposit;
Expand Down Expand Up @@ -1020,6 +1059,7 @@ construct_runtime!(
Indices: pallet_indices::{Module, Call, Storage, Config<T>, Event<T>},
Balances: pallet_balances::{Module, Call, Storage, Config<T>, Event<T>},
TransactionPayment: pallet_transaction_payment::{Module, Storage},
ElectionProviderMultiPhase: pallet_election_provider_multi_phase::{Module, Call, Storage, Event<T>, ValidateUnsigned},
Staking: pallet_staking::{Module, Call, Config<T>, Storage, Event<T>, ValidateUnsigned},
Session: pallet_session::{Module, Call, Storage, Event, Config<T>},
Democracy: pallet_democracy::{Module, Call, Storage, Config, Event<T>},
Expand Down Expand Up @@ -1386,6 +1426,7 @@ impl_runtime_apis! {
add_benchmark!(params, batches, pallet_contracts, Contracts);
add_benchmark!(params, batches, pallet_democracy, Democracy);
add_benchmark!(params, batches, pallet_elections_phragmen, Elections);
add_benchmark!(params, batches, pallet_election_provider_multi_phase, ElectionProviderMultiPhase);
add_benchmark!(params, batches, pallet_grandpa, Grandpa);
add_benchmark!(params, batches, pallet_identity, Identity);
add_benchmark!(params, batches, pallet_im_online, ImOnline);
Expand Down
2 changes: 1 addition & 1 deletion frame/babe/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ sp-std = { version = "3.0.0", default-features = false, path = "../../primitives
sp-timestamp = { version = "3.0.0", default-features = false, path = "../../primitives/timestamp" }

[dev-dependencies]
frame-benchmarking = { version = "3.0.0", path = "../benchmarking" }
pallet-balances = { version = "3.0.0", path = "../balances" }
pallet-offences = { version = "3.0.0", path = "../offences" }
pallet-staking = { version = "3.0.0", path = "../staking" }
pallet-staking-reward-curve = { version = "3.0.0", path = "../staking/reward-curve" }
sp-core = { version = "3.0.0", path = "../../primitives/core" }
sp-election-providers = { version = "3.0.0", path = "../../primitives/election-providers" }

[features]
default = ["std"]
Expand Down
12 changes: 9 additions & 3 deletions frame/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,12 +413,14 @@ impl<T: Config> Module<T> {
/// In other word, this is only accurate if no slots are missed. Given missed slots, the slot
/// number will grow while the block number will not. Hence, the result can be interpreted as an
/// upper bound.
// -------------- IMPORTANT NOTE --------------
//
// ## IMPORTANT NOTE
//
// This implementation is linked to how [`should_epoch_change`] is working. This might need to
// be updated accordingly, if the underlying mechanics of slot and epochs change.
//
// WEIGHT NOTE: This function is tied to the weight of `EstimateNextSessionRotation`. If you update
// this function, you must also update the corresponding weight.
// WEIGHT NOTE: This function is tied to the weight of `EstimateNextSessionRotation`. If you
// update this function, you must also update the corresponding weight.
pub fn next_expected_epoch_change(now: T::BlockNumber) -> Option<T::BlockNumber> {
let next_slot = Self::current_epoch_start().saturating_add(T::EpochDuration::get());
next_slot
Expand Down Expand Up @@ -754,6 +756,10 @@ impl<T: Config> OnTimestampSet<T::Moment> for Module<T> {
}

impl<T: Config> frame_support::traits::EstimateNextSessionRotation<T::BlockNumber> for Module<T> {
fn average_session_length() -> T::BlockNumber {
T::EpochDuration::get().saturated_into()
}

fn estimate_next_session_rotation(now: T::BlockNumber) -> Option<T::BlockNumber> {
Self::next_expected_epoch_change(now)
}
Expand Down
9 changes: 9 additions & 0 deletions frame/babe/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ use sp_consensus_babe::{AuthorityId, AuthorityPair, Slot};
use sp_consensus_vrf::schnorrkel::{VRFOutput, VRFProof};
use sp_staking::SessionIndex;
use pallet_staking::EraIndex;
use sp_election_providers::onchain;
use pallet_session::historical as pallet_session_historical;

type DummyValidatorId = u64;
Expand Down Expand Up @@ -183,6 +184,13 @@ parameter_types! {
pub const StakingUnsignedPriority: u64 = u64::max_value() / 2;
}

impl onchain::Config for Test {
type AccountId = <Self as frame_system::Config>::AccountId;
type BlockNumber = <Self as frame_system::Config>::BlockNumber;
type Accuracy = Perbill;
type DataProvider = Staking;
}

impl pallet_staking::Config for Test {
type RewardRemainder = ();
type CurrencyToVote = frame_support::traits::SaturatingCurrencyToVote;
Expand All @@ -205,6 +213,7 @@ impl pallet_staking::Config for Test {
type MaxIterations = ();
type MinSolutionScoreBump = ();
type OffchainSolutionWeightLimit = ();
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type WeightInfo = ();
}

Expand Down
66 changes: 66 additions & 0 deletions frame/election-provider-multi-phase/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
[package]
name = "pallet-election-provider-multi-phase"
version = "3.0.0"
authors = ["Parity Technologies <[email protected]>"]
edition = "2018"
license = "Apache-2.0"
homepage = "https://substrate.dev"
repository = "https://github.com/paritytech/substrate/"
description = "PALLET two phase election providers"
readme = "README.md"

[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

[dependencies]
static_assertions = "1.1.0"
serde = { version = "1.0.101", optional = true }
codec = { package = "parity-scale-codec", version = "2.0.0", default-features = false, features = ["derive"] }

frame-support = { version = "3.0.0", default-features = false, path = "../support" }
frame-system = { version = "3.0.0", default-features = false, path = "../system" }

sp-io ={ version = "3.0.0", default-features = false, path = "../../primitives/io" }
sp-std = { version = "3.0.0", default-features = false, path = "../../primitives/std" }
sp-runtime = { version = "3.0.0", default-features = false, path = "../../primitives/runtime" }
sp-npos-elections = { version = "3.0.0", default-features = false, path = "../../primitives/npos-elections" }
sp-arithmetic = { version = "3.0.0", default-features = false, path = "../../primitives/arithmetic" }
sp-election-providers = { version = "3.0.0", default-features = false, path = "../../primitives/election-providers" }

# Optional imports for benchmarking
frame-benchmarking = { version = "3.0.0", default-features = false, path = "../benchmarking", optional = true }
rand = { version = "0.7.3", default-features = false, optional = true, features = ["alloc", "small_rng"] }

[dev-dependencies]
paste = "1.0.3"
parking_lot = "0.11.0"
rand = { version = "0.7.3" }
hex-literal = "0.3.1"
substrate-test-utils = { version = "3.0.0", path = "../../test-utils" }
sp-io = { version = "3.0.0", path = "../../primitives/io" }
sp-core = { version = "3.0.0", path = "../../primitives/core" }
sp-tracing = { version = "3.0.0", path = "../../primitives/tracing" }
sp-election-providers = { version = "3.0.0", features = ["runtime-benchmarks"], path = "../../primitives/election-providers" }
pallet-balances = { version = "3.0.0", path = "../balances" }
frame-benchmarking = { path = "../benchmarking" }

[features]
default = ["std"]
std = [
"serde",
"codec/std",

"frame-support/std",
"frame-system/std",

"sp-io/std",
"sp-std/std",
"sp-runtime/std",
"sp-npos-elections/std",
"sp-arithmetic/std",
"sp-election-providers/std",
]
runtime-benchmarks = [
"frame-benchmarking",
"rand",
]
Loading

0 comments on commit 1c434cd

Please sign in to comment.