Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 17 additions & 8 deletions pallets/proxy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -126,7 +127,7 @@ pub mod pallet {
pub trait Config: frame_system::Config {
/// The overarching call type.
type RuntimeCall: Parameter
+ Dispatchable<RuntimeOrigin = Self::RuntimeOrigin>
+ Dispatchable<RuntimeOrigin = Self::RuntimeOrigin, PostInfo = PostDispatchInfo>
+ GetDispatchInfo
+ From<frame_system::Call<Self>>
+ IsSubType<Call<Self>>
Expand Down Expand Up @@ -242,15 +243,17 @@ pub mod pallet {
real: AccountIdLookupOf<T>,
force_proxy_type: Option<T::ProxyType>,
call: Box<<T as Config>::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::<T>::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.
Expand Down Expand Up @@ -552,7 +555,7 @@ pub mod pallet {
real: AccountIdLookupOf<T>,
force_proxy_type: Option<T::ProxyType>,
call: Box<<T as Config>::RuntimeCall>,
) -> DispatchResult {
) -> DispatchResultWithPostInfo {
ensure_signed(origin)?;
let delegate = T::Lookup::lookup(delegate)?;
let real = T::Lookup::lookup(real)?;
Expand All @@ -567,9 +570,11 @@ pub mod pallet {
})
.map_err(|_| Error::<T>::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.
Expand Down Expand Up @@ -1101,7 +1106,7 @@ impl<T: Config> Pallet<T> {
def: ProxyDefinition<T::AccountId, T::ProxyType, BlockNumberFor<T>>,
real: T::AccountId,
call: <T as Config>::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();
Expand All @@ -1127,13 +1132,17 @@ impl<T: Config> Pallet<T> {
_ => 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::<T>::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.
Expand Down
58 changes: 58 additions & 0 deletions pallets/proxy/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(|| {
Expand Down Expand Up @@ -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(|| {
Expand Down
Loading