Skip to content

Commit

Permalink
Remove without_storage_info for the poa pallet - V2 (#633)
Browse files Browse the repository at this point in the history
* remove without_storage_info

Signed-off-by: R.Rajeshkumar <rajesh@nodle.com>

* remove without_storage_info

Signed-off-by: R.Rajeshkumar <rajesh@nodle.com>

* runtime migration updates

Signed-off-by: R.Rajeshkumar <rajesh@nodle.com>

* runtime migration updates

Signed-off-by: R.Rajeshkumar <rajesh@nodle.com>

* staking migration changes

Signed-off-by: R.Rajeshkumar <rajesh@nodle.com>

Co-authored-by: R.Rajeshkumar <rajesh@nodle.com>
Co-authored-by: Alex Sedighi <alex@nodle.com>
  • Loading branch information
3 people committed Jul 28, 2022
1 parent a331f30 commit 8a1b78c
Show file tree
Hide file tree
Showing 10 changed files with 458 additions and 267 deletions.
6 changes: 5 additions & 1 deletion Cargo.lock

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

9 changes: 8 additions & 1 deletion pallets/poa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ std = [
"frame-support/std",
"frame-system/std",
"pallet-session/std",
"pallet-membership/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
"sp-staking/std",
]
try-runtime = ["frame-support/try-runtime"]

[dependencies]
log = { version = "0.4.14", default-features = false }
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] }
serde = { version = "1.0.136", optional = true, features = ["derive"] }
scale-info = { version = "2.0.1", default-features = false, features = ["derive"] }
Expand All @@ -28,6 +32,9 @@ pallet-session = { git = "https://github.com/paritytech/substrate", default-feat
sp-io = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.20" }
sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.20" }
sp-std = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.20" }
sp-staking = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.20" }

[dev-dependencies]
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.20" }
sp-tracing = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.20" }
sp-core = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.20" }
pallet-membership = { git = "https://github.com/paritytech/substrate", default-features = false , branch = "polkadot-v0.9.20" }
97 changes: 43 additions & 54 deletions pallets/poa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,65 +24,76 @@
#[cfg(test)]
mod tests;

use frame_support::traits::{ChangeMembers, InitializeMembers};
mod migrations;

use codec::{Decode, Encode};

use frame_support::{pallet_prelude::MaxEncodedLen, traits::SortedMembers};
use pallet_session::SessionManager;
use sp_runtime::traits::Convert;
use scale_info::TypeInfo;
use sp_runtime::RuntimeDebug;
use sp_staking::SessionIndex;
use sp_std::prelude::Vec;

pub use pallet::*;

// A value placed in storage that represents the current version of the POA storage.
// This value is used by the `on_runtime_upgrade` logic to determine whether we run storage
// migration logic. This should match directly with the semantic versions of the Rust crate.
#[derive(Encode, MaxEncodedLen, Decode, Clone, Copy, PartialEq, Eq, RuntimeDebug, TypeInfo)]
enum Releases {
V0, // Legacy version
V1, // Adds storage info
}

impl Default for Releases {
fn default() -> Self {
Releases::V0
}
}

#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;

#[pallet::config]
pub trait Config: frame_system::Config + pallet_session::Config {}
pub trait Config: frame_system::Config + pallet_session::Config {
type ValidatorsSet: SortedMembers<Self::AccountId>;
}

#[pallet::pallet]
#[pallet::without_storage_info]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(PhantomData<T>);

#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}

#[pallet::call]
impl<T: Config> Pallet<T> {}

#[pallet::storage]
#[pallet::getter(fn validators)]
pub type Validators<T: Config> = StorageValue<_, Vec<T::AccountId>, ValueQuery>;
}
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
#[cfg(feature = "try-runtime")]
fn pre_upgrade() -> Result<(), &'static str> {
migrations::v1::pre_upgrade::<T>()
}

impl<T: Config> ChangeMembers<T::AccountId> for Pallet<T> {
fn change_members_sorted(_incoming: &[T::AccountId], _outgoing: &[T::AccountId], new: &[T::AccountId]) {
<Validators<T>>::put(new);
}
}
fn on_runtime_upgrade() -> frame_support::weights::Weight {
migrations::v1::on_runtime_upgrade::<T>()
}

impl<T: Config> InitializeMembers<T::AccountId> for Pallet<T> {
fn initialize_members(init: &[T::AccountId]) {
<Validators<T>>::put(init);
// Shouldn't need a flag update here as this should happen at genesis
#[cfg(feature = "try-runtime")]
fn post_upgrade() -> Result<(), &'static str> {
migrations::v1::post_upgrade::<T>()
}
}
}

/// Compatibility code for the session historical code
pub type FullIdentification = u32;
pub struct FullIdentificationOf<T>(sp_std::marker::PhantomData<T>);
#[pallet::call]
impl<T: Config> Pallet<T> {}

impl<T: Config> Convert<T::AccountId, Option<FullIdentification>> for FullIdentificationOf<T> {
fn convert(_validator: T::AccountId) -> Option<FullIdentification> {
Some(0)
}
#[pallet::storage]
pub(crate) type StorageVersion<T: Config> = StorageValue<_, Releases, ValueQuery>;
}

type SessionIndex = u32; // A shim while waiting for this type to be exposed by `session`
impl<T: Config> SessionManager<T::AccountId> for Pallet<T> {
fn new_session(_: SessionIndex) -> Option<Vec<T::AccountId>> {
let all_keys = Validators::<T>::get();
let all_keys = T::ValidatorsSet::sorted_members();
if all_keys.is_empty() {
None
} else {
Expand All @@ -93,25 +104,3 @@ impl<T: Config> SessionManager<T::AccountId> for Pallet<T> {
fn start_session(_: SessionIndex) {}
fn end_session(_: SessionIndex) {}
}

impl<T: Config> pallet_session::historical::SessionManager<T::AccountId, FullIdentification> for Pallet<T> {
fn new_session(new_index: SessionIndex) -> Option<Vec<(T::AccountId, FullIdentification)>> {
<Self as pallet_session::SessionManager<_>>::new_session(new_index).map(|validators| {
validators
.into_iter()
.map(|v| {
let full_identification = FullIdentificationOf::<T>::convert(v.clone()).unwrap_or(0);
(v, full_identification)
})
.collect()
})
}

fn start_session(start_index: SessionIndex) {
<Self as pallet_session::SessionManager<_>>::start_session(start_index)
}

fn end_session(end_index: SessionIndex) {
<Self as pallet_session::SessionManager<_>>::end_session(end_index)
}
}
118 changes: 118 additions & 0 deletions pallets/poa/src/migrations.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* This file is part of the Nodle Chain distributed at https://github.com/NodleCode/chain
* Copyright (C) 2020-2022 Nodle International
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

pub mod v1 {
use crate::{Config, Releases, StorageVersion};
use frame_support::{storage::migration::remove_storage_prefix, traits::Get, weights::Weight};

pub fn on_runtime_upgrade<T: Config>() -> Weight {
log::info!(
"on_runtime_upgrade[{:#?}]=> Running migration with current storage version {:?} / onchain {:?}",
line!(),
crate::Releases::V1,
<StorageVersion<T>>::get(),
);

if <StorageVersion<T>>::get() == Releases::V0 {
let pallet_prefix: &[u8] = b"Poa";
let storage_item_prefix: &[u8] = b"Validators";

remove_storage_prefix(pallet_prefix, storage_item_prefix, &[]);

<StorageVersion<T>>::put(crate::Releases::V1);

log::info!(
"on_runtime_upgrade[{:#?}]=> Removed Validators, Migrated to storage version {:?}",
line!(),
<StorageVersion<T>>::get()
);

T::DbWeight::get().reads_writes(1, 1)
} else {
log::info!(
"on_runtime_upgrade[{:#?}]=> Migration did not executed. This probably should be removed",
line!(),
);
T::DbWeight::get().reads(1)
}
}

#[cfg(feature = "try-runtime")]
pub fn pre_upgrade<T: Config>() -> Result<(), &'static str> {
use frame_support::storage::migration::get_storage_value;

log::info!(
"pre_upgrade[{:#?}]=> with current storage version {:?} / onchain {:?}",
line!(),
crate::Releases::V1,
<StorageVersion<T>>::get(),
);

if <StorageVersion<T>>::get() == Releases::V0 {
let pallet_prefix: &[u8] = b"Poa";
let storage_item_prefix: &[u8] = b"Validators";

let maybe_stored_data = get_storage_value::<Vec<T::AccountId>>(pallet_prefix, storage_item_prefix, &[]);

if let Some(stored_data) = maybe_stored_data {
log::info!(
"pre_upgrade[{:#?}]=> Validators count :: [{:#?}]",
line!(),
stored_data.len(),
);
} else {
log::error!("pre_upgrade[{:#?}]=> Storage Validators not found", line!(),);
Err("Storage Validators not found")?;
}
} else {
log::info!(
"pre_upgrade[{:#?}]=> Migration did not executed. This probably should be removed",
line!(),
);
}

Ok(())
}

#[cfg(feature = "try-runtime")]
pub fn post_upgrade<T: Config>() -> Result<(), &'static str> {
use frame_support::storage::migration::get_storage_value;
log::info!(
"post_upgrade[{:#?}]=> with current storage version {:?} / onchain {:?}",
line!(),
crate::Releases::V1,
<StorageVersion<T>>::get(),
);

if <StorageVersion<T>>::get() == Releases::V1 {
let pallet_prefix: &[u8] = b"Poa";
let storage_item_prefix: &[u8] = b"Validators";

if get_storage_value::<Vec<T::AccountId>>(pallet_prefix, storage_item_prefix, &[]).is_some() {
Err("Storage Validators not removed")?;
}
} else {
log::info!(
"post_upgrade[{:#?}]=> Migration did not executed. This probably should be removed",
line!(),
);
}

Ok(())
}
}

0 comments on commit 8a1b78c

Please sign in to comment.