From e7f9157cc9d0dd2f7fc160a6249594ad9347c730 Mon Sep 17 00:00:00 2001
From: Squirrel <gilescope@gmail.com>
Date: Tue, 17 Jan 2023 16:26:10 +0000
Subject: [PATCH] Breakout mock runtimes to separate files (#13150)

* break out moch runtimes to separate files

* tranaction-payment: break out tests & mock runtime to separate files
---
 .../asset-tx-payment/src/lib.rs               |   2 +
 .../asset-tx-payment/src/mock.rs              | 213 ++++
 .../asset-tx-payment/src/tests.rs             | 197 +---
 .../frame/transaction-payment/src/lib.rs      | 961 +-----------------
 .../frame/transaction-payment/src/mock.rs     | 162 +++
 .../frame/transaction-payment/src/tests.rs    | 836 +++++++++++++++
 6 files changed, 1223 insertions(+), 1148 deletions(-)
 create mode 100644 substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
 create mode 100644 substrate/frame/transaction-payment/src/mock.rs
 create mode 100644 substrate/frame/transaction-payment/src/tests.rs

diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs
index 43cc1efa085..230b307317f 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/lib.rs
@@ -59,6 +59,8 @@ use sp_runtime::{
 	FixedPointOperand,
 };
 
+#[cfg(test)]
+mod mock;
 #[cfg(test)]
 mod tests;
 
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
new file mode 100644
index 00000000000..ddb02f5a611
--- /dev/null
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/mock.rs
@@ -0,0 +1,213 @@
+// Copyright (C) 2021-2022 Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::*;
+use crate as pallet_asset_tx_payment;
+
+use codec;
+use frame_support::{
+	dispatch::DispatchClass,
+	pallet_prelude::*,
+	parameter_types,
+	traits::{AsEnsureOriginWithArg, ConstU32, ConstU64, ConstU8, FindAuthor},
+	weights::{Weight, WeightToFee as WeightToFeeT},
+	ConsensusEngineId,
+};
+use frame_system as system;
+use frame_system::EnsureRoot;
+use pallet_transaction_payment::CurrencyAdapter;
+use sp_core::H256;
+use sp_runtime::{
+	testing::Header,
+	traits::{BlakeTwo256, ConvertInto, IdentityLookup, SaturatedConversion},
+};
+
+type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
+type Block = frame_system::mocking::MockBlock<Runtime>;
+type Balance = u64;
+type AccountId = u64;
+
+frame_support::construct_runtime!(
+	pub enum Runtime where
+		Block = Block,
+		NodeBlock = Block,
+		UncheckedExtrinsic = UncheckedExtrinsic,
+	{
+		System: system::{Pallet, Call, Config, Storage, Event<T>},
+		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
+		TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>},
+		Assets: pallet_assets::{Pallet, Call, Storage, Event<T>},
+		Authorship: pallet_authorship::{Pallet, Call, Storage},
+		AssetTxPayment: pallet_asset_tx_payment::{Pallet, Event<T>},
+	}
+);
+
+parameter_types! {
+	pub(crate) static ExtrinsicBaseWeight: Weight = Weight::zero();
+}
+
+pub struct BlockWeights;
+impl Get<frame_system::limits::BlockWeights> for BlockWeights {
+	fn get() -> frame_system::limits::BlockWeights {
+		frame_system::limits::BlockWeights::builder()
+			.base_block(Weight::zero())
+			.for_class(DispatchClass::all(), |weights| {
+				weights.base_extrinsic = ExtrinsicBaseWeight::get().into();
+			})
+			.for_class(DispatchClass::non_mandatory(), |weights| {
+				weights.max_total = Weight::from_ref_time(1024).set_proof_size(u64::MAX).into();
+			})
+			.build_or_panic()
+	}
+}
+
+parameter_types! {
+	pub static WeightToFee: u64 = 1;
+	pub static TransactionByteFee: u64 = 1;
+}
+
+impl frame_system::Config for Runtime {
+	type BaseCallFilter = frame_support::traits::Everything;
+	type BlockWeights = BlockWeights;
+	type BlockLength = ();
+	type DbWeight = ();
+	type RuntimeOrigin = RuntimeOrigin;
+	type Index = u64;
+	type BlockNumber = u64;
+	type RuntimeCall = RuntimeCall;
+	type Hash = H256;
+	type Hashing = BlakeTwo256;
+	type AccountId = AccountId;
+	type Lookup = IdentityLookup<Self::AccountId>;
+	type Header = Header;
+	type RuntimeEvent = RuntimeEvent;
+	type BlockHashCount = ConstU64<250>;
+	type Version = ();
+	type PalletInfo = PalletInfo;
+	type AccountData = pallet_balances::AccountData<u64>;
+	type OnNewAccount = ();
+	type OnKilledAccount = ();
+	type SystemWeightInfo = ();
+	type SS58Prefix = ();
+	type OnSetCode = ();
+	type MaxConsumers = ConstU32<16>;
+}
+
+parameter_types! {
+	pub const ExistentialDeposit: u64 = 10;
+}
+
+impl pallet_balances::Config for Runtime {
+	type Balance = Balance;
+	type RuntimeEvent = RuntimeEvent;
+	type DustRemoval = ();
+	type ExistentialDeposit = ConstU64<10>;
+	type AccountStore = System;
+	type MaxLocks = ();
+	type WeightInfo = ();
+	type MaxReserves = ConstU32<50>;
+	type ReserveIdentifier = [u8; 8];
+}
+
+impl WeightToFeeT for WeightToFee {
+	type Balance = u64;
+
+	fn weight_to_fee(weight: &Weight) -> Self::Balance {
+		Self::Balance::saturated_from(weight.ref_time())
+			.saturating_mul(WEIGHT_TO_FEE.with(|v| *v.borrow()))
+	}
+}
+
+impl WeightToFeeT for TransactionByteFee {
+	type Balance = u64;
+
+	fn weight_to_fee(weight: &Weight) -> Self::Balance {
+		Self::Balance::saturated_from(weight.ref_time())
+			.saturating_mul(TRANSACTION_BYTE_FEE.with(|v| *v.borrow()))
+	}
+}
+
+impl pallet_transaction_payment::Config for Runtime {
+	type RuntimeEvent = RuntimeEvent;
+	type OnChargeTransaction = CurrencyAdapter<Balances, ()>;
+	type WeightToFee = WeightToFee;
+	type LengthToFee = TransactionByteFee;
+	type FeeMultiplierUpdate = ();
+	type OperationalFeeMultiplier = ConstU8<5>;
+}
+
+type AssetId = u32;
+
+impl pallet_assets::Config for Runtime {
+	type RuntimeEvent = RuntimeEvent;
+	type Balance = Balance;
+	type AssetId = AssetId;
+	type AssetIdParameter = codec::Compact<AssetId>;
+	type Currency = Balances;
+	type CreateOrigin = AsEnsureOriginWithArg<frame_system::EnsureSigned<AccountId>>;
+	type ForceOrigin = EnsureRoot<AccountId>;
+	type AssetDeposit = ConstU64<2>;
+	type AssetAccountDeposit = ConstU64<2>;
+	type MetadataDepositBase = ConstU64<0>;
+	type MetadataDepositPerByte = ConstU64<0>;
+	type ApprovalDeposit = ConstU64<0>;
+	type StringLimit = ConstU32<20>;
+	type Freezer = ();
+	type Extra = ();
+	type CallbackHandle = ();
+	type WeightInfo = ();
+	type RemoveItemsLimit = ConstU32<1000>;
+	pallet_assets::runtime_benchmarks_enabled! {
+		type BenchmarkHelper = ();
+	}
+}
+
+pub struct HardcodedAuthor;
+pub(crate) const BLOCK_AUTHOR: AccountId = 1234;
+impl FindAuthor<AccountId> for HardcodedAuthor {
+	fn find_author<'a, I>(_: I) -> Option<AccountId>
+	where
+		I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
+	{
+		Some(BLOCK_AUTHOR)
+	}
+}
+
+impl pallet_authorship::Config for Runtime {
+	type FindAuthor = HardcodedAuthor;
+	type UncleGenerations = ();
+	type FilterUncle = ();
+	type EventHandler = ();
+}
+
+pub struct CreditToBlockAuthor;
+impl HandleCredit<AccountId, Assets> for CreditToBlockAuthor {
+	fn handle_credit(credit: CreditOf<AccountId, Assets>) {
+		if let Some(author) = pallet_authorship::Pallet::<Runtime>::author() {
+			// What to do in case paying the author fails (e.g. because `fee < min_balance`)
+			// default: drop the result which will trigger the `OnDrop` of the imbalance.
+			let _ = <Assets as Balanced<AccountId>>::resolve(&author, credit);
+		}
+	}
+}
+
+impl Config for Runtime {
+	type RuntimeEvent = RuntimeEvent;
+	type Fungibles = Assets;
+	type OnChargeAssetTransaction = FungiblesAdapter<
+		pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>,
+		CreditToBlockAuthor,
+	>;
+}
diff --git a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs
index b79b87a93c7..f76293f4564 100644
--- a/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs
+++ b/substrate/frame/transaction-payment/asset-tx-payment/src/tests.rs
@@ -14,209 +14,22 @@
 // limitations under the License.
 
 use super::*;
-use crate as pallet_asset_tx_payment;
 
-use codec;
 use frame_support::{
 	assert_ok,
-	dispatch::{DispatchClass, DispatchInfo, PostDispatchInfo},
+	dispatch::{DispatchInfo, PostDispatchInfo},
 	pallet_prelude::*,
-	parameter_types,
-	traits::{fungibles::Mutate, AsEnsureOriginWithArg, ConstU32, ConstU64, ConstU8, FindAuthor},
-	weights::{Weight, WeightToFee as WeightToFeeT},
-	ConsensusEngineId,
+	traits::fungibles::Mutate,
+	weights::Weight,
 };
 use frame_system as system;
-use frame_system::EnsureRoot;
+use mock::{ExtrinsicBaseWeight, *};
 use pallet_balances::Call as BalancesCall;
-use pallet_transaction_payment::CurrencyAdapter;
-use sp_core::H256;
-use sp_runtime::{
-	testing::Header,
-	traits::{BlakeTwo256, ConvertInto, IdentityLookup, SaturatedConversion, StaticLookup},
-};
-
-type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
-type Block = frame_system::mocking::MockBlock<Runtime>;
-type Balance = u64;
-type AccountId = u64;
-
-frame_support::construct_runtime!(
-	pub enum Runtime where
-		Block = Block,
-		NodeBlock = Block,
-		UncheckedExtrinsic = UncheckedExtrinsic,
-	{
-		System: system::{Pallet, Call, Config, Storage, Event<T>},
-		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
-		TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>},
-		Assets: pallet_assets::{Pallet, Call, Storage, Event<T>},
-		Authorship: pallet_authorship::{Pallet, Call, Storage},
-		AssetTxPayment: pallet_asset_tx_payment::{Pallet, Event<T>},
-	}
-);
+use sp_runtime::traits::StaticLookup;
 
 const CALL: &<Runtime as frame_system::Config>::RuntimeCall =
 	&RuntimeCall::Balances(BalancesCall::transfer { dest: 2, value: 69 });
 
-parameter_types! {
-	static ExtrinsicBaseWeight: Weight = Weight::zero();
-}
-
-pub struct BlockWeights;
-impl Get<frame_system::limits::BlockWeights> for BlockWeights {
-	fn get() -> frame_system::limits::BlockWeights {
-		frame_system::limits::BlockWeights::builder()
-			.base_block(Weight::zero())
-			.for_class(DispatchClass::all(), |weights| {
-				weights.base_extrinsic = ExtrinsicBaseWeight::get().into();
-			})
-			.for_class(DispatchClass::non_mandatory(), |weights| {
-				weights.max_total = Weight::from_ref_time(1024).set_proof_size(u64::MAX).into();
-			})
-			.build_or_panic()
-	}
-}
-
-parameter_types! {
-	pub static WeightToFee: u64 = 1;
-	pub static TransactionByteFee: u64 = 1;
-}
-
-impl frame_system::Config for Runtime {
-	type BaseCallFilter = frame_support::traits::Everything;
-	type BlockWeights = BlockWeights;
-	type BlockLength = ();
-	type DbWeight = ();
-	type RuntimeOrigin = RuntimeOrigin;
-	type Index = u64;
-	type BlockNumber = u64;
-	type RuntimeCall = RuntimeCall;
-	type Hash = H256;
-	type Hashing = BlakeTwo256;
-	type AccountId = AccountId;
-	type Lookup = IdentityLookup<Self::AccountId>;
-	type Header = Header;
-	type RuntimeEvent = RuntimeEvent;
-	type BlockHashCount = ConstU64<250>;
-	type Version = ();
-	type PalletInfo = PalletInfo;
-	type AccountData = pallet_balances::AccountData<u64>;
-	type OnNewAccount = ();
-	type OnKilledAccount = ();
-	type SystemWeightInfo = ();
-	type SS58Prefix = ();
-	type OnSetCode = ();
-	type MaxConsumers = ConstU32<16>;
-}
-
-parameter_types! {
-	pub const ExistentialDeposit: u64 = 10;
-}
-
-impl pallet_balances::Config for Runtime {
-	type Balance = Balance;
-	type RuntimeEvent = RuntimeEvent;
-	type DustRemoval = ();
-	type ExistentialDeposit = ConstU64<10>;
-	type AccountStore = System;
-	type MaxLocks = ();
-	type WeightInfo = ();
-	type MaxReserves = ConstU32<50>;
-	type ReserveIdentifier = [u8; 8];
-}
-
-impl WeightToFeeT for WeightToFee {
-	type Balance = u64;
-
-	fn weight_to_fee(weight: &Weight) -> Self::Balance {
-		Self::Balance::saturated_from(weight.ref_time())
-			.saturating_mul(WEIGHT_TO_FEE.with(|v| *v.borrow()))
-	}
-}
-
-impl WeightToFeeT for TransactionByteFee {
-	type Balance = u64;
-
-	fn weight_to_fee(weight: &Weight) -> Self::Balance {
-		Self::Balance::saturated_from(weight.ref_time())
-			.saturating_mul(TRANSACTION_BYTE_FEE.with(|v| *v.borrow()))
-	}
-}
-
-impl pallet_transaction_payment::Config for Runtime {
-	type RuntimeEvent = RuntimeEvent;
-	type OnChargeTransaction = CurrencyAdapter<Balances, ()>;
-	type WeightToFee = WeightToFee;
-	type LengthToFee = TransactionByteFee;
-	type FeeMultiplierUpdate = ();
-	type OperationalFeeMultiplier = ConstU8<5>;
-}
-
-type AssetId = u32;
-
-impl pallet_assets::Config for Runtime {
-	type RuntimeEvent = RuntimeEvent;
-	type Balance = Balance;
-	type AssetId = AssetId;
-	type AssetIdParameter = codec::Compact<AssetId>;
-	type Currency = Balances;
-	type CreateOrigin = AsEnsureOriginWithArg<frame_system::EnsureSigned<AccountId>>;
-	type ForceOrigin = EnsureRoot<AccountId>;
-	type AssetDeposit = ConstU64<2>;
-	type AssetAccountDeposit = ConstU64<2>;
-	type MetadataDepositBase = ConstU64<0>;
-	type MetadataDepositPerByte = ConstU64<0>;
-	type ApprovalDeposit = ConstU64<0>;
-	type StringLimit = ConstU32<20>;
-	type Freezer = ();
-	type Extra = ();
-	type CallbackHandle = ();
-	type WeightInfo = ();
-	type RemoveItemsLimit = ConstU32<1000>;
-	pallet_assets::runtime_benchmarks_enabled! {
-		type BenchmarkHelper = ();
-	}
-}
-
-pub struct HardcodedAuthor;
-const BLOCK_AUTHOR: AccountId = 1234;
-impl FindAuthor<AccountId> for HardcodedAuthor {
-	fn find_author<'a, I>(_: I) -> Option<AccountId>
-	where
-		I: 'a + IntoIterator<Item = (ConsensusEngineId, &'a [u8])>,
-	{
-		Some(BLOCK_AUTHOR)
-	}
-}
-
-impl pallet_authorship::Config for Runtime {
-	type FindAuthor = HardcodedAuthor;
-	type UncleGenerations = ();
-	type FilterUncle = ();
-	type EventHandler = ();
-}
-
-pub struct CreditToBlockAuthor;
-impl HandleCredit<AccountId, Assets> for CreditToBlockAuthor {
-	fn handle_credit(credit: CreditOf<AccountId, Assets>) {
-		if let Some(author) = pallet_authorship::Pallet::<Runtime>::author() {
-			// What to do in case paying the author fails (e.g. because `fee < min_balance`)
-			// default: drop the result which will trigger the `OnDrop` of the imbalance.
-			let _ = <Assets as Balanced<AccountId>>::resolve(&author, credit);
-		}
-	}
-}
-
-impl Config for Runtime {
-	type RuntimeEvent = RuntimeEvent;
-	type Fungibles = Assets;
-	type OnChargeAssetTransaction = FungiblesAdapter<
-		pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>,
-		CreditToBlockAuthor,
-	>;
-}
-
 pub struct ExtBuilder {
 	balance_factor: u64,
 	base_weight: Weight,
diff --git a/substrate/frame/transaction-payment/src/lib.rs b/substrate/frame/transaction-payment/src/lib.rs
index ce747fa6bd8..13adbf89c42 100644
--- a/substrate/frame/transaction-payment/src/lib.rs
+++ b/substrate/frame/transaction-payment/src/lib.rs
@@ -70,6 +70,11 @@ use frame_support::{
 	weights::{Weight, WeightToFee},
 };
 
+#[cfg(test)]
+mod mock;
+#[cfg(test)]
+mod tests;
+
 mod payment;
 mod types;
 
@@ -847,959 +852,3 @@ where
 		Self::compute_actual_fee(len, &info, &post_info, Zero::zero())
 	}
 }
-
-#[cfg(test)]
-mod tests {
-	use super::*;
-	use crate as pallet_transaction_payment;
-
-	use codec::Encode;
-
-	use sp_core::H256;
-	use sp_runtime::{
-		testing::{Header, TestXt},
-		traits::{BlakeTwo256, IdentityLookup, One},
-		transaction_validity::InvalidTransaction,
-	};
-
-	use frame_support::{
-		assert_noop, assert_ok,
-		dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo},
-		parameter_types,
-		traits::{ConstU32, ConstU64, Currency, GenesisBuild, Imbalance, OnUnbalanced},
-		weights::{Weight, WeightToFee as WeightToFeeT},
-	};
-	use frame_system as system;
-	use pallet_balances::Call as BalancesCall;
-
-	type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
-	type Block = frame_system::mocking::MockBlock<Runtime>;
-
-	frame_support::construct_runtime!(
-		pub enum Runtime where
-			Block = Block,
-			NodeBlock = Block,
-			UncheckedExtrinsic = UncheckedExtrinsic,
-		{
-			System: system::{Pallet, Call, Config, Storage, Event<T>},
-			Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
-			TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>},
-		}
-	);
-
-	const CALL: &<Runtime as frame_system::Config>::RuntimeCall =
-		&RuntimeCall::Balances(BalancesCall::transfer { dest: 2, value: 69 });
-
-	parameter_types! {
-		static ExtrinsicBaseWeight: Weight = Weight::zero();
-	}
-
-	pub struct BlockWeights;
-	impl Get<frame_system::limits::BlockWeights> for BlockWeights {
-		fn get() -> frame_system::limits::BlockWeights {
-			frame_system::limits::BlockWeights::builder()
-				.base_block(Weight::zero())
-				.for_class(DispatchClass::all(), |weights| {
-					weights.base_extrinsic = ExtrinsicBaseWeight::get().into();
-				})
-				.for_class(DispatchClass::non_mandatory(), |weights| {
-					weights.max_total = Weight::from_ref_time(1024).set_proof_size(u64::MAX).into();
-				})
-				.build_or_panic()
-		}
-	}
-
-	parameter_types! {
-		pub static WeightToFee: u64 = 1;
-		pub static TransactionByteFee: u64 = 1;
-		pub static OperationalFeeMultiplier: u8 = 5;
-	}
-
-	impl frame_system::Config for Runtime {
-		type BaseCallFilter = frame_support::traits::Everything;
-		type BlockWeights = BlockWeights;
-		type BlockLength = ();
-		type DbWeight = ();
-		type RuntimeOrigin = RuntimeOrigin;
-		type Index = u64;
-		type BlockNumber = u64;
-		type RuntimeCall = RuntimeCall;
-		type Hash = H256;
-		type Hashing = BlakeTwo256;
-		type AccountId = u64;
-		type Lookup = IdentityLookup<Self::AccountId>;
-		type Header = Header;
-		type RuntimeEvent = RuntimeEvent;
-		type BlockHashCount = ConstU64<250>;
-		type Version = ();
-		type PalletInfo = PalletInfo;
-		type AccountData = pallet_balances::AccountData<u64>;
-		type OnNewAccount = ();
-		type OnKilledAccount = ();
-		type SystemWeightInfo = ();
-		type SS58Prefix = ();
-		type OnSetCode = ();
-		type MaxConsumers = ConstU32<16>;
-	}
-
-	impl pallet_balances::Config for Runtime {
-		type Balance = u64;
-		type RuntimeEvent = RuntimeEvent;
-		type DustRemoval = ();
-		type ExistentialDeposit = ConstU64<1>;
-		type AccountStore = System;
-		type MaxLocks = ();
-		type MaxReserves = ();
-		type ReserveIdentifier = [u8; 8];
-		type WeightInfo = ();
-	}
-
-	impl WeightToFeeT for WeightToFee {
-		type Balance = u64;
-
-		fn weight_to_fee(weight: &Weight) -> Self::Balance {
-			Self::Balance::saturated_from(weight.ref_time())
-				.saturating_mul(WEIGHT_TO_FEE.with(|v| *v.borrow()))
-		}
-	}
-
-	impl WeightToFeeT for TransactionByteFee {
-		type Balance = u64;
-
-		fn weight_to_fee(weight: &Weight) -> Self::Balance {
-			Self::Balance::saturated_from(weight.ref_time())
-				.saturating_mul(TRANSACTION_BYTE_FEE.with(|v| *v.borrow()))
-		}
-	}
-
-	parameter_types! {
-		static TipUnbalancedAmount: u64 = 0;
-		static FeeUnbalancedAmount: u64 = 0;
-	}
-
-	pub struct DealWithFees;
-	impl OnUnbalanced<pallet_balances::NegativeImbalance<Runtime>> for DealWithFees {
-		fn on_unbalanceds<B>(
-			mut fees_then_tips: impl Iterator<Item = pallet_balances::NegativeImbalance<Runtime>>,
-		) {
-			if let Some(fees) = fees_then_tips.next() {
-				FeeUnbalancedAmount::mutate(|a| *a += fees.peek());
-				if let Some(tips) = fees_then_tips.next() {
-					TipUnbalancedAmount::mutate(|a| *a += tips.peek());
-				}
-			}
-		}
-	}
-
-	impl Config for Runtime {
-		type RuntimeEvent = RuntimeEvent;
-		type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
-		type OperationalFeeMultiplier = OperationalFeeMultiplier;
-		type WeightToFee = WeightToFee;
-		type LengthToFee = TransactionByteFee;
-		type FeeMultiplierUpdate = ();
-	}
-
-	pub struct ExtBuilder {
-		balance_factor: u64,
-		base_weight: Weight,
-		byte_fee: u64,
-		weight_to_fee: u64,
-		initial_multiplier: Option<Multiplier>,
-	}
-
-	impl Default for ExtBuilder {
-		fn default() -> Self {
-			Self {
-				balance_factor: 1,
-				base_weight: Weight::zero(),
-				byte_fee: 1,
-				weight_to_fee: 1,
-				initial_multiplier: None,
-			}
-		}
-	}
-
-	impl ExtBuilder {
-		pub fn base_weight(mut self, base_weight: Weight) -> Self {
-			self.base_weight = base_weight;
-			self
-		}
-		pub fn byte_fee(mut self, byte_fee: u64) -> Self {
-			self.byte_fee = byte_fee;
-			self
-		}
-		pub fn weight_fee(mut self, weight_to_fee: u64) -> Self {
-			self.weight_to_fee = weight_to_fee;
-			self
-		}
-		pub fn balance_factor(mut self, factor: u64) -> Self {
-			self.balance_factor = factor;
-			self
-		}
-		pub fn with_initial_multiplier(mut self, multiplier: Multiplier) -> Self {
-			self.initial_multiplier = Some(multiplier);
-			self
-		}
-		fn set_constants(&self) {
-			ExtrinsicBaseWeight::mutate(|v| *v = self.base_weight);
-			TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.byte_fee);
-			WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee);
-		}
-		pub fn build(self) -> sp_io::TestExternalities {
-			self.set_constants();
-			let mut t = frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap();
-			pallet_balances::GenesisConfig::<Runtime> {
-				balances: if self.balance_factor > 0 {
-					vec![
-						(1, 10 * self.balance_factor),
-						(2, 20 * self.balance_factor),
-						(3, 30 * self.balance_factor),
-						(4, 40 * self.balance_factor),
-						(5, 50 * self.balance_factor),
-						(6, 60 * self.balance_factor),
-					]
-				} else {
-					vec![]
-				},
-			}
-			.assimilate_storage(&mut t)
-			.unwrap();
-
-			if let Some(multiplier) = self.initial_multiplier {
-				let genesis = pallet::GenesisConfig { multiplier };
-				GenesisBuild::<Runtime>::assimilate_storage(&genesis, &mut t).unwrap();
-			}
-
-			t.into()
-		}
-	}
-
-	/// create a transaction info struct from weight. Handy to avoid building the whole struct.
-	pub fn info_from_weight(w: Weight) -> DispatchInfo {
-		// pays_fee: Pays::Yes -- class: DispatchClass::Normal
-		DispatchInfo { weight: w, ..Default::default() }
-	}
-
-	fn post_info_from_weight(w: Weight) -> PostDispatchInfo {
-		PostDispatchInfo { actual_weight: Some(w), pays_fee: Default::default() }
-	}
-
-	fn post_info_from_pays(p: Pays) -> PostDispatchInfo {
-		PostDispatchInfo { actual_weight: None, pays_fee: p }
-	}
-
-	fn default_post_info() -> PostDispatchInfo {
-		PostDispatchInfo { actual_weight: None, pays_fee: Default::default() }
-	}
-
-	#[test]
-	fn signed_extension_transaction_payment_work() {
-		ExtBuilder::default()
-			.balance_factor(10)
-			.base_weight(Weight::from_ref_time(5))
-			.build()
-			.execute_with(|| {
-				let len = 10;
-				let pre = ChargeTransactionPayment::<Runtime>::from(0)
-					.pre_dispatch(&1, CALL, &info_from_weight(Weight::from_ref_time(5)), len)
-					.unwrap();
-				assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10);
-
-				assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-					Some(pre),
-					&info_from_weight(Weight::from_ref_time(5)),
-					&default_post_info(),
-					len,
-					&Ok(())
-				));
-				assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10);
-				assert_eq!(FeeUnbalancedAmount::get(), 5 + 5 + 10);
-				assert_eq!(TipUnbalancedAmount::get(), 0);
-
-				FeeUnbalancedAmount::mutate(|a| *a = 0);
-
-				let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
-					.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_ref_time(100)), len)
-					.unwrap();
-				assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
-
-				assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-					Some(pre),
-					&info_from_weight(Weight::from_ref_time(100)),
-					&post_info_from_weight(Weight::from_ref_time(50)),
-					len,
-					&Ok(())
-				));
-				assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 50 - 5);
-				assert_eq!(FeeUnbalancedAmount::get(), 5 + 10 + 50);
-				assert_eq!(TipUnbalancedAmount::get(), 5);
-			});
-	}
-
-	#[test]
-	fn signed_extension_transaction_payment_multiplied_refund_works() {
-		ExtBuilder::default()
-			.balance_factor(10)
-			.base_weight(Weight::from_ref_time(5))
-			.build()
-			.execute_with(|| {
-				let len = 10;
-				<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
-
-				let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
-					.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_ref_time(100)), len)
-					.unwrap();
-				// 5 base fee, 10 byte fee, 3/2 * 100 weight fee, 5 tip
-				assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5);
-
-				assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-					Some(pre),
-					&info_from_weight(Weight::from_ref_time(100)),
-					&post_info_from_weight(Weight::from_ref_time(50)),
-					len,
-					&Ok(())
-				));
-				// 75 (3/2 of the returned 50 units of weight) is refunded
-				assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 75 - 5);
-			});
-	}
-
-	#[test]
-	fn signed_extension_transaction_payment_is_bounded() {
-		ExtBuilder::default().balance_factor(1000).byte_fee(0).build().execute_with(|| {
-			// maximum weight possible
-			assert_ok!(ChargeTransactionPayment::<Runtime>::from(0).pre_dispatch(
-				&1,
-				CALL,
-				&info_from_weight(Weight::MAX),
-				10
-			));
-			// fee will be proportional to what is the actual maximum weight in the runtime.
-			assert_eq!(
-				Balances::free_balance(&1),
-				(10000 -
-					<Runtime as frame_system::Config>::BlockWeights::get().max_block.ref_time()) as u64
-			);
-		});
-	}
-
-	#[test]
-	fn signed_extension_allows_free_transactions() {
-		ExtBuilder::default()
-			.base_weight(Weight::from_ref_time(100))
-			.balance_factor(0)
-			.build()
-			.execute_with(|| {
-				// 1 ain't have a penny.
-				assert_eq!(Balances::free_balance(1), 0);
-
-				let len = 100;
-
-				// This is a completely free (and thus wholly insecure/DoS-ridden) transaction.
-				let operational_transaction = DispatchInfo {
-					weight: Weight::from_ref_time(0),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::No,
-				};
-				assert_ok!(ChargeTransactionPayment::<Runtime>::from(0).validate(
-					&1,
-					CALL,
-					&operational_transaction,
-					len
-				));
-
-				// like a InsecureFreeNormal
-				let free_transaction = DispatchInfo {
-					weight: Weight::from_ref_time(0),
-					class: DispatchClass::Normal,
-					pays_fee: Pays::Yes,
-				};
-				assert_noop!(
-					ChargeTransactionPayment::<Runtime>::from(0).validate(
-						&1,
-						CALL,
-						&free_transaction,
-						len
-					),
-					TransactionValidityError::Invalid(InvalidTransaction::Payment),
-				);
-			});
-	}
-
-	#[test]
-	fn signed_ext_length_fee_is_also_updated_per_congestion() {
-		ExtBuilder::default()
-			.base_weight(Weight::from_ref_time(5))
-			.balance_factor(10)
-			.build()
-			.execute_with(|| {
-				// all fees should be x1.5
-				<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
-				let len = 10;
-
-				assert_ok!(
-					ChargeTransactionPayment::<Runtime>::from(10) // tipped
-						.pre_dispatch(&1, CALL, &info_from_weight(Weight::from_ref_time(3)), len)
-				);
-				assert_eq!(
-					Balances::free_balance(1),
-					100 // original
-				- 10 // tip
-				- 5 // base
-				- 10 // len
-				- (3 * 3 / 2) // adjusted weight
-				);
-			})
-	}
-
-	#[test]
-	fn query_info_and_fee_details_works() {
-		let call = RuntimeCall::Balances(BalancesCall::transfer { dest: 2, value: 69 });
-		let origin = 111111;
-		let extra = ();
-		let xt = TestXt::new(call.clone(), Some((origin, extra)));
-		let info = xt.get_dispatch_info();
-		let ext = xt.encode();
-		let len = ext.len() as u32;
-
-		let unsigned_xt = TestXt::<_, ()>::new(call, None);
-		let unsigned_xt_info = unsigned_xt.get_dispatch_info();
-
-		ExtBuilder::default()
-			.base_weight(Weight::from_ref_time(5))
-			.weight_fee(2)
-			.build()
-			.execute_with(|| {
-				// all fees should be x1.5
-				<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
-
-				assert_eq!(
-					TransactionPayment::query_info(xt.clone(), len),
-					RuntimeDispatchInfo {
-						weight: info.weight,
-						class: info.class,
-						partial_fee: 5 * 2 /* base * weight_fee */
-						+ len as u64  /* len * 1 */
-						+ info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */
-					},
-				);
-
-				assert_eq!(
-					TransactionPayment::query_info(unsigned_xt.clone(), len),
-					RuntimeDispatchInfo {
-						weight: unsigned_xt_info.weight,
-						class: unsigned_xt_info.class,
-						partial_fee: 0,
-					},
-				);
-
-				assert_eq!(
-					TransactionPayment::query_fee_details(xt, len),
-					FeeDetails {
-						inclusion_fee: Some(InclusionFee {
-							base_fee: 5 * 2,
-							len_fee: len as u64,
-							adjusted_weight_fee: info
-								.weight
-								.min(BlockWeights::get().max_block)
-								.ref_time() as u64 * 2 * 3 / 2
-						}),
-						tip: 0,
-					},
-				);
-
-				assert_eq!(
-					TransactionPayment::query_fee_details(unsigned_xt, len),
-					FeeDetails { inclusion_fee: None, tip: 0 },
-				);
-			});
-	}
-
-	#[test]
-	fn query_call_info_and_fee_details_works() {
-		let call = RuntimeCall::Balances(BalancesCall::transfer { dest: 2, value: 69 });
-		let info = call.get_dispatch_info();
-		let encoded_call = call.encode();
-		let len = encoded_call.len() as u32;
-
-		ExtBuilder::default()
-			.base_weight(Weight::from_ref_time(5))
-			.weight_fee(2)
-			.build()
-			.execute_with(|| {
-				// all fees should be x1.5
-				<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
-
-				assert_eq!(
-					TransactionPayment::query_call_info(call.clone(), len),
-					RuntimeDispatchInfo {
-						weight: info.weight,
-						class: info.class,
-						partial_fee: 5 * 2 /* base * weight_fee */
-						+ len as u64  /* len * 1 */
-						+ info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */
-					},
-				);
-
-				assert_eq!(
-					TransactionPayment::query_call_fee_details(call, len),
-					FeeDetails {
-						inclusion_fee: Some(InclusionFee {
-							base_fee: 5 * 2,     /* base * weight_fee */
-							len_fee: len as u64, /* len * 1 */
-							adjusted_weight_fee: info
-								.weight
-								.min(BlockWeights::get().max_block)
-								.ref_time() as u64 * 2 * 3 / 2  /* weight * weight_fee * multipler */
-						}),
-						tip: 0,
-					},
-				);
-			});
-	}
-
-	#[test]
-	fn compute_fee_works_without_multiplier() {
-		ExtBuilder::default()
-			.base_weight(Weight::from_ref_time(100))
-			.byte_fee(10)
-			.balance_factor(0)
-			.build()
-			.execute_with(|| {
-				// Next fee multiplier is zero
-				assert_eq!(<NextFeeMultiplier<Runtime>>::get(), Multiplier::one());
-
-				// Tip only, no fees works
-				let dispatch_info = DispatchInfo {
-					weight: Weight::from_ref_time(0),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::No,
-				};
-				assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 10), 10);
-				// No tip, only base fee works
-				let dispatch_info = DispatchInfo {
-					weight: Weight::from_ref_time(0),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::Yes,
-				};
-				assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
-				// Tip + base fee works
-				assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 69), 169);
-				// Len (byte fee) + base fee works
-				assert_eq!(Pallet::<Runtime>::compute_fee(42, &dispatch_info, 0), 520);
-				// Weight fee + base fee works
-				let dispatch_info = DispatchInfo {
-					weight: Weight::from_ref_time(1000),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::Yes,
-				};
-				assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 0), 1100);
-			});
-	}
-
-	#[test]
-	fn compute_fee_works_with_multiplier() {
-		ExtBuilder::default()
-			.base_weight(Weight::from_ref_time(100))
-			.byte_fee(10)
-			.balance_factor(0)
-			.build()
-			.execute_with(|| {
-				// Add a next fee multiplier. Fees will be x3/2.
-				<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
-				// Base fee is unaffected by multiplier
-				let dispatch_info = DispatchInfo {
-					weight: Weight::from_ref_time(0),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::Yes,
-				};
-				assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
-
-				// Everything works together :)
-				let dispatch_info = DispatchInfo {
-					weight: Weight::from_ref_time(123),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::Yes,
-				};
-				// 123 weight, 456 length, 100 base
-				assert_eq!(
-					Pallet::<Runtime>::compute_fee(456, &dispatch_info, 789),
-					100 + (3 * 123 / 2) + 4560 + 789,
-				);
-			});
-	}
-
-	#[test]
-	fn compute_fee_works_with_negative_multiplier() {
-		ExtBuilder::default()
-			.base_weight(Weight::from_ref_time(100))
-			.byte_fee(10)
-			.balance_factor(0)
-			.build()
-			.execute_with(|| {
-				// Add a next fee multiplier. All fees will be x1/2.
-				<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(1, 2));
-
-				// Base fee is unaffected by multiplier.
-				let dispatch_info = DispatchInfo {
-					weight: Weight::from_ref_time(0),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::Yes,
-				};
-				assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
-
-				// Everything works together.
-				let dispatch_info = DispatchInfo {
-					weight: Weight::from_ref_time(123),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::Yes,
-				};
-				// 123 weight, 456 length, 100 base
-				assert_eq!(
-					Pallet::<Runtime>::compute_fee(456, &dispatch_info, 789),
-					100 + (123 / 2) + 4560 + 789,
-				);
-			});
-	}
-
-	#[test]
-	fn compute_fee_does_not_overflow() {
-		ExtBuilder::default()
-			.base_weight(Weight::from_ref_time(100))
-			.byte_fee(10)
-			.balance_factor(0)
-			.build()
-			.execute_with(|| {
-				// Overflow is handled
-				let dispatch_info = DispatchInfo {
-					weight: Weight::MAX,
-					class: DispatchClass::Operational,
-					pays_fee: Pays::Yes,
-				};
-				assert_eq!(
-					Pallet::<Runtime>::compute_fee(u32::MAX, &dispatch_info, u64::MAX),
-					u64::MAX
-				);
-			});
-	}
-
-	#[test]
-	fn refund_does_not_recreate_account() {
-		ExtBuilder::default()
-			.balance_factor(10)
-			.base_weight(Weight::from_ref_time(5))
-			.build()
-			.execute_with(|| {
-				// So events are emitted
-				System::set_block_number(10);
-				let len = 10;
-				let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
-					.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_ref_time(100)), len)
-					.unwrap();
-				assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
-
-				// kill the account between pre and post dispatch
-				assert_ok!(Balances::transfer(Some(2).into(), 3, Balances::free_balance(2)));
-				assert_eq!(Balances::free_balance(2), 0);
-
-				assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-					Some(pre),
-					&info_from_weight(Weight::from_ref_time(100)),
-					&post_info_from_weight(Weight::from_ref_time(50)),
-					len,
-					&Ok(())
-				));
-				assert_eq!(Balances::free_balance(2), 0);
-				// Transfer Event
-				System::assert_has_event(RuntimeEvent::Balances(
-					pallet_balances::Event::Transfer { from: 2, to: 3, amount: 80 },
-				));
-				// Killed Event
-				System::assert_has_event(RuntimeEvent::System(system::Event::KilledAccount {
-					account: 2,
-				}));
-			});
-	}
-
-	#[test]
-	fn actual_weight_higher_than_max_refunds_nothing() {
-		ExtBuilder::default()
-			.balance_factor(10)
-			.base_weight(Weight::from_ref_time(5))
-			.build()
-			.execute_with(|| {
-				let len = 10;
-				let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
-					.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_ref_time(100)), len)
-					.unwrap();
-				assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
-
-				assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-					Some(pre),
-					&info_from_weight(Weight::from_ref_time(100)),
-					&post_info_from_weight(Weight::from_ref_time(101)),
-					len,
-					&Ok(())
-				));
-				assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
-			});
-	}
-
-	#[test]
-	fn zero_transfer_on_free_transaction() {
-		ExtBuilder::default()
-			.balance_factor(10)
-			.base_weight(Weight::from_ref_time(5))
-			.build()
-			.execute_with(|| {
-				// So events are emitted
-				System::set_block_number(10);
-				let len = 10;
-				let dispatch_info = DispatchInfo {
-					weight: Weight::from_ref_time(100),
-					pays_fee: Pays::No,
-					class: DispatchClass::Normal,
-				};
-				let user = 69;
-				let pre = ChargeTransactionPayment::<Runtime>::from(0)
-					.pre_dispatch(&user, CALL, &dispatch_info, len)
-					.unwrap();
-				assert_eq!(Balances::total_balance(&user), 0);
-				assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
-					Some(pre),
-					&dispatch_info,
-					&default_post_info(),
-					len,
-					&Ok(())
-				));
-				assert_eq!(Balances::total_balance(&user), 0);
-				// TransactionFeePaid Event
-				System::assert_has_event(RuntimeEvent::TransactionPayment(
-					pallet_transaction_payment::Event::TransactionFeePaid {
-						who: user,
-						actual_fee: 0,
-						tip: 0,
-					},
-				));
-			});
-	}
-
-	#[test]
-	fn refund_consistent_with_actual_weight() {
-		ExtBuilder::default()
-			.balance_factor(10)
-			.base_weight(Weight::from_ref_time(7))
-			.build()
-			.execute_with(|| {
-				let info = info_from_weight(Weight::from_ref_time(100));
-				let post_info = post_info_from_weight(Weight::from_ref_time(33));
-				let prev_balance = Balances::free_balance(2);
-				let len = 10;
-				let tip = 5;
-
-				<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(5, 4));
-
-				let pre = ChargeTransactionPayment::<Runtime>::from(tip)
-					.pre_dispatch(&2, CALL, &info, len)
-					.unwrap();
-
-				ChargeTransactionPayment::<Runtime>::post_dispatch(
-					Some(pre),
-					&info,
-					&post_info,
-					len,
-					&Ok(()),
-				)
-				.unwrap();
-
-				let refund_based_fee = prev_balance - Balances::free_balance(2);
-				let actual_fee =
-					Pallet::<Runtime>::compute_actual_fee(len as u32, &info, &post_info, tip);
-
-				// 33 weight, 10 length, 7 base, 5 tip
-				assert_eq!(actual_fee, 7 + 10 + (33 * 5 / 4) + 5);
-				assert_eq!(refund_based_fee, actual_fee);
-			});
-	}
-
-	#[test]
-	fn should_alter_operational_priority() {
-		let tip = 5;
-		let len = 10;
-
-		ExtBuilder::default().balance_factor(100).build().execute_with(|| {
-			let normal = DispatchInfo {
-				weight: Weight::from_ref_time(100),
-				class: DispatchClass::Normal,
-				pays_fee: Pays::Yes,
-			};
-			let priority = ChargeTransactionPayment::<Runtime>(tip)
-				.validate(&2, CALL, &normal, len)
-				.unwrap()
-				.priority;
-
-			assert_eq!(priority, 60);
-
-			let priority = ChargeTransactionPayment::<Runtime>(2 * tip)
-				.validate(&2, CALL, &normal, len)
-				.unwrap()
-				.priority;
-
-			assert_eq!(priority, 110);
-		});
-
-		ExtBuilder::default().balance_factor(100).build().execute_with(|| {
-			let op = DispatchInfo {
-				weight: Weight::from_ref_time(100),
-				class: DispatchClass::Operational,
-				pays_fee: Pays::Yes,
-			};
-			let priority = ChargeTransactionPayment::<Runtime>(tip)
-				.validate(&2, CALL, &op, len)
-				.unwrap()
-				.priority;
-			assert_eq!(priority, 5810);
-
-			let priority = ChargeTransactionPayment::<Runtime>(2 * tip)
-				.validate(&2, CALL, &op, len)
-				.unwrap()
-				.priority;
-			assert_eq!(priority, 6110);
-		});
-	}
-
-	#[test]
-	fn no_tip_has_some_priority() {
-		let tip = 0;
-		let len = 10;
-
-		ExtBuilder::default().balance_factor(100).build().execute_with(|| {
-			let normal = DispatchInfo {
-				weight: Weight::from_ref_time(100),
-				class: DispatchClass::Normal,
-				pays_fee: Pays::Yes,
-			};
-			let priority = ChargeTransactionPayment::<Runtime>(tip)
-				.validate(&2, CALL, &normal, len)
-				.unwrap()
-				.priority;
-
-			assert_eq!(priority, 10);
-		});
-
-		ExtBuilder::default().balance_factor(100).build().execute_with(|| {
-			let op = DispatchInfo {
-				weight: Weight::from_ref_time(100),
-				class: DispatchClass::Operational,
-				pays_fee: Pays::Yes,
-			};
-			let priority = ChargeTransactionPayment::<Runtime>(tip)
-				.validate(&2, CALL, &op, len)
-				.unwrap()
-				.priority;
-			assert_eq!(priority, 5510);
-		});
-	}
-
-	#[test]
-	fn higher_tip_have_higher_priority() {
-		let get_priorities = |tip: u64| {
-			let mut priority1 = 0;
-			let mut priority2 = 0;
-			let len = 10;
-			ExtBuilder::default().balance_factor(100).build().execute_with(|| {
-				let normal = DispatchInfo {
-					weight: Weight::from_ref_time(100),
-					class: DispatchClass::Normal,
-					pays_fee: Pays::Yes,
-				};
-				priority1 = ChargeTransactionPayment::<Runtime>(tip)
-					.validate(&2, CALL, &normal, len)
-					.unwrap()
-					.priority;
-			});
-
-			ExtBuilder::default().balance_factor(100).build().execute_with(|| {
-				let op = DispatchInfo {
-					weight: Weight::from_ref_time(100),
-					class: DispatchClass::Operational,
-					pays_fee: Pays::Yes,
-				};
-				priority2 = ChargeTransactionPayment::<Runtime>(tip)
-					.validate(&2, CALL, &op, len)
-					.unwrap()
-					.priority;
-			});
-
-			(priority1, priority2)
-		};
-
-		let mut prev_priorities = get_priorities(0);
-
-		for tip in 1..3 {
-			let priorities = get_priorities(tip);
-			assert!(prev_priorities.0 < priorities.0);
-			assert!(prev_priorities.1 < priorities.1);
-			prev_priorities = priorities;
-		}
-	}
-
-	#[test]
-	fn post_info_can_change_pays_fee() {
-		ExtBuilder::default()
-			.balance_factor(10)
-			.base_weight(Weight::from_ref_time(7))
-			.build()
-			.execute_with(|| {
-				let info = info_from_weight(Weight::from_ref_time(100));
-				let post_info = post_info_from_pays(Pays::No);
-				let prev_balance = Balances::free_balance(2);
-				let len = 10;
-				let tip = 5;
-
-				<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(5, 4));
-
-				let pre = ChargeTransactionPayment::<Runtime>::from(tip)
-					.pre_dispatch(&2, CALL, &info, len)
-					.unwrap();
-
-				ChargeTransactionPayment::<Runtime>::post_dispatch(
-					Some(pre),
-					&info,
-					&post_info,
-					len,
-					&Ok(()),
-				)
-				.unwrap();
-
-				let refund_based_fee = prev_balance - Balances::free_balance(2);
-				let actual_fee =
-					Pallet::<Runtime>::compute_actual_fee(len as u32, &info, &post_info, tip);
-
-				// Only 5 tip is paid
-				assert_eq!(actual_fee, 5);
-				assert_eq!(refund_based_fee, actual_fee);
-			});
-	}
-
-	#[test]
-	fn genesis_config_works() {
-		ExtBuilder::default()
-			.with_initial_multiplier(Multiplier::from_u32(100))
-			.build()
-			.execute_with(|| {
-				assert_eq!(
-					<NextFeeMultiplier<Runtime>>::get(),
-					Multiplier::saturating_from_integer(100)
-				);
-			});
-	}
-
-	#[test]
-	fn genesis_default_works() {
-		ExtBuilder::default().build().execute_with(|| {
-			assert_eq!(<NextFeeMultiplier<Runtime>>::get(), Multiplier::saturating_from_integer(1));
-		});
-	}
-}
diff --git a/substrate/frame/transaction-payment/src/mock.rs b/substrate/frame/transaction-payment/src/mock.rs
new file mode 100644
index 00000000000..e214458b376
--- /dev/null
+++ b/substrate/frame/transaction-payment/src/mock.rs
@@ -0,0 +1,162 @@
+// This file is part of Substrate.
+
+// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::*;
+use crate as pallet_transaction_payment;
+
+use sp_core::H256;
+use sp_runtime::{
+	testing::Header,
+	traits::{BlakeTwo256, IdentityLookup},
+};
+
+use frame_support::{
+	dispatch::DispatchClass,
+	parameter_types,
+	traits::{ConstU32, ConstU64, Imbalance, OnUnbalanced},
+	weights::{Weight, WeightToFee as WeightToFeeT},
+};
+use frame_system as system;
+use pallet_balances::Call as BalancesCall;
+
+type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Runtime>;
+type Block = frame_system::mocking::MockBlock<Runtime>;
+
+frame_support::construct_runtime!(
+	pub enum Runtime where
+		Block = Block,
+		NodeBlock = Block,
+		UncheckedExtrinsic = UncheckedExtrinsic,
+	{
+		System: system::{Pallet, Call, Config, Storage, Event<T>},
+		Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
+		TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>},
+	}
+);
+
+pub(crate) const CALL: &<Runtime as frame_system::Config>::RuntimeCall =
+	&RuntimeCall::Balances(BalancesCall::transfer { dest: 2, value: 69 });
+
+parameter_types! {
+	pub(crate) static ExtrinsicBaseWeight: Weight = Weight::zero();
+}
+
+pub struct BlockWeights;
+impl Get<frame_system::limits::BlockWeights> for BlockWeights {
+	fn get() -> frame_system::limits::BlockWeights {
+		frame_system::limits::BlockWeights::builder()
+			.base_block(Weight::zero())
+			.for_class(DispatchClass::all(), |weights| {
+				weights.base_extrinsic = ExtrinsicBaseWeight::get().into();
+			})
+			.for_class(DispatchClass::non_mandatory(), |weights| {
+				weights.max_total = Weight::from_ref_time(1024).set_proof_size(u64::MAX).into();
+			})
+			.build_or_panic()
+	}
+}
+
+parameter_types! {
+	pub static WeightToFee: u64 = 1;
+	pub static TransactionByteFee: u64 = 1;
+	pub static OperationalFeeMultiplier: u8 = 5;
+}
+
+impl frame_system::Config for Runtime {
+	type BaseCallFilter = frame_support::traits::Everything;
+	type BlockWeights = BlockWeights;
+	type BlockLength = ();
+	type DbWeight = ();
+	type RuntimeOrigin = RuntimeOrigin;
+	type Index = u64;
+	type BlockNumber = u64;
+	type RuntimeCall = RuntimeCall;
+	type Hash = H256;
+	type Hashing = BlakeTwo256;
+	type AccountId = u64;
+	type Lookup = IdentityLookup<Self::AccountId>;
+	type Header = Header;
+	type RuntimeEvent = RuntimeEvent;
+	type BlockHashCount = ConstU64<250>;
+	type Version = ();
+	type PalletInfo = PalletInfo;
+	type AccountData = pallet_balances::AccountData<u64>;
+	type OnNewAccount = ();
+	type OnKilledAccount = ();
+	type SystemWeightInfo = ();
+	type SS58Prefix = ();
+	type OnSetCode = ();
+	type MaxConsumers = ConstU32<16>;
+}
+
+impl pallet_balances::Config for Runtime {
+	type Balance = u64;
+	type RuntimeEvent = RuntimeEvent;
+	type DustRemoval = ();
+	type ExistentialDeposit = ConstU64<1>;
+	type AccountStore = System;
+	type MaxLocks = ();
+	type MaxReserves = ();
+	type ReserveIdentifier = [u8; 8];
+	type WeightInfo = ();
+}
+
+impl WeightToFeeT for WeightToFee {
+	type Balance = u64;
+
+	fn weight_to_fee(weight: &Weight) -> Self::Balance {
+		Self::Balance::saturated_from(weight.ref_time())
+			.saturating_mul(WEIGHT_TO_FEE.with(|v| *v.borrow()))
+	}
+}
+
+impl WeightToFeeT for TransactionByteFee {
+	type Balance = u64;
+
+	fn weight_to_fee(weight: &Weight) -> Self::Balance {
+		Self::Balance::saturated_from(weight.ref_time())
+			.saturating_mul(TRANSACTION_BYTE_FEE.with(|v| *v.borrow()))
+	}
+}
+
+parameter_types! {
+	pub(crate) static TipUnbalancedAmount: u64 = 0;
+	pub(crate) static FeeUnbalancedAmount: u64 = 0;
+}
+
+pub struct DealWithFees;
+impl OnUnbalanced<pallet_balances::NegativeImbalance<Runtime>> for DealWithFees {
+	fn on_unbalanceds<B>(
+		mut fees_then_tips: impl Iterator<Item = pallet_balances::NegativeImbalance<Runtime>>,
+	) {
+		if let Some(fees) = fees_then_tips.next() {
+			FeeUnbalancedAmount::mutate(|a| *a += fees.peek());
+			if let Some(tips) = fees_then_tips.next() {
+				TipUnbalancedAmount::mutate(|a| *a += tips.peek());
+			}
+		}
+	}
+}
+
+impl Config for Runtime {
+	type RuntimeEvent = RuntimeEvent;
+	type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
+	type OperationalFeeMultiplier = OperationalFeeMultiplier;
+	type WeightToFee = WeightToFee;
+	type LengthToFee = TransactionByteFee;
+	type FeeMultiplierUpdate = ();
+}
diff --git a/substrate/frame/transaction-payment/src/tests.rs b/substrate/frame/transaction-payment/src/tests.rs
new file mode 100644
index 00000000000..ee54c1130e6
--- /dev/null
+++ b/substrate/frame/transaction-payment/src/tests.rs
@@ -0,0 +1,836 @@
+// This file is part of Substrate.
+
+// Copyright (C) 2019-2022 Parity Technologies (UK) Ltd.
+// SPDX-License-Identifier: Apache-2.0
+
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// 	http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+use super::*;
+use crate as pallet_transaction_payment;
+
+use codec::Encode;
+
+use sp_runtime::{testing::TestXt, traits::One, transaction_validity::InvalidTransaction};
+
+use frame_support::{
+	assert_noop, assert_ok,
+	dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, PostDispatchInfo},
+	traits::{Currency, GenesisBuild},
+	weights::Weight,
+};
+use frame_system as system;
+use mock::*;
+use pallet_balances::Call as BalancesCall;
+
+pub struct ExtBuilder {
+	balance_factor: u64,
+	base_weight: Weight,
+	byte_fee: u64,
+	weight_to_fee: u64,
+	initial_multiplier: Option<Multiplier>,
+}
+
+impl Default for ExtBuilder {
+	fn default() -> Self {
+		Self {
+			balance_factor: 1,
+			base_weight: Weight::zero(),
+			byte_fee: 1,
+			weight_to_fee: 1,
+			initial_multiplier: None,
+		}
+	}
+}
+
+impl ExtBuilder {
+	pub fn base_weight(mut self, base_weight: Weight) -> Self {
+		self.base_weight = base_weight;
+		self
+	}
+	pub fn byte_fee(mut self, byte_fee: u64) -> Self {
+		self.byte_fee = byte_fee;
+		self
+	}
+	pub fn weight_fee(mut self, weight_to_fee: u64) -> Self {
+		self.weight_to_fee = weight_to_fee;
+		self
+	}
+	pub fn balance_factor(mut self, factor: u64) -> Self {
+		self.balance_factor = factor;
+		self
+	}
+	pub fn with_initial_multiplier(mut self, multiplier: Multiplier) -> Self {
+		self.initial_multiplier = Some(multiplier);
+		self
+	}
+	fn set_constants(&self) {
+		ExtrinsicBaseWeight::mutate(|v| *v = self.base_weight);
+		TRANSACTION_BYTE_FEE.with(|v| *v.borrow_mut() = self.byte_fee);
+		WEIGHT_TO_FEE.with(|v| *v.borrow_mut() = self.weight_to_fee);
+	}
+	pub fn build(self) -> sp_io::TestExternalities {
+		self.set_constants();
+		let mut t = frame_system::GenesisConfig::default().build_storage::<Runtime>().unwrap();
+		pallet_balances::GenesisConfig::<Runtime> {
+			balances: if self.balance_factor > 0 {
+				vec![
+					(1, 10 * self.balance_factor),
+					(2, 20 * self.balance_factor),
+					(3, 30 * self.balance_factor),
+					(4, 40 * self.balance_factor),
+					(5, 50 * self.balance_factor),
+					(6, 60 * self.balance_factor),
+				]
+			} else {
+				vec![]
+			},
+		}
+		.assimilate_storage(&mut t)
+		.unwrap();
+
+		if let Some(multiplier) = self.initial_multiplier {
+			let genesis = pallet::GenesisConfig { multiplier };
+			GenesisBuild::<Runtime>::assimilate_storage(&genesis, &mut t).unwrap();
+		}
+
+		t.into()
+	}
+}
+
+/// create a transaction info struct from weight. Handy to avoid building the whole struct.
+pub fn info_from_weight(w: Weight) -> DispatchInfo {
+	// pays_fee: Pays::Yes -- class: DispatchClass::Normal
+	DispatchInfo { weight: w, ..Default::default() }
+}
+
+fn post_info_from_weight(w: Weight) -> PostDispatchInfo {
+	PostDispatchInfo { actual_weight: Some(w), pays_fee: Default::default() }
+}
+
+fn post_info_from_pays(p: Pays) -> PostDispatchInfo {
+	PostDispatchInfo { actual_weight: None, pays_fee: p }
+}
+
+fn default_post_info() -> PostDispatchInfo {
+	PostDispatchInfo { actual_weight: None, pays_fee: Default::default() }
+}
+
+#[test]
+fn signed_extension_transaction_payment_work() {
+	ExtBuilder::default()
+		.balance_factor(10)
+		.base_weight(Weight::from_ref_time(5))
+		.build()
+		.execute_with(|| {
+			let len = 10;
+			let pre = ChargeTransactionPayment::<Runtime>::from(0)
+				.pre_dispatch(&1, CALL, &info_from_weight(Weight::from_ref_time(5)), len)
+				.unwrap();
+			assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10);
+
+			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
+				Some(pre),
+				&info_from_weight(Weight::from_ref_time(5)),
+				&default_post_info(),
+				len,
+				&Ok(())
+			));
+			assert_eq!(Balances::free_balance(1), 100 - 5 - 5 - 10);
+			assert_eq!(FeeUnbalancedAmount::get(), 5 + 5 + 10);
+			assert_eq!(TipUnbalancedAmount::get(), 0);
+
+			FeeUnbalancedAmount::mutate(|a| *a = 0);
+
+			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
+				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_ref_time(100)), len)
+				.unwrap();
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
+
+			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
+				Some(pre),
+				&info_from_weight(Weight::from_ref_time(100)),
+				&post_info_from_weight(Weight::from_ref_time(50)),
+				len,
+				&Ok(())
+			));
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 50 - 5);
+			assert_eq!(FeeUnbalancedAmount::get(), 5 + 10 + 50);
+			assert_eq!(TipUnbalancedAmount::get(), 5);
+		});
+}
+
+#[test]
+fn signed_extension_transaction_payment_multiplied_refund_works() {
+	ExtBuilder::default()
+		.balance_factor(10)
+		.base_weight(Weight::from_ref_time(5))
+		.build()
+		.execute_with(|| {
+			let len = 10;
+			<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
+
+			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
+				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_ref_time(100)), len)
+				.unwrap();
+			// 5 base fee, 10 byte fee, 3/2 * 100 weight fee, 5 tip
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 150 - 5);
+
+			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
+				Some(pre),
+				&info_from_weight(Weight::from_ref_time(100)),
+				&post_info_from_weight(Weight::from_ref_time(50)),
+				len,
+				&Ok(())
+			));
+			// 75 (3/2 of the returned 50 units of weight) is refunded
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 75 - 5);
+		});
+}
+
+#[test]
+fn signed_extension_transaction_payment_is_bounded() {
+	ExtBuilder::default().balance_factor(1000).byte_fee(0).build().execute_with(|| {
+		// maximum weight possible
+		assert_ok!(ChargeTransactionPayment::<Runtime>::from(0).pre_dispatch(
+			&1,
+			CALL,
+			&info_from_weight(Weight::MAX),
+			10
+		));
+		// fee will be proportional to what is the actual maximum weight in the runtime.
+		assert_eq!(
+			Balances::free_balance(&1),
+			(10000 - <Runtime as frame_system::Config>::BlockWeights::get().max_block.ref_time())
+				as u64
+		);
+	});
+}
+
+#[test]
+fn signed_extension_allows_free_transactions() {
+	ExtBuilder::default()
+		.base_weight(Weight::from_ref_time(100))
+		.balance_factor(0)
+		.build()
+		.execute_with(|| {
+			// 1 ain't have a penny.
+			assert_eq!(Balances::free_balance(1), 0);
+
+			let len = 100;
+
+			// This is a completely free (and thus wholly insecure/DoS-ridden) transaction.
+			let operational_transaction = DispatchInfo {
+				weight: Weight::from_ref_time(0),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::No,
+			};
+			assert_ok!(ChargeTransactionPayment::<Runtime>::from(0).validate(
+				&1,
+				CALL,
+				&operational_transaction,
+				len
+			));
+
+			// like a InsecureFreeNormal
+			let free_transaction = DispatchInfo {
+				weight: Weight::from_ref_time(0),
+				class: DispatchClass::Normal,
+				pays_fee: Pays::Yes,
+			};
+			assert_noop!(
+				ChargeTransactionPayment::<Runtime>::from(0).validate(
+					&1,
+					CALL,
+					&free_transaction,
+					len
+				),
+				TransactionValidityError::Invalid(InvalidTransaction::Payment),
+			);
+		});
+}
+
+#[test]
+fn signed_ext_length_fee_is_also_updated_per_congestion() {
+	ExtBuilder::default()
+		.base_weight(Weight::from_ref_time(5))
+		.balance_factor(10)
+		.build()
+		.execute_with(|| {
+			// all fees should be x1.5
+			<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
+			let len = 10;
+
+			assert_ok!(ChargeTransactionPayment::<Runtime>::from(10) // tipped
+				.pre_dispatch(&1, CALL, &info_from_weight(Weight::from_ref_time(3)), len));
+			assert_eq!(
+				Balances::free_balance(1),
+				100 // original
+            - 10 // tip
+            - 5 // base
+            - 10 // len
+            - (3 * 3 / 2) // adjusted weight
+			);
+		})
+}
+
+#[test]
+fn query_info_and_fee_details_works() {
+	let call = RuntimeCall::Balances(BalancesCall::transfer { dest: 2, value: 69 });
+	let origin = 111111;
+	let extra = ();
+	let xt = TestXt::new(call.clone(), Some((origin, extra)));
+	let info = xt.get_dispatch_info();
+	let ext = xt.encode();
+	let len = ext.len() as u32;
+
+	let unsigned_xt = TestXt::<_, ()>::new(call, None);
+	let unsigned_xt_info = unsigned_xt.get_dispatch_info();
+
+	ExtBuilder::default()
+        .base_weight(Weight::from_ref_time(5))
+        .weight_fee(2)
+        .build()
+        .execute_with(|| {
+            // all fees should be x1.5
+            <NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
+
+            assert_eq!(
+                TransactionPayment::query_info(xt.clone(), len),
+                RuntimeDispatchInfo {
+                    weight: info.weight,
+                    class: info.class,
+                    partial_fee: 5 * 2 /* base * weight_fee */
+                    + len as u64  /* len * 1 */
+                    + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */
+                },
+            );
+
+            assert_eq!(
+                TransactionPayment::query_info(unsigned_xt.clone(), len),
+                RuntimeDispatchInfo {
+                    weight: unsigned_xt_info.weight,
+                    class: unsigned_xt_info.class,
+                    partial_fee: 0,
+                },
+            );
+
+            assert_eq!(
+                TransactionPayment::query_fee_details(xt, len),
+                FeeDetails {
+                    inclusion_fee: Some(InclusionFee {
+                        base_fee: 5 * 2,
+                        len_fee: len as u64,
+                        adjusted_weight_fee: info
+                            .weight
+                            .min(BlockWeights::get().max_block)
+                            .ref_time() as u64 * 2 * 3 / 2
+                    }),
+                    tip: 0,
+                },
+            );
+
+            assert_eq!(
+                TransactionPayment::query_fee_details(unsigned_xt, len),
+                FeeDetails { inclusion_fee: None, tip: 0 },
+            );
+        });
+}
+
+#[test]
+fn query_call_info_and_fee_details_works() {
+	let call = RuntimeCall::Balances(BalancesCall::transfer { dest: 2, value: 69 });
+	let info = call.get_dispatch_info();
+	let encoded_call = call.encode();
+	let len = encoded_call.len() as u32;
+
+	ExtBuilder::default()
+        .base_weight(Weight::from_ref_time(5))
+        .weight_fee(2)
+        .build()
+        .execute_with(|| {
+            // all fees should be x1.5
+            <NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
+
+            assert_eq!(
+                TransactionPayment::query_call_info(call.clone(), len),
+                RuntimeDispatchInfo {
+                    weight: info.weight,
+                    class: info.class,
+                    partial_fee: 5 * 2 /* base * weight_fee */
+                    + len as u64  /* len * 1 */
+                    + info.weight.min(BlockWeights::get().max_block).ref_time() as u64 * 2 * 3 / 2 /* weight */
+                },
+            );
+
+            assert_eq!(
+                TransactionPayment::query_call_fee_details(call, len),
+                FeeDetails {
+                    inclusion_fee: Some(InclusionFee {
+                        base_fee: 5 * 2,     /* base * weight_fee */
+                        len_fee: len as u64, /* len * 1 */
+                        adjusted_weight_fee: info
+                            .weight
+                            .min(BlockWeights::get().max_block)
+                            .ref_time() as u64 * 2 * 3 / 2  /* weight * weight_fee * multipler */
+                    }),
+                    tip: 0,
+                },
+            );
+        });
+}
+
+#[test]
+fn compute_fee_works_without_multiplier() {
+	ExtBuilder::default()
+		.base_weight(Weight::from_ref_time(100))
+		.byte_fee(10)
+		.balance_factor(0)
+		.build()
+		.execute_with(|| {
+			// Next fee multiplier is zero
+			assert_eq!(<NextFeeMultiplier<Runtime>>::get(), Multiplier::one());
+
+			// Tip only, no fees works
+			let dispatch_info = DispatchInfo {
+				weight: Weight::from_ref_time(0),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::No,
+			};
+			assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 10), 10);
+			// No tip, only base fee works
+			let dispatch_info = DispatchInfo {
+				weight: Weight::from_ref_time(0),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::Yes,
+			};
+			assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
+			// Tip + base fee works
+			assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 69), 169);
+			// Len (byte fee) + base fee works
+			assert_eq!(Pallet::<Runtime>::compute_fee(42, &dispatch_info, 0), 520);
+			// Weight fee + base fee works
+			let dispatch_info = DispatchInfo {
+				weight: Weight::from_ref_time(1000),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::Yes,
+			};
+			assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 0), 1100);
+		});
+}
+
+#[test]
+fn compute_fee_works_with_multiplier() {
+	ExtBuilder::default()
+		.base_weight(Weight::from_ref_time(100))
+		.byte_fee(10)
+		.balance_factor(0)
+		.build()
+		.execute_with(|| {
+			// Add a next fee multiplier. Fees will be x3/2.
+			<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(3, 2));
+			// Base fee is unaffected by multiplier
+			let dispatch_info = DispatchInfo {
+				weight: Weight::from_ref_time(0),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::Yes,
+			};
+			assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
+
+			// Everything works together :)
+			let dispatch_info = DispatchInfo {
+				weight: Weight::from_ref_time(123),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::Yes,
+			};
+			// 123 weight, 456 length, 100 base
+			assert_eq!(
+				Pallet::<Runtime>::compute_fee(456, &dispatch_info, 789),
+				100 + (3 * 123 / 2) + 4560 + 789,
+			);
+		});
+}
+
+#[test]
+fn compute_fee_works_with_negative_multiplier() {
+	ExtBuilder::default()
+		.base_weight(Weight::from_ref_time(100))
+		.byte_fee(10)
+		.balance_factor(0)
+		.build()
+		.execute_with(|| {
+			// Add a next fee multiplier. All fees will be x1/2.
+			<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(1, 2));
+
+			// Base fee is unaffected by multiplier.
+			let dispatch_info = DispatchInfo {
+				weight: Weight::from_ref_time(0),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::Yes,
+			};
+			assert_eq!(Pallet::<Runtime>::compute_fee(0, &dispatch_info, 0), 100);
+
+			// Everything works together.
+			let dispatch_info = DispatchInfo {
+				weight: Weight::from_ref_time(123),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::Yes,
+			};
+			// 123 weight, 456 length, 100 base
+			assert_eq!(
+				Pallet::<Runtime>::compute_fee(456, &dispatch_info, 789),
+				100 + (123 / 2) + 4560 + 789,
+			);
+		});
+}
+
+#[test]
+fn compute_fee_does_not_overflow() {
+	ExtBuilder::default()
+		.base_weight(Weight::from_ref_time(100))
+		.byte_fee(10)
+		.balance_factor(0)
+		.build()
+		.execute_with(|| {
+			// Overflow is handled
+			let dispatch_info = DispatchInfo {
+				weight: Weight::MAX,
+				class: DispatchClass::Operational,
+				pays_fee: Pays::Yes,
+			};
+			assert_eq!(
+				Pallet::<Runtime>::compute_fee(u32::MAX, &dispatch_info, u64::MAX),
+				u64::MAX
+			);
+		});
+}
+
+#[test]
+fn refund_does_not_recreate_account() {
+	ExtBuilder::default()
+		.balance_factor(10)
+		.base_weight(Weight::from_ref_time(5))
+		.build()
+		.execute_with(|| {
+			// So events are emitted
+			System::set_block_number(10);
+			let len = 10;
+			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
+				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_ref_time(100)), len)
+				.unwrap();
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
+
+			// kill the account between pre and post dispatch
+			assert_ok!(Balances::transfer(Some(2).into(), 3, Balances::free_balance(2)));
+			assert_eq!(Balances::free_balance(2), 0);
+
+			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
+				Some(pre),
+				&info_from_weight(Weight::from_ref_time(100)),
+				&post_info_from_weight(Weight::from_ref_time(50)),
+				len,
+				&Ok(())
+			));
+			assert_eq!(Balances::free_balance(2), 0);
+			// Transfer Event
+			System::assert_has_event(RuntimeEvent::Balances(pallet_balances::Event::Transfer {
+				from: 2,
+				to: 3,
+				amount: 80,
+			}));
+			// Killed Event
+			System::assert_has_event(RuntimeEvent::System(system::Event::KilledAccount {
+				account: 2,
+			}));
+		});
+}
+
+#[test]
+fn actual_weight_higher_than_max_refunds_nothing() {
+	ExtBuilder::default()
+		.balance_factor(10)
+		.base_weight(Weight::from_ref_time(5))
+		.build()
+		.execute_with(|| {
+			let len = 10;
+			let pre = ChargeTransactionPayment::<Runtime>::from(5 /* tipped */)
+				.pre_dispatch(&2, CALL, &info_from_weight(Weight::from_ref_time(100)), len)
+				.unwrap();
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
+
+			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
+				Some(pre),
+				&info_from_weight(Weight::from_ref_time(100)),
+				&post_info_from_weight(Weight::from_ref_time(101)),
+				len,
+				&Ok(())
+			));
+			assert_eq!(Balances::free_balance(2), 200 - 5 - 10 - 100 - 5);
+		});
+}
+
+#[test]
+fn zero_transfer_on_free_transaction() {
+	ExtBuilder::default()
+		.balance_factor(10)
+		.base_weight(Weight::from_ref_time(5))
+		.build()
+		.execute_with(|| {
+			// So events are emitted
+			System::set_block_number(10);
+			let len = 10;
+			let dispatch_info = DispatchInfo {
+				weight: Weight::from_ref_time(100),
+				pays_fee: Pays::No,
+				class: DispatchClass::Normal,
+			};
+			let user = 69;
+			let pre = ChargeTransactionPayment::<Runtime>::from(0)
+				.pre_dispatch(&user, CALL, &dispatch_info, len)
+				.unwrap();
+			assert_eq!(Balances::total_balance(&user), 0);
+			assert_ok!(ChargeTransactionPayment::<Runtime>::post_dispatch(
+				Some(pre),
+				&dispatch_info,
+				&default_post_info(),
+				len,
+				&Ok(())
+			));
+			assert_eq!(Balances::total_balance(&user), 0);
+			// TransactionFeePaid Event
+			System::assert_has_event(RuntimeEvent::TransactionPayment(
+				pallet_transaction_payment::Event::TransactionFeePaid {
+					who: user,
+					actual_fee: 0,
+					tip: 0,
+				},
+			));
+		});
+}
+
+#[test]
+fn refund_consistent_with_actual_weight() {
+	ExtBuilder::default()
+		.balance_factor(10)
+		.base_weight(Weight::from_ref_time(7))
+		.build()
+		.execute_with(|| {
+			let info = info_from_weight(Weight::from_ref_time(100));
+			let post_info = post_info_from_weight(Weight::from_ref_time(33));
+			let prev_balance = Balances::free_balance(2);
+			let len = 10;
+			let tip = 5;
+
+			<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(5, 4));
+
+			let pre = ChargeTransactionPayment::<Runtime>::from(tip)
+				.pre_dispatch(&2, CALL, &info, len)
+				.unwrap();
+
+			ChargeTransactionPayment::<Runtime>::post_dispatch(
+				Some(pre),
+				&info,
+				&post_info,
+				len,
+				&Ok(()),
+			)
+			.unwrap();
+
+			let refund_based_fee = prev_balance - Balances::free_balance(2);
+			let actual_fee =
+				Pallet::<Runtime>::compute_actual_fee(len as u32, &info, &post_info, tip);
+
+			// 33 weight, 10 length, 7 base, 5 tip
+			assert_eq!(actual_fee, 7 + 10 + (33 * 5 / 4) + 5);
+			assert_eq!(refund_based_fee, actual_fee);
+		});
+}
+
+#[test]
+fn should_alter_operational_priority() {
+	let tip = 5;
+	let len = 10;
+
+	ExtBuilder::default().balance_factor(100).build().execute_with(|| {
+		let normal = DispatchInfo {
+			weight: Weight::from_ref_time(100),
+			class: DispatchClass::Normal,
+			pays_fee: Pays::Yes,
+		};
+		let priority = ChargeTransactionPayment::<Runtime>(tip)
+			.validate(&2, CALL, &normal, len)
+			.unwrap()
+			.priority;
+
+		assert_eq!(priority, 60);
+
+		let priority = ChargeTransactionPayment::<Runtime>(2 * tip)
+			.validate(&2, CALL, &normal, len)
+			.unwrap()
+			.priority;
+
+		assert_eq!(priority, 110);
+	});
+
+	ExtBuilder::default().balance_factor(100).build().execute_with(|| {
+		let op = DispatchInfo {
+			weight: Weight::from_ref_time(100),
+			class: DispatchClass::Operational,
+			pays_fee: Pays::Yes,
+		};
+		let priority = ChargeTransactionPayment::<Runtime>(tip)
+			.validate(&2, CALL, &op, len)
+			.unwrap()
+			.priority;
+		assert_eq!(priority, 5810);
+
+		let priority = ChargeTransactionPayment::<Runtime>(2 * tip)
+			.validate(&2, CALL, &op, len)
+			.unwrap()
+			.priority;
+		assert_eq!(priority, 6110);
+	});
+}
+
+#[test]
+fn no_tip_has_some_priority() {
+	let tip = 0;
+	let len = 10;
+
+	ExtBuilder::default().balance_factor(100).build().execute_with(|| {
+		let normal = DispatchInfo {
+			weight: Weight::from_ref_time(100),
+			class: DispatchClass::Normal,
+			pays_fee: Pays::Yes,
+		};
+		let priority = ChargeTransactionPayment::<Runtime>(tip)
+			.validate(&2, CALL, &normal, len)
+			.unwrap()
+			.priority;
+
+		assert_eq!(priority, 10);
+	});
+
+	ExtBuilder::default().balance_factor(100).build().execute_with(|| {
+		let op = DispatchInfo {
+			weight: Weight::from_ref_time(100),
+			class: DispatchClass::Operational,
+			pays_fee: Pays::Yes,
+		};
+		let priority = ChargeTransactionPayment::<Runtime>(tip)
+			.validate(&2, CALL, &op, len)
+			.unwrap()
+			.priority;
+		assert_eq!(priority, 5510);
+	});
+}
+
+#[test]
+fn higher_tip_have_higher_priority() {
+	let get_priorities = |tip: u64| {
+		let mut priority1 = 0;
+		let mut priority2 = 0;
+		let len = 10;
+		ExtBuilder::default().balance_factor(100).build().execute_with(|| {
+			let normal = DispatchInfo {
+				weight: Weight::from_ref_time(100),
+				class: DispatchClass::Normal,
+				pays_fee: Pays::Yes,
+			};
+			priority1 = ChargeTransactionPayment::<Runtime>(tip)
+				.validate(&2, CALL, &normal, len)
+				.unwrap()
+				.priority;
+		});
+
+		ExtBuilder::default().balance_factor(100).build().execute_with(|| {
+			let op = DispatchInfo {
+				weight: Weight::from_ref_time(100),
+				class: DispatchClass::Operational,
+				pays_fee: Pays::Yes,
+			};
+			priority2 = ChargeTransactionPayment::<Runtime>(tip)
+				.validate(&2, CALL, &op, len)
+				.unwrap()
+				.priority;
+		});
+
+		(priority1, priority2)
+	};
+
+	let mut prev_priorities = get_priorities(0);
+
+	for tip in 1..3 {
+		let priorities = get_priorities(tip);
+		assert!(prev_priorities.0 < priorities.0);
+		assert!(prev_priorities.1 < priorities.1);
+		prev_priorities = priorities;
+	}
+}
+
+#[test]
+fn post_info_can_change_pays_fee() {
+	ExtBuilder::default()
+		.balance_factor(10)
+		.base_weight(Weight::from_ref_time(7))
+		.build()
+		.execute_with(|| {
+			let info = info_from_weight(Weight::from_ref_time(100));
+			let post_info = post_info_from_pays(Pays::No);
+			let prev_balance = Balances::free_balance(2);
+			let len = 10;
+			let tip = 5;
+
+			<NextFeeMultiplier<Runtime>>::put(Multiplier::saturating_from_rational(5, 4));
+
+			let pre = ChargeTransactionPayment::<Runtime>::from(tip)
+				.pre_dispatch(&2, CALL, &info, len)
+				.unwrap();
+
+			ChargeTransactionPayment::<Runtime>::post_dispatch(
+				Some(pre),
+				&info,
+				&post_info,
+				len,
+				&Ok(()),
+			)
+			.unwrap();
+
+			let refund_based_fee = prev_balance - Balances::free_balance(2);
+			let actual_fee =
+				Pallet::<Runtime>::compute_actual_fee(len as u32, &info, &post_info, tip);
+
+			// Only 5 tip is paid
+			assert_eq!(actual_fee, 5);
+			assert_eq!(refund_based_fee, actual_fee);
+		});
+}
+
+#[test]
+fn genesis_config_works() {
+	ExtBuilder::default()
+		.with_initial_multiplier(Multiplier::from_u32(100))
+		.build()
+		.execute_with(|| {
+			assert_eq!(
+				<NextFeeMultiplier<Runtime>>::get(),
+				Multiplier::saturating_from_integer(100)
+			);
+		});
+}
+
+#[test]
+fn genesis_default_works() {
+	ExtBuilder::default().build().execute_with(|| {
+		assert_eq!(<NextFeeMultiplier<Runtime>>::get(), Multiplier::saturating_from_integer(1));
+	});
+}
-- 
GitLab