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

pallet-session: Migrate the historical part to the new pallet macro #9878

Merged
merged 16 commits into from
Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from 11 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
4 changes: 2 additions & 2 deletions frame/session/benchmarking/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

mod mock;

use sp_runtime::traits::{One, StaticLookup};
use sp_std::{prelude::*, vec};

use frame_benchmarking::benchmarks;
Expand All @@ -30,12 +31,11 @@ use frame_support::{
traits::{KeyOwnerProofSystem, OnInitialize},
};
use frame_system::RawOrigin;
use pallet_session::{historical::Module as Historical, Pallet as Session, *};
use pallet_session::{historical::Pallet as Historical, Pallet as Session, *};
use pallet_staking::{
benchmarking::create_validator_with_nominators, testing_utils::create_validators,
RewardDestination,
};
use sp_runtime::traits::{One, StaticLookup};

const MAX_VALIDATORS: u32 = 1000;

Expand Down
136 changes: 74 additions & 62 deletions frame/session/src/historical/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,62 +26,74 @@
//! These roots and proofs of inclusion can be generated at any time during the current session.
//! Afterwards, the proofs can be fed to a consensus module when reporting misbehavior.

use super::{Pallet as SessionModule, SessionIndex};
pub mod offchain;
pub mod onchain;
mod shared;

use codec::{Decode, Encode};
use frame_support::{
decl_module, decl_storage, print,
traits::{ValidatorSet, ValidatorSetWithIdentification},
Parameter,
};
use sp_runtime::{
traits::{Convert, OpaqueKeys},
KeyTypeId,
};
use sp_session::{MembershipProof, ValidatorCount};
use sp_staking::SessionIndex;
use sp_std::prelude::*;
use sp_trie::{
trie_types::{TrieDB, TrieDBMut},
MemoryDB, Recorder, Trie, TrieMut, EMPTY_PREFIX,
};

pub mod offchain;
pub mod onchain;
mod shared;
use frame_support::{
print,
traits::{KeyOwnerProofSystem, StorageVersion, ValidatorSet, ValidatorSetWithIdentification},
Parameter,
};

/// Config necessary for the historical module.
pub trait Config: super::Config {
/// Full identification of the validator.
type FullIdentification: Parameter;

/// A conversion from validator ID to full identification.
///
/// This should contain any references to economic actors associated with the
/// validator, since they may be outdated by the time this is queried from a
/// historical trie.
///
/// It must return the identification for the current session index.
type FullIdentificationOf: Convert<Self::ValidatorId, Option<Self::FullIdentification>>;
}
use crate::{self as pallet_session, Pallet as Session};

pub use pallet::*;

decl_storage! {
trait Store for Module<T: Config> as Session {
/// Mapping from historical session indices to session-data root hash and validator count.
HistoricalSessions get(fn historical_root):
map hasher(twox_64_concat) SessionIndex => Option<(T::Hash, ValidatorCount)>;
/// The range of historical sessions we store. [first, last)
StoredRange: Option<(SessionIndex, SessionIndex)>;
/// Deprecated.
CachedObsolete:
map hasher(twox_64_concat) SessionIndex
=> Option<Vec<(T::ValidatorId, T::FullIdentification)>>;
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;

/// The current storage version.
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);

#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
#[pallet::storage_version(STORAGE_VERSION)]
pub struct Pallet<T>(_);

/// Config necessary for the historical pallet.
#[pallet::config]
pub trait Config: pallet_session::Config + frame_system::Config {
/// Full identification of the validator.
type FullIdentification: Parameter;

/// A conversion from validator ID to full identification.
///
/// This should contain any references to economic actors associated with the
/// validator, since they may be outdated by the time this is queried from a
/// historical trie.
///
/// It must return the identification for the current session index.
type FullIdentificationOf: Convert<Self::ValidatorId, Option<Self::FullIdentification>>;
}
}

decl_module! {
pub struct Module<T: Config> for enum Call where origin: T::Origin {}
/// Mapping from historical session indices to session-data root hash and validator count.
#[pallet::storage]
#[pallet::getter(fn historical_root)]
pub type HistoricalSessions<T: Config> =
StorageMap<_, Twox64Concat, SessionIndex, (T::Hash, ValidatorCount), OptionQuery>;

/// The range of historical sessions we store. [first, last)
#[pallet::storage]
pub type StoredRange<T> = StorageValue<_, (SessionIndex, SessionIndex), OptionQuery>;
}

impl<T: Config> Module<T> {
impl<T: Config> Pallet<T> {
/// Prune historical stored session roots up to (but not including)
/// `up_to`.
pub fn prune_up_to(up_to: SessionIndex) {
Expand Down Expand Up @@ -109,7 +121,7 @@ impl<T: Config> Module<T> {
}
}

impl<T: Config> ValidatorSet<T::AccountId> for Module<T> {
impl<T: Config> ValidatorSet<T::AccountId> for Pallet<T> {
type ValidatorId = T::ValidatorId;
type ValidatorIdOf = T::ValidatorIdOf;

Expand All @@ -122,15 +134,15 @@ impl<T: Config> ValidatorSet<T::AccountId> for Module<T> {
}
}

impl<T: Config> ValidatorSetWithIdentification<T::AccountId> for Module<T> {
impl<T: Config> ValidatorSetWithIdentification<T::AccountId> for Pallet<T> {
type Identification = T::FullIdentification;
type IdentificationOf = T::FullIdentificationOf;
}

/// 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>
pallet_session::SessionManager<ValidatorId>
{
/// If there was a validator set change, its returns the set of new validators along with their
/// full identifications.
Expand All @@ -150,7 +162,7 @@ pub struct NoteHistoricalRoot<T, I>(sp_std::marker::PhantomData<(T, I)>);

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| {
<StoredRange<T>>::mutate(|range| {
range.get_or_insert_with(|| (new_index, new_index)).1 = new_index + 1;
});

Expand Down Expand Up @@ -183,7 +195,7 @@ impl<T: Config, I: SessionManager<T::ValidatorId, T::FullIdentification>> NoteHi
}
}

impl<T: Config, I> crate::SessionManager<T::ValidatorId> for NoteHistoricalRoot<T, I>
impl<T: Config, I> pallet_session::SessionManager<T::ValidatorId> for NoteHistoricalRoot<T, I>
where
I: SessionManager<T::ValidatorId, T::FullIdentification>,
{
Expand All @@ -207,7 +219,7 @@ where

/// A tuple of the validator's ID and their full identification.
pub type IdentificationTuple<T> =
(<T as crate::Config>::ValidatorId, <T as Config>::FullIdentification);
(<T as pallet_session::Config>::ValidatorId, <T as Config>::FullIdentification);

/// A trie instance for checking and generating proofs.
pub struct ProvingTrie<T: Config> {
Expand All @@ -227,7 +239,7 @@ impl<T: Config> ProvingTrie<T> {
let mut trie = TrieDBMut::new(&mut db, &mut root);
for (i, (validator, full_id)) in validators.into_iter().enumerate() {
let i = i as u32;
let keys = match <SessionModule<T>>::load_keys(&validator) {
let keys = match <Session<T>>::load_keys(&validator) {
None => continue,
Some(k) => k,
};
Expand Down Expand Up @@ -304,15 +316,13 @@ impl<T: Config> ProvingTrie<T> {
}
}

impl<T: Config, D: AsRef<[u8]>> frame_support::traits::KeyOwnerProofSystem<(KeyTypeId, D)>
for Module<T>
{
impl<T: Config, D: AsRef<[u8]>> KeyOwnerProofSystem<(KeyTypeId, D)> for Pallet<T> {
type Proof = MembershipProof;
type IdentificationTuple = IdentificationTuple<T>;

fn prove(key: (KeyTypeId, D)) -> Option<Self::Proof> {
let session = <SessionModule<T>>::current_index();
let validators = <SessionModule<T>>::validators()
let session = <Session<T>>::current_index();
let validators = <Session<T>>::validators()
.into_iter()
.filter_map(|validator| {
T::FullIdentificationOf::convert(validator.clone())
Expand All @@ -335,10 +345,10 @@ impl<T: Config, D: AsRef<[u8]>> frame_support::traits::KeyOwnerProofSystem<(KeyT
fn check_proof(key: (KeyTypeId, D), proof: Self::Proof) -> Option<IdentificationTuple<T>> {
let (id, data) = key;

if proof.session == <SessionModule<T>>::current_index() {
<SessionModule<T>>::key_owner(id, data.as_ref()).and_then(|owner| {
if proof.session == <Session<T>>::current_index() {
<Session<T>>::key_owner(id, data.as_ref()).and_then(|owner| {
T::FullIdentificationOf::convert(owner.clone()).and_then(move |id| {
let count = <SessionModule<T>>::validators().len() as ValidatorCount;
let count = <Session<T>>::validators().len() as ValidatorCount;

if count != proof.validator_count {
return None
Expand Down Expand Up @@ -374,7 +384,7 @@ pub(crate) mod tests {
BasicExternalities,
};

type Historical = Module<Test>;
type Historical = Pallet<Test>;

pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
Expand All @@ -386,7 +396,9 @@ pub(crate) mod tests {
frame_system::Pallet::<Test>::inc_providers(k);
}
});
crate::GenesisConfig::<Test> { keys }.assimilate_storage(&mut t).unwrap();
pallet_session::GenesisConfig::<Test> { keys }
.assimilate_storage(&mut t)
.unwrap();
sp_io::TestExternalities::new(t)
}

Expand Down Expand Up @@ -436,27 +448,27 @@ pub(crate) mod tests {
Session::on_initialize(i);
}

assert_eq!(StoredRange::get(), Some((0, 100)));
assert_eq!(<StoredRange<Test>>::get(), Some((0, 100)));

for i in 0..100 {
assert!(Historical::historical_root(i).is_some())
}

Historical::prune_up_to(10);
assert_eq!(StoredRange::get(), Some((10, 100)));
assert_eq!(<StoredRange<Test>>::get(), Some((10, 100)));

Historical::prune_up_to(9);
assert_eq!(StoredRange::get(), Some((10, 100)));
assert_eq!(<StoredRange<Test>>::get(), Some((10, 100)));

for i in 10..100 {
assert!(Historical::historical_root(i).is_some())
}

Historical::prune_up_to(99);
assert_eq!(StoredRange::get(), Some((99, 100)));
assert_eq!(<StoredRange<Test>>::get(), Some((99, 100)));

Historical::prune_up_to(100);
assert_eq!(StoredRange::get(), None);
assert_eq!(<StoredRange<Test>>::get(), None);

for i in 99..199u64 {
set_next_validators(vec![i]);
Expand All @@ -466,14 +478,14 @@ pub(crate) mod tests {
Session::on_initialize(i);
}

assert_eq!(StoredRange::get(), Some((100, 200)));
assert_eq!(<StoredRange<Test>>::get(), Some((100, 200)));

for i in 100..200 {
assert!(Historical::historical_root(i).is_some())
}

Historical::prune_up_to(9999);
assert_eq!(StoredRange::get(), None);
assert_eq!(<StoredRange<Test>>::get(), None);

for i in 100..200 {
assert!(Historical::historical_root(i).is_none())
Expand Down
4 changes: 2 additions & 2 deletions frame/session/src/historical/offchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ pub fn keep_newest<T: Config>(n_to_keep: usize) {
mod tests {
use super::*;
use crate::{
historical::{onchain, Module},
historical::{onchain, Pallet},
mock::{force_new_session, set_next_validators, Session, System, Test, NEXT_VALIDATORS},
};

Expand All @@ -156,7 +156,7 @@ mod tests {
BasicExternalities,
};

type Historical = Module<Test>;
type Historical = Pallet<Test>;

pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default()
Expand Down
1 change: 1 addition & 0 deletions frame/session/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@

#[cfg(feature = "historical")]
pub mod historical;
pub mod migrations;
#[cfg(test)]
mod mock;
#[cfg(test)]
Expand Down
24 changes: 24 additions & 0 deletions frame/session/src/migrations/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// This file is part of Substrate.

// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: Apache-2.0

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/// Version 1.
///
/// In version 0 session historical pallet uses `Session` for storage module prefix.
/// In version 1 it uses its name as configured in `construct_runtime`.
/// This migration moves session historical pallet storages from old prefix to new prefix.
#[cfg(feature = "historical")]
pub mod v1;
Loading