From 682f8cd22f5bcb76d1b98820b62be49d11deae10 Mon Sep 17 00:00:00 2001
From: Guillaume Thiolliere <gui.thiolliere@gmail.com>
Date: Sat, 25 Jan 2025 12:04:45 +0900
Subject: [PATCH] `set_validation_data` register weight manually, do not use
 refund when the pre dispatch is zero. (#7327)

Related https://github.com/paritytech/polkadot-sdk/issues/6772

For an extrinsic, in the post dispatch info, the actual weight is only
used to reclaim unused weight. If the actual weight is more than the pre
dispatch weight, then the extrinsic is using the minimum, e.g., the
weight used registered in pre dispatch.

In parachain-system pallet one call is `set_validation_data`. This call
is returning an actual weight, but the pre-dispatch weight is 0.

This PR fix the disregard of actual weight of `set_validation_data` by
registering it manually.
---
 cumulus/pallets/parachain-system/src/lib.rs | 14 ++++++++++----
 prdoc/pr_7327.prdoc                         | 11 +++++++++++
 2 files changed, 21 insertions(+), 4 deletions(-)
 create mode 100644 prdoc/pr_7327.prdoc

diff --git a/cumulus/pallets/parachain-system/src/lib.rs b/cumulus/pallets/parachain-system/src/lib.rs
index 6857b08e66b..fa754ea29cc 100644
--- a/cumulus/pallets/parachain-system/src/lib.rs
+++ b/cumulus/pallets/parachain-system/src/lib.rs
@@ -45,7 +45,7 @@ use cumulus_primitives_core::{
 use cumulus_primitives_parachain_inherent::{MessageQueueChain, ParachainInherentData};
 use frame_support::{
 	defensive,
-	dispatch::{DispatchResult, Pays, PostDispatchInfo},
+	dispatch::DispatchResult,
 	ensure,
 	inherent::{InherentData, InherentIdentifier, ProvideInherent},
 	traits::{Get, HandleMessage},
@@ -567,11 +567,12 @@ pub mod pallet {
 		/// if the appropriate time has come.
 		#[pallet::call_index(0)]
 		#[pallet::weight((0, DispatchClass::Mandatory))]
-		// TODO: This weight should be corrected.
+		// TODO: This weight should be corrected. Currently the weight is registered manually in the
+		// call with `register_extra_weight_unchecked`.
 		pub fn set_validation_data(
 			origin: OriginFor<T>,
 			data: ParachainInherentData,
-		) -> DispatchResultWithPostInfo {
+		) -> DispatchResult {
 			ensure_none(origin)?;
 			assert!(
 				!<ValidationData<T>>::exists(),
@@ -692,7 +693,12 @@ pub mod pallet {
 				vfp.relay_parent_number,
 			));
 
-			Ok(PostDispatchInfo { actual_weight: Some(total_weight), pays_fee: Pays::No })
+			frame_system::Pallet::<T>::register_extra_weight_unchecked(
+				total_weight,
+				DispatchClass::Mandatory,
+			);
+
+			Ok(())
 		}
 
 		#[pallet::call_index(1)]
diff --git a/prdoc/pr_7327.prdoc b/prdoc/pr_7327.prdoc
new file mode 100644
index 00000000000..bb2d7a671af
--- /dev/null
+++ b/prdoc/pr_7327.prdoc
@@ -0,0 +1,11 @@
+title: Correctly register the weight n `set_validation_data` in `cumulus-pallet-parachain-system`
+
+doc:
+  - audience: Runtime Dev
+    description: |
+        The actual weight of the call was register as a refund, but the pre-dispatch weight is 0,
+        and we can't refund from 0. Now the actual weight is registered manually instead of ignored.
+
+crates:
+  - name: cumulus-pallet-parachain-system
+    bump: patch
-- 
GitLab