From e8da320734ae44803f89dd2b35b3cfea0e1ecca1 Mon Sep 17 00:00:00 2001
From: Kevin Wang <wy721@qq.com>
Date: Mon, 25 Sep 2023 21:13:11 +0800
Subject: [PATCH] contracts: Fix incorrect storage alias in mirgration (#1687)

# Description

We are recently trying to upgrade our Substrate version from
`polkadot-v0.9.43` to `polkadot-v1.0.0` and we noticed a critical issue:
all deployed contracts seem to be experiencing a `CodeNotFound` error.
After a thorough investigation, it appears that the root cause of this
issue lies in the mismatch between the storage alias of `CodeInfoOf<T>`
in the migration and its original definition.

This PR corrects the storage alias to align it with its original
definition

I am uncertain about the proper approach for adding tests to this
change. Would the team consider taking over this PR to bring it to
completion?

---------

Co-authored-by: pgherveou <pgherveou@gmail.com>
---
 substrate/frame/contracts/src/migration.rs    | 26 +++++++++++++++++++
 .../frame/contracts/src/migration/v12.rs      |  2 +-
 .../frame/contracts/src/migration/v14.rs      |  2 +-
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/substrate/frame/contracts/src/migration.rs b/substrate/frame/contracts/src/migration.rs
index 3e3d6f37884..27146207312 100644
--- a/substrate/frame/contracts/src/migration.rs
+++ b/substrate/frame/contracts/src/migration.rs
@@ -328,6 +328,32 @@ impl<T: Config, const TEST_ALL_STEPS: bool> OnRuntimeUpgrade for Migration<T, TE
 		);
 		Ok(Default::default())
 	}
+
+	#[cfg(feature = "try-runtime")]
+	fn post_upgrade(_state: Vec<u8>) -> Result<(), TryRuntimeError> {
+		if !TEST_ALL_STEPS {
+			return Ok(())
+		}
+
+		log::info!(target: LOG_TARGET, "=== POST UPGRADE CHECKS ===");
+
+		// Ensure that the hashing algorithm is correct for each storage map.
+		if let Some(hash) = crate::CodeInfoOf::<T>::iter_keys().next() {
+			crate::CodeInfoOf::<T>::get(hash).expect("CodeInfo exists for hash; qed");
+		}
+		if let Some(hash) = crate::PristineCode::<T>::iter_keys().next() {
+			crate::PristineCode::<T>::get(hash).expect("PristineCode exists for hash; qed");
+		}
+		if let Some(account_id) = crate::ContractInfoOf::<T>::iter_keys().next() {
+			crate::ContractInfoOf::<T>::get(account_id)
+				.expect("ContractInfo exists for account_id; qed");
+		}
+		if let Some(nonce) = crate::DeletionQueue::<T>::iter_keys().next() {
+			crate::DeletionQueue::<T>::get(nonce).expect("DeletionQueue exists for nonce; qed");
+		}
+
+		Ok(())
+	}
 }
 
 /// The result of running the migration.
diff --git a/substrate/frame/contracts/src/migration/v12.rs b/substrate/frame/contracts/src/migration/v12.rs
index eb045aa42e9..4ddc57584b3 100644
--- a/substrate/frame/contracts/src/migration/v12.rs
+++ b/substrate/frame/contracts/src/migration/v12.rs
@@ -96,7 +96,7 @@ where
 
 #[storage_alias]
 pub type CodeInfoOf<T: Config, OldCurrency> =
-	StorageMap<Pallet<T>, Twox64Concat, CodeHash<T>, CodeInfo<T, OldCurrency>>;
+	StorageMap<Pallet<T>, Identity, CodeHash<T>, CodeInfo<T, OldCurrency>>;
 
 #[storage_alias]
 pub type PristineCode<T: Config> = StorageMap<Pallet<T>, Identity, CodeHash<T>, Vec<u8>>;
diff --git a/substrate/frame/contracts/src/migration/v14.rs b/substrate/frame/contracts/src/migration/v14.rs
index efb49dff4f1..94534d05fdf 100644
--- a/substrate/frame/contracts/src/migration/v14.rs
+++ b/substrate/frame/contracts/src/migration/v14.rs
@@ -70,7 +70,7 @@ mod old {
 
 	#[storage_alias]
 	pub type CodeInfoOf<T: Config, OldCurrency> =
-		StorageMap<Pallet<T>, Twox64Concat, CodeHash<T>, CodeInfo<T, OldCurrency>>;
+		StorageMap<Pallet<T>, Identity, CodeHash<T>, CodeInfo<T, OldCurrency>>;
 }
 
 #[cfg(feature = "runtime-benchmarks")]
-- 
GitLab