diff --git a/cumulus/pallets/dmp-queue/src/tests.rs b/cumulus/pallets/dmp-queue/src/tests.rs
index 70d542ea2ed2abe9f09573205560dc96bf5c3011..368a1c0b436430495ffd005eb1a632dca16ab249 100644
--- a/cumulus/pallets/dmp-queue/src/tests.rs
+++ b/cumulus/pallets/dmp-queue/src/tests.rs
@@ -21,11 +21,7 @@
 use super::{migration::*, mock::*};
 use crate::*;
 
-use frame_support::{
-	pallet_prelude::*,
-	traits::{OnFinalize, OnIdle, OnInitialize},
-	StorageNoopGuard,
-};
+use frame_support::{pallet_prelude::*, traits::OnIdle, StorageNoopGuard};
 
 #[test]
 fn migration_works() {
@@ -183,14 +179,12 @@ fn migration_too_long_ignored() {
 }
 
 fn run_to_block(n: u64) {
-	assert!(n > System::block_number(), "Cannot go back in time");
-
-	while System::block_number() < n {
-		AllPalletsWithSystem::on_finalize(System::block_number());
-		System::set_block_number(System::block_number() + 1);
-		AllPalletsWithSystem::on_initialize(System::block_number());
-		AllPalletsWithSystem::on_idle(System::block_number(), Weight::MAX);
-	}
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default().after_initialize(|bn| {
+			AllPalletsWithSystem::on_idle(bn, Weight::MAX);
+		}),
+	);
 }
 
 fn assert_only_event(e: Event<Runtime>) {
diff --git a/polkadot/runtime/common/src/assigned_slots/mod.rs b/polkadot/runtime/common/src/assigned_slots/mod.rs
index 65942c127b1cc05260c67c44b2350cf8b8b4490c..dea29f53cad4f586c49c6261c6862a2b1eb05f71 100644
--- a/polkadot/runtime/common/src/assigned_slots/mod.rs
+++ b/polkadot/runtime/common/src/assigned_slots/mod.rs
@@ -788,39 +788,14 @@ mod tests {
 		t.into()
 	}
 
-	fn run_to_block(n: BlockNumber) {
-		while System::block_number() < n {
-			let mut block = System::block_number();
-			// on_finalize hooks
-			AssignedSlots::on_finalize(block);
-			Slots::on_finalize(block);
-			Parachains::on_finalize(block);
-			ParasShared::on_finalize(block);
-			Configuration::on_finalize(block);
-			Balances::on_finalize(block);
-			System::on_finalize(block);
-			// Set next block
-			System::set_block_number(block + 1);
-			block = System::block_number();
-			// on_initialize hooks
-			System::on_initialize(block);
-			Balances::on_initialize(block);
-			Configuration::on_initialize(block);
-			ParasShared::on_initialize(block);
-			Parachains::on_initialize(block);
-			Slots::on_initialize(block);
-			AssignedSlots::on_initialize(block);
-		}
-	}
-
 	#[test]
 	fn basic_setup_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 			assert_eq!(AssignedSlots::current_lease_period_index(), 0);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 
-			run_to_block(3);
+			System::run_to_block::<AllPalletsWithSystem>(3);
 			assert_eq!(AssignedSlots::current_lease_period_index(), 1);
 		});
 	}
@@ -828,7 +803,7 @@ mod tests {
 	#[test]
 	fn assign_perm_slot_fails_for_unknown_para() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_noop!(
 				AssignedSlots::assign_perm_parachain_slot(
@@ -843,7 +818,7 @@ mod tests {
 	#[test]
 	fn assign_perm_slot_fails_for_invalid_origin() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_noop!(
 				AssignedSlots::assign_perm_parachain_slot(
@@ -858,7 +833,7 @@ mod tests {
 	#[test]
 	fn assign_perm_slot_fails_when_not_parathread() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -881,7 +856,7 @@ mod tests {
 	#[test]
 	fn assign_perm_slot_fails_when_existing_lease() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -920,7 +895,7 @@ mod tests {
 	#[test]
 	fn assign_perm_slot_fails_when_max_perm_slots_exceeded() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -967,7 +942,7 @@ mod tests {
 	fn assign_perm_slot_succeeds_for_parathread() {
 		new_test_ext().execute_with(|| {
 			let mut block = 1;
-			run_to_block(block);
+			System::run_to_block::<AllPalletsWithSystem>(block);
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
 				ParaId::from(1_u32),
@@ -1000,7 +975,7 @@ mod tests {
 				assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 2), true);
 
 				block += 1;
-				run_to_block(block);
+				System::run_to_block::<AllPalletsWithSystem>(block);
 			}
 
 			// Para lease ended, downgraded back to parathread (on-demand parachain)
@@ -1012,7 +987,7 @@ mod tests {
 	#[test]
 	fn assign_temp_slot_fails_for_unknown_para() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_noop!(
 				AssignedSlots::assign_temp_parachain_slot(
@@ -1028,7 +1003,7 @@ mod tests {
 	#[test]
 	fn assign_temp_slot_fails_for_invalid_origin() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_noop!(
 				AssignedSlots::assign_temp_parachain_slot(
@@ -1044,7 +1019,7 @@ mod tests {
 	#[test]
 	fn assign_temp_slot_fails_when_not_parathread() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -1068,7 +1043,7 @@ mod tests {
 	#[test]
 	fn assign_temp_slot_fails_when_existing_lease() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -1109,7 +1084,7 @@ mod tests {
 	#[test]
 	fn assign_temp_slot_fails_when_max_temp_slots_exceeded() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			// Register 6 paras & a temp slot for each
 			for n in 0..=5 {
@@ -1151,7 +1126,7 @@ mod tests {
 	fn assign_temp_slot_succeeds_for_single_parathread() {
 		new_test_ext().execute_with(|| {
 			let mut block = 1;
-			run_to_block(block);
+			System::run_to_block::<AllPalletsWithSystem>(block);
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
 				ParaId::from(1_u32),
@@ -1195,7 +1170,7 @@ mod tests {
 				assert_eq!(Slots::already_leased(ParaId::from(1_u32), 0, 1), true);
 
 				block += 1;
-				run_to_block(block);
+				System::run_to_block::<AllPalletsWithSystem>(block);
 			}
 
 			// Block 6
@@ -1210,7 +1185,7 @@ mod tests {
 
 			// Block 12
 			// Para should get a turn after TemporarySlotLeasePeriodLength * LeasePeriod blocks
-			run_to_block(12);
+			System::run_to_block::<AllPalletsWithSystem>(12);
 			println!("block #{}", block);
 			println!("lease period #{}", AssignedSlots::current_lease_period_index());
 			println!("lease {:?}", slots::Leases::<Test>::get(ParaId::from(1_u32)));
@@ -1225,7 +1200,7 @@ mod tests {
 	fn assign_temp_slot_succeeds_for_multiple_parathreads() {
 		new_test_ext().execute_with(|| {
 			// Block 1, Period 0
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			// Register 6 paras & a temp slot for each
 			// (3 slots in current lease period, 3 in the next one)
@@ -1251,7 +1226,7 @@ mod tests {
 			// Block 1-5, Period 0-1
 			for n in 1..=5 {
 				if n > 1 {
-					run_to_block(n);
+					System::run_to_block::<AllPalletsWithSystem>(n);
 				}
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(0)), true);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(1_u32)), false);
@@ -1264,7 +1239,7 @@ mod tests {
 
 			// Block 6-11, Period 2-3
 			for n in 6..=11 {
-				run_to_block(n);
+				System::run_to_block::<AllPalletsWithSystem>(n);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(0)), false);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(1_u32)), true);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(2_u32)), false);
@@ -1276,7 +1251,7 @@ mod tests {
 
 			// Block 12-17, Period 4-5
 			for n in 12..=17 {
-				run_to_block(n);
+				System::run_to_block::<AllPalletsWithSystem>(n);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(0)), false);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(1_u32)), false);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(2_u32)), false);
@@ -1288,7 +1263,7 @@ mod tests {
 
 			// Block 18-23, Period 6-7
 			for n in 18..=23 {
-				run_to_block(n);
+				System::run_to_block::<AllPalletsWithSystem>(n);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(0)), true);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(1_u32)), false);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(2_u32)), true);
@@ -1300,7 +1275,7 @@ mod tests {
 
 			// Block 24-29, Period 8-9
 			for n in 24..=29 {
-				run_to_block(n);
+				System::run_to_block::<AllPalletsWithSystem>(n);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(0)), false);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(1_u32)), true);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(2_u32)), false);
@@ -1312,7 +1287,7 @@ mod tests {
 
 			// Block 30-35, Period 10-11
 			for n in 30..=35 {
-				run_to_block(n);
+				System::run_to_block::<AllPalletsWithSystem>(n);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(0)), false);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(1_u32)), false);
 				assert_eq!(TestRegistrar::<Test>::is_parachain(ParaId::from(2_u32)), false);
@@ -1327,7 +1302,7 @@ mod tests {
 	#[test]
 	fn unassign_slot_fails_for_unknown_para() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_noop!(
 				AssignedSlots::unassign_parachain_slot(RuntimeOrigin::root(), ParaId::from(1_u32),),
@@ -1339,7 +1314,7 @@ mod tests {
 	#[test]
 	fn unassign_slot_fails_for_invalid_origin() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_noop!(
 				AssignedSlots::assign_perm_parachain_slot(
@@ -1354,7 +1329,7 @@ mod tests {
 	#[test]
 	fn unassign_perm_slot_succeeds() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -1386,7 +1361,7 @@ mod tests {
 	#[test]
 	fn unassign_temp_slot_succeeds() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -1419,7 +1394,7 @@ mod tests {
 	#[test]
 	fn set_max_permanent_slots_fails_for_no_root_origin() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_noop!(
 				AssignedSlots::set_max_permanent_slots(RuntimeOrigin::signed(1), 5),
@@ -1430,7 +1405,7 @@ mod tests {
 	#[test]
 	fn set_max_permanent_slots_succeeds() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_eq!(MaxPermanentSlots::<Test>::get(), 2);
 			assert_ok!(AssignedSlots::set_max_permanent_slots(RuntimeOrigin::root(), 10),);
@@ -1441,7 +1416,7 @@ mod tests {
 	#[test]
 	fn set_max_temporary_slots_fails_for_no_root_origin() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_noop!(
 				AssignedSlots::set_max_temporary_slots(RuntimeOrigin::signed(1), 5),
@@ -1452,7 +1427,7 @@ mod tests {
 	#[test]
 	fn set_max_temporary_slots_succeeds() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_eq!(MaxTemporarySlots::<Test>::get(), 6);
 			assert_ok!(AssignedSlots::set_max_temporary_slots(RuntimeOrigin::root(), 12),);
diff --git a/polkadot/runtime/common/src/auctions/mock.rs b/polkadot/runtime/common/src/auctions/mock.rs
index 9fe19e579cfa2ce8b19eda13863f3888920a1610..e0365d363ca23e2823498c0f81f221b6bde394e5 100644
--- a/polkadot/runtime/common/src/auctions/mock.rs
+++ b/polkadot/runtime/common/src/auctions/mock.rs
@@ -20,8 +20,7 @@
 use super::*;
 use crate::{auctions, mock::TestRegistrar};
 use frame_support::{
-	assert_ok, derive_impl, ord_parameter_types, parameter_types,
-	traits::{EitherOfDiverse, OnFinalize, OnInitialize},
+	assert_ok, derive_impl, ord_parameter_types, parameter_types, traits::EitherOfDiverse,
 };
 use frame_system::{EnsureRoot, EnsureSignedBy};
 use pallet_balances;
@@ -244,15 +243,3 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
 	});
 	ext
 }
-
-pub fn run_to_block(n: BlockNumber) {
-	while System::block_number() < n {
-		Auctions::on_finalize(System::block_number());
-		Balances::on_finalize(System::block_number());
-		System::on_finalize(System::block_number());
-		System::set_block_number(System::block_number() + 1);
-		System::on_initialize(System::block_number());
-		Balances::on_initialize(System::block_number());
-		Auctions::on_initialize(System::block_number());
-	}
-}
diff --git a/polkadot/runtime/common/src/auctions/tests.rs b/polkadot/runtime/common/src/auctions/tests.rs
index 07574eeb295d334adceb4deffa406862206b62d1..26e2ac47df84e49e05652108d788a7e4a011a70e 100644
--- a/polkadot/runtime/common/src/auctions/tests.rs
+++ b/polkadot/runtime/common/src/auctions/tests.rs
@@ -36,7 +36,7 @@ fn basic_setup_works() {
 			AuctionStatus::<u32>::NotStarted
 		);
 
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 
 		assert_eq!(AuctionCounter::<Test>::get(), 0);
 		assert_eq!(TestLeaser::deposit_held(0u32.into(), &1), 0);
@@ -50,7 +50,7 @@ fn basic_setup_works() {
 #[test]
 fn can_start_auction() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 
 		assert_noop!(Auctions::new_auction(RuntimeOrigin::signed(1), 5, 1), BadOrigin);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
@@ -66,7 +66,7 @@ fn can_start_auction() {
 #[test]
 fn bidding_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5));
 
@@ -82,7 +82,7 @@ fn bidding_works() {
 #[test]
 fn under_bidding_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5));
@@ -96,7 +96,7 @@ fn under_bidding_works() {
 #[test]
 fn over_bidding_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 5));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 1, 4, 6));
@@ -115,7 +115,7 @@ fn over_bidding_works() {
 #[test]
 fn auction_proceeds_correctly() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 
@@ -125,49 +125,49 @@ fn auction_proceeds_correctly() {
 			AuctionStatus::<u32>::StartingPeriod
 		);
 
-		run_to_block(2);
+		System::run_to_block::<AllPalletsWithSystem>(2);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::StartingPeriod
 		);
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::StartingPeriod
 		);
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::StartingPeriod
 		);
 
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::StartingPeriod
 		);
 
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(0, 0)
 		);
 
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(1, 0)
 		);
 
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(2, 0)
 		);
 
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::NotStarted
@@ -178,12 +178,12 @@ fn auction_proceeds_correctly() {
 #[test]
 fn can_win_auction() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1));
 		assert_eq!(Balances::reserved_balance(1), 1);
 		assert_eq!(Balances::free_balance(1), 9);
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 
 		assert_eq!(
 			leases(),
@@ -201,7 +201,7 @@ fn can_win_auction() {
 #[test]
 fn can_win_auction_with_late_randomness() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1));
 		assert_eq!(Balances::reserved_balance(1), 1);
@@ -210,7 +210,7 @@ fn can_win_auction_with_late_randomness() {
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::StartingPeriod
 		);
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		// Auction has not yet ended.
 		assert_eq!(leases(), vec![]);
 		assert_eq!(
@@ -222,7 +222,7 @@ fn can_win_auction_with_late_randomness() {
 		set_last_random(H256::zero(), 8);
 		// Auction definitely ended now, but we don't know exactly when in the last 3 blocks yet
 		// since no randomness available yet.
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		// Auction has now ended... But auction winner still not yet decided, so no leases yet.
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
@@ -233,7 +233,7 @@ fn can_win_auction_with_late_randomness() {
 		// Random seed now updated to a value known at block 9, when the auction ended. This
 		// means that the winner can now be chosen.
 		set_last_random(H256::zero(), 9);
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		// Auction ended and winner selected
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
@@ -255,10 +255,10 @@ fn can_win_auction_with_late_randomness() {
 #[test]
 fn can_win_incomplete_auction() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 4, 4, 5));
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 
 		assert_eq!(leases(), vec![((0.into(), 4), LeaseData { leaser: 1, amount: 5 }),]);
 		assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5);
@@ -268,13 +268,13 @@ fn can_win_incomplete_auction() {
 #[test]
 fn should_choose_best_combination() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(2), 0.into(), 1, 2, 3, 4));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), 0.into(), 1, 4, 4, 2));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1.into(), 1, 1, 4, 2));
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 
 		assert_eq!(
 			leases(),
@@ -295,7 +295,7 @@ fn should_choose_best_combination() {
 #[test]
 fn gap_bid_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 
 		// User 1 will make a bid for period 1 and 4 for the same Para 0
@@ -314,7 +314,7 @@ fn gap_bid_works() {
 		assert_eq!(Balances::reserved_balance(3), 3);
 
 		// End the auction.
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 
 		assert_eq!(
 			leases(),
@@ -334,11 +334,11 @@ fn gap_bid_works() {
 #[test]
 fn deposit_credit_should_work() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 5));
 		assert_eq!(Balances::reserved_balance(1), 5);
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 
 		assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]);
 		assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5);
@@ -347,7 +347,7 @@ fn deposit_credit_should_work() {
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 2, 2, 2, 6));
 		// Only 1 reserved since we have a deposit credit of 5.
 		assert_eq!(Balances::reserved_balance(1), 1);
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 
 		assert_eq!(
 			leases(),
@@ -363,11 +363,11 @@ fn deposit_credit_should_work() {
 #[test]
 fn deposit_credit_on_alt_para_should_not_count() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 1, 5));
 		assert_eq!(Balances::reserved_balance(1), 5);
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 
 		assert_eq!(leases(), vec![((0.into(), 1), LeaseData { leaser: 1, amount: 5 }),]);
 		assert_eq!(TestLeaser::deposit_held(0.into(), &1), 5);
@@ -376,7 +376,7 @@ fn deposit_credit_on_alt_para_should_not_count() {
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 1.into(), 2, 2, 2, 6));
 		// 6 reserved since we are bidding on a new para; only works because we don't
 		assert_eq!(Balances::reserved_balance(1), 6);
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 
 		assert_eq!(
 			leases(),
@@ -393,12 +393,12 @@ fn deposit_credit_on_alt_para_should_not_count() {
 #[test]
 fn multiple_bids_work_pre_ending() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 
 		for i in 1..6u64 {
-			run_to_block(i as _);
+			System::run_to_block::<AllPalletsWithSystem>(i as _);
 			assert_ok!(Auctions::bid(RuntimeOrigin::signed(i), 0.into(), 1, 1, 4, i));
 			for j in 1..6 {
 				assert_eq!(Balances::reserved_balance(j), if j == i { j } else { 0 });
@@ -406,7 +406,7 @@ fn multiple_bids_work_pre_ending() {
 			}
 		}
 
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert_eq!(
 			leases(),
 			vec![
@@ -422,12 +422,12 @@ fn multiple_bids_work_pre_ending() {
 #[test]
 fn multiple_bids_work_post_ending() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 0, 1));
 
 		for i in 1..6u64 {
-			run_to_block(((i - 1) / 2 + 1) as _);
+			System::run_to_block::<AllPalletsWithSystem>(((i - 1) / 2 + 1) as _);
 			assert_ok!(Auctions::bid(RuntimeOrigin::signed(i), 0.into(), 1, 1, 4, i));
 			for j in 1..6 {
 				assert_eq!(Balances::reserved_balance(j), if j <= i { j } else { 0 });
@@ -438,7 +438,7 @@ fn multiple_bids_work_post_ending() {
 			assert_eq!(ReservedAmounts::<Test>::get((i, ParaId::from(0))).unwrap(), i);
 		}
 
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_eq!(
 			leases(),
 			(1..=4)
@@ -501,7 +501,7 @@ fn calculate_winners_works() {
 #[test]
 fn lower_bids_are_correctly_refunded() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 1, 1));
 		let para_1 = ParaId::from(1_u32);
 		let para_2 = ParaId::from(2_u32);
@@ -527,7 +527,7 @@ fn initialize_winners_in_ending_period_works() {
 	new_test_ext().execute_with(|| {
 		let ed: u64 = <Test as pallet_balances::Config>::ExistentialDeposit::get();
 		assert_eq!(ed, 1);
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 1));
 		let para_1 = ParaId::from(1_u32);
 		let para_2 = ParaId::from(2_u32);
@@ -546,20 +546,20 @@ fn initialize_winners_in_ending_period_works() {
 		winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 19));
 		assert_eq!(Winning::<Test>::get(0), Some(winning));
 
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::StartingPeriod
 		);
 
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(0, 0)
 		);
 		assert_eq!(Winning::<Test>::get(0), Some(winning));
 
-		run_to_block(11);
+		System::run_to_block::<AllPalletsWithSystem>(11);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(1, 0)
@@ -567,7 +567,7 @@ fn initialize_winners_in_ending_period_works() {
 		assert_eq!(Winning::<Test>::get(1), Some(winning));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 3, 4, 29));
 
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(2, 0)
@@ -580,7 +580,7 @@ fn initialize_winners_in_ending_period_works() {
 #[test]
 fn handle_bid_requires_registered_para() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_noop!(
 			Auctions::bid(RuntimeOrigin::signed(1), 1337.into(), 1, 1, 4, 1),
@@ -599,12 +599,12 @@ fn handle_bid_requires_registered_para() {
 #[test]
 fn handle_bid_checks_existing_lease_periods() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 2, 3, 1));
 		assert_eq!(Balances::reserved_balance(1), 1);
 		assert_eq!(Balances::free_balance(1), 9);
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 
 		assert_eq!(
 			leases(),
@@ -644,7 +644,7 @@ fn less_winning_samples_work() {
 		EndingPeriod::set(30);
 		SampleLength::set(10);
 
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 11));
 		let para_1 = ParaId::from(1_u32);
 		let para_2 = ParaId::from(2_u32);
@@ -663,13 +663,13 @@ fn less_winning_samples_work() {
 		winning[SlotRange::TwoThree as u8 as usize] = Some((2, para_2, 19));
 		assert_eq!(Winning::<Test>::get(0), Some(winning));
 
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::StartingPeriod
 		);
 
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(0, 0)
@@ -681,19 +681,19 @@ fn less_winning_samples_work() {
 		winning[SlotRange::ThreeThree as u8 as usize] = Some((3, para_3, 29));
 		assert_eq!(Winning::<Test>::get(0), Some(winning));
 
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(1, 0)
 		);
 		assert_eq!(Winning::<Test>::get(1), Some(winning));
-		run_to_block(25);
+		System::run_to_block::<AllPalletsWithSystem>(25);
 		// Overbid mid sample
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(3), para_3, 1, 13, 14, 29));
 		winning[SlotRange::TwoThree as u8 as usize] = Some((3, para_3, 29));
 		assert_eq!(Winning::<Test>::get(1), Some(winning));
 
-		run_to_block(30);
+		System::run_to_block::<AllPalletsWithSystem>(30);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(2, 0)
@@ -701,7 +701,7 @@ fn less_winning_samples_work() {
 		assert_eq!(Winning::<Test>::get(2), Some(winning));
 
 		set_last_random(H256::from([254; 32]), 40);
-		run_to_block(40);
+		System::run_to_block::<AllPalletsWithSystem>(40);
 		// Auction ended and winner selected
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
@@ -729,71 +729,71 @@ fn auction_status_works() {
 			AuctionStatus::<u32>::NotStarted
 		);
 
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 9, 11));
 
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::StartingPeriod
 		);
 
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(0, 0)
 		);
 
-		run_to_block(11);
+		System::run_to_block::<AllPalletsWithSystem>(11);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(0, 1)
 		);
 
-		run_to_block(19);
+		System::run_to_block::<AllPalletsWithSystem>(19);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(0, 9)
 		);
 
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(1, 0)
 		);
 
-		run_to_block(25);
+		System::run_to_block::<AllPalletsWithSystem>(25);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(1, 5)
 		);
 
-		run_to_block(30);
+		System::run_to_block::<AllPalletsWithSystem>(30);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(2, 0)
 		);
 
-		run_to_block(39);
+		System::run_to_block::<AllPalletsWithSystem>(39);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::EndingPeriod(2, 9)
 		);
 
-		run_to_block(40);
+		System::run_to_block::<AllPalletsWithSystem>(40);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::VrfDelay(0)
 		);
 
-		run_to_block(44);
+		System::run_to_block::<AllPalletsWithSystem>(44);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::VrfDelay(4)
 		);
 
 		set_last_random(dummy_hash(), 45);
-		run_to_block(45);
+		System::run_to_block::<AllPalletsWithSystem>(45);
 		assert_eq!(
 			Auctions::auction_status(System::block_number()),
 			AuctionStatus::<u32>::NotStarted
@@ -804,7 +804,7 @@ fn auction_status_works() {
 #[test]
 fn can_cancel_auction() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Auctions::new_auction(RuntimeOrigin::signed(6), 5, 1));
 		assert_ok!(Auctions::bid(RuntimeOrigin::signed(1), 0.into(), 1, 1, 4, 1));
 		assert_eq!(Balances::reserved_balance(1), 1);
diff --git a/polkadot/runtime/common/src/crowdloan/mod.rs b/polkadot/runtime/common/src/crowdloan/mod.rs
index 8cf288197e3dd56085f96c928ae6a5b7f79a2a86..f8b3169407e83e87e999729ab6c247b8a67bdc2a 100644
--- a/polkadot/runtime/common/src/crowdloan/mod.rs
+++ b/polkadot/runtime/common/src/crowdloan/mod.rs
@@ -858,10 +858,7 @@ mod crypto {
 mod tests {
 	use super::*;
 
-	use frame_support::{
-		assert_noop, assert_ok, derive_impl, parameter_types,
-		traits::{OnFinalize, OnInitialize},
-	};
+	use frame_support::{assert_noop, assert_ok, derive_impl, parameter_types};
 	use polkadot_primitives::Id as ParaId;
 	use sp_core::H256;
 	use std::{cell::RefCell, collections::BTreeMap, sync::Arc};
@@ -1111,18 +1108,6 @@ mod tests {
 		unreachable!()
 	}
 
-	fn run_to_block(n: u64) {
-		while System::block_number() < n {
-			Crowdloan::on_finalize(System::block_number());
-			Balances::on_finalize(System::block_number());
-			System::on_finalize(System::block_number());
-			System::set_block_number(System::block_number() + 1);
-			System::on_initialize(System::block_number());
-			Balances::on_initialize(System::block_number());
-			Crowdloan::on_initialize(System::block_number());
-		}
-	}
-
 	fn last_event() -> RuntimeEvent {
 		System::events().pop().expect("RuntimeEvent expected").event
 	}
@@ -1426,7 +1411,7 @@ mod tests {
 			);
 
 			// Move past end date
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 
 			// Cannot contribute to ended fund
 			assert_noop!(
@@ -1451,7 +1436,7 @@ mod tests {
 			// crowdloan that has starting period 1.
 			let para_3 = new_para();
 			assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para_3, 1000, 1, 4, 40, None));
-			run_to_block(40);
+			System::run_to_block::<AllPalletsWithSystem>(40);
 			let now = System::block_number();
 			assert_eq!(TestAuctioneer::lease_period_index(now).unwrap().0, 2);
 			assert_noop!(
@@ -1483,12 +1468,12 @@ mod tests {
 				None
 			));
 
-			run_to_block(8);
+			System::run_to_block::<AllPalletsWithSystem>(8);
 			// Can def contribute when auction is running.
 			assert!(TestAuctioneer::auction_status(System::block_number()).is_ending().is_some());
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 250, None));
 
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 			// Can't contribute when auction is in the VRF delay period.
 			assert!(TestAuctioneer::auction_status(System::block_number()).is_vrf());
 			assert_noop!(
@@ -1496,7 +1481,7 @@ mod tests {
 				Error::<Test>::VrfDelayInProgress
 			);
 
-			run_to_block(15);
+			System::run_to_block::<AllPalletsWithSystem>(15);
 			// Its fine to contribute when no auction is running.
 			assert!(!TestAuctioneer::auction_status(System::block_number()).is_in_progress());
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 250, None));
@@ -1526,15 +1511,15 @@ mod tests {
 			let bidder = Crowdloan::fund_account_id(index);
 
 			// Fund crowdloan
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None));
-			run_to_block(3);
+			System::run_to_block::<AllPalletsWithSystem>(3);
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 150, None));
-			run_to_block(5);
+			System::run_to_block::<AllPalletsWithSystem>(5);
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(4), para, 200, None));
-			run_to_block(8);
+			System::run_to_block::<AllPalletsWithSystem>(8);
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 250, None));
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 
 			assert_eq!(
 				bids(),
@@ -1561,7 +1546,7 @@ mod tests {
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None));
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 50, None));
 
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 			let account_id = Crowdloan::fund_account_id(index);
 			// para has no reserved funds, indicating it did not win the auction.
 			assert_eq!(Balances::reserved_balance(&account_id), 0);
@@ -1591,7 +1576,7 @@ mod tests {
 			assert_ok!(Crowdloan::create(RuntimeOrigin::signed(1), para, 1000, 1, 1, 9, None));
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None));
 
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 			let account_id = Crowdloan::fund_account_id(index);
 
 			// user sends the crowdloan funds trying to make an accounting error
@@ -1636,7 +1621,7 @@ mod tests {
 			);
 
 			// Move to the end of the crowdloan
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 			assert_ok!(Crowdloan::refund(RuntimeOrigin::signed(1337), para));
 
 			// Funds are returned
@@ -1671,7 +1656,7 @@ mod tests {
 			assert_eq!(Balances::free_balance(account_id), 21000);
 
 			// Move to the end of the crowdloan
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 			assert_ok!(Crowdloan::refund(RuntimeOrigin::signed(1337), para));
 			assert_eq!(
 				last_event(),
@@ -1705,7 +1690,7 @@ mod tests {
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None));
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 50, None));
 
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 			// All funds are refunded
 			assert_ok!(Crowdloan::refund(RuntimeOrigin::signed(2), para));
 
@@ -1730,7 +1715,7 @@ mod tests {
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para, 100, None));
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(3), para, 50, None));
 
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 
 			// We test the historic case where crowdloan accounts only have one provider:
 			{
@@ -1770,7 +1755,7 @@ mod tests {
 				Error::<Test>::NotReadyToDissolve
 			);
 
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 			set_winner(para, 1, true);
 			// Can't dissolve when it won.
 			assert_noop!(
@@ -1815,13 +1800,13 @@ mod tests {
 			// simulate the reserving of para's funds. this actually happens in the Slots pallet.
 			assert_ok!(Balances::reserve(&account_id, 149));
 
-			run_to_block(19);
+			System::run_to_block::<AllPalletsWithSystem>(19);
 			assert_noop!(
 				Crowdloan::withdraw(RuntimeOrigin::signed(2), 2, para),
 				Error::<Test>::BidOrLeaseActive
 			);
 
-			run_to_block(20);
+			System::run_to_block::<AllPalletsWithSystem>(20);
 			// simulate the unreserving of para's funds, now that the lease expired. this actually
 			// happens in the Slots pallet.
 			Balances::unreserve(&account_id, 150);
@@ -1949,7 +1934,7 @@ mod tests {
 				Error::<Test>::NoContributions
 			);
 			assert_ok!(Crowdloan::contribute(RuntimeOrigin::signed(2), para_1, 100, None));
-			run_to_block(6);
+			System::run_to_block::<AllPalletsWithSystem>(6);
 			assert_ok!(Crowdloan::poke(RuntimeOrigin::signed(1), para_1));
 			assert_eq!(crowdloan::NewRaise::<Test>::get(), vec![para_1]);
 			assert_noop!(
diff --git a/polkadot/runtime/common/src/integration_tests.rs b/polkadot/runtime/common/src/integration_tests.rs
index 8a76a138305ea8ffe3aa098c06d35bfae3dab7c7..bb4ad8b75065cb3761bc6690baf0fd1fce8a0cca 100644
--- a/polkadot/runtime/common/src/integration_tests.rs
+++ b/polkadot/runtime/common/src/integration_tests.rs
@@ -28,7 +28,7 @@ use alloc::sync::Arc;
 use codec::Encode;
 use frame_support::{
 	assert_noop, assert_ok, derive_impl, parameter_types,
-	traits::{ConstU32, Currency, OnFinalize, OnInitialize},
+	traits::{ConstU32, Currency},
 	weights::Weight,
 	PalletId,
 };
@@ -377,14 +377,12 @@ fn add_blocks(n: u32) {
 }
 
 fn run_to_block(n: u32) {
-	assert!(System::block_number() < n);
-	while System::block_number() < n {
-		let block_number = System::block_number();
-		AllPalletsWithSystem::on_finalize(block_number);
-		System::set_block_number(block_number + 1);
-		maybe_new_session(block_number + 1);
-		AllPalletsWithSystem::on_initialize(block_number + 1);
-	}
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default().before_initialize(|bn| {
+			maybe_new_session(bn);
+		}),
+	);
 }
 
 fn run_to_session(n: u32) {
diff --git a/polkadot/runtime/common/src/paras_registrar/mock.rs b/polkadot/runtime/common/src/paras_registrar/mock.rs
index 1627fd70365d450ccf91025f1cf3a71e45b052d9..07b8fbca5189fc9d361b574ec4af7ad28be16cb6 100644
--- a/polkadot/runtime/common/src/paras_registrar/mock.rs
+++ b/polkadot/runtime/common/src/paras_registrar/mock.rs
@@ -20,10 +20,7 @@
 use super::*;
 use crate::paras_registrar;
 use alloc::collections::btree_map::BTreeMap;
-use frame_support::{
-	derive_impl, parameter_types,
-	traits::{OnFinalize, OnInitialize},
-};
+use frame_support::{derive_impl, parameter_types};
 use frame_system::limits;
 use polkadot_primitives::{Balance, BlockNumber, MAX_CODE_SIZE};
 use polkadot_runtime_parachains::{configuration, origin, shared};
@@ -205,26 +202,21 @@ pub const VALIDATORS: &[Sr25519Keyring] = &[
 pub fn run_to_block(n: BlockNumber) {
 	// NOTE that this function only simulates modules of interest. Depending on new pallet may
 	// require adding it here.
-	assert!(System::block_number() < n);
-	while System::block_number() < n {
-		let b = System::block_number();
-
-		if System::block_number() > 1 {
-			System::on_finalize(System::block_number());
-		}
-		// Session change every 3 blocks.
-		if (b + 1) % BLOCKS_PER_SESSION == 0 {
-			let session_index = shared::CurrentSessionIndex::<Test>::get() + 1;
-			let validators_pub_keys = VALIDATORS.iter().map(|v| v.public().into()).collect();
-
-			shared::Pallet::<Test>::set_session_index(session_index);
-			shared::Pallet::<Test>::set_active_validators_ascending(validators_pub_keys);
-
-			Parachains::test_on_new_session();
-		}
-		System::set_block_number(b + 1);
-		System::on_initialize(System::block_number());
-	}
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default().before_finalize(|bn| {
+			// Session change every 3 blocks.
+			if (bn + 1) % BLOCKS_PER_SESSION == 0 {
+				let session_index = shared::CurrentSessionIndex::<Test>::get() + 1;
+				let validators_pub_keys = VALIDATORS.iter().map(|v| v.public().into()).collect();
+
+				shared::Pallet::<Test>::set_session_index(session_index);
+				shared::Pallet::<Test>::set_active_validators_ascending(validators_pub_keys);
+
+				Parachains::test_on_new_session();
+			}
+		}),
+	);
 }
 
 pub fn run_to_session(n: BlockNumber) {
diff --git a/polkadot/runtime/common/src/slots/mod.rs b/polkadot/runtime/common/src/slots/mod.rs
index 333f14c6608acb1d62df7fadbfe297741a39d6cd..59a1f1870b2dcbf0193d2d321c2b24f6984c55ca 100644
--- a/polkadot/runtime/common/src/slots/mod.rs
+++ b/polkadot/runtime/common/src/slots/mod.rs
@@ -584,28 +584,16 @@ mod tests {
 		t.into()
 	}
 
-	fn run_to_block(n: BlockNumber) {
-		while System::block_number() < n {
-			Slots::on_finalize(System::block_number());
-			Balances::on_finalize(System::block_number());
-			System::on_finalize(System::block_number());
-			System::set_block_number(System::block_number() + 1);
-			System::on_initialize(System::block_number());
-			Balances::on_initialize(System::block_number());
-			Slots::on_initialize(System::block_number());
-		}
-	}
-
 	#[test]
 	fn basic_setup_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 			assert_eq!(Slots::lease_period_length(), (10, 0));
 			let now = System::block_number();
 			assert_eq!(Slots::lease_period_index(now).unwrap().0, 0);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 
-			run_to_block(10);
+			System::run_to_block::<AllPalletsWithSystem>(10);
 			let now = System::block_number();
 			assert_eq!(Slots::lease_period_index(now).unwrap().0, 1);
 		});
@@ -614,7 +602,7 @@ mod tests {
 	#[test]
 	fn lease_lifecycle_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -627,11 +615,11 @@ mod tests {
 			assert_eq!(Slots::deposit_held(1.into(), &1), 1);
 			assert_eq!(Balances::reserved_balance(1), 1);
 
-			run_to_block(19);
+			System::run_to_block::<AllPalletsWithSystem>(19);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 1);
 			assert_eq!(Balances::reserved_balance(1), 1);
 
-			run_to_block(20);
+			System::run_to_block::<AllPalletsWithSystem>(20);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 			assert_eq!(Balances::reserved_balance(1), 0);
 
@@ -645,7 +633,7 @@ mod tests {
 	#[test]
 	fn lease_interrupted_lifecycle_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -657,19 +645,19 @@ mod tests {
 			assert_ok!(Slots::lease_out(1.into(), &1, 6, 1, 1));
 			assert_ok!(Slots::lease_out(1.into(), &1, 4, 3, 1));
 
-			run_to_block(19);
+			System::run_to_block::<AllPalletsWithSystem>(19);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 6);
 			assert_eq!(Balances::reserved_balance(1), 6);
 
-			run_to_block(20);
+			System::run_to_block::<AllPalletsWithSystem>(20);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 4);
 			assert_eq!(Balances::reserved_balance(1), 4);
 
-			run_to_block(39);
+			System::run_to_block::<AllPalletsWithSystem>(39);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 4);
 			assert_eq!(Balances::reserved_balance(1), 4);
 
-			run_to_block(40);
+			System::run_to_block::<AllPalletsWithSystem>(40);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 			assert_eq!(Balances::reserved_balance(1), 0);
 
@@ -688,7 +676,7 @@ mod tests {
 	#[test]
 	fn lease_relayed_lifecycle_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -704,25 +692,25 @@ mod tests {
 			assert_eq!(Slots::deposit_held(1.into(), &2), 4);
 			assert_eq!(Balances::reserved_balance(2), 4);
 
-			run_to_block(19);
+			System::run_to_block::<AllPalletsWithSystem>(19);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 6);
 			assert_eq!(Balances::reserved_balance(1), 6);
 			assert_eq!(Slots::deposit_held(1.into(), &2), 4);
 			assert_eq!(Balances::reserved_balance(2), 4);
 
-			run_to_block(20);
+			System::run_to_block::<AllPalletsWithSystem>(20);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 			assert_eq!(Balances::reserved_balance(1), 0);
 			assert_eq!(Slots::deposit_held(1.into(), &2), 4);
 			assert_eq!(Balances::reserved_balance(2), 4);
 
-			run_to_block(29);
+			System::run_to_block::<AllPalletsWithSystem>(29);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 			assert_eq!(Balances::reserved_balance(1), 0);
 			assert_eq!(Slots::deposit_held(1.into(), &2), 4);
 			assert_eq!(Balances::reserved_balance(2), 4);
 
-			run_to_block(30);
+			System::run_to_block::<AllPalletsWithSystem>(30);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 			assert_eq!(Balances::reserved_balance(1), 0);
 			assert_eq!(Slots::deposit_held(1.into(), &2), 0);
@@ -738,7 +726,7 @@ mod tests {
 	#[test]
 	fn lease_deposit_increase_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -755,11 +743,11 @@ mod tests {
 			assert_eq!(Slots::deposit_held(1.into(), &1), 6);
 			assert_eq!(Balances::reserved_balance(1), 6);
 
-			run_to_block(29);
+			System::run_to_block::<AllPalletsWithSystem>(29);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 6);
 			assert_eq!(Balances::reserved_balance(1), 6);
 
-			run_to_block(30);
+			System::run_to_block::<AllPalletsWithSystem>(30);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 			assert_eq!(Balances::reserved_balance(1), 0);
 
@@ -773,7 +761,7 @@ mod tests {
 	#[test]
 	fn lease_deposit_decrease_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -790,19 +778,19 @@ mod tests {
 			assert_eq!(Slots::deposit_held(1.into(), &1), 6);
 			assert_eq!(Balances::reserved_balance(1), 6);
 
-			run_to_block(19);
+			System::run_to_block::<AllPalletsWithSystem>(19);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 6);
 			assert_eq!(Balances::reserved_balance(1), 6);
 
-			run_to_block(20);
+			System::run_to_block::<AllPalletsWithSystem>(20);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 4);
 			assert_eq!(Balances::reserved_balance(1), 4);
 
-			run_to_block(29);
+			System::run_to_block::<AllPalletsWithSystem>(29);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 4);
 			assert_eq!(Balances::reserved_balance(1), 4);
 
-			run_to_block(30);
+			System::run_to_block::<AllPalletsWithSystem>(30);
 			assert_eq!(Slots::deposit_held(1.into(), &1), 0);
 			assert_eq!(Balances::reserved_balance(1), 0);
 
@@ -816,7 +804,7 @@ mod tests {
 	#[test]
 	fn clear_all_leases_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -852,7 +840,7 @@ mod tests {
 	#[test]
 	fn lease_out_current_lease_period() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
@@ -867,7 +855,7 @@ mod tests {
 				dummy_validation_code()
 			));
 
-			run_to_block(20);
+			System::run_to_block::<AllPalletsWithSystem>(20);
 			let now = System::block_number();
 			assert_eq!(Slots::lease_period_index(now).unwrap().0, 2);
 			// Can't lease from the past
@@ -884,7 +872,7 @@ mod tests {
 	#[test]
 	fn trigger_onboard_works() {
 		new_test_ext().execute_with(|| {
-			run_to_block(1);
+			System::run_to_block::<AllPalletsWithSystem>(1);
 			assert_ok!(TestRegistrar::<Test>::register(
 				1,
 				ParaId::from(1_u32),
diff --git a/prdoc/pr_7109.prdoc b/prdoc/pr_7109.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..e54ef3295135c50222a11efed540b82d5d8f64c9
--- /dev/null
+++ b/prdoc/pr_7109.prdoc
@@ -0,0 +1,11 @@
+title: Add "run to block" tools
+doc:
+- audience: Runtime Dev
+  description: |-
+    Introduce `frame_system::Pallet::run_to_block`, `frame_system::Pallet::run_to_block_with`, and `frame_system::RunToBlockHooks` to establish a generic `run_to_block` mechanism for mock tests, minimizing redundant implementations across various pallets.
+
+    Closes #299.
+
+crates:
+- name: frame-system
+  bump: minor
diff --git a/substrate/frame/examples/multi-block-migrations/src/mock.rs b/substrate/frame/examples/multi-block-migrations/src/mock.rs
index b2a946e1c505c2bd71e6929ff031d0b365ad702e..64940db080c42872eaae9c24778185b582acd60b 100644
--- a/substrate/frame/examples/multi-block-migrations/src/mock.rs
+++ b/substrate/frame/examples/multi-block-migrations/src/mock.rs
@@ -25,10 +25,7 @@
 //! using the [`Migrations`] type.
 
 use frame_support::{
-	construct_runtime, derive_impl,
-	migrations::MultiStepMigrator,
-	pallet_prelude::Weight,
-	traits::{OnFinalize, OnInitialize},
+	construct_runtime, derive_impl, migrations::MultiStepMigrator, pallet_prelude::Weight,
 };
 
 type Block = frame_system::mocking::MockBlock<Runtime>;
@@ -81,13 +78,11 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
 
 #[allow(dead_code)]
 pub fn run_to_block(n: u64) {
-	assert!(System::block_number() < n);
-	while System::block_number() < n {
-		let b = System::block_number();
-		AllPalletsWithSystem::on_finalize(b);
-		// Done by Executive:
-		<Runtime as frame_system::Config>::MultiBlockMigrator::step();
-		System::set_block_number(b + 1);
-		AllPalletsWithSystem::on_initialize(b + 1);
-	}
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default().after_initialize(|_| {
+			// Done by Executive:
+			<Runtime as frame_system::Config>::MultiBlockMigrator::step();
+		}),
+	);
 }
diff --git a/substrate/frame/fast-unstake/src/mock.rs b/substrate/frame/fast-unstake/src/mock.rs
index 757052e230a187ed9ce712a2b30bc5a5f2e9febb..f044fc610187578afd9276d48fb0ad5f2c6569ad 100644
--- a/substrate/frame/fast-unstake/src/mock.rs
+++ b/substrate/frame/fast-unstake/src/mock.rs
@@ -266,22 +266,19 @@ impl ExtBuilder {
 }
 
 pub(crate) fn run_to_block(n: u64, on_idle: bool) {
-	let current_block = System::block_number();
-	assert!(n > current_block);
-	while System::block_number() < n {
-		Balances::on_finalize(System::block_number());
-		Staking::on_finalize(System::block_number());
-		FastUnstake::on_finalize(System::block_number());
-
-		System::set_block_number(System::block_number() + 1);
-
-		Balances::on_initialize(System::block_number());
-		Staking::on_initialize(System::block_number());
-		FastUnstake::on_initialize(System::block_number());
-		if on_idle {
-			FastUnstake::on_idle(System::block_number(), BlockWeights::get().max_block);
-		}
-	}
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default()
+			.before_finalize(|_| {
+				// Satisfy the timestamp pallet.
+				Timestamp::set_timestamp(0);
+			})
+			.after_initialize(|bn| {
+				if on_idle {
+					FastUnstake::on_idle(bn, BlockWeights::get().max_block);
+				}
+			}),
+	);
 }
 
 pub(crate) fn next_block(on_idle: bool) {
diff --git a/substrate/frame/identity/src/tests.rs b/substrate/frame/identity/src/tests.rs
index 7bf5b2a727607e910bc7a2470c383aa236a18e35..01bc312723aa52f9d3bd6efcb9867d1777888f22 100644
--- a/substrate/frame/identity/src/tests.rs
+++ b/substrate/frame/identity/src/tests.rs
@@ -26,7 +26,7 @@ use crate::{
 use codec::{Decode, Encode};
 use frame_support::{
 	assert_err, assert_noop, assert_ok, derive_impl, parameter_types,
-	traits::{ConstU32, ConstU64, Get, OnFinalize, OnInitialize},
+	traits::{ConstU32, ConstU64, Get},
 	BoundedVec,
 };
 use frame_system::EnsureRoot;
@@ -114,18 +114,6 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
 	ext
 }
 
-fn run_to_block(n: u64) {
-	while System::block_number() < n {
-		Identity::on_finalize(System::block_number());
-		Balances::on_finalize(System::block_number());
-		System::on_finalize(System::block_number());
-		System::set_block_number(System::block_number() + 1);
-		System::on_initialize(System::block_number());
-		Balances::on_initialize(System::block_number());
-		Identity::on_initialize(System::block_number());
-	}
-}
-
 fn account(id: u8) -> AccountIdOf<Test> {
 	[id; 32].into()
 }
@@ -1714,7 +1702,7 @@ fn unaccepted_usernames_through_grant_should_expire() {
 			Some((who.clone(), expiration, Provider::Allocation))
 		);
 
-		run_to_block(now + expiration - 1);
+		System::run_to_block::<AllPalletsWithSystem>(now + expiration - 1);
 
 		// Cannot be removed
 		assert_noop!(
@@ -1722,7 +1710,7 @@ fn unaccepted_usernames_through_grant_should_expire() {
 			Error::<Test>::NotExpired
 		);
 
-		run_to_block(now + expiration);
+		System::run_to_block::<AllPalletsWithSystem>(now + expiration);
 
 		// Anyone can remove
 		assert_ok!(Identity::remove_expired_approval(
@@ -1782,7 +1770,7 @@ fn unaccepted_usernames_through_deposit_should_expire() {
 			Some((who.clone(), expiration, Provider::AuthorityDeposit(username_deposit)))
 		);
 
-		run_to_block(now + expiration - 1);
+		System::run_to_block::<AllPalletsWithSystem>(now + expiration - 1);
 
 		// Cannot be removed
 		assert_noop!(
@@ -1790,7 +1778,7 @@ fn unaccepted_usernames_through_deposit_should_expire() {
 			Error::<Test>::NotExpired
 		);
 
-		run_to_block(now + expiration);
+		System::run_to_block::<AllPalletsWithSystem>(now + expiration);
 
 		// Anyone can remove
 		assert_eq!(
diff --git a/substrate/frame/lottery/src/mock.rs b/substrate/frame/lottery/src/mock.rs
index d2c442e2ac6e5acd0b096308ebed02ad9fe0f78e..b771ed0849f6929d9f9dba5bfb32e54fc400b76f 100644
--- a/substrate/frame/lottery/src/mock.rs
+++ b/substrate/frame/lottery/src/mock.rs
@@ -20,10 +20,7 @@
 use super::*;
 use crate as pallet_lottery;
 
-use frame_support::{
-	derive_impl, parameter_types,
-	traits::{ConstU32, OnFinalize, OnInitialize},
-};
+use frame_support::{derive_impl, parameter_types, traits::ConstU32};
 use frame_support_test::TestRandomness;
 use frame_system::EnsureRoot;
 use sp_runtime::{BuildStorage, Perbill};
@@ -83,16 +80,3 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
 	.unwrap();
 	t.into()
 }
-
-/// Run until a particular block.
-pub fn run_to_block(n: u64) {
-	while System::block_number() < n {
-		if System::block_number() > 1 {
-			Lottery::on_finalize(System::block_number());
-			System::on_finalize(System::block_number());
-		}
-		System::set_block_number(System::block_number() + 1);
-		System::on_initialize(System::block_number());
-		Lottery::on_initialize(System::block_number());
-	}
-}
diff --git a/substrate/frame/lottery/src/tests.rs b/substrate/frame/lottery/src/tests.rs
index ae3a6c858f2426e2119f090a5c3e4f53b51a333b..119be5df49250989835a71081e280d31f8837c2b 100644
--- a/substrate/frame/lottery/src/tests.rs
+++ b/substrate/frame/lottery/src/tests.rs
@@ -17,12 +17,11 @@
 
 //! Tests for the module.
 
-use super::*;
-use frame_support::{assert_noop, assert_ok, assert_storage_noop};
-use mock::{
-	new_test_ext, run_to_block, Balances, BalancesCall, Lottery, RuntimeCall, RuntimeOrigin,
-	SystemCall, Test,
+use crate::{
+	mock::{Lottery, *},
+	*,
 };
+use frame_support::{assert_noop, assert_ok, assert_storage_noop};
 use sp_runtime::{traits::BadOrigin, TokenError};
 
 #[test]
@@ -74,13 +73,13 @@ fn basic_end_to_end_works() {
 		assert_eq!(TicketsCount::<Test>::get(), 4);
 
 		// Go to end
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 		assert_ok!(Lottery::buy_ticket(RuntimeOrigin::signed(5), call.clone()));
 		// Ticket isn't bought
 		assert_eq!(TicketsCount::<Test>::get(), 4);
 
 		// Go to payout
-		run_to_block(25);
+		System::run_to_block::<AllPalletsWithSystem>(25);
 		// User 1 wins
 		assert_eq!(Balances::free_balance(&1), 70 + 40);
 		// Lottery is reset and restarted
@@ -115,11 +114,11 @@ fn stop_repeat_works() {
 		// Lottery still exists.
 		assert!(crate::Lottery::<Test>::get().is_some());
 		// End and pick a winner.
-		run_to_block(length + delay);
+		System::run_to_block::<AllPalletsWithSystem>(length + delay);
 
 		// Lottery stays dead and does not repeat.
 		assert!(crate::Lottery::<Test>::get().is_none());
-		run_to_block(length + delay + 1);
+		System::run_to_block::<AllPalletsWithSystem>(length + delay + 1);
 		assert!(crate::Lottery::<Test>::get().is_none());
 	});
 }
@@ -281,7 +280,7 @@ fn buy_ticket_works() {
 		assert_ok!(Lottery::start_lottery(RuntimeOrigin::root(), 1, 20, 5, false));
 
 		// Go to start, buy ticket for transfer
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_ok!(Lottery::buy_ticket(RuntimeOrigin::signed(1), call));
 		assert_eq!(TicketsCount::<Test>::get(), 1);
 
@@ -300,12 +299,12 @@ fn buy_ticket_works() {
 		assert_eq!(TicketsCount::<Test>::get(), 2);
 
 		// Go to end, can't buy tickets anymore
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 		assert_ok!(Lottery::buy_ticket(RuntimeOrigin::signed(2), call.clone()));
 		assert_eq!(TicketsCount::<Test>::get(), 2);
 
 		// Go to payout, can't buy tickets when there is no lottery open
-		run_to_block(25);
+		System::run_to_block::<AllPalletsWithSystem>(25);
 		assert_ok!(Lottery::buy_ticket(RuntimeOrigin::signed(2), call.clone()));
 		assert_eq!(TicketsCount::<Test>::get(), 0);
 		assert_eq!(LotteryIndex::<Test>::get(), 1);
@@ -409,7 +408,7 @@ fn no_participants_works() {
 		assert_ok!(Lottery::start_lottery(RuntimeOrigin::root(), 10, length, delay, false));
 
 		// End the lottery, no one wins.
-		run_to_block(length + delay);
+		System::run_to_block::<AllPalletsWithSystem>(length + delay);
 	});
 }
 
diff --git a/substrate/frame/migrations/src/mock.rs b/substrate/frame/migrations/src/mock.rs
index 48ff175f8137860823589122060f158f53e4c4fd..ea86899cad83ce5dee779ee24aee088e60e17894 100644
--- a/substrate/frame/migrations/src/mock.rs
+++ b/substrate/frame/migrations/src/mock.rs
@@ -21,12 +21,7 @@
 
 use crate::{mock_helpers::*, Event, Historic};
 
-use frame_support::{
-	derive_impl,
-	migrations::*,
-	traits::{OnFinalize, OnInitialize},
-	weights::Weight,
-};
+use frame_support::{derive_impl, migrations::*, weights::Weight};
 use frame_system::EventRecord;
 use sp_core::H256;
 
@@ -113,18 +108,18 @@ pub fn test_closure<R>(f: impl FnOnce() -> R) -> R {
 	ext.execute_with(f)
 }
 
-pub fn run_to_block(n: u32) {
-	while System::block_number() < n as u64 {
-		log::debug!("Block {}", System::block_number());
-		System::set_block_number(System::block_number() + 1);
-		System::on_initialize(System::block_number());
-		Migrations::on_initialize(System::block_number());
-		// Executive calls this:
-		<Migrations as MultiStepMigrator>::step();
-
-		Migrations::on_finalize(System::block_number());
-		System::on_finalize(System::block_number());
-	}
+pub fn run_to_block(n: u64) {
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default()
+			.before_initialize(|bn| {
+				log::debug!("Block {bn}");
+			})
+			.after_initialize(|_| {
+				// Executive calls this:
+				<Migrations as MultiStepMigrator>::step();
+			}),
+	);
 }
 
 /// Returns the historic migrations, sorted by their identifier.
diff --git a/substrate/frame/nis/src/mock.rs b/substrate/frame/nis/src/mock.rs
index 2b008f8ec2a41e3580e61d4bd1c28ba044368273..08e69ef0de0542ae755fbd762403147e802a1470 100644
--- a/substrate/frame/nis/src/mock.rs
+++ b/substrate/frame/nis/src/mock.rs
@@ -21,7 +21,7 @@ use crate::{self as pallet_nis, Perquintill, WithMaximumOf};
 
 use frame_support::{
 	derive_impl, ord_parameter_types, parameter_types,
-	traits::{fungible::Inspect, ConstU32, ConstU64, OnFinalize, OnInitialize, StorageMapShim},
+	traits::{fungible::Inspect, ConstU32, ConstU64, StorageMapShim},
 	weights::Weight,
 	PalletId,
 };
@@ -145,15 +145,3 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
 pub fn new_test_ext_empty() -> sp_io::TestExternalities {
 	frame_system::GenesisConfig::<Test>::default().build_storage().unwrap().into()
 }
-
-pub fn run_to_block(n: u64) {
-	while System::block_number() < n {
-		Nis::on_finalize(System::block_number());
-		Balances::on_finalize(System::block_number());
-		System::on_finalize(System::block_number());
-		System::set_block_number(System::block_number() + 1);
-		System::on_initialize(System::block_number());
-		Balances::on_initialize(System::block_number());
-		Nis::on_initialize(System::block_number());
-	}
-}
diff --git a/substrate/frame/nis/src/tests.rs b/substrate/frame/nis/src/tests.rs
index a17aaf421827f3aba79fa36065178922b0af6d93..10c39a0d48edb4f7c586d55d54e4ada7495aede4 100644
--- a/substrate/frame/nis/src/tests.rs
+++ b/substrate/frame/nis/src/tests.rs
@@ -55,7 +55,7 @@ fn enlarge(amount: Balance, max_bids: u32) {
 #[test]
 fn basic_setup_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 
 		for q in 0..3 {
 			assert!(Queues::<Test>::get(q).is_empty());
@@ -76,7 +76,7 @@ fn basic_setup_works() {
 #[test]
 fn place_bid_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_noop!(Nis::place_bid(signed(1), 1, 2), Error::<Test>::AmountTooSmall);
 		assert_noop!(Nis::place_bid(signed(1), 101, 2), FundsUnavailable);
 		assert_noop!(Nis::place_bid(signed(1), 10, 4), Error::<Test>::DurationTooBig);
@@ -90,7 +90,7 @@ fn place_bid_works() {
 #[test]
 fn place_bid_queuing_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 20, 2));
 		assert_ok!(Nis::place_bid(signed(1), 10, 2));
 		assert_ok!(Nis::place_bid(signed(1), 5, 2));
@@ -116,7 +116,7 @@ fn place_bid_queuing_works() {
 #[test]
 fn place_bid_fails_when_queue_full() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 10, 2));
 		assert_ok!(Nis::place_bid(signed(2), 10, 2));
 		assert_ok!(Nis::place_bid(signed(3), 10, 2));
@@ -128,7 +128,7 @@ fn place_bid_fails_when_queue_full() {
 #[test]
 fn multiple_place_bids_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 10, 1));
 		assert_ok!(Nis::place_bid(signed(1), 10, 2));
 		assert_ok!(Nis::place_bid(signed(1), 10, 2));
@@ -154,7 +154,7 @@ fn multiple_place_bids_works() {
 #[test]
 fn retract_single_item_queue_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 10, 1));
 		assert_ok!(Nis::place_bid(signed(1), 10, 2));
 		assert_ok!(Nis::retract_bid(signed(1), 10, 1));
@@ -169,7 +169,7 @@ fn retract_single_item_queue_works() {
 #[test]
 fn retract_with_other_and_duplicate_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 10, 1));
 		assert_ok!(Nis::place_bid(signed(1), 10, 2));
 		assert_ok!(Nis::place_bid(signed(1), 10, 2));
@@ -190,7 +190,7 @@ fn retract_with_other_and_duplicate_works() {
 #[test]
 fn retract_non_existent_item_fails() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_noop!(Nis::retract_bid(signed(1), 10, 1), Error::<Test>::UnknownBid);
 		assert_ok!(Nis::place_bid(signed(1), 10, 1));
 		assert_noop!(Nis::retract_bid(signed(1), 20, 1), Error::<Test>::UnknownBid);
@@ -202,7 +202,7 @@ fn retract_non_existent_item_fails() {
 #[test]
 fn basic_enlarge_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		assert_ok!(Nis::place_bid(signed(2), 40, 2));
 		enlarge(40, 2);
@@ -240,7 +240,7 @@ fn basic_enlarge_works() {
 #[test]
 fn enlarge_respects_bids_limit() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		assert_ok!(Nis::place_bid(signed(2), 40, 2));
 		assert_ok!(Nis::place_bid(signed(3), 40, 2));
@@ -285,7 +285,7 @@ fn enlarge_respects_bids_limit() {
 #[test]
 fn enlarge_respects_amount_limit_and_will_split() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 80, 1));
 		enlarge(40, 2);
 
@@ -317,7 +317,7 @@ fn enlarge_respects_amount_limit_and_will_split() {
 #[test]
 fn basic_thaw_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		assert_eq!(Nis::issuance().effective, 400);
 		assert_eq!(Balances::free_balance(1), 60);
@@ -330,9 +330,9 @@ fn basic_thaw_works() {
 		assert_eq!(Balances::reserved_balance(1), 40);
 		assert_eq!(holdings(), 40);
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert_noop!(Nis::thaw_private(signed(1), 0, None), Error::<Test>::NotExpired);
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_noop!(Nis::thaw_private(signed(1), 1, None), Error::<Test>::UnknownReceipt);
 		assert_noop!(Nis::thaw_private(signed(2), 0, None), Error::<Test>::NotOwner);
 
@@ -359,12 +359,12 @@ fn basic_thaw_works() {
 #[test]
 fn partial_thaw_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 80, 1));
 		enlarge(80, 1);
 		assert_eq!(holdings(), 80);
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		let prop = Perquintill::from_rational(4_100_000, 21_000_000u64);
 		assert_noop!(Nis::thaw_private(signed(1), 0, Some(prop)), Error::<Test>::MakesDust);
 		let prop = Perquintill::from_rational(1_050_000, 21_000_000u64);
@@ -402,10 +402,10 @@ fn partial_thaw_works() {
 #[test]
 fn thaw_respects_transfers() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		enlarge(40, 1);
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 
 		assert_eq!(Nis::owner(&0), Some(1));
 		assert_eq!(Balances::reserved_balance(&1), 40);
@@ -428,10 +428,10 @@ fn thaw_respects_transfers() {
 #[test]
 fn communify_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		enlarge(40, 1);
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 
 		assert_eq!(Nis::owner(&0), Some(1));
 		assert_eq!(Balances::reserved_balance(&1), 40);
@@ -479,10 +479,10 @@ fn communify_works() {
 #[test]
 fn privatize_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		enlarge(40, 1);
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_noop!(Nis::privatize(signed(2), 0), Error::<Test>::AlreadyPrivate);
 		assert_ok!(Nis::communify(signed(1), 0));
 
@@ -503,11 +503,11 @@ fn privatize_works() {
 #[test]
 fn privatize_and_thaw_with_another_receipt_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		assert_ok!(Nis::place_bid(signed(2), 40, 1));
 		enlarge(80, 2);
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 
 		assert_ok!(Nis::communify(signed(1), 0));
 		assert_ok!(Nis::communify(signed(2), 1));
@@ -535,7 +535,7 @@ fn privatize_and_thaw_with_another_receipt_works() {
 #[test]
 fn communal_thaw_when_issuance_higher_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Balances::transfer_allow_death(signed(2), 1, 1));
 		assert_ok!(Nis::place_bid(signed(1), 100, 1));
 		enlarge(100, 1);
@@ -552,7 +552,7 @@ fn communal_thaw_when_issuance_higher_works() {
 		assert_ok!(Balances::mint_into(&3, 50));
 		assert_ok!(Balances::mint_into(&4, 50));
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 
 		// Unfunded initially...
 		assert_noop!(Nis::thaw_communal(signed(1), 0), Error::<Test>::Unfunded);
@@ -581,7 +581,7 @@ fn communal_thaw_when_issuance_higher_works() {
 #[test]
 fn private_thaw_when_issuance_higher_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Balances::transfer_allow_death(signed(2), 1, 1));
 		assert_ok!(Nis::place_bid(signed(1), 100, 1));
 		enlarge(100, 1);
@@ -591,7 +591,7 @@ fn private_thaw_when_issuance_higher_works() {
 		assert_ok!(Balances::mint_into(&3, 50));
 		assert_ok!(Balances::mint_into(&4, 50));
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 
 		// Unfunded initially...
 		assert_noop!(Nis::thaw_private(signed(1), 0, None), Error::<Test>::Unfunded);
@@ -609,7 +609,7 @@ fn private_thaw_when_issuance_higher_works() {
 #[test]
 fn thaw_with_ignored_issuance_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		// Give account zero some balance.
 		assert_ok!(Balances::mint_into(&0, 200));
 
@@ -622,7 +622,7 @@ fn thaw_with_ignored_issuance_works() {
 		assert_ok!(Balances::transfer_allow_death(signed(0), 3, 50));
 		assert_ok!(Balances::transfer_allow_death(signed(0), 4, 50));
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// Unfunded initially...
 		assert_noop!(Nis::thaw_private(signed(1), 0, None), Error::<Test>::Unfunded);
 		// ...so we fund...
@@ -640,7 +640,7 @@ fn thaw_with_ignored_issuance_works() {
 #[test]
 fn thaw_when_issuance_lower_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Balances::transfer_allow_death(signed(2), 1, 1));
 		assert_ok!(Nis::place_bid(signed(1), 100, 1));
 		enlarge(100, 1);
@@ -650,7 +650,7 @@ fn thaw_when_issuance_lower_works() {
 		assert_ok!(Balances::burn_from(&3, 25, Expendable, Exact, Force));
 		assert_ok!(Balances::burn_from(&4, 25, Expendable, Exact, Force));
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_ok!(Nis::thaw_private(signed(1), 0, None));
 
 		assert_ok!(Balances::transfer_allow_death(signed(1), 2, 1));
@@ -662,7 +662,7 @@ fn thaw_when_issuance_lower_works() {
 #[test]
 fn multiple_thaws_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Balances::transfer_allow_death(signed(3), 1, 1));
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		assert_ok!(Nis::place_bid(signed(1), 60, 1));
@@ -675,11 +675,11 @@ fn multiple_thaws_works() {
 		assert_ok!(Balances::mint_into(&4, 100));
 		assert_ok!(Nis::fund_deficit(signed(1)));
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_ok!(Nis::thaw_private(signed(1), 0, None));
 		assert_ok!(Nis::thaw_private(signed(1), 1, None));
 		assert_noop!(Nis::thaw_private(signed(2), 2, None), Error::<Test>::Throttled);
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_ok!(Nis::thaw_private(signed(2), 2, None));
 
 		assert_ok!(Balances::transfer_allow_death(signed(1), 3, 1));
@@ -693,7 +693,7 @@ fn multiple_thaws_works() {
 #[test]
 fn multiple_thaws_works_in_alternative_thaw_order() {
 	new_test_ext().execute_with(|| {
-		run_to_block(1);
+		System::run_to_block::<AllPalletsWithSystem>(1);
 		assert_ok!(Balances::transfer_allow_death(signed(3), 1, 1));
 		assert_ok!(Nis::place_bid(signed(1), 40, 1));
 		assert_ok!(Nis::place_bid(signed(1), 60, 1));
@@ -706,12 +706,12 @@ fn multiple_thaws_works_in_alternative_thaw_order() {
 		assert_ok!(Balances::mint_into(&4, 100));
 		assert_ok!(Nis::fund_deficit(signed(1)));
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_ok!(Nis::thaw_private(signed(2), 2, None));
 		assert_noop!(Nis::thaw_private(signed(1), 1, None), Error::<Test>::Throttled);
 		assert_ok!(Nis::thaw_private(signed(1), 0, None));
 
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_ok!(Nis::thaw_private(signed(1), 1, None));
 
 		assert_ok!(Balances::transfer_allow_death(signed(1), 3, 1));
@@ -725,7 +725,7 @@ fn multiple_thaws_works_in_alternative_thaw_order() {
 #[test]
 fn enlargement_to_target_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(2);
+		System::run_to_block::<AllPalletsWithSystem>(2);
 		let w = <() as WeightInfo>::process_queues() +
 			<() as WeightInfo>::process_queue() +
 			(<() as WeightInfo>::process_bid() * 2);
@@ -737,7 +737,7 @@ fn enlargement_to_target_works() {
 		assert_ok!(Nis::place_bid(signed(3), 40, 3));
 		Target::set(Perquintill::from_percent(40));
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert_eq!(Queues::<Test>::get(1), vec![Bid { amount: 40, who: 1 },]);
 		assert_eq!(
 			Queues::<Test>::get(2),
@@ -749,7 +749,7 @@ fn enlargement_to_target_works() {
 		);
 		assert_eq!(QueueTotals::<Test>::get(), vec![(1, 40), (2, 80), (2, 80)]);
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// Two new items should have been issued to 2 & 3 for 40 each & duration of 3.
 		assert_eq!(
 			Receipts::<Test>::get(0).unwrap(),
@@ -778,7 +778,7 @@ fn enlargement_to_target_works() {
 			}
 		);
 
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		// No change
 		assert_eq!(
 			Summary::<Test>::get(),
@@ -791,7 +791,7 @@ fn enlargement_to_target_works() {
 			}
 		);
 
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		// Two new items should have been issued to 1 & 2 for 40 each & duration of 2.
 		assert_eq!(
 			Receipts::<Test>::get(2).unwrap(),
@@ -820,7 +820,7 @@ fn enlargement_to_target_works() {
 			}
 		);
 
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		// No change now.
 		assert_eq!(
 			Summary::<Test>::get(),
@@ -835,7 +835,7 @@ fn enlargement_to_target_works() {
 
 		// Set target a bit higher to use up the remaining bid.
 		Target::set(Perquintill::from_percent(60));
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 
 		// One new item should have been issued to 1 for 40 each & duration of 2.
 		assert_eq!(
diff --git a/substrate/frame/nomination-pools/src/mock.rs b/substrate/frame/nomination-pools/src/mock.rs
index cc942039760c0208776fc2f045310a9cb501c73a..f544e79ec48192b77718c7ab2ef0b40d6cea3bd0 100644
--- a/substrate/frame/nomination-pools/src/mock.rs
+++ b/substrate/frame/nomination-pools/src/mock.rs
@@ -435,18 +435,7 @@ parameter_types! {
 /// Helper to run a specified amount of blocks.
 pub fn run_blocks(n: u64) {
 	let current_block = System::block_number();
-	run_to_block(n + current_block);
-}
-
-/// Helper to run to a specific block.
-pub fn run_to_block(n: u64) {
-	let current_block = System::block_number();
-	assert!(n > current_block);
-	while System::block_number() < n {
-		Pools::on_finalize(System::block_number());
-		System::set_block_number(System::block_number() + 1);
-		Pools::on_initialize(System::block_number());
-	}
+	System::run_to_block::<AllPalletsWithSystem>(n + current_block);
 }
 
 /// All events of this pallet.
diff --git a/substrate/frame/recovery/src/mock.rs b/substrate/frame/recovery/src/mock.rs
index 3930db82d6c77ad0133e0726e904c0ac0efb4bc7..86f13b0da4f7632cc67a49a899a670f592030d2e 100644
--- a/substrate/frame/recovery/src/mock.rs
+++ b/substrate/frame/recovery/src/mock.rs
@@ -20,10 +20,7 @@
 use super::*;
 
 use crate as recovery;
-use frame_support::{
-	derive_impl, parameter_types,
-	traits::{OnFinalize, OnInitialize},
-};
+use frame_support::{derive_impl, parameter_types};
 use sp_runtime::BuildStorage;
 
 type Block = frame_system::mocking::MockBlock<Test>;
@@ -86,14 +83,3 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
 	.unwrap();
 	t.into()
 }
-
-/// Run until a particular block.
-pub fn run_to_block(n: u64) {
-	while System::block_number() < n {
-		if System::block_number() > 1 {
-			System::on_finalize(System::block_number());
-		}
-		System::set_block_number(System::block_number() + 1);
-		System::on_initialize(System::block_number());
-	}
-}
diff --git a/substrate/frame/recovery/src/tests.rs b/substrate/frame/recovery/src/tests.rs
index 93df07015852e689db0ec02114642baa303ee349..97085df2ae788f34ee43a1c705563e5dd0a46cea 100644
--- a/substrate/frame/recovery/src/tests.rs
+++ b/substrate/frame/recovery/src/tests.rs
@@ -17,12 +17,8 @@
 
 //! Tests for the module.
 
-use super::*;
+use crate::{mock::*, *};
 use frame_support::{assert_noop, assert_ok, traits::Currency};
-use mock::{
-	new_test_ext, run_to_block, Balances, BalancesCall, MaxFriends, Recovery, RecoveryCall,
-	RuntimeCall, RuntimeOrigin, Test,
-};
 use sp_runtime::{bounded_vec, traits::BadOrigin};
 
 #[test]
@@ -70,7 +66,7 @@ fn recovery_life_cycle_works() {
 			delay_period
 		));
 		// Some time has passed, and the user lost their keys!
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		// Using account 1, the user begins the recovery process to recover the lost account
 		assert_ok!(Recovery::initiate_recovery(RuntimeOrigin::signed(1), 5));
 		// Off chain, the user contacts their friends and asks them to vouch for the recovery
@@ -84,7 +80,7 @@ fn recovery_life_cycle_works() {
 			Error::<Test>::DelayPeriod
 		);
 		// We need to wait at least the delay_period number of blocks before we can recover
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 		assert_ok!(Recovery::claim_recovery(RuntimeOrigin::signed(1), 5));
 		// Account 1 can use account 5 to close the active recovery process, claiming the deposited
 		// funds used to initiate the recovery process into account 5.
@@ -128,7 +124,7 @@ fn malicious_recovery_fails() {
 			delay_period
 		));
 		// Some time has passed, and account 1 wants to try and attack this account!
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		// Using account 1, the malicious user begins the recovery process on account 5
 		assert_ok!(Recovery::initiate_recovery(RuntimeOrigin::signed(1), 5));
 		// Off chain, the user **tricks** their friends and asks them to vouch for the recovery
@@ -144,7 +140,7 @@ fn malicious_recovery_fails() {
 			Error::<Test>::DelayPeriod
 		);
 		// Account 1 needs to wait...
-		run_to_block(19);
+		System::run_to_block::<AllPalletsWithSystem>(19);
 		// One more block to wait!
 		assert_noop!(
 			Recovery::claim_recovery(RuntimeOrigin::signed(1), 5),
@@ -158,7 +154,7 @@ fn malicious_recovery_fails() {
 		// Thanks for the free money!
 		assert_eq!(Balances::total_balance(&5), 110);
 		// The recovery process has been closed, so account 1 can't make the claim
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 		assert_noop!(
 			Recovery::claim_recovery(RuntimeOrigin::signed(1), 5),
 			Error::<Test>::NotStarted
@@ -397,7 +393,7 @@ fn claim_recovery_handles_basic_errors() {
 			Recovery::claim_recovery(RuntimeOrigin::signed(1), 5),
 			Error::<Test>::DelayPeriod
 		);
-		run_to_block(11);
+		System::run_to_block::<AllPalletsWithSystem>(11);
 		// Cannot claim an account which has not passed the threshold number of votes
 		assert_ok!(Recovery::vouch_recovery(RuntimeOrigin::signed(2), 5, 1));
 		assert_ok!(Recovery::vouch_recovery(RuntimeOrigin::signed(3), 5, 1));
@@ -427,7 +423,7 @@ fn claim_recovery_works() {
 		assert_ok!(Recovery::vouch_recovery(RuntimeOrigin::signed(3), 5, 1));
 		assert_ok!(Recovery::vouch_recovery(RuntimeOrigin::signed(4), 5, 1));
 
-		run_to_block(11);
+		System::run_to_block::<AllPalletsWithSystem>(11);
 
 		// Account can be recovered.
 		assert_ok!(Recovery::claim_recovery(RuntimeOrigin::signed(1), 5));
@@ -439,7 +435,7 @@ fn claim_recovery_works() {
 		assert_ok!(Recovery::vouch_recovery(RuntimeOrigin::signed(3), 5, 4));
 		assert_ok!(Recovery::vouch_recovery(RuntimeOrigin::signed(4), 5, 4));
 
-		run_to_block(21);
+		System::run_to_block::<AllPalletsWithSystem>(21);
 
 		// Account is re-recovered.
 		assert_ok!(Recovery::claim_recovery(RuntimeOrigin::signed(4), 5));
diff --git a/substrate/frame/root-offences/src/mock.rs b/substrate/frame/root-offences/src/mock.rs
index a27fb36f64a6478f00a1379160bbcd7d63c59d6b..7a96b8eade4e13f290020ffc0f0a12fa5f72600d 100644
--- a/substrate/frame/root-offences/src/mock.rs
+++ b/substrate/frame/root-offences/src/mock.rs
@@ -25,7 +25,7 @@ use frame_election_provider_support::{
 };
 use frame_support::{
 	derive_impl, parameter_types,
-	traits::{ConstU32, ConstU64, Hooks, OneSessionHandler},
+	traits::{ConstU32, ConstU64, OneSessionHandler},
 };
 use pallet_staking::StakerStatus;
 use sp_runtime::{curve::PiecewiseLinear, testing::UintAuthorityId, traits::Zero, BuildStorage};
@@ -283,16 +283,12 @@ pub(crate) fn start_session(session_index: SessionIndex) {
 /// a block import/propose process where we first initialize the block, then execute some stuff (not
 /// in the function), and then finalize the block.
 pub(crate) fn run_to_block(n: BlockNumber) {
-	Staking::on_finalize(System::block_number());
-	for b in (System::block_number() + 1)..=n {
-		System::set_block_number(b);
-		Session::on_initialize(b);
-		<Staking as Hooks<u64>>::on_initialize(b);
-		Timestamp::set_timestamp(System::block_number() * BLOCK_TIME + INIT_TIMESTAMP);
-		if b != n {
-			Staking::on_finalize(System::block_number());
-		}
-	}
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default().after_initialize(|bn| {
+			Timestamp::set_timestamp(bn * BLOCK_TIME + INIT_TIMESTAMP);
+		}),
+	);
 }
 
 pub(crate) fn active_era() -> EraIndex {
diff --git a/substrate/frame/scheduler/src/mock.rs b/substrate/frame/scheduler/src/mock.rs
index 8d36ca1c42e3ad916a5cd38e2ef3fa7bcfea5483..43a964bcf149731d7df03ad80d6247a82b2a8ec0 100644
--- a/substrate/frame/scheduler/src/mock.rs
+++ b/substrate/frame/scheduler/src/mock.rs
@@ -22,7 +22,7 @@ use super::*;
 use crate as scheduler;
 use frame_support::{
 	derive_impl, ord_parameter_types, parameter_types,
-	traits::{ConstU32, Contains, EitherOfDiverse, EqualPrivilegeOnly, OnFinalize, OnInitialize},
+	traits::{ConstU32, Contains, EitherOfDiverse, EqualPrivilegeOnly},
 };
 use frame_system::{EnsureRoot, EnsureSignedBy};
 use sp_runtime::{BuildStorage, Perbill};
@@ -236,14 +236,6 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
 	t.into()
 }
 
-pub fn run_to_block(n: u64) {
-	while System::block_number() < n {
-		Scheduler::on_finalize(System::block_number());
-		System::set_block_number(System::block_number() + 1);
-		Scheduler::on_initialize(System::block_number());
-	}
-}
-
 pub fn root() -> OriginCaller {
 	system::RawOrigin::Root.into()
 }
diff --git a/substrate/frame/scheduler/src/tests.rs b/substrate/frame/scheduler/src/tests.rs
index 3023a370a4b6034e4ec9366fcaa065035edccec3..7552239341088d7ad46c287edc23f1dd5b417088 100644
--- a/substrate/frame/scheduler/src/tests.rs
+++ b/substrate/frame/scheduler/src/tests.rs
@@ -20,7 +20,7 @@
 use super::*;
 use crate::mock::{
 	logger::{self, Threshold},
-	new_test_ext, root, run_to_block, LoggerCall, RuntimeCall, Scheduler, Test, *,
+	new_test_ext, root, LoggerCall, RuntimeCall, Scheduler, Test, *,
 };
 use frame_support::{
 	assert_err, assert_noop, assert_ok,
@@ -52,14 +52,14 @@ fn basic_scheduling_works() {
 		));
 
 		// `log` runtime call should not have executed yet
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// `log` runtime call should have executed at block 4
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -87,17 +87,17 @@ fn scheduling_with_preimages_works() {
 		assert!(Preimage::is_requested(&hash));
 
 		// `log` runtime call should not have executed yet
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// preimage should not have been removed when executed by the scheduler
 		assert!(!Preimage::len(&hash).is_some());
 		assert!(!Preimage::is_requested(&hash));
 		// `log` runtime call should have executed at block 4
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -105,7 +105,7 @@ fn scheduling_with_preimages_works() {
 #[test]
 fn schedule_after_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(2);
+		System::run_to_block::<AllPalletsWithSystem>(2);
 		let call =
 			RuntimeCall::Logger(LoggerCall::log { i: 42, weight: Weight::from_parts(10, 0) });
 		assert!(!<Test as frame_system::Config>::BaseCallFilter::contains(&call));
@@ -117,11 +117,11 @@ fn schedule_after_works() {
 			root(),
 			Preimage::bound(call).unwrap()
 		));
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert!(logger::log().is_empty());
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -129,7 +129,7 @@ fn schedule_after_works() {
 #[test]
 fn schedule_after_zero_works() {
 	new_test_ext().execute_with(|| {
-		run_to_block(2);
+		System::run_to_block::<AllPalletsWithSystem>(2);
 		let call =
 			RuntimeCall::Logger(LoggerCall::log { i: 42, weight: Weight::from_parts(10, 0) });
 		assert!(!<Test as frame_system::Config>::BaseCallFilter::contains(&call));
@@ -141,9 +141,9 @@ fn schedule_after_zero_works() {
 			Preimage::bound(call).unwrap()
 		));
 		// Will trigger on the next block.
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -163,19 +163,19 @@ fn periodic_scheduling_works() {
 			}))
 			.unwrap()
 		));
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]);
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]);
 	});
 }
@@ -201,37 +201,37 @@ fn retry_scheduling_works() {
 		// retry 10 times every 3 blocks
 		assert_ok!(Scheduler::set_retry(root().into(), (4, 0), 10, 3));
 		assert_eq!(Retries::<Test>::iter().count(), 1);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert!(Agenda::<Test>::get(4)[0].is_some());
 		// task should be retried in block 7
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(Agenda::<Test>::get(4).is_empty());
 		assert!(Agenda::<Test>::get(7)[0].is_some());
 		assert!(logger::log().is_empty());
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert!(Agenda::<Test>::get(7)[0].is_some());
 		assert!(logger::log().is_empty());
 		// task still fails, should be retried in block 10
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert!(Agenda::<Test>::get(7).is_empty());
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		assert!(logger::log().is_empty());
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		assert!(logger::log().is_empty());
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert!(logger::log().is_empty());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		// finally it should succeed
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
-		run_to_block(11);
+		System::run_to_block::<AllPalletsWithSystem>(11);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -262,37 +262,37 @@ fn named_retry_scheduling_works() {
 		// retry 10 times every 3 blocks
 		assert_ok!(Scheduler::set_retry_named(root().into(), [1u8; 32], 10, 3));
 		assert_eq!(Retries::<Test>::iter().count(), 1);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert!(Agenda::<Test>::get(4)[0].is_some());
 		// task should be retried in block 7
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(Agenda::<Test>::get(4).is_empty());
 		assert!(Agenda::<Test>::get(7)[0].is_some());
 		assert!(logger::log().is_empty());
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert!(Agenda::<Test>::get(7)[0].is_some());
 		assert!(logger::log().is_empty());
 		// task still fails, should be retried in block 10
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert!(Agenda::<Test>::get(7).is_empty());
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		assert!(logger::log().is_empty());
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		assert!(logger::log().is_empty());
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert!(logger::log().is_empty());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		// finally it should succeed
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
-		run_to_block(11);
+		System::run_to_block::<AllPalletsWithSystem>(11);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -333,11 +333,11 @@ fn retry_scheduling_multiple_tasks_works() {
 		// task 42 will be retried 10 times every 3 blocks
 		assert_ok!(Scheduler::set_retry(root().into(), (4, 1), 10, 3));
 		assert_eq!(Retries::<Test>::iter().count(), 2);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert_eq!(Agenda::<Test>::get(4).len(), 2);
 		// both tasks fail
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(Agenda::<Test>::get(4).is_empty());
 		// 20 is rescheduled for next block
 		assert_eq!(Agenda::<Test>::get(5).len(), 1);
@@ -345,41 +345,41 @@ fn retry_scheduling_multiple_tasks_works() {
 		assert_eq!(Agenda::<Test>::get(7).len(), 1);
 		assert!(logger::log().is_empty());
 		// 20 still fails
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		// 20 rescheduled for next block
 		assert_eq!(Agenda::<Test>::get(6).len(), 1);
 		assert_eq!(Agenda::<Test>::get(7).len(), 1);
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert!(logger::log().is_empty());
 		// 20 still fails
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		// rescheduled for next block together with 42
 		assert_eq!(Agenda::<Test>::get(7).len(), 2);
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert!(logger::log().is_empty());
 		// both tasks will fail, for 20 it was the last retry so it's dropped
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert!(Agenda::<Test>::get(7).is_empty());
 		assert!(Agenda::<Test>::get(8).is_empty());
 		// 42 is rescheduled for block 10
 		assert_eq!(Agenda::<Test>::get(10).len(), 1);
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert!(logger::log().is_empty());
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		assert_eq!(Agenda::<Test>::get(10).len(), 1);
 		assert!(logger::log().is_empty());
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert!(logger::log().is_empty());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		// 42 runs successfully
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
-		run_to_block(11);
+		System::run_to_block::<AllPalletsWithSystem>(11);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -422,11 +422,11 @@ fn retry_scheduling_multiple_named_tasks_works() {
 		// task 42 will be retried 10 times every 3 block
 		assert_ok!(Scheduler::set_retry_named(root().into(), [42u8; 32], 10, 3));
 		assert_eq!(Retries::<Test>::iter().count(), 2);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert_eq!(Agenda::<Test>::get(4).len(), 2);
 		// both tasks fail
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(Agenda::<Test>::get(4).is_empty());
 		// 42 is rescheduled for block 7
 		assert_eq!(Agenda::<Test>::get(7).len(), 1);
@@ -434,41 +434,41 @@ fn retry_scheduling_multiple_named_tasks_works() {
 		assert_eq!(Agenda::<Test>::get(5).len(), 1);
 		assert!(logger::log().is_empty());
 		// 20 still fails
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		// 20 rescheduled for next block
 		assert_eq!(Agenda::<Test>::get(6).len(), 1);
 		assert_eq!(Agenda::<Test>::get(7).len(), 1);
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert!(logger::log().is_empty());
 		// 20 still fails
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		// 20 rescheduled for next block together with 42
 		assert_eq!(Agenda::<Test>::get(7).len(), 2);
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert!(logger::log().is_empty());
 		// both tasks will fail, for 20 it was the last retry so it's dropped
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert!(Agenda::<Test>::get(7).is_empty());
 		assert!(Agenda::<Test>::get(8).is_empty());
 		// 42 is rescheduled for block 10
 		assert_eq!(Agenda::<Test>::get(10).len(), 1);
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert!(logger::log().is_empty());
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		assert_eq!(Agenda::<Test>::get(10).len(), 1);
 		assert!(logger::log().is_empty());
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert!(logger::log().is_empty());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		// 42 runs successfully
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
-		run_to_block(11);
+		System::run_to_block::<AllPalletsWithSystem>(11);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -495,33 +495,33 @@ fn retry_scheduling_with_period_works() {
 		// 42 will be retried 10 times every 2 blocks
 		assert_ok!(Scheduler::set_retry(root().into(), (4, 0), 10, 2));
 		assert_eq!(Retries::<Test>::iter().count(), 1);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert!(Agenda::<Test>::get(4)[0].is_some());
 		// 42 runs successfully once, it will run again at block 7
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(Agenda::<Test>::get(4).is_empty());
 		assert!(Agenda::<Test>::get(7)[0].is_some());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// nothing changed
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert!(Agenda::<Test>::get(7)[0].is_some());
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// 42 runs successfully again, it will run again at block 10
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert!(Agenda::<Test>::get(7).is_empty());
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
 		// 42 has 10 retries left out of a total of 10
 		assert_eq!(Retries::<Test>::get((10, 0)).unwrap().remaining, 10);
 		// 42 will fail because we're outside the set threshold (block number in `4..8`), so it
 		// should be retried in 2 blocks (at block 12)
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		// should be queued for the normal period of 3 blocks
 		assert!(Agenda::<Test>::get(13)[0].is_some());
 		// should also be queued to be retried in 2 blocks
@@ -532,7 +532,7 @@ fn retry_scheduling_with_period_works() {
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
 		// 42 will fail again
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		// should still be queued for the normal period
 		assert!(Agenda::<Test>::get(13)[0].is_some());
 		// should be queued to be retried in 2 blocks
@@ -543,7 +543,7 @@ fn retry_scheduling_with_period_works() {
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
 		// 42 will fail for the regular periodic run
-		run_to_block(13);
+		System::run_to_block::<AllPalletsWithSystem>(13);
 		// should still be queued for the normal period
 		assert!(Agenda::<Test>::get(16)[0].is_some());
 		// should still be queued to be retried next block
@@ -560,7 +560,7 @@ fn retry_scheduling_with_period_works() {
 		// change the threshold to allow the task to succeed
 		Threshold::<Test>::put((14, 100));
 		// first retry should now succeed
-		run_to_block(14);
+		System::run_to_block::<AllPalletsWithSystem>(14);
 		assert!(Agenda::<Test>::get(15)[0].as_ref().unwrap().maybe_periodic.is_none());
 		assert_eq!(Agenda::<Test>::get(16).iter().filter(|entry| entry.is_some()).count(), 1);
 		assert!(Agenda::<Test>::get(16)[0].is_some());
@@ -569,7 +569,7 @@ fn retry_scheduling_with_period_works() {
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]);
 		// second retry should also succeed
-		run_to_block(15);
+		System::run_to_block::<AllPalletsWithSystem>(15);
 		assert_eq!(Agenda::<Test>::get(16).iter().filter(|entry| entry.is_some()).count(), 1);
 		assert!(Agenda::<Test>::get(16)[0].is_some());
 		assert!(Agenda::<Test>::get(17).is_empty());
@@ -580,7 +580,7 @@ fn retry_scheduling_with_period_works() {
 			vec![(root(), 42u32), (root(), 42u32), (root(), 42u32), (root(), 42u32)]
 		);
 		// normal periodic run on block 16 will succeed
-		run_to_block(16);
+		System::run_to_block::<AllPalletsWithSystem>(16);
 		// next periodic run at block 19
 		assert!(Agenda::<Test>::get(19)[0].is_some());
 		assert!(Agenda::<Test>::get(18).is_empty());
@@ -598,7 +598,7 @@ fn retry_scheduling_with_period_works() {
 			]
 		);
 		// final periodic run on block 19 will succeed
-		run_to_block(19);
+		System::run_to_block::<AllPalletsWithSystem>(19);
 		// next periodic run at block 19
 		assert_eq!(Agenda::<Test>::iter().count(), 0);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
@@ -639,33 +639,33 @@ fn named_retry_scheduling_with_period_works() {
 		// 42 will be retried 10 times every 2 blocks
 		assert_ok!(Scheduler::set_retry_named(root().into(), [42u8; 32], 10, 2));
 		assert_eq!(Retries::<Test>::iter().count(), 1);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert!(Agenda::<Test>::get(4)[0].is_some());
 		// 42 runs successfully once, it will run again at block 7
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(Agenda::<Test>::get(4).is_empty());
 		assert!(Agenda::<Test>::get(7)[0].is_some());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// nothing changed
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert!(Agenda::<Test>::get(7)[0].is_some());
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// 42 runs successfully again, it will run again at block 10
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert!(Agenda::<Test>::get(7).is_empty());
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
 		// 42 has 10 retries left out of a total of 10
 		assert_eq!(Retries::<Test>::get((10, 0)).unwrap().remaining, 10);
 		// 42 will fail because we're outside the set threshold (block number in `4..8`), so it
 		// should be retried in 2 blocks (at block 12)
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		// should be queued for the normal period of 3 blocks
 		assert!(Agenda::<Test>::get(13)[0].is_some());
 		// should also be queued to be retried in 2 blocks
@@ -677,7 +677,7 @@ fn named_retry_scheduling_with_period_works() {
 		assert_eq!(Lookup::<Test>::get([42u8; 32]).unwrap(), (13, 0));
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
 		// 42 will fail again
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		// should still be queued for the normal period
 		assert!(Agenda::<Test>::get(13)[0].is_some());
 		// should be queued to be retried in 2 blocks
@@ -688,7 +688,7 @@ fn named_retry_scheduling_with_period_works() {
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
 		// 42 will fail for the regular periodic run
-		run_to_block(13);
+		System::run_to_block::<AllPalletsWithSystem>(13);
 		// should still be queued for the normal period
 		assert!(Agenda::<Test>::get(16)[0].is_some());
 		// should still be queued to be retried next block
@@ -706,7 +706,7 @@ fn named_retry_scheduling_with_period_works() {
 		// change the threshold to allow the task to succeed
 		Threshold::<Test>::put((14, 100));
 		// first retry should now succeed
-		run_to_block(14);
+		System::run_to_block::<AllPalletsWithSystem>(14);
 		assert!(Agenda::<Test>::get(15)[0].as_ref().unwrap().maybe_periodic.is_none());
 		assert_eq!(Agenda::<Test>::get(16).iter().filter(|entry| entry.is_some()).count(), 1);
 		assert!(Agenda::<Test>::get(16)[0].is_some());
@@ -715,7 +715,7 @@ fn named_retry_scheduling_with_period_works() {
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]);
 		// second retry should also succeed
-		run_to_block(15);
+		System::run_to_block::<AllPalletsWithSystem>(15);
 		assert_eq!(Agenda::<Test>::get(16).iter().filter(|entry| entry.is_some()).count(), 1);
 		assert!(Agenda::<Test>::get(16)[0].is_some());
 		assert!(Agenda::<Test>::get(17).is_empty());
@@ -727,7 +727,7 @@ fn named_retry_scheduling_with_period_works() {
 			vec![(root(), 42u32), (root(), 42u32), (root(), 42u32), (root(), 42u32)]
 		);
 		// normal periodic run on block 16 will succeed
-		run_to_block(16);
+		System::run_to_block::<AllPalletsWithSystem>(16);
 		// next periodic run at block 19
 		assert!(Agenda::<Test>::get(19)[0].is_some());
 		assert!(Agenda::<Test>::get(18).is_empty());
@@ -746,7 +746,7 @@ fn named_retry_scheduling_with_period_works() {
 			]
 		);
 		// final periodic run on block 19 will succeed
-		run_to_block(19);
+		System::run_to_block::<AllPalletsWithSystem>(19);
 		// next periodic run at block 19
 		assert_eq!(Agenda::<Test>::iter().count(), 0);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
@@ -786,12 +786,12 @@ fn retry_scheduling_expires() {
 		// task 42 will be retried 3 times every block
 		assert_ok!(Scheduler::set_retry(root().into(), (4, 0), 3, 1));
 		assert_eq!(Retries::<Test>::iter().count(), 1);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		// task 42 is scheduled for next block
 		assert!(Agenda::<Test>::get(4)[0].is_some());
 		// task fails because we're past block 3
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// task is scheduled for next block
 		assert!(Agenda::<Test>::get(4).is_empty());
 		assert!(Agenda::<Test>::get(5)[0].is_some());
@@ -799,7 +799,7 @@ fn retry_scheduling_expires() {
 		assert_eq!(Retries::<Test>::get((5, 0)).unwrap().remaining, 2);
 		assert!(logger::log().is_empty());
 		// task fails again
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		// task is scheduled for next block
 		assert!(Agenda::<Test>::get(5).is_empty());
 		assert!(Agenda::<Test>::get(6)[0].is_some());
@@ -807,7 +807,7 @@ fn retry_scheduling_expires() {
 		assert_eq!(Retries::<Test>::get((6, 0)).unwrap().remaining, 1);
 		assert!(logger::log().is_empty());
 		// task fails again
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		// task is scheduled for next block
 		assert!(Agenda::<Test>::get(6).is_empty());
 		assert!(Agenda::<Test>::get(7)[0].is_some());
@@ -815,7 +815,7 @@ fn retry_scheduling_expires() {
 		assert_eq!(Retries::<Test>::get((7, 0)).unwrap().remaining, 0);
 		assert!(logger::log().is_empty());
 		// task fails again
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		// task ran out of retries so it gets dropped
 		assert_eq!(Agenda::<Test>::iter().count(), 0);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
@@ -949,17 +949,17 @@ fn retry_periodic_full_cycle() {
 		// 42 will be retried 2 times every block
 		assert_ok!(Scheduler::set_retry_named(root().into(), [42u8; 32], 2, 1));
 		assert_eq!(Retries::<Test>::iter().count(), 1);
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert!(logger::log().is_empty());
 		assert!(Agenda::<Test>::get(10)[0].is_some());
 		// 42 runs successfully once, it will run again at block 110
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert!(Agenda::<Test>::get(10).is_empty());
 		assert!(Agenda::<Test>::get(110)[0].is_some());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// nothing changed
-		run_to_block(109);
+		System::run_to_block::<AllPalletsWithSystem>(109);
 		assert!(Agenda::<Test>::get(110)[0].is_some());
 		// original task still has 2 remaining retries
 		assert_eq!(Retries::<Test>::get((110, 0)).unwrap().remaining, 2);
@@ -968,7 +968,7 @@ fn retry_periodic_full_cycle() {
 		Threshold::<Test>::put((1, 2));
 		// 42 will fail because we're outside the set threshold (block number in `1..2`), so it
 		// should be retried next block (at block 111)
-		run_to_block(110);
+		System::run_to_block::<AllPalletsWithSystem>(110);
 		// should be queued for the normal period of 100 blocks
 		assert!(Agenda::<Test>::get(210)[0].is_some());
 		// should also be queued to be retried next block
@@ -980,7 +980,7 @@ fn retry_periodic_full_cycle() {
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// 42 retry will fail again
-		run_to_block(111);
+		System::run_to_block::<AllPalletsWithSystem>(111);
 		// should still be queued for the normal period
 		assert!(Agenda::<Test>::get(210)[0].is_some());
 		// should be queued to be retried next block
@@ -991,20 +991,20 @@ fn retry_periodic_full_cycle() {
 		assert_eq!(Retries::<Test>::iter().count(), 2);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// 42 retry will fail again
-		run_to_block(112);
+		System::run_to_block::<AllPalletsWithSystem>(112);
 		// should still be queued for the normal period
 		assert!(Agenda::<Test>::get(210)[0].is_some());
 		// 42 retry clone ran out of retries, must have been evicted
 		assert_eq!(Agenda::<Test>::iter().count(), 1);
 
 		// advance
-		run_to_block(209);
+		System::run_to_block::<AllPalletsWithSystem>(209);
 		// should still be queued for the normal period
 		assert!(Agenda::<Test>::get(210)[0].is_some());
 		// 42 retry clone ran out of retries, must have been evicted
 		assert_eq!(Agenda::<Test>::iter().count(), 1);
 		// 42 should fail again and should spawn another retry clone
-		run_to_block(210);
+		System::run_to_block::<AllPalletsWithSystem>(210);
 		// should be queued for the normal period of 100 blocks
 		assert!(Agenda::<Test>::get(310)[0].is_some());
 		// should also be queued to be retried next block
@@ -1018,7 +1018,7 @@ fn retry_periodic_full_cycle() {
 		// make 42 run successfully again
 		Threshold::<Test>::put((1, 1000));
 		// 42 retry clone should now succeed
-		run_to_block(211);
+		System::run_to_block::<AllPalletsWithSystem>(211);
 		// should be queued for the normal period of 100 blocks
 		assert!(Agenda::<Test>::get(310)[0].is_some());
 		// retry was successful, retry task should have been discarded
@@ -1029,7 +1029,7 @@ fn retry_periodic_full_cycle() {
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
 
 		// fast forward to the last periodic run of 42
-		run_to_block(310);
+		System::run_to_block::<AllPalletsWithSystem>(310);
 		// 42 was successful, the period ended as this was the 4th scheduled periodic run so 42 must
 		// have been discarded
 		assert_eq!(Agenda::<Test>::iter().count(), 0);
@@ -1057,7 +1057,7 @@ fn reschedule_works() {
 			(4, 0)
 		);
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 
 		assert_eq!(Scheduler::do_reschedule((4, 0), DispatchTime::At(6)).unwrap(), (6, 0));
@@ -1067,13 +1067,13 @@ fn reschedule_works() {
 			Error::<Test>::RescheduleNoChange
 		);
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(logger::log().is_empty());
 
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -1097,7 +1097,7 @@ fn reschedule_named_works() {
 			(4, 0)
 		);
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 
 		assert_eq!(Scheduler::do_reschedule_named([1u8; 32], DispatchTime::At(6)).unwrap(), (6, 0));
@@ -1107,13 +1107,13 @@ fn reschedule_named_works() {
 			Error::<Test>::RescheduleNoChange
 		);
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(logger::log().is_empty());
 
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -1137,16 +1137,16 @@ fn reschedule_named_periodic_works() {
 			(4, 0)
 		);
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 
 		assert_eq!(Scheduler::do_reschedule_named([1u8; 32], DispatchTime::At(5)).unwrap(), (5, 0));
 		assert_eq!(Scheduler::do_reschedule_named([1u8; 32], DispatchTime::At(6)).unwrap(), (6, 0));
 
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert!(logger::log().is_empty());
 
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 
 		assert_eq!(
@@ -1154,16 +1154,16 @@ fn reschedule_named_periodic_works() {
 			(10, 0)
 		);
 
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32)]);
 
-		run_to_block(13);
+		System::run_to_block::<AllPalletsWithSystem>(13);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]);
 
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 42u32), (root(), 42u32)]);
 	});
 }
@@ -1197,11 +1197,11 @@ fn cancel_named_scheduling_works_with_normal_cancel() {
 			.unwrap(),
 		)
 		.unwrap();
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert_ok!(Scheduler::do_cancel_named(None, [1u8; 32]));
 		assert_ok!(Scheduler::do_cancel(None, i));
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert!(logger::log().is_empty());
 	});
 }
@@ -1251,13 +1251,13 @@ fn cancel_named_periodic_scheduling_works() {
 			.unwrap(),
 		)
 		.unwrap();
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		assert_ok!(Scheduler::do_cancel_named(None, [1u8; 32]));
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]);
 	});
 }
@@ -1283,9 +1283,9 @@ fn scheduler_respects_weight_limits() {
 			Preimage::bound(call).unwrap(),
 		));
 		// 69 and 42 do not fit together
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]);
 	});
 }
@@ -1316,26 +1316,26 @@ fn retry_respects_weight_limits() {
 		// set a retry config for 20 for 10 retries every block
 		assert_ok!(Scheduler::set_retry(root().into(), (4, 0), 10, 1));
 		// 20 should fail and be retried later
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(Agenda::<Test>::get(5)[0].is_some());
 		assert!(Agenda::<Test>::get(8)[0].is_some());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert!(logger::log().is_empty());
 		// 20 still fails but is scheduled next block together with 42
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert_eq!(Agenda::<Test>::get(8).len(), 2);
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert!(logger::log().is_empty());
 		// 20 and 42 do not fit together
 		// 42 is executed as it was first in the queue
 		// 20 is still on the 8th block's agenda
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		assert!(Agenda::<Test>::get(8)[0].is_none());
 		assert!(Agenda::<Test>::get(8)[1].is_some());
 		assert_eq!(Retries::<Test>::iter().count(), 1);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// 20 is executed and the schedule is cleared
-		run_to_block(9);
+		System::run_to_block::<AllPalletsWithSystem>(9);
 		assert_eq!(Agenda::<Test>::iter().count(), 0);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
 		assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 20u32)]);
@@ -1386,7 +1386,7 @@ fn try_schedule_retry_respects_weight_limits() {
 		// set a retry config for 20 for 10 retries every block
 		assert_ok!(Scheduler::set_retry(root().into(), (4, 0), 10, 1));
 		// 20 should fail and, because of insufficient weight, it should not be scheduled again
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// nothing else should be scheduled
 		assert_eq!(Agenda::<Test>::iter().count(), 0);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
@@ -1415,7 +1415,7 @@ fn scheduler_does_not_delete_permanently_overweight_call() {
 			Preimage::bound(call).unwrap(),
 		));
 		// Never executes.
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![]);
 
 		// Assert the `PermanentlyOverweight` event.
@@ -1445,7 +1445,7 @@ fn scheduler_handles_periodic_failure() {
 			bound.clone(),
 		));
 		// Executes 5 times till block 20.
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 		assert_eq!(logger::log().len(), 5);
 
 		// Block 28 will already be full.
@@ -1460,7 +1460,7 @@ fn scheduler_handles_periodic_failure() {
 		}
 
 		// Going to block 24 will emit a `PeriodicFailed` event.
-		run_to_block(24);
+		System::run_to_block::<AllPalletsWithSystem>(24);
 		assert_eq!(logger::log().len(), 6);
 
 		assert_eq!(
@@ -1498,7 +1498,7 @@ fn scheduler_handles_periodic_unavailable_preimage() {
 		assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(1), call.encode()));
 
 		// Executes 1 times till block 4.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log().len(), 1);
 
 		// As the public api doesn't support to remove a noted preimage, we need to first unnote it
@@ -1508,7 +1508,7 @@ fn scheduler_handles_periodic_unavailable_preimage() {
 		Preimage::request(&hash);
 
 		// Does not ever execute again.
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log().len(), 1);
 
 		// The preimage is not requested anymore.
@@ -1536,7 +1536,7 @@ fn scheduler_respects_priority_ordering() {
 			root(),
 			Preimage::bound(call).unwrap(),
 		));
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 69u32), (root(), 42u32)]);
 	});
 }
@@ -1571,10 +1571,10 @@ fn scheduler_respects_priority_ordering_with_soft_deadlines() {
 		));
 
 		// 2600 does not fit with 69 or 42, but has higher priority, so will go through
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 2600u32)]);
 		// 69 and 42 fit together
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_eq!(logger::log(), vec![(root(), 2600u32), (root(), 69u32), (root(), 42u32)]);
 	});
 }
@@ -1701,14 +1701,14 @@ fn root_calls_works() {
 			Scheduler::schedule_named(RuntimeOrigin::root(), [1u8; 32], 4, None, 127, call,)
 		);
 		assert_ok!(Scheduler::schedule(RuntimeOrigin::root(), 4, None, 127, call2));
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Scheduled calls are in the agenda.
 		assert_eq!(Agenda::<Test>::get(4).len(), 2);
 		assert!(logger::log().is_empty());
 		assert_ok!(Scheduler::cancel_named(RuntimeOrigin::root(), [1u8; 32]));
 		assert_ok!(Scheduler::cancel(RuntimeOrigin::root(), 4, 1));
 		// Scheduled calls are made NONE, so should not effect state
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert!(logger::log().is_empty());
 	});
 }
@@ -1716,7 +1716,7 @@ fn root_calls_works() {
 #[test]
 fn fails_to_schedule_task_in_the_past() {
 	new_test_ext().execute_with(|| {
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 
 		let call1 = Box::new(RuntimeCall::Logger(LoggerCall::log {
 			i: 69,
@@ -1768,14 +1768,14 @@ fn should_use_origin() {
 			call,
 		));
 		assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, None, 127, call2,));
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Scheduled calls are in the agenda.
 		assert_eq!(Agenda::<Test>::get(4).len(), 2);
 		assert!(logger::log().is_empty());
 		assert_ok!(Scheduler::cancel_named(system::RawOrigin::Signed(1).into(), [1u8; 32]));
 		assert_ok!(Scheduler::cancel(system::RawOrigin::Signed(1).into(), 4, 1));
 		// Scheduled calls are made NONE, so should not effect state
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert!(logger::log().is_empty());
 	});
 }
@@ -1829,7 +1829,7 @@ fn should_check_origin_for_cancel() {
 			call,
 		));
 		assert_ok!(Scheduler::schedule(system::RawOrigin::Signed(1).into(), 4, None, 127, call2,));
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Scheduled calls are in the agenda.
 		assert_eq!(Agenda::<Test>::get(4).len(), 2);
 		assert!(logger::log().is_empty());
@@ -1840,7 +1840,7 @@ fn should_check_origin_for_cancel() {
 		assert_noop!(Scheduler::cancel(system::RawOrigin::Signed(2).into(), 4, 1), BadOrigin);
 		assert_noop!(Scheduler::cancel_named(system::RawOrigin::Root.into(), [1u8; 32]), BadOrigin);
 		assert_noop!(Scheduler::cancel(system::RawOrigin::Root.into(), 4, 1), BadOrigin);
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_eq!(
 			logger::log(),
 			vec![
@@ -1888,17 +1888,17 @@ fn cancel_removes_retry_entry() {
 		// task 42 will be retried 10 times every 3 blocks
 		assert_ok!(Scheduler::set_retry_named(root().into(), [1u8; 32], 10, 1));
 		assert_eq!(Retries::<Test>::iter().count(), 2);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert_eq!(Agenda::<Test>::get(4).len(), 2);
 		// both tasks fail
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(Agenda::<Test>::get(4).is_empty());
 		// 42 and 20 are rescheduled for next block
 		assert_eq!(Agenda::<Test>::get(5).len(), 2);
 		assert!(logger::log().is_empty());
 		// 42 and 20 still fail
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		// 42 and 20 rescheduled for next block
 		assert_eq!(Agenda::<Test>::get(6).len(), 2);
 		assert_eq!(Retries::<Test>::iter().count(), 2);
@@ -1909,7 +1909,7 @@ fn cancel_removes_retry_entry() {
 		assert!(Scheduler::cancel(root().into(), 6, 0).is_ok());
 
 		// 20 is removed, 42 still fails
-		run_to_block(6);
+		System::run_to_block::<AllPalletsWithSystem>(6);
 		// 42 rescheduled for next block
 		assert_eq!(Agenda::<Test>::get(7).len(), 1);
 		// 20's retry entry is removed
@@ -1920,7 +1920,7 @@ fn cancel_removes_retry_entry() {
 		assert!(Scheduler::cancel(root().into(), 7, 0).is_ok());
 
 		// both tasks are canceled, everything is removed now
-		run_to_block(7);
+		System::run_to_block::<AllPalletsWithSystem>(7);
 		assert!(Agenda::<Test>::get(8).is_empty());
 		assert_eq!(Retries::<Test>::iter().count(), 0);
 	});
@@ -1963,7 +1963,7 @@ fn cancel_retries_works() {
 		// task 42 will be retried 10 times every 3 blocks
 		assert_ok!(Scheduler::set_retry_named(root().into(), [1u8; 32], 10, 1));
 		assert_eq!(Retries::<Test>::iter().count(), 2);
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		assert!(logger::log().is_empty());
 		assert_eq!(Agenda::<Test>::get(4).len(), 2);
 		// cancel the retry config for 20
@@ -1972,7 +1972,7 @@ fn cancel_retries_works() {
 		// cancel the retry config for 42
 		assert_ok!(Scheduler::cancel_retry_named(root().into(), [1u8; 32]));
 		assert_eq!(Retries::<Test>::iter().count(), 0);
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// both tasks failed and there are no more retries, so they are evicted
 		assert_eq!(Agenda::<Test>::get(4).len(), 0);
 		assert_eq!(Retries::<Test>::iter().count(), 0);
@@ -2287,7 +2287,7 @@ fn postponed_named_task_cannot_be_rescheduled() {
 		assert!(Lookup::<Test>::contains_key(name));
 
 		// Run to a very large block.
-		run_to_block(10);
+		System::run_to_block::<AllPalletsWithSystem>(10);
 
 		// It was not executed.
 		assert!(logger::log().is_empty());
@@ -2321,7 +2321,7 @@ fn postponed_named_task_cannot_be_rescheduled() {
 		// Finally add the preimage.
 		assert_ok!(Preimage::note_preimage(RuntimeOrigin::signed(0), call.encode()));
 
-		run_to_block(1000);
+		System::run_to_block::<AllPalletsWithSystem>(1000);
 		// It did not execute.
 		assert!(logger::log().is_empty());
 		assert!(!Preimage::is_requested(&hash));
@@ -2357,14 +2357,14 @@ fn scheduler_v3_anon_basic_works() {
 		)
 		.unwrap();
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Did not execute till block 3.
 		assert!(logger::log().is_empty());
 		// Executes in block 4.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// ... but not again.
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -2389,7 +2389,7 @@ fn scheduler_v3_anon_cancel_works() {
 		// Cancel the call.
 		assert_ok!(<Scheduler as Anon<_, _, _>>::cancel(address));
 		// It did not get executed.
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert!(logger::log().is_empty());
 		// Cannot cancel again.
 		assert_err!(<Scheduler as Anon<_, _, _>>::cancel(address), DispatchError::Unavailable);
@@ -2413,7 +2413,7 @@ fn scheduler_v3_anon_reschedule_works() {
 		)
 		.unwrap();
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Did not execute till block 3.
 		assert!(logger::log().is_empty());
 
@@ -2430,9 +2430,9 @@ fn scheduler_v3_anon_reschedule_works() {
 		// Re-schedule to block 5.
 		assert_ok!(<Scheduler as Anon<_, _, _>>::reschedule(address, DispatchTime::At(5)));
 		// Scheduled for block 5.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(logger::log().is_empty());
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		// Does execute in block 5.
 		assert_eq!(logger::log(), vec![(root(), 42)]);
 		// Cannot re-schedule executed task.
@@ -2461,14 +2461,14 @@ fn scheduler_v3_anon_next_schedule_time_works() {
 		)
 		.unwrap();
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Did not execute till block 3.
 		assert!(logger::log().is_empty());
 
 		// Scheduled for block 4.
 		assert_eq!(<Scheduler as Anon<_, _, _>>::next_dispatch_time(address), Ok(4));
 		// Block 4 executes it.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 42)]);
 
 		// It has no dispatch time anymore.
@@ -2498,7 +2498,7 @@ fn scheduler_v3_anon_reschedule_and_next_schedule_time_work() {
 		)
 		.unwrap();
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Did not execute till block 3.
 		assert!(logger::log().is_empty());
 
@@ -2512,10 +2512,10 @@ fn scheduler_v3_anon_reschedule_and_next_schedule_time_work() {
 		assert_eq!(<Scheduler as Anon<_, _, _>>::next_dispatch_time(address), Ok(5));
 
 		// Block 4 does nothing.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(logger::log().is_empty());
 		// Block 5 executes it.
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		assert_eq!(logger::log(), vec![(root(), 42)]);
 	});
 }
@@ -2548,7 +2548,7 @@ fn scheduler_v3_anon_schedule_agenda_overflows() {
 			DispatchError::Exhausted
 		);
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// All scheduled calls are executed.
 		assert_eq!(logger::log().len() as u32, max);
 	});
@@ -2597,7 +2597,7 @@ fn scheduler_v3_anon_cancel_and_schedule_fills_holes() {
 			assert_eq!(i, index);
 		}
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// Maximum number of calls are executed.
 		assert_eq!(logger::log().len() as u32, max);
 	});
@@ -2643,7 +2643,7 @@ fn scheduler_v3_anon_reschedule_fills_holes() {
 			assert_eq!(new, want);
 		}
 
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		// Maximum number of calls are executed.
 		assert_eq!(logger::log().len() as u32, max);
 	});
@@ -2670,14 +2670,14 @@ fn scheduler_v3_named_basic_works() {
 		)
 		.unwrap();
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Did not execute till block 3.
 		assert!(logger::log().is_empty());
 		// Executes in block 4.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 		// ... but not again.
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert_eq!(logger::log(), vec![(root(), 42u32)]);
 	});
 }
@@ -2705,7 +2705,7 @@ fn scheduler_v3_named_cancel_named_works() {
 		// Cancel the call by name.
 		assert_ok!(<Scheduler as Named<_, _, _>>::cancel_named(name));
 		// It did not get executed.
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert!(logger::log().is_empty());
 		// Cannot cancel again.
 		assert_noop!(<Scheduler as Named<_, _, _>>::cancel_named(name), DispatchError::Unavailable);
@@ -2735,7 +2735,7 @@ fn scheduler_v3_named_cancel_without_name_works() {
 		// Cancel the call by address.
 		assert_ok!(<Scheduler as Anon<_, _, _>>::cancel(address));
 		// It did not get executed.
-		run_to_block(100);
+		System::run_to_block::<AllPalletsWithSystem>(100);
 		assert!(logger::log().is_empty());
 		// Cannot cancel again.
 		assert_err!(<Scheduler as Anon<_, _, _>>::cancel(address), DispatchError::Unavailable);
@@ -2762,7 +2762,7 @@ fn scheduler_v3_named_reschedule_named_works() {
 		)
 		.unwrap();
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Did not execute till block 3.
 		assert!(logger::log().is_empty());
 
@@ -2784,9 +2784,9 @@ fn scheduler_v3_named_reschedule_named_works() {
 		// Re-schedule to block 5.
 		assert_ok!(<Scheduler as Named<_, _, _>>::reschedule_named(name, DispatchTime::At(5)));
 		// Scheduled for block 5.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert!(logger::log().is_empty());
-		run_to_block(5);
+		System::run_to_block::<AllPalletsWithSystem>(5);
 		// Does execute in block 5.
 		assert_eq!(logger::log(), vec![(root(), 42)]);
 		// Cannot re-schedule executed task.
@@ -2822,7 +2822,7 @@ fn scheduler_v3_named_next_schedule_time_works() {
 		)
 		.unwrap();
 
-		run_to_block(3);
+		System::run_to_block::<AllPalletsWithSystem>(3);
 		// Did not execute till block 3.
 		assert!(logger::log().is_empty());
 
@@ -2831,7 +2831,7 @@ fn scheduler_v3_named_next_schedule_time_works() {
 		// Also works by address.
 		assert_eq!(<Scheduler as Anon<_, _, _>>::next_dispatch_time(address), Ok(4));
 		// Block 4 executes it.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 		assert_eq!(logger::log(), vec![(root(), 42)]);
 
 		// It has no dispatch time anymore.
@@ -3025,7 +3025,7 @@ fn unavailable_call_is_detected() {
 		assert!(Preimage::is_requested(&hash));
 
 		// Executes in block 4.
-		run_to_block(4);
+		System::run_to_block::<AllPalletsWithSystem>(4);
 
 		assert_eq!(
 			System::events().last().unwrap().event,
diff --git a/substrate/frame/society/src/mock.rs b/substrate/frame/society/src/mock.rs
index 3c27c08a10610f44ebaf2fc72678f52be2f06507..8cb5dc823753b3b15351a98ba782fa696ed91ca5 100644
--- a/substrate/frame/society/src/mock.rs
+++ b/substrate/frame/society/src/mock.rs
@@ -138,18 +138,6 @@ impl EnvBuilder {
 	}
 }
 
-/// Run until a particular block.
-pub fn run_to_block(n: u64) {
-	while System::block_number() < n {
-		if System::block_number() > 1 {
-			System::on_finalize(System::block_number());
-		}
-		System::set_block_number(System::block_number() + 1);
-		System::on_initialize(System::block_number());
-		Society::on_initialize(System::block_number());
-	}
-}
-
 /// Creates a bid struct using input parameters.
 pub fn bid<AccountId, Balance>(
 	who: AccountId,
@@ -173,12 +161,12 @@ pub fn candidacy<AccountId, Balance>(
 pub fn next_challenge() {
 	let challenge_period: u64 = <Test as Config>::ChallengePeriod::get();
 	let now = System::block_number();
-	run_to_block(now + challenge_period - now % challenge_period);
+	System::run_to_block::<AllPalletsWithSystem>(now + challenge_period - now % challenge_period);
 }
 
 pub fn next_voting() {
 	if let Period::Voting { more, .. } = Society::period() {
-		run_to_block(System::block_number() + more);
+		System::run_to_block::<AllPalletsWithSystem>(System::block_number() + more);
 	}
 }
 
@@ -235,8 +223,11 @@ pub fn conclude_intake(allow_resignation: bool, judge_intake: Option<bool>) {
 pub fn next_intake() {
 	let claim_period: u64 = <Test as Config>::ClaimPeriod::get();
 	match Society::period() {
-		Period::Voting { more, .. } => run_to_block(System::block_number() + more + claim_period),
-		Period::Claim { more, .. } => run_to_block(System::block_number() + more),
+		Period::Voting { more, .. } => System::run_to_block::<AllPalletsWithSystem>(
+			System::block_number() + more + claim_period,
+		),
+		Period::Claim { more, .. } =>
+			System::run_to_block::<AllPalletsWithSystem>(System::block_number() + more),
 	}
 }
 
diff --git a/substrate/frame/society/src/tests.rs b/substrate/frame/society/src/tests.rs
index 2a13f99855b59f66764ffc2fd93fe3479df47c46..22832f18b6fe0305e3a4fa025776ce9d36730b22 100644
--- a/substrate/frame/society/src/tests.rs
+++ b/substrate/frame/society/src/tests.rs
@@ -272,7 +272,7 @@ fn bidding_works() {
 		// 40, now a member, can vote for 50
 		assert_ok!(Society::vote(Origin::signed(40), 50, true));
 		conclude_intake(true, None);
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		// 50 is now a member
 		assert_eq!(members(), vec![10, 30, 40, 50]);
 		// Pot is increased by 1000, and 500 is paid out. Total payout so far is 1200.
@@ -282,7 +282,7 @@ fn bidding_works() {
 		assert_eq!(candidacies(), vec![]);
 		assert_ok!(Society::defender_vote(Origin::signed(10), true)); // Keep defender around
 																// Next period
-		run_to_block(16);
+		System::run_to_block::<AllPalletsWithSystem>(16);
 		// Same members
 		assert_eq!(members(), vec![10, 30, 40, 50]);
 		// Pot is increased by 1000 again
@@ -294,7 +294,7 @@ fn bidding_works() {
 		// Candidate 60 is voted in.
 		assert_ok!(Society::vote(Origin::signed(50), 60, true));
 		conclude_intake(true, None);
-		run_to_block(20);
+		System::run_to_block::<AllPalletsWithSystem>(20);
 		// 60 joins as a member
 		assert_eq!(members(), vec![10, 30, 40, 50, 60]);
 		// Pay them
@@ -368,7 +368,7 @@ fn rejecting_skeptic_on_approved_is_punished() {
 		}
 		conclude_intake(true, None);
 		assert_eq!(Members::<Test>::get(10).unwrap().strikes, 0);
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		assert_eq!(members(), vec![10, 20, 30, 40]);
 		assert_eq!(Members::<Test>::get(skeptic).unwrap().strikes, 1);
 	});
@@ -418,7 +418,7 @@ fn slash_payout_works() {
 			Payouts::<Test>::get(20),
 			PayoutRecord { paid: 0, payouts: vec![(8, 500)].try_into().unwrap() }
 		);
-		run_to_block(8);
+		System::run_to_block::<AllPalletsWithSystem>(8);
 		// payout should be here, but 500 less
 		assert_ok!(Society::payout(RuntimeOrigin::signed(20)));
 		assert_eq!(Balances::free_balance(20), 550);
@@ -1315,7 +1315,7 @@ fn drop_candidate_works() {
 		assert_ok!(Society::vote(Origin::signed(10), 40, false));
 		assert_ok!(Society::vote(Origin::signed(20), 40, false));
 		assert_ok!(Society::vote(Origin::signed(30), 40, false));
-		run_to_block(12);
+		System::run_to_block::<AllPalletsWithSystem>(12);
 		assert_ok!(Society::drop_candidate(Origin::signed(50), 40));
 		// 40 candidacy has gone.
 		assert_eq!(candidates(), vec![]);
diff --git a/substrate/frame/src/lib.rs b/substrate/frame/src/lib.rs
index f79a52bc6c5bf8343a6a4a6d022be5090f71873c..e3e58fc01b5fac66b5908daee1e17fd3f6e1b011 100644
--- a/substrate/frame/src/lib.rs
+++ b/substrate/frame/src/lib.rs
@@ -325,7 +325,7 @@ pub mod testing_prelude {
 		assert_storage_noop, hypothetically, storage_alias,
 	};
 
-	pub use frame_system::{self, mocking::*};
+	pub use frame_system::{self, mocking::*, RunToBlockHooks};
 
 	#[deprecated(note = "Use `frame::testing_prelude::TestState` instead.")]
 	pub use sp_io::TestExternalities;
diff --git a/substrate/frame/staking/src/mock.rs b/substrate/frame/staking/src/mock.rs
index df8cb38e8b371be821c9843255ce30ffb47ae647..769b84826b41613f27873fed650f47999806441f 100644
--- a/substrate/frame/staking/src/mock.rs
+++ b/substrate/frame/staking/src/mock.rs
@@ -25,7 +25,7 @@ use frame_election_provider_support::{
 use frame_support::{
 	assert_ok, derive_impl, ord_parameter_types, parameter_types,
 	traits::{
-		ConstU64, Currency, EitherOfDiverse, FindAuthor, Get, Hooks, Imbalance, LockableCurrency,
+		ConstU64, Currency, EitherOfDiverse, FindAuthor, Get, Imbalance, LockableCurrency,
 		OnUnbalanced, OneSessionHandler, WithdrawReasons,
 	},
 	weights::constants::RocksDbWeight,
@@ -155,7 +155,7 @@ impl pallet_session::historical::Config for Test {
 }
 impl pallet_authorship::Config for Test {
 	type FindAuthor = Author11;
-	type EventHandler = Pallet<Test>;
+	type EventHandler = ();
 }
 
 impl pallet_timestamp::Config for Test {
@@ -544,13 +544,10 @@ impl ExtBuilder {
 		let mut ext = sp_io::TestExternalities::from(storage);
 
 		if self.initialize_first_session {
-			// We consider all test to start after timestamp is initialized This must be ensured by
-			// having `timestamp::on_initialize` called before `staking::on_initialize`. Also, if
-			// session length is 1, then it is already triggered.
 			ext.execute_with(|| {
-				System::set_block_number(1);
-				Session::on_initialize(1);
-				<Staking as Hooks<u64>>::on_initialize(1);
+				run_to_block(1);
+
+				// Force reset the timestamp to the initial timestamp for easy testing.
 				Timestamp::set_timestamp(INIT_TIMESTAMP);
 			});
 		}
@@ -618,33 +615,31 @@ pub(crate) fn bond_virtual_nominator(
 /// a block import/propose process where we first initialize the block, then execute some stuff (not
 /// in the function), and then finalize the block.
 pub(crate) fn run_to_block(n: BlockNumber) {
-	Staking::on_finalize(System::block_number());
-	for b in (System::block_number() + 1)..=n {
-		System::set_block_number(b);
-		Session::on_initialize(b);
-		<Staking as Hooks<u64>>::on_initialize(b);
-		Timestamp::set_timestamp(System::block_number() * BLOCK_TIME + INIT_TIMESTAMP);
-		if b != n {
-			Staking::on_finalize(System::block_number());
-		}
-	}
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default().after_initialize(|bn| {
+			Timestamp::set_timestamp(bn * BLOCK_TIME + INIT_TIMESTAMP);
+		}),
+	);
 }
 
 /// Progresses from the current block number (whatever that may be) to the `P * session_index + 1`.
-pub(crate) fn start_session(session_index: SessionIndex) {
+pub(crate) fn start_session(end_session_idx: SessionIndex) {
+	let period = Period::get();
 	let end: u64 = if Offset::get().is_zero() {
-		(session_index as u64) * Period::get()
+		(end_session_idx as u64) * period
 	} else {
-		Offset::get() + (session_index.saturating_sub(1) as u64) * Period::get()
+		Offset::get() + (end_session_idx.saturating_sub(1) as u64) * period
 	};
+
 	run_to_block(end);
+
+	let curr_session_idx = Session::current_index();
+
 	// session must have progressed properly.
 	assert_eq!(
-		Session::current_index(),
-		session_index,
-		"current session index = {}, expected = {}",
-		Session::current_index(),
-		session_index,
+		curr_session_idx, end_session_idx,
+		"current session index = {curr_session_idx}, expected = {end_session_idx}",
 	);
 }
 
diff --git a/substrate/frame/state-trie-migration/src/lib.rs b/substrate/frame/state-trie-migration/src/lib.rs
index 61323b70b33d22be543c1da9c9ad9797b7f41885..1dc1a3928f2b89e3b3aaa31dd8789a10423fa7c5 100644
--- a/substrate/frame/state-trie-migration/src/lib.rs
+++ b/substrate/frame/state-trie-migration/src/lib.rs
@@ -1309,16 +1309,17 @@ mod mock {
 	pub(crate) fn run_to_block(n: u32) -> (H256, Weight) {
 		let mut root = Default::default();
 		let mut weight_sum = Weight::zero();
+
 		log::trace!(target: LOG_TARGET, "running from {:?} to {:?}", System::block_number(), n);
-		while System::block_number() < n {
-			System::set_block_number(System::block_number() + 1);
-			System::on_initialize(System::block_number());
 
-			weight_sum += StateTrieMigration::on_initialize(System::block_number());
+		System::run_to_block_with::<AllPalletsWithSystem>(
+			n,
+			frame_system::RunToBlockHooks::default().after_initialize(|bn| {
+				weight_sum += StateTrieMigration::on_initialize(bn);
+				root = *System::finalize().state_root();
+			}),
+		);
 
-			root = *System::finalize().state_root();
-			System::on_finalize(System::block_number());
-		}
 		(root, weight_sum)
 	}
 }
diff --git a/substrate/frame/system/src/lib.rs b/substrate/frame/system/src/lib.rs
index 894e1898ed15523576eef010c211a3f0f79dece5..f2bb5e290c94378a9afa9381e51720b2e724aa4f 100644
--- a/substrate/frame/system/src/lib.rs
+++ b/substrate/frame/system/src/lib.rs
@@ -1974,6 +1974,51 @@ impl<T: Config> Pallet<T> {
 			.collect::<_>()
 	}
 
+	/// Simulate the execution of a block sequence up to a specified height, injecting the
+	/// provided hooks at each block.
+	///
+	/// `on_finalize` is always called before `on_initialize` with the current block number.
+	/// `on_initalize` is always called with the next block number.
+	///
+	/// These hooks allows custom logic to be executed at each block at specific location.
+	/// For example, you might use one of them to set a timestamp for each block.
+	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
+	pub fn run_to_block_with<AllPalletsWithSystem>(
+		n: BlockNumberFor<T>,
+		mut hooks: RunToBlockHooks<T>,
+	) where
+		AllPalletsWithSystem: frame_support::traits::OnInitialize<BlockNumberFor<T>>
+			+ frame_support::traits::OnFinalize<BlockNumberFor<T>>,
+	{
+		let mut bn = Self::block_number();
+
+		while bn < n {
+			// Skip block 0.
+			if !bn.is_zero() {
+				(hooks.before_finalize)(bn);
+				AllPalletsWithSystem::on_finalize(bn);
+				(hooks.after_finalize)(bn);
+			}
+
+			bn += One::one();
+
+			Self::set_block_number(bn);
+			(hooks.before_initialize)(bn);
+			AllPalletsWithSystem::on_initialize(bn);
+			(hooks.after_initialize)(bn);
+		}
+	}
+
+	/// Simulate the execution of a block sequence up to a specified height.
+	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
+	pub fn run_to_block<AllPalletsWithSystem>(n: BlockNumberFor<T>)
+	where
+		AllPalletsWithSystem: frame_support::traits::OnInitialize<BlockNumberFor<T>>
+			+ frame_support::traits::OnFinalize<BlockNumberFor<T>>,
+	{
+		Self::run_to_block_with::<AllPalletsWithSystem>(n, Default::default());
+	}
+
 	/// Set the block number to something in particular. Can be used as an alternative to
 	/// `initialize` for tests that don't need to bother with the other environment entries.
 	#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
@@ -2347,6 +2392,72 @@ impl<T: Config> Lookup for ChainContext<T> {
 	}
 }
 
+/// Hooks for the [`Pallet::run_to_block_with`] function.
+#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
+pub struct RunToBlockHooks<'a, T>
+where
+	T: 'a + Config,
+{
+	before_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
+	after_initialize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
+	before_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
+	after_finalize: Box<dyn 'a + FnMut(BlockNumberFor<T>)>,
+}
+
+#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
+impl<'a, T> RunToBlockHooks<'a, T>
+where
+	T: 'a + Config,
+{
+	/// Set the hook function logic before the initialization of the block.
+	pub fn before_initialize<F>(mut self, f: F) -> Self
+	where
+		F: 'a + FnMut(BlockNumberFor<T>),
+	{
+		self.before_initialize = Box::new(f);
+		self
+	}
+	/// Set the hook function logic after the initialization of the block.
+	pub fn after_initialize<F>(mut self, f: F) -> Self
+	where
+		F: 'a + FnMut(BlockNumberFor<T>),
+	{
+		self.after_initialize = Box::new(f);
+		self
+	}
+	/// Set the hook function logic before the finalization of the block.
+	pub fn before_finalize<F>(mut self, f: F) -> Self
+	where
+		F: 'a + FnMut(BlockNumberFor<T>),
+	{
+		self.before_finalize = Box::new(f);
+		self
+	}
+	/// Set the hook function logic after the finalization of the block.
+	pub fn after_finalize<F>(mut self, f: F) -> Self
+	where
+		F: 'a + FnMut(BlockNumberFor<T>),
+	{
+		self.after_finalize = Box::new(f);
+		self
+	}
+}
+
+#[cfg(any(feature = "std", feature = "runtime-benchmarks", test))]
+impl<'a, T> Default for RunToBlockHooks<'a, T>
+where
+	T: Config,
+{
+	fn default() -> Self {
+		Self {
+			before_initialize: Box::new(|_| {}),
+			after_initialize: Box::new(|_| {}),
+			before_finalize: Box::new(|_| {}),
+			after_finalize: Box::new(|_| {}),
+		}
+	}
+}
+
 /// Prelude to be used alongside pallet macro, for ease of use.
 pub mod pallet_prelude {
 	pub use crate::{ensure_none, ensure_root, ensure_signed, ensure_signed_or_root};
diff --git a/substrate/frame/transaction-storage/src/mock.rs b/substrate/frame/transaction-storage/src/mock.rs
index 73174b73dbacc7c803ad947c3108165688832767..84a77043d577c010bdd71a60e5673d4da241f11b 100644
--- a/substrate/frame/transaction-storage/src/mock.rs
+++ b/substrate/frame/transaction-storage/src/mock.rs
@@ -21,10 +21,7 @@ use crate::{
 	self as pallet_transaction_storage, TransactionStorageProof, DEFAULT_MAX_BLOCK_TRANSACTIONS,
 	DEFAULT_MAX_TRANSACTION_SIZE,
 };
-use frame_support::{
-	derive_impl,
-	traits::{ConstU32, OnFinalize, OnInitialize},
-};
+use frame_support::{derive_impl, traits::ConstU32};
 use sp_runtime::{traits::IdentityLookup, BuildStorage};
 
 pub type Block = frame_system::mocking::MockBlock<Test>;
@@ -80,15 +77,13 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
 	t.into()
 }
 
-pub fn run_to_block(n: u64, f: impl Fn() -> Option<TransactionStorageProof>) {
-	while System::block_number() < n {
-		if let Some(proof) = f() {
-			TransactionStorage::check_proof(RuntimeOrigin::none(), proof).unwrap();
-		}
-		TransactionStorage::on_finalize(System::block_number());
-		System::on_finalize(System::block_number());
-		System::set_block_number(System::block_number() + 1);
-		System::on_initialize(System::block_number());
-		TransactionStorage::on_initialize(System::block_number());
-	}
+pub fn run_to_block(n: u64, f: impl Fn() -> Option<TransactionStorageProof> + 'static) {
+	System::run_to_block_with::<AllPalletsWithSystem>(
+		n,
+		frame_system::RunToBlockHooks::default().before_finalize(|_| {
+			if let Some(proof) = f() {
+				TransactionStorage::check_proof(RuntimeOrigin::none(), proof).unwrap();
+			}
+		}),
+	);
 }