Skip to content

Commit c707e66

Browse files
authored
feat: staking v5 migrations (#249)
* wip: initialize v5 migrations * fix: try-runtime run even if everything is up to date * wip: staking migrations * tests: add tests * fix tests * chore: 🧹 * add benchmarks * fix weights
1 parent 0fc6376 commit c707e66

File tree

12 files changed

+105
-71
lines changed

12 files changed

+105
-71
lines changed

pallets/delegation/src/migrations.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl<T: Config> VersionMigratorTrait<T> for DelegationStorageVersion {
5858
fn pre_migrate(&self) -> Result<(), &str> {
5959
match *self {
6060
Self::V1 => v1::pre_migrate::<T>(),
61-
Self::V2 => Err("Already latest v2 version."),
61+
Self::V2 => Ok(()),
6262
}
6363
}
6464

@@ -76,7 +76,7 @@ impl<T: Config> VersionMigratorTrait<T> for DelegationStorageVersion {
7676
fn post_migrate(&self) -> Result<(), &str> {
7777
match *self {
7878
Self::V1 => v1::post_migrate::<T>(),
79-
Self::V2 => Err("Migration from v2 should have never happened in the first place."),
79+
Self::V2 => Ok(()),
8080
}
8181
}
8282
}
@@ -104,11 +104,6 @@ impl<T: Config> DelegationStorageMigrator<T> {
104104
/// latest possible.
105105
#[cfg(feature = "try-runtime")]
106106
pub(crate) fn pre_migrate() -> Result<(), &'static str> {
107-
ensure!(
108-
StorageVersion::<T>::get() < DelegationStorageVersion::latest(),
109-
"Already the latest storage version."
110-
);
111-
112107
// Don't need to check for any other pre_migrate, as in try-runtime it is also
113108
// called in the migrate() function. Same applies for post_migrate checks for
114109
// each version migrator.

pallets/did/src/migrations.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ impl<T: Config> VersionMigratorTrait<T> for DidStorageVersion {
5858
fn pre_migrate(&self) -> Result<(), &str> {
5959
match *self {
6060
Self::V1 => v1::pre_migrate::<T>(),
61-
Self::V2 => Err("Already latest v2 version."),
61+
Self::V2 => Ok(()),
6262
}
6363
}
6464

@@ -76,7 +76,7 @@ impl<T: Config> VersionMigratorTrait<T> for DidStorageVersion {
7676
fn post_migrate(&self) -> Result<(), &str> {
7777
match *self {
7878
Self::V1 => v1::post_migrate::<T>(),
79-
Self::V2 => Err("Migration from v2 should have never happened in the first place."),
79+
Self::V2 => Ok(()),
8080
}
8181
}
8282
}
@@ -104,11 +104,6 @@ impl<T: Config> DidStorageMigrator<T> {
104104
/// latest possible.
105105
#[cfg(feature = "try-runtime")]
106106
pub(crate) fn pre_migrate() -> Result<(), &'static str> {
107-
ensure!(
108-
StorageVersion::<T>::get() < DidStorageVersion::latest(),
109-
"Already the latest storage version."
110-
);
111-
112107
// Don't need to check for any other pre_migrate, as in try-runtime it is also
113108
// called in the migrate() function. Same applies for post_migrate checks for
114109
// each version migrator.

pallets/parachain-staking/src/default_weights.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 128
2424
2525
// Executed Command:
26-
// /home/willi/mashnet-node/target/release/kilt-parachain
26+
// target/release/kilt-parachain
2727
// benchmark
2828
// --chain=dev
2929
// --steps=50
@@ -33,8 +33,8 @@
3333
// --execution=wasm
3434
// --wasm-execution=compiled
3535
// --heap-pages=4096
36-
// --output=../../pallets/parachain-staking/src/default_weights.rs
37-
// --template=../../.maintain/weight-template.hbs
36+
// --output=pallets/parachain-staking/src/default_weights.rs
37+
// --template=.maintain/weight-template.hbs
3838

3939

4040
#![cfg_attr(rustfmt, rustfmt_skip)]

pallets/parachain-staking/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ pub mod pallet {
593593
/// It maps from an account to its information.
594594
#[pallet::storage]
595595
#[pallet::getter(fn candidate_pool)]
596+
#[pallet::storage_prefix = "CollatorState"]
596597
pub(crate) type CandidatePool<T: Config> = StorageMap<
597598
_,
598599
Twox64Concat,
@@ -613,6 +614,7 @@ pub mod pallet {
613614
/// non collating candidates is not included in [TotalCollatorStake].
614615
#[pallet::storage]
615616
#[pallet::getter(fn total_collator_stake)]
617+
#[pallet::storage_prefix = "Total"]
616618
pub(crate) type TotalCollatorStake<T: Config> = StorageValue<_, TotalStake<BalanceOf<T>>, ValueQuery>;
617619

618620
/// The collator candidates with the highest amount of stake.
@@ -626,6 +628,7 @@ pub mod pallet {
626628
/// that a collator can drop out of the collator set by reducing his stake.
627629
#[pallet::storage]
628630
#[pallet::getter(fn top_candidates)]
631+
#[pallet::storage_prefix = "CollatorPool"]
629632
pub(crate) type TopCandidates<T: Config> =
630633
StorageValue<_, OrderedSet<Stake<T::AccountId, BalanceOf<T>>, T::MaxTopCandidates>, ValueQuery>;
631634

pallets/parachain-staking/src/migrations.rs

Lines changed: 14 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ use crate::*;
2929
mod v2;
3030
mod v3;
3131
mod v4;
32+
mod v5;
3233

3334
/// A trait that allows version migrators to access the underlying pallet's
3435
/// context, e.g., its Config trait.
@@ -53,13 +54,14 @@ pub enum StakingStorageVersion {
5354
V2_0_0, // New Reward calculation, MaxCollatorCandidateStake
5455
V3_0_0, // Update InflationConfig
5556
V4, // Sort TopCandidates and parachain-stakings by amount
57+
V5, // Remove SelectedCandidates, Count Candidates
5658
}
5759

5860
#[cfg(feature = "try-runtime")]
5961
impl StakingStorageVersion {
6062
/// The latest storage version.
6163
fn latest() -> Self {
62-
Self::V4
64+
Self::V5
6365
}
6466
}
6567

@@ -84,7 +86,8 @@ impl<T: Config> VersionMigratorTrait<T> for StakingStorageVersion {
8486
Self::V1_0_0 => v2::pre_migrate::<T>(),
8587
Self::V2_0_0 => v3::pre_migrate::<T>(),
8688
Self::V3_0_0 => v4::pre_migrate::<T>(),
87-
Self::V4 => Err("Already on latest version v4."),
89+
Self::V4 => v5::pre_migrate::<T>(),
90+
Self::V5 => Ok(()),
8891
}
8992
}
9093

@@ -94,7 +97,8 @@ impl<T: Config> VersionMigratorTrait<T> for StakingStorageVersion {
9497
Self::V1_0_0 => v2::migrate::<T>(),
9598
Self::V2_0_0 => v3::migrate::<T>(),
9699
Self::V3_0_0 => v4::migrate::<T>(),
97-
Self::V4 => Weight::zero(),
100+
Self::V4 => v5::migrate::<T>(),
101+
Self::V5 => Weight::zero(),
98102
}
99103
}
100104

@@ -106,7 +110,8 @@ impl<T: Config> VersionMigratorTrait<T> for StakingStorageVersion {
106110
Self::V1_0_0 => v2::post_migrate::<T>(),
107111
Self::V2_0_0 => v3::post_migrate::<T>(),
108112
Self::V3_0_0 => v4::post_migrate::<T>(),
109-
Self::V4 => Err("Migration from v4 should have never happened in the first place."),
113+
Self::V4 => v5::post_migrate::<T>(),
114+
Self::V5 => Ok(()),
110115
}
111116
}
112117
}
@@ -126,20 +131,16 @@ impl<T: Config> StakingStorageMigrator<T> {
126131
StakingStorageVersion::V1_0_0 => Some(StakingStorageVersion::V2_0_0),
127132
StakingStorageVersion::V2_0_0 => Some(StakingStorageVersion::V3_0_0),
128133
// Migration happens naturally, no need to point to the latest version
129-
StakingStorageVersion::V3_0_0 => None,
130-
StakingStorageVersion::V4 => None,
134+
StakingStorageVersion::V3_0_0 => Some(StakingStorageVersion::V4),
135+
StakingStorageVersion::V4 => Some(StakingStorageVersion::V5),
136+
StakingStorageVersion::V5 => None,
131137
}
132138
}
133139

134140
/// Checks whether the latest storage version deployed is lower than the
135141
/// latest possible.
136142
#[cfg(feature = "try-runtime")]
137143
pub(crate) fn pre_migrate() -> Result<(), &'static str> {
138-
ensure!(
139-
StorageVersion::<T>::get() < StakingStorageVersion::latest(),
140-
"Already the latest storage version."
141-
);
142-
143144
// Don't need to check for any other pre_migrate, as in try-runtime it is also
144145
// called in the migrate() function. Same applies for post_migrate checks for
145146
// each version migrator.
@@ -198,35 +199,11 @@ mod tests {
198199

199200
use crate::mock::Test as TestRuntime;
200201

201-
#[test]
202-
fn ok_from_v1_migration() {
203-
let mut ext = mock::ExtBuilder::default()
204-
.with_balances(vec![(1, 100), (2, 100)])
205-
.with_collators(vec![(1, 100), (2, 100)])
206-
.with_storage_version(StakingStorageVersion::V1_0_0)
207-
.build();
208-
ext.execute_with(|| {
209-
#[cfg(feature = "try-runtime")]
210-
assert!(
211-
StakingStorageMigrator::<TestRuntime>::pre_migrate().is_ok(),
212-
"Storage pre-migrate from v1 should not fail."
213-
);
214-
215-
StakingStorageMigrator::<TestRuntime>::migrate();
216-
217-
#[cfg(feature = "try-runtime")]
218-
assert!(
219-
StakingStorageMigrator::<TestRuntime>::post_migrate().is_ok(),
220-
"Storage post-migrate from v1 should not fail."
221-
);
222-
});
223-
}
224-
225202
#[test]
226203
fn ok_from_default_migration() {
227204
let mut ext = mock::ExtBuilder::default()
228-
.with_balances(vec![(1, 100), (2, 100)])
229-
.with_collators(vec![(1, 100), (2, 100)])
205+
.with_balances((0..15).into_iter().map(|n| (n, 120)).collect())
206+
.with_collators((0..15).into_iter().map(|n| (n, 100)).collect())
230207
.build();
231208
ext.execute_with(|| {
232209
#[cfg(feature = "try-runtime")]
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// KILT Blockchain – https://botlabs.org
2+
// Copyright (C) 2019-2021 BOTLabs GmbH
3+
4+
// The KILT Blockchain is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
9+
// The KILT Blockchain is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU General Public License for more details.
13+
14+
// You should have received a copy of the GNU General Public License
15+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
17+
// If you feel like getting in touch with us, you can do so at info@botlabs.org
18+
19+
use crate::{migrations::StakingStorageVersion, CandidateCount, CandidatePool, Config, StorageVersion};
20+
use frame_support::{dispatch::Weight, storage::StorageValue, traits::Get};
21+
22+
#[cfg(feature = "try-runtime")]
23+
pub(crate) fn pre_migrate<T: Config>() -> Result<(), &'static str> {
24+
assert_eq!(StorageVersion::<T>::get(), StakingStorageVersion::V4);
25+
Ok(())
26+
}
27+
28+
pub(crate) fn migrate<T: Config>() -> Weight {
29+
log::info!("Migrating staking to StakingStorageVersion::V5");
30+
31+
// Kill selected candidates list
32+
old::SelectedCandidates::<T>::kill();
33+
34+
// count candidates
35+
let counter: u32 = CandidatePool::<T>::iter().fold(0, |acc, _| acc.saturating_add(1));
36+
CandidateCount::<T>::put(counter);
37+
38+
// update storage version
39+
StorageVersion::<T>::put(StakingStorageVersion::V5);
40+
log::info!("Completed staking migration to StakingStorageVersion::V5");
41+
42+
T::DbWeight::get().reads_writes(counter.saturating_add(2).into(), 3)
43+
}
44+
45+
#[cfg(feature = "try-runtime")]
46+
pub(crate) fn post_migrate<T: Config>() -> Result<(), &'static str> {
47+
assert_eq!(StorageVersion::<T>::get(), StakingStorageVersion::V5);
48+
assert!(CandidateCount::<T>::get() > T::MinCollators::get());
49+
Ok(())
50+
}
51+
52+
pub(crate) mod old {
53+
use super::*;
54+
use frame_support::{decl_module, decl_storage};
55+
use sp_std::prelude::*;
56+
57+
decl_module! {
58+
pub struct OldPallet<T: Config> for enum Call where origin: T::Origin {}
59+
}
60+
61+
decl_storage! {
62+
trait Store for OldPallet<T: Config> as ParachainStaking {
63+
pub(crate) SelectedCandidates: Vec<T::AccountId>;
64+
}
65+
}
66+
}

pallets/parachain-staking/src/mock.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,6 @@ impl ExtBuilder {
273273
self
274274
}
275275

276-
pub(crate) fn with_storage_version(mut self, storage_version: StakingStorageVersion) -> Self {
277-
self.storage_version = storage_version;
278-
self
279-
}
280-
281276
pub(crate) fn build(self) -> sp_io::TestExternalities {
282277
let mut t = frame_system::GenesisConfig::default()
283278
.build_storage::<Test>()

runtimes/peregrine/src/lib.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
104104
spec_name: create_runtime_str!("mashnet-node"),
105105
impl_name: create_runtime_str!("mashnet-node"),
106106
authoring_version: 4,
107-
spec_version: 22,
107+
spec_version: 23,
108108
impl_version: 0,
109109
apis: RUNTIME_API_VERSIONS,
110110
transaction_version: 2,
@@ -1131,12 +1131,15 @@ impl_runtime_apis! {
11311131
}
11321132
}
11331133

1134-
// From the Polkadot repo: https://github.com/paritytech/polkadot/blob/master/runtime/polkadot/src/lib.rs#L1371
1134+
// From the Polkadot repo: https://github.com/paritytech/polkadot/blob/1876963f254f31f8cd2d7b8d5fb26cd38b7836ab/runtime/polkadot/src/lib.rs#L1413
11351135
#[cfg(feature = "try-runtime")]
11361136
impl frame_try_runtime::TryRuntime<Block> for Runtime {
11371137
fn on_runtime_upgrade() -> Result<(Weight, Weight), sp_runtime::RuntimeString> {
11381138
log::info!("try-runtime::on_runtime_upgrade for peregrine runtime.");
1139-
let weight = Executive::try_runtime_upgrade()?;
1139+
let weight = Executive::try_runtime_upgrade().map_err(|err|{
1140+
log::info!("try-runtime::on_runtime_upgrade failed with: {:?}", err);
1141+
err
1142+
})?;
11401143
Ok((weight, RuntimeBlockWeights::get().max_block))
11411144
}
11421145
}

runtimes/peregrine/src/weights/parachain_staking.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 128
2424
2525
// Executed Command:
26-
// /home/willi/mashnet-node/target/release/kilt-parachain
26+
// target/release/kilt-parachain
2727
// benchmark
2828
// --execution=wasm
2929
// --wasm-execution=Compiled
@@ -33,9 +33,9 @@
3333
// --steps=50
3434
// --repeat=20
3535
// --output
36-
// ../../runtimes/peregrine/src/weights/parachain_staking.rs
36+
// runtimes/peregrine/src/weights/parachain_staking.rs
3737
// --template
38-
// ../../.maintain/runtime-weight-template.hbs
38+
// .maintain/runtime-weight-template.hbs
3939

4040

4141
#![cfg_attr(rustfmt, rustfmt_skip)]
@@ -214,4 +214,4 @@ impl<T: frame_system::Config> parachain_staking::WeightInfo for WeightInfo<T> {
214214
(17_765_000_u64)
215215
.saturating_add(T::DbWeight::get().writes(1_u64))
216216
}
217-
}
217+
}

runtimes/spiritnet/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
8787
spec_name: create_runtime_str!("kilt-spiritnet"),
8888
impl_name: create_runtime_str!("kilt-spiritnet"),
8989
authoring_version: 1,
90-
spec_version: 22,
90+
spec_version: 23,
9191
impl_version: 0,
9292
apis: RUNTIME_API_VERSIONS,
9393
transaction_version: 1,

0 commit comments

Comments
 (0)