Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit ce3c31f

Browse files
authored
Improve post and pre migration checks for pallet-membership (#9746)
* improve post and pre migration checks * prevent some more false positive * prevent another false positive * fix unused import * Apply suggestions from code review
1 parent 3486a13 commit ce3c31f

File tree

2 files changed

+41
-40
lines changed

2 files changed

+41
-40
lines changed

frame/membership/src/lib.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -790,9 +790,16 @@ mod tests {
790790
fn migration_v4() {
791791
new_test_ext().execute_with(|| {
792792
use frame_support::traits::PalletInfo;
793-
let old_pallet_name =
793+
let old_pallet_name = "OldMembership";
794+
let new_pallet_name =
794795
<Test as frame_system::Config>::PalletInfo::name::<Membership>().unwrap();
795-
let new_pallet_name = "NewMembership";
796+
797+
frame_support::storage::migration::move_pallet(
798+
new_pallet_name.as_bytes(),
799+
old_pallet_name.as_bytes(),
800+
);
801+
802+
StorageVersion::new(0).put::<Membership>();
796803

797804
crate::migrations::v4::pre_migrate::<Membership, _>(old_pallet_name, new_pallet_name);
798805
crate::migrations::v4::migrate::<Test, Membership, _>(old_pallet_name, new_pallet_name);

frame/membership/src/migrations/v4.rs

Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@
1515
// See the License for the specific language governing permissions and
1616
// limitations under the License.
1717

18-
use sp_core::hexdisplay::HexDisplay;
19-
use sp_io::{hashing::twox_128, storage};
18+
use sp_io::hashing::twox_128;
2019

2120
use frame_support::{
2221
traits::{
@@ -85,28 +84,22 @@ pub fn pre_migrate<P: GetStorageVersion, N: AsRef<str>>(old_pallet_name: N, new_
8584
let new_pallet_name = new_pallet_name.as_ref();
8685
log_migration("pre-migration", old_pallet_name, new_pallet_name);
8786

88-
let old_pallet_prefix = twox_128(old_pallet_name.as_bytes());
89-
assert!(storage::next_key(&old_pallet_prefix)
90-
.map_or(true, |next_key| next_key.starts_with(&old_pallet_prefix)));
87+
if new_pallet_name == old_pallet_name {
88+
return
89+
}
9190

9291
let new_pallet_prefix = twox_128(new_pallet_name.as_bytes());
93-
let storage_version_key =
94-
[&new_pallet_prefix, &twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX)[..]].concat();
95-
// ensure nothing is stored in the new prefix.
96-
assert!(
97-
storage::next_key(&new_pallet_prefix).map_or(
98-
// either nothing is there
99-
true,
100-
// or we ensure that it has no common prefix with twox_128(new),
101-
// or isn't the storage version that is already stored using the pallet name
102-
|next_key| {
103-
!next_key.starts_with(&new_pallet_prefix) || next_key == storage_version_key
104-
},
105-
),
106-
"unexpected next_key({}) = {:?}",
107-
new_pallet_name,
108-
HexDisplay::from(&storage::next_key(&new_pallet_prefix).unwrap()),
92+
let storage_version_key = twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX);
93+
94+
let mut new_pallet_prefix_iter = frame_support::storage::KeyPrefixIterator::new(
95+
new_pallet_prefix.to_vec(),
96+
new_pallet_prefix.to_vec(),
97+
|key| Ok(key.to_vec()),
10998
);
99+
100+
// Ensure nothing except maybe the storage_version_key is stored in the new prefix.
101+
assert!(new_pallet_prefix_iter.all(|key| key == storage_version_key));
102+
110103
assert!(<P as GetStorageVersion>::on_chain_storage_version() < 4);
111104
}
112105

@@ -119,26 +112,27 @@ pub fn post_migrate<P: GetStorageVersion, N: AsRef<str>>(old_pallet_name: N, new
119112
let new_pallet_name = new_pallet_name.as_ref();
120113
log_migration("post-migration", old_pallet_name, new_pallet_name);
121114

122-
let old_pallet_prefix = twox_128(old_pallet_name.as_bytes());
123-
#[cfg(test)]
124-
{
125-
let storage_version_key =
126-
[&old_pallet_prefix, &twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX)[..]].concat();
127-
assert!(storage::next_key(&old_pallet_prefix)
128-
.map_or(true, |next_key| !next_key.starts_with(&old_pallet_prefix) ||
129-
next_key == storage_version_key));
130-
}
131-
#[cfg(not(test))]
132-
{
133-
// Assert that nothing remains at the old prefix
134-
assert!(storage::next_key(&old_pallet_prefix)
135-
.map_or(true, |next_key| !next_key.starts_with(&old_pallet_prefix)));
115+
if new_pallet_name == old_pallet_name {
116+
return
136117
}
137118

119+
// Assert that nothing remains at the old prefix.
120+
let old_pallet_prefix = twox_128(old_pallet_name.as_bytes());
121+
let old_pallet_prefix_iter = frame_support::storage::KeyPrefixIterator::new(
122+
old_pallet_prefix.to_vec(),
123+
old_pallet_prefix.to_vec(),
124+
|_| Ok(()),
125+
);
126+
assert_eq!(old_pallet_prefix_iter.count(), 0);
127+
128+
// NOTE: storage_version_key is already in the new prefix.
138129
let new_pallet_prefix = twox_128(new_pallet_name.as_bytes());
139-
// Assert that the storages have been moved to the new prefix
140-
assert!(storage::next_key(&new_pallet_prefix)
141-
.map_or(true, |next_key| next_key.starts_with(&new_pallet_prefix)));
130+
let new_pallet_prefix_iter = frame_support::storage::KeyPrefixIterator::new(
131+
new_pallet_prefix.to_vec(),
132+
new_pallet_prefix.to_vec(),
133+
|_| Ok(()),
134+
);
135+
assert!(new_pallet_prefix_iter.count() >= 1);
142136

143137
assert_eq!(<P as GetStorageVersion>::on_chain_storage_version(), 4);
144138
}

0 commit comments

Comments
 (0)