1
// This file is part of Substrate.
2

            
3
// Copyright (C) Parity Technologies (UK) Ltd.
4
// SPDX-License-Identifier: Apache-2.0
5

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

            
18
use frame_support::{
19
	traits::{Get, OnRuntimeUpgrade},
20
	weights::Weight,
21
};
22

            
23
use crate::{Config, CurrentSetId, SetIdSession, LOG_TARGET};
24

            
25
pub use v5::MigrateV4ToV5;
26

            
27
/// Version 4.
28
pub mod v4;
29
mod v5;
30

            
31
/// This migration will clean up all stale set id -> session entries from the
32
/// `SetIdSession` storage map, only the latest `max_set_id_session_entries`
33
/// will be kept.
34
///
35
/// This migration should be added with a runtime upgrade that introduces the
36
/// `MaxSetIdSessionEntries` constant to the pallet (although it could also be
37
/// done later on).
38
pub struct CleanupSetIdSessionMap<T>(core::marker::PhantomData<T>);
39
impl<T: Config> OnRuntimeUpgrade for CleanupSetIdSessionMap<T> {
40
	fn on_runtime_upgrade() -> Weight {
41
		// NOTE: since this migration will loop over all stale entries in the
42
		// map we need to set some cutoff value, otherwise the migration might
43
		// take too long to run. for scenarios where there are that many entries
44
		// to cleanup a multiblock migration will be needed instead.
45
		if CurrentSetId::<T>::get() > 25_000 {
46
			log::warn!(
47
				target: LOG_TARGET,
48
				"CleanupSetIdSessionMap migration was aborted since there are too many entries to cleanup."
49
			);
50

            
51
			return T::DbWeight::get().reads(1)
52
		}
53

            
54
		cleanup_set_id_sesion_map::<T>()
55
	}
56
}
57

            
58
fn cleanup_set_id_sesion_map<T: Config>() -> Weight {
59
	let until_set_id = CurrentSetId::<T>::get().saturating_sub(T::MaxSetIdSessionEntries::get());
60

            
61
	for set_id in 0..=until_set_id {
62
		SetIdSession::<T>::remove(set_id);
63
	}
64

            
65
	T::DbWeight::get()
66
		.reads(1)
67
		.saturating_add(T::DbWeight::get().writes(until_set_id + 1))
68
}