Repository: paritytech/substrate
File: frame/im-online/src/migration.rs (Rust)

Code before:

/// The original data layout of the im-online pallet (`ReceivedHeartbeats` storage item).
mod v0 {
	use super::*;
	use frame_support::traits::WrapperOpaque;

	/// A type that is the same as `OpaqueNetworkState` but with [`Vec`] replaced with
	/// [`WeakBoundedVec<Limit>`] where Limit is the respective size limit
	/// `PeerIdEncodingLimit` represents the size limit of the encoding of `PeerId`
	/// `MultiAddrEncodingLimit` represents the size limit of the encoding of `MultiAddr`
	/// `AddressesLimit` represents the size limit of the vector of peers connected
	#[derive(Clone, Eq, PartialEq, Encode, Decode, MaxEncodedLen, TypeInfo)]
	pub struct BoundedOpaqueNetworkState<
		PeerIdEncodingLimit,
		MultiAddrEncodingLimit,
		AddressesLimit,
	> where
		PeerIdEncodingLimit: Get<u32>,
		MultiAddrEncodingLimit: Get<u32>,
		AddressesLimit: Get<u32>,
	{
		/// PeerId of the local node in SCALE encoded.
		pub peer_id: WeakBoundedVec<u8, PeerIdEncodingLimit>,
		/// List of addresses the node knows it can be reached as.
		pub external_addresses:
			WeakBoundedVec<WeakBoundedVec<u8, MultiAddrEncodingLimit>, AddressesLimit>,
	}

	#[storage_alias]
	pub(crate) type ReceivedHeartbeats<T: Config> = StorageDoubleMap<
		Pallet<T>,
		Twox64Concat,
		SessionIndex,
		Twox64Concat,
		AuthIndex,
		WrapperOpaque<
			BoundedOpaqueNetworkState<
				ConstU32<1_000>,
				ConstU32<1_000>,
				<T as Config>::MaxPeerInHeartbeats,
			>,
		>,
	>;
}

pub mod v1 {
	use super::*;

	/// Simple migration that replaces `ReceivedHeartbeats` values with `true`.
	pub struct Migration<T>(sp_std::marker::PhantomData<T>);


Review comment (suggestion):
```suggestion
		/// PeerId of the local node in SCALE encoded.
		pub peer_id: Vec<u8>,
		/// List of addresses the node knows it can be reached as.
		pub external_addresses:
			Vec<Vec<u8>>,
```

No need to use `WeakBoundedVec` and makes the code easier.

Code after:
	use super::*;
	use frame_support::traits::WrapperOpaque;

	#[derive(Encode, Decode)]
	pub(super) struct BoundedOpaqueNetworkState {
		/// PeerId of the local node in SCALE encoded.
		pub peer_id: Vec<u8>,
		/// List of addresses the node knows it can be reached as.
		pub external_addresses: Vec<Vec<u8>>,
	}

	#[storage_alias]
	pub(super) type ReceivedHeartbeats<T: Config> = StorageDoubleMap<
		Pallet<T>,
		Twox64Concat,
		SessionIndex,
		Twox64Concat,
		AuthIndex,
		WrapperOpaque<BoundedOpaqueNetworkState>,
	>;
}

pub mod v1 {
	use super::*;

	/// Simple migration that replaces `ReceivedHeartbeats` values with `true`.
	pub struct Migration<T>(sp_std::marker::PhantomData<T>);

	impl<T: Config> OnRuntimeUpgrade for Migration<T> {
		#[cfg(feature = "try-runtime")]
		fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
			ensure!(StorageVersion::get::<Pallet<T>>() == 0, "can only upgrade from version 0");

			let count = v0::ReceivedHeartbeats::<T>::iter().count();
			log::info!(target: TARGET, "Migrating {} received heartbeats", count);

			Ok((count as u32).encode())
		}

		fn on_runtime_upgrade() -> Weight {
			let mut weight = T::DbWeight::get().reads(1);
			if StorageVersion::get::<Pallet<T>>() != 0 {
				log::warn!(
					target: TARGET,
					"Skipping migration because current storage version is not 0"
				);
				return weight
			}

			let heartbeats = v0::ReceivedHeartbeats::<T>::drain().collect::<Vec<_>>();