Repository: paritytech/substrate
File: frame/transaction-payment/src/lib.rs (Rust)

Code before:
where
	T: frame_system::Config,
	S: Get<Perquintill>,
	V: Get<Multiplier>,
	M: Get<Multiplier>,
	X: Get<Multiplier>,
{
	fn convert(previous: Multiplier) -> Multiplier {
		// Defensive only. The multiplier in storage should always be at most positive. Nonetheless
		// we recover here in case of errors, because any value below this would be stale and can
		// never change.
		let min_multiplier = M::get();
		let max_multiplier = X::get();
		let previous = previous.max(min_multiplier);

		let weights = T::BlockWeights::get();
		// the computed ratio is only among the normal class.
		let normal_max_weight =
			weights.get(DispatchClass::Normal).max_total.unwrap_or(weights.max_block);
		let current_block_weight = <frame_system::Pallet<T>>::block_weight();
		let normal_block_weight =
			current_block_weight.get(DispatchClass::Normal).min(normal_max_weight);

		// take only the scarcer resource into account.
		let (normal_block_weight, normal_max_weight) =
			if normal_block_weight.ref_time() > normal_block_weight.proof_size() {
				(normal_block_weight.ref_time(), normal_max_weight.ref_time())
			} else {
				(normal_block_weight.proof_size(), normal_max_weight.proof_size())
			};

		let target_block_fullness = S::get();
		let adjustment_variable = V::get();

		let target_weight = (target_block_fullness * normal_max_weight) as u128;
		let block_weight = normal_block_weight as u128;

		// determines if the first_term is positive
		let positive = block_weight >= target_weight;
		let diff_abs = block_weight.max(target_weight) - block_weight.min(target_weight);

		// defensive only, a test case assures that the maximum weight diff can fit in Multiplier
		// without any saturation.
		let diff = Multiplier::saturating_from_rational(diff_abs, normal_max_weight.max(1));
		let diff_squared = diff.saturating_mul(diff);

		let v_squared_2 = adjustment_variable.saturating_mul(adjustment_variable) /
			Multiplier::saturating_from_integer(2);

		let first_term = adjustment_variable.saturating_mul(diff);
		let second_term = v_squared_2.saturating_mul(diff_squared);

Review comment (suggestion):
You can *never* compare `proof_size` with `ref_time` directly.  
I did something different in the other MR: first converting them to a currency and them comparing the currency values.

I think the correct approach here is to calculate the ratio per dimension to the max block and select by the larger ration.  
So for example a call with weight `[2, 4]` and a max-block weight of `[3, 10]` would be limited by the first dimension since `2/3 > 4/10`.



Code after:
	}
	fn variability() -> Multiplier {
		V::get()
	}
}

impl<T, S, V, M, X> Convert<Multiplier, Multiplier> for TargetedFeeAdjustment<T, S, V, M, X>
where
	T: frame_system::Config,
	S: Get<Perquintill>,
	V: Get<Multiplier>,
	M: Get<Multiplier>,
	X: Get<Multiplier>,
{
	fn convert(previous: Multiplier) -> Multiplier {
		// Defensive only. The multiplier in storage should always be at most positive. Nonetheless
		// we recover here in case of errors, because any value below this would be stale and can
		// never change.
		let min_multiplier = M::get();
		let max_multiplier = X::get();
		let previous = previous.max(min_multiplier);

		let weights = T::BlockWeights::get();
		// the computed ratio is only among the normal class.
		let normal_max_weight =
			weights.get(DispatchClass::Normal).max_total.unwrap_or(weights.max_block);
		let current_block_weight = <frame_system::Pallet<T>>::block_weight();
		let normal_block_weight =
			current_block_weight.get(DispatchClass::Normal).min(normal_max_weight);

		// Normalize dimensions so they can be compared. Ensure (defensive) max weight is non-zero.
		let normalized_ref_time = Perbill::from_rational(
			normal_block_weight.ref_time(),
			normal_max_weight.ref_time().max(1),
		);
		let normalized_proof_size = Perbill::from_rational(
			normal_block_weight.proof_size(),
			normal_max_weight.proof_size().max(1),
		);

		// Pick the limiting dimension. If the proof size is the limiting dimension, then the
		// multiplier is adjusted by the proof size. Otherwise, it is adjusted by the ref time.
		let (normal_limiting_dimension, max_limiting_dimension) =
			if normalized_ref_time < normalized_proof_size {
				(normal_block_weight.proof_size(), normal_max_weight.proof_size())
			} else {
				(normal_block_weight.ref_time(), normal_max_weight.ref_time())
			};

		let target_block_fullness = S::get();
		let adjustment_variable = V::get();