From 2904c51236ffd4cc1e6261ef10374d1409cb5b9c Mon Sep 17 00:00:00 2001 From: UnArbosSix Date: Fri, 7 Aug 2026 12:53:21 -0700 Subject: [PATCH] propagate inner post-dispatch weight --- pallets/proxy/src/lib.rs | 25 ++++++++++------ pallets/proxy/src/tests.rs | 58 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 8 deletions(-) diff --git a/pallets/proxy/src/lib.rs b/pallets/proxy/src/lib.rs index 1fca855327..488889e7ec 100644 --- a/pallets/proxy/src/lib.rs +++ b/pallets/proxy/src/lib.rs @@ -39,6 +39,7 @@ use frame::{ prelude::*, traits::{Currency, InstanceFilter, ReservableCurrency}, }; +use frame_support::dispatch::extract_actual_weight; use frame_system::pallet_prelude::BlockNumberFor as SystemBlockNumberFor; pub use pallet::*; use subtensor_macros::freeze_struct; @@ -126,7 +127,7 @@ pub mod pallet { pub trait Config: frame_system::Config { /// The overarching call type. type RuntimeCall: Parameter - + Dispatchable + + Dispatchable + GetDispatchInfo + From> + IsSubType> @@ -242,15 +243,17 @@ pub mod pallet { real: AccountIdLookupOf, force_proxy_type: Option, call: Box<::RuntimeCall>, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { let who = ensure_signed(origin)?; let real = T::Lookup::lookup(real)?; let def = Self::find_proxy(&real, &who, force_proxy_type)?; ensure!(def.delay.is_zero(), Error::::Unannounced); - Self::do_proxy(def, real, *call); + let weight = T::WeightInfo::proxy(T::MaxProxies::get()) + .saturating_add(T::DbWeight::get().reads_writes(1, 1)) + .saturating_add(Self::do_proxy(def, real, *call)); - Ok(()) + Ok(Some(weight).into()) } /// Register a proxy account for the sender that is able to make calls on its behalf. @@ -552,7 +555,7 @@ pub mod pallet { real: AccountIdLookupOf, force_proxy_type: Option, call: Box<::RuntimeCall>, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { ensure_signed(origin)?; let delegate = T::Lookup::lookup(delegate)?; let real = T::Lookup::lookup(real)?; @@ -567,9 +570,11 @@ pub mod pallet { }) .map_err(|_| Error::::Unannounced)?; - Self::do_proxy(def, real, *call); + let weight = T::WeightInfo::proxy_announced(T::MaxPending::get(), T::MaxProxies::get()) + .saturating_add(T::DbWeight::get().reads_writes(1, 1)) + .saturating_add(Self::do_proxy(def, real, *call)); - Ok(()) + Ok(Some(weight).into()) } /// Poke / Adjust deposits made for proxies and announcements based on current values. @@ -1101,7 +1106,7 @@ impl Pallet { def: ProxyDefinition>, real: T::AccountId, call: ::RuntimeCall, - ) { + ) -> Weight { use frame::traits::{InstanceFilter as _, OriginTrait as _}; // This is a freshly authenticated new account, the origin restrictions doesn't apply. let mut origin: T::RuntimeOrigin = frame_system::RawOrigin::Signed(real.clone()).into(); @@ -1127,13 +1132,17 @@ impl Pallet { _ => def.proxy_type.filter(c), } }); + let info = call.get_dispatch_info(); let e = call.dispatch(origin); + let actual_weight = extract_actual_weight(&e, &info); LastCallResult::::insert(real, e.map(|_| ()).map_err(|e| e.error)); Self::deposit_event(Event::ProxyExecuted { result: e.map(|_| ()).map_err(|e| e.error), }); + + actual_weight } /// Removes all proxy delegates for a given delegator. diff --git a/pallets/proxy/src/tests.rs b/pallets/proxy/src/tests.rs index 5bc5be2415..d3ce6f82cf 100644 --- a/pallets/proxy/src/tests.rs +++ b/pallets/proxy/src/tests.rs @@ -175,6 +175,12 @@ fn call_transfer(dest: u64, value: u64) -> RuntimeCall { RuntimeCall::Balances(BalancesCall::transfer_allow_death { dest, value }) } +fn call_batch_with_refund() -> RuntimeCall { + RuntimeCall::Utility(UtilityCall::batch { + calls: vec![call_transfer(6, 20), call_transfer(6, 1)], + }) +} + #[test] fn announcement_works() { new_test_ext().execute_with(|| { @@ -363,6 +369,58 @@ fn calling_proxy_doesnt_remove_announcement() { }); } +#[test] +fn proxy_propagates_inner_actual_weight() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(1), + 2, + ProxyType::Any, + 0 + )); + + let call = RuntimeCall::Proxy(ProxyCall::new_call_variant_proxy( + 1, + None, + Box::new(call_batch_with_refund()), + )); + let info = call.get_dispatch_info(); + let result = call.dispatch(RuntimeOrigin::signed(2)); + + assert_ok!(result); + assert_ne!(extract_actual_weight(&result, &info), info.call_weight); + }); +} + +#[test] +fn proxy_announced_propagates_inner_actual_weight() { + new_test_ext().execute_with(|| { + assert_ok!(Proxy::add_proxy( + RuntimeOrigin::signed(1), + 2, + ProxyType::Any, + 1 + )); + + let call = Box::new(call_batch_with_refund()); + assert_ok!(Proxy::announce( + RuntimeOrigin::signed(2), + 1, + BlakeTwo256::hash_of(&call) + )); + System::set_block_number(2); + + let call = RuntimeCall::Proxy(ProxyCall::new_call_variant_proxy_announced( + 2, 1, None, call, + )); + let info = call.get_dispatch_info(); + let result = call.dispatch(RuntimeOrigin::signed(0)); + + assert_ok!(result); + assert_ne!(extract_actual_weight(&result, &info), info.call_weight); + }); +} + #[test] fn delayed_requires_pre_announcement() { new_test_ext().execute_with(|| {