Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 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 bin/node/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ frame-benchmarking = { version = "3.1.0", default-features = false, path = "../.
frame-support = { version = "3.0.0", default-features = false, path = "../../../frame/support" }
frame-system = { version = "3.0.0", default-features = false, path = "../../../frame/system" }
frame-system-benchmarking = { version = "3.0.0", default-features = false, path = "../../../frame/system/benchmarking", optional = true }
frame-election-provider-support = { version = "3.0.0", default-features = false, path = "../../../frame/election-provider-support" }
frame-system-rpc-runtime-api = { version = "3.0.0", default-features = false, path = "../../../frame/system/rpc/runtime-api/" }
frame-try-runtime = { version = "0.9.0", default-features = false, path = "../../../frame/try-runtime", optional = true }
pallet-assets = { version = "3.0.0", default-features = false, path = "../../../frame/assets" }
Expand Down
5 changes: 4 additions & 1 deletion bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -467,14 +467,15 @@ pallet_staking_reward_curve::build! {
}

parameter_types! {
pub const SessionsPerEra: sp_staking::SessionIndex = 3; // TODO: just for testing, revert at last.
pub const SessionsPerEra: sp_staking::SessionIndex = 1; // TODO: just for testing, revert at last.
pub const BondingDuration: pallet_staking::EraIndex = 24 * 28;
pub const SlashDeferDuration: pallet_staking::EraIndex = 24 * 7; // 1/4 the bonding duration.
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
pub const MaxNominatorRewardedPerValidator: u32 = 256;
pub OffchainRepeat: BlockNumber = 5;
}

use frame_election_provider_support::onchain;
impl pallet_staking::Config for Runtime {
const MAX_NOMINATIONS: u32 = MAX_NOMINATIONS;
type Currency = Balances;
Expand All @@ -498,6 +499,8 @@ impl pallet_staking::Config for Runtime {
type NextNewSession = Session;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type ElectionProvider = ElectionProviderMultiPhase;
type GenesisElectionProvider =
onchain::OnChainSequentialPhragmen<pallet_election_provider_multi_phase::OnChainConfig<Self>>;
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
}

Expand Down
1 change: 1 addition & 0 deletions frame/babe/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,7 @@ impl pallet_staking::Config for Test {
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type NextNewSession = Session;
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
type WeightInfo = ();
}

Expand Down
32 changes: 11 additions & 21 deletions frame/election-provider-multi-phase/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ pub type CompactAccuracyOf<T> = <CompactOf<T> as CompactSolution>::Accuracy;
pub type OnChainAccuracyOf<T> = <T as Config>::OnChainAccuracy;

/// Wrapper type that implements the configurations needed for the on-chain backup.
struct OnChainConfig<T: Config>(sp_std::marker::PhantomData<T>);
pub struct OnChainConfig<T: Config>(sp_std::marker::PhantomData<T>);
impl<T: Config> onchain::Config for OnChainConfig<T> {
type AccountId = T::AccountId;
type BlockNumber = T::BlockNumber;
Expand Down Expand Up @@ -1277,27 +1277,17 @@ impl<T: Config> ElectionProvider<T::AccountId, T::BlockNumber> for Pallet<T> {
type DataProvider = T::DataProvider;

fn elect() -> Result<(Supports<T::AccountId>, Weight), Self::Error> {
if Self::round() > 1 {
match Self::do_elect() {
Ok((supports, weight)) => {
// all went okay, put sign to be Off, clean snapshot, etc.
Self::rotate_round();
Ok((supports, weight))
}
Err(why) => {
log!(error, "Entering emergency mode.");
<CurrentPhase<T>>::put(Phase::Emergency);
Err(why)
}
match Self::do_elect() {
Ok((supports, weight)) => {
// all went okay, put sign to be Off, clean snapshot, etc.
Self::rotate_round();
Ok((supports, weight))
}
Err(why) => {
log!(error, "Entering emergency mode.");
<CurrentPhase<T>>::put(Phase::Emergency);
Err(why)
}
} else {
// first round, always run on-chain.
// TODO: move all of this into a new trait like `GenesisElectionProvide`, or a new
// function in the same trait.
let result = Self::onchain_fallback();
log!(info, "Finalized initial election round with onchain compute.");
Self::rotate_round();
result
}
}
}
Expand Down
1 change: 1 addition & 0 deletions frame/grandpa/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ impl pallet_staking::Config for Test {
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type NextNewSession = Session;
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
type WeightInfo = ();
}

Expand Down
1 change: 1 addition & 0 deletions frame/offences/benchmarking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ impl pallet_staking::Config for Test {
type NextNewSession = Session;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
type WeightInfo = ();
}

Expand Down
2 changes: 2 additions & 0 deletions frame/session/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ frame-support = { version = "3.0.0", default-features = false, path = "../suppor
frame-system = { version = "3.0.0", default-features = false, path = "../system" }
pallet-timestamp = { version = "3.0.0", default-features = false, path = "../timestamp" }
sp-trie = { version = "3.0.0", optional = true, default-features = false, path = "../../primitives/trie" }
log = { version = "0.4.0", default-features = false }
impl-trait-for-tuples = "0.2.1"

[dev-dependencies]
Expand All @@ -44,5 +45,6 @@ std = [
"sp-staking/std",
"pallet-timestamp/std",
"sp-trie/std",
"log/std",
]
try-runtime = ["frame-support/try-runtime"]
1 change: 1 addition & 0 deletions frame/session/benchmarking/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ impl pallet_staking::Config for Test {
type NextNewSession = Session;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type ElectionProvider = onchain::OnChainSequentialPhragmen<Self>;
type GenesisElectionProvider = Self::ElectionProvider;
type WeightInfo = ();
}

Expand Down
41 changes: 31 additions & 10 deletions frame/session/src/historical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,17 @@ impl<T: Config> ValidatorSetWithIdentification<T::AccountId> for Module<T> {

/// Specialization of the crate-level `SessionManager` which returns the set of full identification
/// when creating a new session.
pub trait SessionManager<ValidatorId, FullIdentification>: crate::SessionManager<ValidatorId> {
pub trait SessionManager<ValidatorId, FullIdentification>:
crate::SessionManager<ValidatorId>
{
/// If there was a validator set change, its returns the set of new validators along with their
/// full identifications.
fn new_session(new_index: SessionIndex) -> Option<Vec<(ValidatorId, FullIdentification)>>;
fn new_session_genesis(
new_index: SessionIndex,
) -> Option<Vec<(ValidatorId, FullIdentification)>> {
<Self as SessionManager<_, _>>::new_session(new_index)
}
fn start_session(start_index: SessionIndex);
fn end_session(end_index: SessionIndex);
}
Expand All @@ -136,19 +143,20 @@ pub trait SessionManager<ValidatorId, FullIdentification>: crate::SessionManager
/// sets the historical trie root of the ending session.
pub struct NoteHistoricalRoot<T, I>(sp_std::marker::PhantomData<(T, I)>);

impl<T: Config, I> crate::SessionManager<T::ValidatorId> for NoteHistoricalRoot<T, I>
where I: SessionManager<T::ValidatorId, T::FullIdentification>
{
fn new_session(new_index: SessionIndex) -> Option<Vec<T::ValidatorId>> {

impl<T: Config, I: SessionManager<T::ValidatorId, T::FullIdentification>> NoteHistoricalRoot<T, I> {
fn do_new_session(new_index: SessionIndex, is_genesis: bool) -> Option<Vec<T::ValidatorId>> {
StoredRange::mutate(|range| {
range.get_or_insert_with(|| (new_index, new_index)).1 = new_index + 1;
});

let new_validators_and_id = <I as SessionManager<_, _>>::new_session(new_index);
let new_validators = new_validators_and_id.as_ref().map(|new_validators| {
new_validators.iter().map(|(v, _id)| v.clone()).collect()
});
let new_validators_and_id = if is_genesis {
<I as SessionManager<_, _>>::new_session_genesis(new_index)
} else {
<I as SessionManager<_, _>>::new_session(new_index)
};
let new_validators = new_validators_and_id
.as_ref()
.map(|new_validators| new_validators.iter().map(|(v, _id)| v.clone()).collect());

if let Some(new_validators) = new_validators_and_id {
let count = new_validators.len() as ValidatorCount;
Expand All @@ -168,6 +176,19 @@ impl<T: Config, I> crate::SessionManager<T::ValidatorId> for NoteHistoricalRoot<

new_validators
}
}

impl<T: Config, I> crate::SessionManager<T::ValidatorId> for NoteHistoricalRoot<T, I>
where
I: SessionManager<T::ValidatorId, T::FullIdentification>,
{
fn new_session(new_index: SessionIndex) -> Option<Vec<T::ValidatorId>> {
Self::do_new_session(new_index, false)
}

fn new_session_genesis(new_index: SessionIndex) -> Option<Vec<T::ValidatorId>> {
Self::do_new_session(new_index, true)
}

fn start_session(start_index: SessionIndex) {
<I as SessionManager<_, _>>::start_session(start_index)
Expand Down
27 changes: 15 additions & 12 deletions frame/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,12 +238,19 @@ pub trait SessionManager<ValidatorId> {
/// `new_session(session)` is guaranteed to be called before `end_session(session-1)`. In other
/// words, a new session must always be planned before an ongoing one can be finished.
fn new_session(new_index: SessionIndex) -> Option<Vec<ValidatorId>>;
/// Same as `new_session`, but it this should only be called at genesis.
///
/// The session manager might decide to treat this in a different way. Default impl is simply
/// using [`new_session`].
fn new_session_genesis(new_index: SessionIndex) -> Option<Vec<ValidatorId>> {
Self::new_session(new_index)
}
/// End the session.
///
/// Because the session pallet can queue validator set the ending session can be lower than the
/// last new session index.
fn end_session(end_index: SessionIndex);
/// Start the session.
/// Start an already planned the session.
///
/// The session start to be used for validation.
fn start_session(start_index: SessionIndex);
Expand Down Expand Up @@ -340,13 +347,9 @@ impl<AId> SessionHandler<AId> for Tuple {
pub struct TestSessionHandler;
impl<AId> SessionHandler<AId> for TestSessionHandler {
const KEY_TYPE_IDS: &'static [KeyTypeId] = &[sp_runtime::key_types::DUMMY];

fn on_genesis_session<Ks: OpaqueKeys>(_: &[(AId, Ks)]) {}

fn on_new_session<Ks: OpaqueKeys>(_: bool, _: &[(AId, Ks)], _: &[(AId, Ks)]) {}

fn on_before_session_ending() {}

fn on_disabled(_: usize) {}
}

Expand Down Expand Up @@ -451,15 +454,15 @@ decl_storage! {
}
}

let initial_validators_0 = T::SessionManager::new_session(0)
let initial_validators_0 = T::SessionManager::new_session_genesis(0)
.unwrap_or_else(|| {
frame_support::print("No initial validator provided by `SessionManager`, use \
session config keys to generate initial validator set.");
config.keys.iter().map(|x| x.1.clone()).collect()
});
assert!(!initial_validators_0.is_empty(), "Empty validator set for session 0 in genesis block!");

let initial_validators_1 = T::SessionManager::new_session(1)
let initial_validators_1 = T::SessionManager::new_session_genesis(1)
.unwrap_or_else(|| initial_validators_0.clone());
assert!(!initial_validators_1.is_empty(), "Empty validator set for session 1 in genesis block!");

Expand Down Expand Up @@ -548,7 +551,7 @@ decl_module! {
/// Actual cost depends on the number of length of `T::Keys::key_ids()` which is fixed.
/// - DbReads: `T::ValidatorIdOf`, `NextKeys`, `origin account`
/// - DbWrites: `NextKeys`, `origin account`
/// - DbWrites per key id: `KeyOwnder`
/// - DbWrites per key id: `KeyOwner`
/// # </weight>
#[weight = T::WeightInfo::purge_keys()]
pub fn purge_keys(origin) {
Expand All @@ -573,17 +576,17 @@ decl_module! {
}

impl<T: Config> Module<T> {
/// Move on to next session. Register new validator set and session keys. Changes
/// to the validator set have a session of delay to take effect. This allows for
/// equivocation punishment after a fork.
/// Move on to next session. Register new validator set and session keys. Changes to the
/// validator set have a session of delay to take effect. This allows for equivocation
/// punishment after a fork.
pub fn rotate_session() {
let session_index = CurrentIndex::get();
log::trace!(target: "runtime::session", "rotating session {:?}", session_index);

let changed = QueuedChanged::get();

// Inform the session handlers that a session is going to end.
T::SessionHandler::on_before_session_ending();

T::SessionManager::end_session(session_index);

// Get queued session keys and validators.
Expand Down
6 changes: 3 additions & 3 deletions frame/staking/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub fn create_validator_with_nominators<T: Config>(
ValidatorCount::put(1);

// Start a new Era
let new_validators = Staking::<T>::try_trigger_new_era(SessionIndex::one()).unwrap();
let new_validators = Staking::<T>::try_trigger_new_era(SessionIndex::one(), true).unwrap();

assert_eq!(new_validators.len(), 1);
assert_eq!(new_validators[0], v_stash, "Our validator was not selected!");
Expand Down Expand Up @@ -484,7 +484,7 @@ benchmarks! {
)?;
let session_index = SessionIndex::one();
}: {
let validators = Staking::<T>::try_trigger_new_era(session_index)
let validators = Staking::<T>::try_trigger_new_era(session_index, true)
.ok_or("`new_era` failed")?;
assert!(validators.len() == v as usize);
}
Expand All @@ -501,7 +501,7 @@ benchmarks! {
None,
)?;
// Start a new Era
let new_validators = Staking::<T>::try_trigger_new_era(SessionIndex::one()).unwrap();
let new_validators = Staking::<T>::try_trigger_new_era(SessionIndex::one(), true).unwrap();
assert!(new_validators.len() == v as usize);

let current_era = CurrentEra::get().unwrap();
Expand Down
Loading