Skip to content

Commit c4a3299

Browse files
committed
nit
1 parent a3b3812 commit c4a3299

File tree

1 file changed

+151
-35
lines changed
  • substrate/frame/proxy/src

1 file changed

+151
-35
lines changed

substrate/frame/proxy/src/lib.rs

+151-35
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ pub struct ProxyDefinition<AccountId, ProxyType, BlockNumber> {
7878
/// The maximun amount that can be transferred by this proxy.
7979
pub max_amount: Option<BalanceOf<T>>,
8080
/// The block number until which the limit is valid.
81-
pub valid_unil: BlockNumber,
81+
pub valid_until: BlockNumber,
8282
}
8383

8484
/// Details surrounding a specific instance of an announcement to make a call.
@@ -92,6 +92,26 @@ pub struct Announcement<AccountId, Hash, BlockNumber> {
9292
height: BlockNumber,
9393
}
9494

95+
/// The type of deposit
96+
#[derive(
97+
Encode,
98+
Decode,
99+
Clone,
100+
Copy,
101+
Eq,
102+
PartialEq,
103+
RuntimeDebug,
104+
MaxEncodedLen,
105+
TypeInfo,
106+
DecodeWithMemTracking,
107+
)]
108+
pub enum DepositKind {
109+
/// Proxy registration deposit
110+
Proxies,
111+
/// Announcement deposit
112+
Announcements,
113+
}
114+
95115
#[frame::pallet]
96116
pub mod pallet {
97117
use super::*;
@@ -147,17 +167,16 @@ pub mod pallet {
147167
#[pallet::constant]
148168
type MaxProxies: Get<u32>;
149169

170+
#[pallet::constant]
171+
type MaxTransferAmount: Get<BalanceOf<Self>>;
172+
150173
/// Weight information for extrinsics in this pallet.
151174
type WeightInfo: WeightInfo;
152175

153176
/// The maximum amount of time-delayed announcements that are allowed to be pending.
154177
#[pallet::constant]
155178
type MaxPending: Get<u32>;
156179

157-
#[pallet::constant]
158-
type MaxTransferAmount: Get<BalanceOf<Self>>;
159-
160-
161180
/// The type of hash used for hashing the call.
162181
type CallHasher: Hash;
163182

@@ -252,12 +271,10 @@ pub mod pallet {
252271
delegate: AccountIdLookupOf<T>,
253272
proxy_type: T::ProxyType,
254273
delay: BlockNumberFor<T>,
255-
max_amount: Option<BalanceOf<T>>,
256-
valid_unil: BlockNumberFor<T>,
257274
) -> DispatchResult {
258275
let who = ensure_signed(origin)?;
259276
let delegate = T::Lookup::lookup(delegate)?;
260-
Self::add_proxy_delegate(&who, delegate, proxy_type, delay, max_amount, valid_unil)
277+
Self::add_proxy_delegate(&who, delegate, proxy_type, delay)
261278
}
262279

263280
/// Unregister a proxy account for the sender.
@@ -319,16 +336,14 @@ pub mod pallet {
319336
proxy_type: T::ProxyType,
320337
delay: BlockNumberFor<T>,
321338
index: u16,
322-
max_amount: Option<BalanceOf<T>>,
323-
valid_unil: BlockNumberFor<T>,
324339
) -> DispatchResult {
325340
let who = ensure_signed(origin)?;
326341

327342
let pure = Self::pure_account(&who, &proxy_type, index, None);
328343
ensure!(!Proxies::<T>::contains_key(&pure), Error::<T>::Duplicate);
329344

330345
let proxy_def =
331-
ProxyDefinition { delegate: who.clone(), proxy_type: proxy_type.clone(), delay, max_amount, valid_unil };
346+
ProxyDefinition { delegate: who.clone(), proxy_type: proxy_type.clone(), delay };
332347
let bounded_proxies: BoundedVec<_, T::MaxProxies> =
333348
vec![proxy_def].try_into().map_err(|_| Error::<T>::TooMany)?;
334349

@@ -541,6 +556,105 @@ pub mod pallet {
541556

542557
Ok(())
543558
}
559+
560+
/// Poke / Adjust deposits made for proxies and announcements based on current values.
561+
/// This can be used by accounts to possibly lower their locked amount.
562+
///
563+
/// The dispatch origin for this call must be _Signed_.
564+
///
565+
/// The transaction fee is waived if the deposit amount has changed.
566+
///
567+
/// Emits `DepositPoked` if successful.
568+
#[pallet::call_index(10)]
569+
#[pallet::weight(T::WeightInfo::poke_deposit())]
570+
pub fn poke_deposit(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
571+
let who = ensure_signed(origin)?;
572+
let mut deposit_updated = false;
573+
574+
// Check and update proxy deposits
575+
Proxies::<T>::try_mutate_exists(&who, |maybe_proxies| -> DispatchResult {
576+
let (proxies, old_deposit) = maybe_proxies.take().unwrap_or_default();
577+
let maybe_new_deposit = Self::rejig_deposit(
578+
&who,
579+
old_deposit,
580+
T::ProxyDepositBase::get(),
581+
T::ProxyDepositFactor::get(),
582+
proxies.len(),
583+
)?;
584+
585+
match maybe_new_deposit {
586+
Some(new_deposit) if new_deposit != old_deposit => {
587+
*maybe_proxies = Some((proxies, new_deposit));
588+
deposit_updated = true;
589+
Self::deposit_event(Event::DepositPoked {
590+
who: who.clone(),
591+
kind: DepositKind::Proxies,
592+
old_deposit,
593+
new_deposit,
594+
});
595+
},
596+
Some(_) => {
597+
*maybe_proxies = Some((proxies, old_deposit));
598+
},
599+
None => {
600+
*maybe_proxies = None;
601+
if !old_deposit.is_zero() {
602+
deposit_updated = true;
603+
Self::deposit_event(Event::DepositPoked {
604+
who: who.clone(),
605+
kind: DepositKind::Proxies,
606+
old_deposit,
607+
new_deposit: BalanceOf::<T>::zero(),
608+
});
609+
}
610+
},
611+
}
612+
Ok(())
613+
})?;
614+
615+
// Check and update announcement deposits
616+
Announcements::<T>::try_mutate_exists(&who, |maybe_announcements| -> DispatchResult {
617+
let (announcements, old_deposit) = maybe_announcements.take().unwrap_or_default();
618+
let maybe_new_deposit = Self::rejig_deposit(
619+
&who,
620+
old_deposit,
621+
T::AnnouncementDepositBase::get(),
622+
T::AnnouncementDepositFactor::get(),
623+
announcements.len(),
624+
)?;
625+
626+
match maybe_new_deposit {
627+
Some(new_deposit) if new_deposit != old_deposit => {
628+
*maybe_announcements = Some((announcements, new_deposit));
629+
deposit_updated = true;
630+
Self::deposit_event(Event::DepositPoked {
631+
who: who.clone(),
632+
kind: DepositKind::Announcements,
633+
old_deposit,
634+
new_deposit,
635+
});
636+
},
637+
Some(_) => {
638+
*maybe_announcements = Some((announcements, old_deposit));
639+
},
640+
None => {
641+
*maybe_announcements = None;
642+
if !old_deposit.is_zero() {
643+
deposit_updated = true;
644+
Self::deposit_event(Event::DepositPoked {
645+
who: who.clone(),
646+
kind: DepositKind::Announcements,
647+
old_deposit,
648+
new_deposit: BalanceOf::<T>::zero(),
649+
});
650+
}
651+
},
652+
}
653+
Ok(())
654+
})?;
655+
656+
Ok(if deposit_updated { Pays::No.into() } else { Pays::Yes.into() })
657+
}
544658
}
545659

546660
#[pallet::event]
@@ -572,6 +686,13 @@ pub mod pallet {
572686
proxy_type: T::ProxyType,
573687
delay: BlockNumberFor<T>,
574688
},
689+
/// A deposit stored for proxies or announcements was poked / updated.
690+
DepositPoked {
691+
who: T::AccountId,
692+
kind: DepositKind,
693+
old_deposit: BalanceOf<T>,
694+
new_deposit: BalanceOf<T>,
695+
},
575696
}
576697

577698
#[pallet::error]
@@ -709,24 +830,14 @@ impl<T: Config> Pallet<T> {
709830
proxy_type: T::ProxyType,
710831
delay: BlockNumberFor<T>,
711832
max_amount: Option<BalanceOf<T>>,
712-
valid_unil: BlockNumberFor<T>,
833+
valid_until: BlockNumberFor<T>
713834
) -> DispatchResult {
714835
ensure!(delegator != &delegatee, Error::<T>::NoSelfProxy);
715836
Proxies::<T>::try_mutate(delegator, |(ref mut proxies, ref mut deposit)| {
716837
let proxy_def = ProxyDefinition {
717838
delegate: delegatee.clone(),
718839
proxy_type: proxy_type.clone(),
719840
delay,
720-
max_amount: if proxy_type == ProxyType::AnyWithLimit {
721-
max_amount
722-
} else {
723-
None
724-
},
725-
valid_unil: if proxy_type = ProxyType::AnyWithLimit {
726-
valid_unil
727-
} else {
728-
None
729-
},
730841
};
731842
let i = proxies.binary_search(&proxy_def).err().ok_or(Error::<T>::Duplicate)?;
732843
proxies.try_insert(i, proxy_def).map_err(|_| Error::<T>::TooMany)?;
@@ -819,9 +930,16 @@ impl<T: Config> Pallet<T> {
819930
let new_deposit =
820931
if len == 0 { BalanceOf::<T>::zero() } else { base + factor * (len as u32).into() };
821932
if new_deposit > old_deposit {
822-
T::Currency::reserve(who, new_deposit - old_deposit)?;
933+
T::Currency::reserve(who, new_deposit.saturating_sub(old_deposit))?;
823934
} else if new_deposit < old_deposit {
824-
T::Currency::unreserve(who, old_deposit - new_deposit);
935+
let excess = old_deposit.saturating_sub(new_deposit);
936+
let remaining_unreserved = T::Currency::unreserve(who, excess);
937+
if !remaining_unreserved.is_zero() {
938+
defensive!(
939+
"Failed to unreserve full amount. (Requested, Actual)",
940+
(excess, excess.saturating_sub(remaining_unreserved))
941+
);
942+
}
825943
}
826944
Ok(if len == 0 { None } else { Some(new_deposit) })
827945
}
@@ -884,24 +1002,22 @@ impl<T: Config> Pallet<T> {
8841002
Some(Call::remove_proxies { .. }) | Some(Call::kill_pure { .. })
8851003
if def.proxy_type != T::ProxyType::default() =>
8861004
false,
887-
// Enforce the max_amount and duration limits for `AnyWithLimit` proxies.
1005+
8881006
if def.proxy_type == ProxyType::AnyWithLimit {
889-
if let Some(Call::Balances(BalancesCall::transfer_allow_death { value, .. })) = c.is_sub_type() {
1007+
if let Some(Call::Balances(BalancesCall::transfer_allow_death { value, .. })) = c {
1008+
// Check the proxy's max_amount limit
8901009
if let Some(max_amount) = def.max_amount {
8911010
if *value > max_amount {
892-
return false;
1011+
return false; // Reject the call if it exceeds the proxy's limit
8931012
}
8941013
}
895-
// Check the duration limit
896-
if let Some(duration) = def.duration {
897-
let current_block = T::BlockNumberProvider::current_block_number();
898-
if current_block > def.delay + valid_unil {
899-
return false;
900-
}
1014+
// Check the global MaxTransferAmount limit
1015+
if *value > T::MaxTransferAmount::get() {
1016+
return false; // Reject the call if it exceeds the global limit
9011017
}
9021018
}
903-
def.proxy_type.filter(c),
9041019
}
1020+
def.proxy_type.filter(c),
9051021
}
9061022
});
9071023
let e = call.dispatch(origin);
@@ -916,4 +1032,4 @@ impl<T: Config> Pallet<T> {
9161032
let (_, old_deposit) = Proxies::<T>::take(&delegator);
9171033
T::Currency::unreserve(&delegator, old_deposit);
9181034
}
919-
}
1035+
}

0 commit comments

Comments
 (0)