-
Notifications
You must be signed in to change notification settings - Fork 2.7k
[Feature] Add a migration that drains and refunds stored calls #12313
Changes from all commits
7bb5e13
8234539
35a4c77
9c0ad6d
1e8a954
a4c139d
fab3fc4
73d5643
dbb2cd2
5377978
e140d00
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,86 @@ | ||||||
// This file is part of Substrate. | ||||||
|
||||||
// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
// 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. | ||||||
|
||||||
// Migrations for Multisig Pallet | ||||||
|
||||||
use super::*; | ||||||
ggwpez marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
use frame_support::{ | ||||||
dispatch::GetStorageVersion, | ||||||
traits::{OnRuntimeUpgrade, WrapperKeepOpaque}, | ||||||
Identity, | ||||||
}; | ||||||
|
||||||
#[cfg(feature = "try-runtime")] | ||||||
use frame_support::ensure; | ||||||
|
||||||
pub mod v1 { | ||||||
use super::*; | ||||||
|
||||||
type OpaqueCall<T> = WrapperKeepOpaque<<T as Config>::RuntimeCall>; | ||||||
|
||||||
#[frame_support::storage_alias] | ||||||
type Calls<T: Config> = StorageMap< | ||||||
Pallet<T>, | ||||||
Identity, | ||||||
[u8; 32], | ||||||
(OpaqueCall<T>, <T as frame_system::Config>::AccountId, BalanceOf<T>), | ||||||
>; | ||||||
|
||||||
pub struct MigrateToV1<T>(sp_std::marker::PhantomData<T>); | ||||||
impl<T: Config> OnRuntimeUpgrade for MigrateToV1<T> { | ||||||
#[cfg(feature = "try-runtime")] | ||||||
fn pre_upgrade() -> Result<Vec<u8>, &'static str> { | ||||||
let onchain = Pallet::<T>::on_chain_storage_version(); | ||||||
|
||||||
ensure!(onchain < 1, "this migration can be deleted"); | ||||||
|
||||||
log!(info, "Number of calls to refund and delete: {}", Calls::<T>::iter().count()); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to be pedantic, we could add some math here that: if the number of calls is so much that this exhausts block weight, abort or log a warning. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or just have a limit configurable limit (eg 100) which can then be tested with try-runtime in advance to respect the limits. |
||||||
|
||||||
Ok(Vec::new()) | ||||||
} | ||||||
|
||||||
fn on_runtime_upgrade() -> Weight { | ||||||
let current = Pallet::<T>::current_storage_version(); | ||||||
let onchain = Pallet::<T>::on_chain_storage_version(); | ||||||
|
||||||
if onchain > 0 { | ||||||
log!(info, "MigrateToV1 should be removed"); | ||||||
return T::DbWeight::get().reads(1) | ||||||
} | ||||||
|
||||||
Calls::<T>::drain().for_each(|(_call_hash, (_data, caller, deposit))| { | ||||||
T::Currency::unreserve(&caller, deposit); | ||||||
}); | ||||||
|
||||||
current.put::<Pallet<T>>(); | ||||||
|
||||||
<T as frame_system::Config>::BlockWeights::get().max_block | ||||||
} | ||||||
|
||||||
#[cfg(feature = "try-runtime")] | ||||||
fn post_upgrade(_state: Vec<u8>) -> Result<(), &'static str> { | ||||||
let onchain = Pallet::<T>::on_chain_storage_version(); | ||||||
ensure!(onchain < 2, "this migration needs to be removed"); | ||||||
ensure!(onchain == 1, "this migration needs to be run"); | ||||||
ensure!( | ||||||
Calls::<T>::iter().count() == 0, | ||||||
"there are some dangling calls that need to be destroyed and refunded" | ||||||
); | ||||||
Ok(()) | ||||||
} | ||||||
} | ||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this in here if you only use it in the migration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I'd rather define logging macro for the whole package and have the opportunity to use it when/if needed. It's also consistent with other pallets which define logging.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ruseinov's point is fair to me, I had to do the same in the past.
@ggwpez what I challenge you about is a way so we won't need to define this log macro per-pallet? wdyt?