From 88d900afbff7ebe600dfe5e3ee9f87fe52c93d1f Mon Sep 17 00:00:00 2001
From: Xavier Lau <x@acg.box>
Date: Mon, 23 Dec 2024 06:18:58 +0800
Subject: [PATCH] Make pallet-recovery supports `BlockNumberProvider` (#6446)

Make pallet-recovery supports `BlockNumberProvider`.

Part of #6297.

---

Polkadot address: 156HGo9setPcU2qhFMVWLkcmtCEGySLwNqa3DaEiYSWtte4Y

---------

Co-authored-by: Guillaume Thiolliere <guillaume.thiolliere@parity.io>
Co-authored-by: GitHub Action <action@github.com>
---
 polkadot/runtime/rococo/src/lib.rs    |  1 +
 polkadot/runtime/westend/src/lib.rs   |  1 +
 prdoc/pr_6446.prdoc                   | 16 ++++++++++++++++
 substrate/bin/node/runtime/src/lib.rs |  1 +
 substrate/frame/recovery/src/lib.rs   | 25 ++++++++++++++++---------
 substrate/frame/recovery/src/mock.rs  |  1 +
 6 files changed, 36 insertions(+), 9 deletions(-)
 create mode 100644 prdoc/pr_6446.prdoc

diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs
index da4f039624a..4034f8bc143 100644
--- a/polkadot/runtime/rococo/src/lib.rs
+++ b/polkadot/runtime/rococo/src/lib.rs
@@ -792,6 +792,7 @@ impl pallet_recovery::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type WeightInfo = ();
 	type RuntimeCall = RuntimeCall;
+	type BlockNumberProvider = System;
 	type Currency = Balances;
 	type ConfigDepositBase = ConfigDepositBase;
 	type FriendDepositFactor = FriendDepositFactor;
diff --git a/polkadot/runtime/westend/src/lib.rs b/polkadot/runtime/westend/src/lib.rs
index cbf2e02ce42..cd8eb4d2505 100644
--- a/polkadot/runtime/westend/src/lib.rs
+++ b/polkadot/runtime/westend/src/lib.rs
@@ -1018,6 +1018,7 @@ impl pallet_recovery::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type WeightInfo = ();
 	type RuntimeCall = RuntimeCall;
+	type BlockNumberProvider = System;
 	type Currency = Balances;
 	type ConfigDepositBase = ConfigDepositBase;
 	type FriendDepositFactor = FriendDepositFactor;
diff --git a/prdoc/pr_6446.prdoc b/prdoc/pr_6446.prdoc
new file mode 100644
index 00000000000..3bfe7d0c7a6
--- /dev/null
+++ b/prdoc/pr_6446.prdoc
@@ -0,0 +1,16 @@
+title: Make pallet-recovery supports `BlockNumberProvider`
+doc:
+- audience: Runtime Dev
+  description: |-
+      pallet-recovery now allows configuring the block provider to be utilized within this pallet. This block is employed for the delay in the recovery process.
+
+      A new associated type has been introduced in the `Config` trait: `BlockNumberProvider`. This can be assigned to `System` to maintain the previous behavior, or it can be set to another block number provider, such as `RelayChain`.
+
+      If the block provider is configured with a value different from `System`, a migration will be necessary for the `Recoverable` and `ActiveRecoveries` storage items.
+crates:
+- name: rococo-runtime
+  bump: major
+- name: westend-runtime
+  bump: major
+- name: pallet-recovery
+  bump: major
diff --git a/substrate/bin/node/runtime/src/lib.rs b/substrate/bin/node/runtime/src/lib.rs
index faffcd23fbc..45ae378cc00 100644
--- a/substrate/bin/node/runtime/src/lib.rs
+++ b/substrate/bin/node/runtime/src/lib.rs
@@ -1653,6 +1653,7 @@ impl pallet_recovery::Config for Runtime {
 	type RuntimeEvent = RuntimeEvent;
 	type WeightInfo = pallet_recovery::weights::SubstrateWeight<Runtime>;
 	type RuntimeCall = RuntimeCall;
+	type BlockNumberProvider = System;
 	type Currency = Balances;
 	type ConfigDepositBase = ConfigDepositBase;
 	type FriendDepositFactor = FriendDepositFactor;
diff --git a/substrate/frame/recovery/src/lib.rs b/substrate/frame/recovery/src/lib.rs
index f8622880538..d8f3c33fbea 100644
--- a/substrate/frame/recovery/src/lib.rs
+++ b/substrate/frame/recovery/src/lib.rs
@@ -156,7 +156,10 @@ use alloc::{boxed::Box, vec::Vec};
 use codec::{Decode, Encode, MaxEncodedLen};
 use scale_info::TypeInfo;
 use sp_runtime::{
-	traits::{CheckedAdd, CheckedMul, Dispatchable, SaturatedConversion, StaticLookup},
+	traits::{
+		BlockNumberProvider, CheckedAdd, CheckedMul, Dispatchable, SaturatedConversion,
+		StaticLookup,
+	},
 	RuntimeDebug,
 };
 
@@ -178,11 +181,12 @@ mod mock;
 mod tests;
 pub mod weights;
 
+type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
 type BalanceOf<T> =
 	<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
-
+type BlockNumberFromProviderOf<T> =
+	<<T as Config>::BlockNumberProvider as BlockNumberProvider>::BlockNumber;
 type FriendsOf<T> = BoundedVec<<T as frame_system::Config>::AccountId, <T as Config>::MaxFriends>;
-type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
 
 /// An active recovery process.
 #[derive(Clone, Eq, PartialEq, Encode, Decode, Default, RuntimeDebug, TypeInfo, MaxEncodedLen)]
@@ -190,7 +194,7 @@ pub struct ActiveRecovery<BlockNumber, Balance, Friends> {
 	/// The block number when the recovery process started.
 	created: BlockNumber,
 	/// The amount held in reserve of the `depositor`,
-	/// To be returned once this recovery process is closed.
+	/// to be returned once this recovery process is closed.
 	deposit: Balance,
 	/// The friends which have vouched so far. Always sorted.
 	friends: Friends,
@@ -236,6 +240,9 @@ pub mod pallet {
 			+ GetDispatchInfo
 			+ From<frame_system::Call<Self>>;
 
+		/// Provider for the block number. Normally this is the `frame_system` pallet.
+		type BlockNumberProvider: BlockNumberProvider;
+
 		/// The currency mechanism.
 		type Currency: ReservableCurrency<Self::AccountId>;
 
@@ -339,7 +346,7 @@ pub mod pallet {
 		_,
 		Twox64Concat,
 		T::AccountId,
-		RecoveryConfig<BlockNumberFor<T>, BalanceOf<T>, FriendsOf<T>>,
+		RecoveryConfig<BlockNumberFromProviderOf<T>, BalanceOf<T>, FriendsOf<T>>,
 	>;
 
 	/// Active recovery attempts.
@@ -354,7 +361,7 @@ pub mod pallet {
 		T::AccountId,
 		Twox64Concat,
 		T::AccountId,
-		ActiveRecovery<BlockNumberFor<T>, BalanceOf<T>, FriendsOf<T>>,
+		ActiveRecovery<BlockNumberFromProviderOf<T>, BalanceOf<T>, FriendsOf<T>>,
 	>;
 
 	/// The list of allowed proxy accounts.
@@ -445,7 +452,7 @@ pub mod pallet {
 			origin: OriginFor<T>,
 			friends: Vec<T::AccountId>,
 			threshold: u16,
-			delay_period: BlockNumberFor<T>,
+			delay_period: BlockNumberFromProviderOf<T>,
 		) -> DispatchResult {
 			let who = ensure_signed(origin)?;
 			// Check account is not already set up for recovery
@@ -511,7 +518,7 @@ pub mod pallet {
 			T::Currency::reserve(&who, recovery_deposit)?;
 			// Create an active recovery status
 			let recovery_status = ActiveRecovery {
-				created: <frame_system::Pallet<T>>::block_number(),
+				created: T::BlockNumberProvider::current_block_number(),
 				deposit: recovery_deposit,
 				friends: Default::default(),
 			};
@@ -596,7 +603,7 @@ pub mod pallet {
 				Self::active_recovery(&account, &who).ok_or(Error::<T>::NotStarted)?;
 			ensure!(!Proxy::<T>::contains_key(&who), Error::<T>::AlreadyProxy);
 			// Make sure the delay period has passed
-			let current_block_number = <frame_system::Pallet<T>>::block_number();
+			let current_block_number = T::BlockNumberProvider::current_block_number();
 			let recoverable_block_number = active_recovery
 				.created
 				.checked_add(&recovery_config.delay_period)
diff --git a/substrate/frame/recovery/src/mock.rs b/substrate/frame/recovery/src/mock.rs
index 8e30cbe997e..3930db82d6c 100644
--- a/substrate/frame/recovery/src/mock.rs
+++ b/substrate/frame/recovery/src/mock.rs
@@ -66,6 +66,7 @@ impl Config for Test {
 	type RuntimeEvent = RuntimeEvent;
 	type WeightInfo = ();
 	type RuntimeCall = RuntimeCall;
+	type BlockNumberProvider = System;
 	type Currency = Balances;
 	type ConfigDepositBase = ConfigDepositBase;
 	type FriendDepositFactor = FriendDepositFactor;
-- 
GitLab