Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions frame/membership/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,9 +790,16 @@ mod tests {
fn migration_v4() {
new_test_ext().execute_with(|| {
use frame_support::traits::PalletInfo;
let old_pallet_name =
let old_pallet_name = "OldMembership";
let new_pallet_name =
<Test as frame_system::Config>::PalletInfo::name::<Membership>().unwrap();
let new_pallet_name = "NewMembership";

frame_support::storage::migration::move_pallet(
new_pallet_name.as_bytes(),
old_pallet_name.as_bytes(),
);

StorageVersion::new(0).put::<Membership>();

crate::migrations::v4::pre_migrate::<Membership, _>(old_pallet_name, new_pallet_name);
crate::migrations::v4::migrate::<Test, Membership, _>(old_pallet_name, new_pallet_name);
Expand Down
70 changes: 32 additions & 38 deletions frame/membership/src/migrations/v4.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use sp_core::hexdisplay::HexDisplay;
use sp_io::{hashing::twox_128, storage};
use sp_io::hashing::twox_128;

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

let old_pallet_prefix = twox_128(old_pallet_name.as_bytes());
assert!(storage::next_key(&old_pallet_prefix)
.map_or(true, |next_key| next_key.starts_with(&old_pallet_prefix)));
if new_pallet_name == old_pallet_name {
return
}

let new_pallet_prefix = twox_128(new_pallet_name.as_bytes());
let storage_version_key =
[&new_pallet_prefix, &twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX)[..]].concat();
// ensure nothing is stored in the new prefix.
assert!(
storage::next_key(&new_pallet_prefix).map_or(
// either nothing is there
true,
// or we ensure that it has no common prefix with twox_128(new),
// or isn't the storage version that is already stored using the pallet name
|next_key| {
!next_key.starts_with(&new_pallet_prefix) || next_key == storage_version_key
},
),
"unexpected next_key({}) = {:?}",
new_pallet_name,
HexDisplay::from(&storage::next_key(&new_pallet_prefix).unwrap()),
let storage_version_key = twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX);

let mut new_pallet_prefix_iter = frame_support::storage::KeyPrefixIterator::new(
new_pallet_prefix.to_vec(),
new_pallet_prefix.to_vec(),
|key| Ok(key.to_vec()),
);

// Ensure nothing except maybe the storage_version_key is stored in the new prefix.
assert!(new_pallet_prefix_iter.all(|key| key == storage_version_key));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the past we only ensured that the first key was sotrage_version_key, now we ensure it is the only one.

Copy link
Contributor

@emostov emostov Sep 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tiny nit, but this doesn't check length and at this point we only expect one key under the new prefix, right? Would it be more accurate to do:

assert!(new_pallet_prefix_iter.next(), Some(storage_version_key));
assert!(new_pallet_prefix_iter.next(), None);

?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes it is true, but I was thinking if they change the name, maybe it is ok not to have anything stored at the new prefix.


assert!(<P as GetStorageVersion>::on_chain_storage_version() < 4);
}

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

let old_pallet_prefix = twox_128(old_pallet_name.as_bytes());
#[cfg(test)]
{
let storage_version_key =
[&old_pallet_prefix, &twox_128(STORAGE_VERSION_STORAGE_KEY_POSTFIX)[..]].concat();
assert!(storage::next_key(&old_pallet_prefix)
.map_or(true, |next_key| !next_key.starts_with(&old_pallet_prefix) ||
next_key == storage_version_key));
}
#[cfg(not(test))]
{
// Assert that nothing remains at the old prefix
assert!(storage::next_key(&old_pallet_prefix)
.map_or(true, |next_key| !next_key.starts_with(&old_pallet_prefix)));
if new_pallet_name == old_pallet_name {
return
}

// Assert that nothing remains at the old prefix.
let old_pallet_prefix = twox_128(old_pallet_name.as_bytes());
let old_pallet_prefix_iter = frame_support::storage::KeyPrefixIterator::new(
old_pallet_prefix.to_vec(),
old_pallet_prefix.to_vec(),
|_| Ok(()),
);
assert_eq!(old_pallet_prefix_iter.count(), 0);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the past we only checked for the first key at the old prefix, and we accepted that it was the storage_version_key, now we ensure nothing remains there.


// NOTE: storage_version_key is already in the new prefix.
let new_pallet_prefix = twox_128(new_pallet_name.as_bytes());
// Assert that the storages have been moved to the new prefix
assert!(storage::next_key(&new_pallet_prefix)
.map_or(true, |next_key| next_key.starts_with(&new_pallet_prefix)));
let new_pallet_prefix_iter = frame_support::storage::KeyPrefixIterator::new(
new_pallet_prefix.to_vec(),
new_pallet_prefix.to_vec(),
|_| Ok(()),
);
assert!(new_pallet_prefix_iter.count() >= 1);

assert_eq!(<P as GetStorageVersion>::on_chain_storage_version(), 4);
}
Expand Down