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
// Migrations for Multisig Pallet
19

            
20
use super::*;
21
use frame_support::{
22
	traits::{GetStorageVersion, OnRuntimeUpgrade, WrapperKeepOpaque},
23
	Identity,
24
};
25

            
26
#[cfg(feature = "try-runtime")]
27
use frame_support::ensure;
28

            
29
pub mod v1 {
30
	use super::*;
31

            
32
	type OpaqueCall<T> = WrapperKeepOpaque<<T as Config>::RuntimeCall>;
33

            
34
	#[frame_support::storage_alias]
35
	type Calls<T: Config> = StorageMap<
36
		Pallet<T>,
37
		Identity,
38
		[u8; 32],
39
		(OpaqueCall<T>, <T as frame_system::Config>::AccountId, BalanceOf<T>),
40
	>;
41

            
42
	pub struct MigrateToV1<T>(core::marker::PhantomData<T>);
43
	impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> {
44
		#[cfg(feature = "try-runtime")]
45
		fn pre_upgrade() -> Result<Vec<u8>, sp_runtime::TryRuntimeError> {
46
			log!(info, "Number of calls to refund and delete: {}", Calls::<T>::iter().count());
47

            
48
			Ok(Vec::new())
49
		}
50

            
51
		fn on_runtime_upgrade() -> Weight {
52
			use sp_runtime::Saturating;
53

            
54
			let current = Pallet::<T>::in_code_storage_version();
55
			let onchain = Pallet::<T>::on_chain_storage_version();
56

            
57
			if onchain > 0 {
58
				log!(info, "MigrateToV1 should be removed");
59
				return T::DbWeight::get().reads(1)
60
			}
61

            
62
			let mut call_count = 0u64;
63
			Calls::<T>::drain().for_each(|(_call_hash, (_data, caller, deposit))| {
64
				T::Currency::unreserve(&caller, deposit);
65
				call_count.saturating_inc();
66
			});
67

            
68
			current.put::<Pallet<T>>();
69

            
70
			T::DbWeight::get().reads_writes(
71
				// Reads: Get Calls + Get Version
72
				call_count.saturating_add(1),
73
				// Writes: Drain Calls + Unreserves + Set version
74
				call_count.saturating_mul(2).saturating_add(1),
75
			)
76
		}
77

            
78
		#[cfg(feature = "try-runtime")]
79
		fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> {
80
			ensure!(
81
				Calls::<T>::iter().count() == 0,
82
				"there are some dangling calls that need to be destroyed and refunded"
83
			);
84
			Ok(())
85
		}
86
	}
87
}