Repository: paritytech/substrate
File: frame/offences/src/migration.rs (Rust)

Code before:
			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!(target: LOG_TARGET, "pallet_offences::MigrateToV1 should be removed");
				return T::DbWeight::get().reads(1)
			}

			let keys_removed = v0::ReportsByKindIndex::<T>::clear(u32::MAX, None).unique as u64;
			let weight = T::DbWeight::get().reads_writes(keys_removed, keys_removed);

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

			weight
		}

		#[cfg(feature = "try-runtime")]
		fn post_upgrade(_state: Vec<u8>) -> Result<(), &'static str> {
			let onchain = Pallet::<T>::on_chain_storage_version();
			ensure!(onchain == 1, "pallet_offences::MigrateToV1 needs to be run");
			ensure!(
				v0::ReportsByKindIndex::<T>::iter().count() == 0,
				"there are some dangling reports that need to be destroyed and refunded"
			);
			Ok(())
		}
	}
}

/// Type of data stored as a deferred offence
type DeferredOffenceOf<T> = (
	Vec<OffenceDetails<<T as frame_system::Config>::AccountId, <T as Config>::IdentificationTuple>>,
	Vec<Perbill>,
	SessionIndex,
);

// Deferred reports that have been rejected by the offence handler and need to be submitted
// at a later time.
#[storage_alias]
type DeferredOffences<T: Config> =
	StorageValue<crate::Pallet<T>, Vec<DeferredOffenceOf<T>>, ValueQuery>;

pub fn remove_deferred_storage<T: Config>() -> Weight {
	let mut weight = T::DbWeight::get().reads_writes(1, 1);
	let deferred = <DeferredOffences<T>>::take();
	log::info!(target: LOG_TARGET, "have {} deferred offences, applying.", deferred.len());
	for (offences, perbill, session) in deferred.iter() {

Review comment (suggestion):
```suggestion
				v0::ReportsByKindIndex::<T>::iter_key().count() == 0,
```
Just to ensure that there are no un-decodables.

Code after:
			);

			Ok(Vec::new())
		}

		fn on_runtime_upgrade() -> Weight {
			let onchain = Pallet::<T>::on_chain_storage_version();

			if onchain > 0 {
				log::info!(target: LOG_TARGET, "pallet_offences::MigrateToV1 should be removed");
				return T::DbWeight::get().reads(1)
			}

			let keys_removed = v0::ReportsByKindIndex::<T>::clear(u32::MAX, None).unique as u64;
			let weight = T::DbWeight::get().reads_writes(keys_removed, keys_removed);

			StorageVersion::new(1).put::<Pallet<T>>();

			weight
		}

		#[cfg(feature = "try-runtime")]
		fn post_upgrade(_state: Vec<u8>) -> Result<(), &'static str> {
			let onchain = Pallet::<T>::on_chain_storage_version();
			ensure!(onchain == 1, "pallet_offences::MigrateToV1 needs to be run");
			ensure!(
				v0::ReportsByKindIndex::<T>::iter_keys().count() == 0,
				"there are some dangling reports that need to be destroyed and refunded"
			);
			Ok(())
		}
	}
}

/// Type of data stored as a deferred offence
type DeferredOffenceOf<T> = (
	Vec<OffenceDetails<<T as frame_system::Config>::AccountId, <T as Config>::IdentificationTuple>>,
	Vec<Perbill>,
	SessionIndex,
);

// Deferred reports that have been rejected by the offence handler and need to be submitted
// at a later time.
#[storage_alias]
type DeferredOffences<T: Config> =
	StorageValue<crate::Pallet<T>, Vec<DeferredOffenceOf<T>>, ValueQuery>;

pub fn remove_deferred_storage<T: Config>() -> Weight {
	let mut weight = T::DbWeight::get().reads_writes(1, 1);
	let deferred = <DeferredOffences<T>>::take();
	log::info!(target: LOG_TARGET, "have {} deferred offences, applying.", deferred.len());