5555//! [`LastSeen`](pallet::LastSeen). This can refine the limit scope (for example by returning a
5656//! tuple of `(netuid, hyperparameter)`).
5757//!
58- //! Each resolver receives the call and may return `Some(identifier)` when scoping is required, or
59- //! `None` to use the global entry. Extrinsics such as
58+ //! Each resolver receives the origin and call and may return `Some(identifier)` when scoping is
59+ //! required, or `None` to use the global entry. Extrinsics such as
6060//! [`set_rate_limit`](pallet::Pallet::set_rate_limit) automatically consult these resolvers.
6161//!
6262//! ```ignore
6363//! pub struct WeightsContextResolver;
6464//!
6565//! // Limits are scoped per netuid.
6666//! pub struct ScopeResolver;
67- //! impl pallet_rate_limiting::RateLimitScopeResolver<RuntimeCall, NetUid, BlockNumber> for ScopeResolver {
68- //! fn context(call: &RuntimeCall) -> Option<NetUid> {
67+ //! impl pallet_rate_limiting::RateLimitScopeResolver<
68+ //! RuntimeOrigin,
69+ //! RuntimeCall,
70+ //! NetUid,
71+ //! BlockNumber,
72+ //! > for ScopeResolver {
73+ //! fn context(origin: &RuntimeOrigin, call: &RuntimeCall) -> Option<NetUid> {
6974//! match call {
7075//! RuntimeCall::Subtensor(pallet_subtensor::Call::set_weights { netuid, .. }) => {
7176//! Some(*netuid)
7479//! }
7580//! }
7681//!
77- //! fn adjust_span(_call: &RuntimeCall, span: BlockNumber) -> BlockNumber {
82+ //! fn should_bypass(origin: &RuntimeOrigin, _call: &RuntimeCall) -> bool {
83+ //! matches!(origin, RuntimeOrigin::Root)
84+ //! }
85+ //!
86+ //! fn adjust_span(_origin: &RuntimeOrigin, _call: &RuntimeCall, span: BlockNumber) -> BlockNumber {
7887//! span
7988//! }
8089//! }
8190//!
8291//! // Usage tracking distinguishes hyperparameter + netuid.
8392//! pub struct UsageResolver;
84- //! impl pallet_rate_limiting::RateLimitUsageResolver<RuntimeCall, (NetUid, HyperParam)> for UsageResolver {
85- //! fn context(call: &RuntimeCall) -> Option<(NetUid, HyperParam)> {
93+ //! impl pallet_rate_limiting::RateLimitUsageResolver<
94+ //! RuntimeOrigin,
95+ //! RuntimeCall,
96+ //! (NetUid, HyperParam),
97+ //! > for UsageResolver {
98+ //! fn context(_origin: &RuntimeOrigin, call: &RuntimeCall) -> Option<(NetUid, HyperParam)> {
8699//! match call {
87100//! RuntimeCall::Subtensor(pallet_subtensor::Call::set_hyperparam {
88101//! netuid,
@@ -128,10 +141,10 @@ pub mod pallet {
128141 use codec:: Codec ;
129142 use frame_support:: {
130143 pallet_prelude:: * ,
131- sp_runtime:: traits:: { Saturating , Zero } ,
132144 traits:: { BuildGenesisConfig , EnsureOrigin , GetCallMetadata } ,
133145 } ;
134146 use frame_system:: pallet_prelude:: * ;
147+ use sp_runtime:: traits:: { DispatchOriginOf , Dispatchable , Saturating , Zero } ;
135148 use sp_std:: { convert:: TryFrom , marker:: PhantomData , vec:: Vec } ;
136149
137150 #[ cfg( feature = "runtime-benchmarks" ) ]
@@ -146,11 +159,14 @@ pub mod pallet {
146159 pub trait Config < I : ' static = ( ) > : frame_system:: Config
147160 where
148161 BlockNumberFor < Self > : MaybeSerializeDeserialize ,
162+ <<Self as Config < I > >:: RuntimeCall as Dispatchable >:: RuntimeOrigin :
163+ From < <Self as frame_system:: Config >:: RuntimeOrigin > ,
149164 {
150165 /// The overarching runtime call type.
151166 type RuntimeCall : Parameter
152167 + Codec
153168 + GetCallMetadata
169+ + Dispatchable
154170 + IsType < <Self as frame_system:: Config >:: RuntimeCall > ;
155171
156172 /// Origin permitted to configure rate limits.
@@ -161,6 +177,7 @@ pub mod pallet {
161177
162178 /// Resolves the scope for the given runtime call when configuring limits.
163179 type LimitScopeResolver : RateLimitScopeResolver <
180+ DispatchOriginOf < <Self as Config < I > >:: RuntimeCall > ,
164181 <Self as Config < I > >:: RuntimeCall ,
165182 Self :: LimitScope ,
166183 BlockNumberFor < Self > ,
@@ -170,7 +187,11 @@ pub mod pallet {
170187 type UsageKey : Parameter + Clone + PartialEq + Eq + Ord + MaybeSerializeDeserialize ;
171188
172189 /// Resolves the usage key for the given runtime call when enforcing limits.
173- type UsageResolver : RateLimitUsageResolver < <Self as Config < I > >:: RuntimeCall , Self :: UsageKey > ;
190+ type UsageResolver : RateLimitUsageResolver <
191+ DispatchOriginOf < <Self as Config < I > >:: RuntimeCall > ,
192+ <Self as Config < I > >:: RuntimeCall ,
193+ Self :: UsageKey ,
194+ > ;
174195
175196 /// Helper used to construct runtime calls for benchmarking.
176197 #[ cfg( feature = "runtime-benchmarks" ) ]
@@ -311,16 +332,17 @@ pub mod pallet {
311332 /// Returns `true` when the given transaction identifier passes its configured rate limit
312333 /// within the provided usage scope.
313334 pub fn is_within_limit (
335+ origin : & DispatchOriginOf < <T as Config < I > >:: RuntimeCall > ,
336+ call : & <T as Config < I > >:: RuntimeCall ,
314337 identifier : & TransactionIdentifier ,
315338 scope : & Option < <T as Config < I > >:: LimitScope > ,
316339 usage_key : & Option < <T as Config < I > >:: UsageKey > ,
317- call : & <T as Config < I > >:: RuntimeCall ,
318340 ) -> Result < bool , DispatchError > {
319- if <T as Config < I > >:: LimitScopeResolver :: should_bypass ( call) {
341+ if <T as Config < I > >:: LimitScopeResolver :: should_bypass ( origin , call) {
320342 return Ok ( true ) ;
321343 }
322344
323- let Some ( block_span) = Self :: effective_span ( call, identifier, scope) else {
345+ let Some ( block_span) = Self :: effective_span ( origin , call, identifier, scope) else {
324346 return Ok ( true ) ;
325347 } ;
326348
@@ -340,13 +362,14 @@ pub mod pallet {
340362 }
341363
342364 pub ( crate ) fn effective_span (
365+ origin : & DispatchOriginOf < <T as Config < I > >:: RuntimeCall > ,
343366 call : & <T as Config < I > >:: RuntimeCall ,
344367 identifier : & TransactionIdentifier ,
345368 scope : & Option < <T as Config < I > >:: LimitScope > ,
346369 ) -> Option < BlockNumberFor < T > > {
347370 let span = Self :: resolved_limit ( identifier, scope) ?;
348371 Some ( <T as Config < I > >:: LimitScopeResolver :: adjust_span (
349- call, span,
372+ origin , call, span,
350373 ) )
351374 }
352375
@@ -491,11 +514,15 @@ pub mod pallet {
491514 call : Box < <T as Config < I > >:: RuntimeCall > ,
492515 limit : RateLimitKind < BlockNumberFor < T > > ,
493516 ) -> DispatchResult {
517+ let resolver_origin: DispatchOriginOf < <T as Config < I > >:: RuntimeCall > =
518+ Into :: < DispatchOriginOf < <T as Config < I > >:: RuntimeCall > > :: into ( origin. clone ( ) ) ;
519+ let scope =
520+ <T as Config < I > >:: LimitScopeResolver :: context ( & resolver_origin, call. as_ref ( ) ) ;
521+ let scope_for_event = scope. clone ( ) ;
522+
494523 T :: AdminOrigin :: ensure_origin ( origin) ?;
495524
496525 let identifier = TransactionIdentifier :: from_call :: < T , I > ( call. as_ref ( ) ) ?;
497- let scope = <T as Config < I > >:: LimitScopeResolver :: context ( call. as_ref ( ) ) ;
498- let scope_for_event = scope. clone ( ) ;
499526
500527 if let Some ( ref sc) = scope {
501528 Limits :: < T , I > :: mutate ( & identifier, |slot| match slot {
@@ -532,11 +559,15 @@ pub mod pallet {
532559 origin : OriginFor < T > ,
533560 call : Box < <T as Config < I > >:: RuntimeCall > ,
534561 ) -> DispatchResult {
562+ let resolver_origin: DispatchOriginOf < <T as Config < I > >:: RuntimeCall > =
563+ Into :: < DispatchOriginOf < <T as Config < I > >:: RuntimeCall > > :: into ( origin. clone ( ) ) ;
564+ let scope =
565+ <T as Config < I > >:: LimitScopeResolver :: context ( & resolver_origin, call. as_ref ( ) ) ;
566+ let usage = <T as Config < I > >:: UsageResolver :: context ( & resolver_origin, call. as_ref ( ) ) ;
567+
535568 T :: AdminOrigin :: ensure_origin ( origin) ?;
536569
537570 let identifier = TransactionIdentifier :: from_call :: < T , I > ( call. as_ref ( ) ) ?;
538- let scope = <T as Config < I > >:: LimitScopeResolver :: context ( call. as_ref ( ) ) ;
539- let usage = <T as Config < I > >:: UsageResolver :: context ( call. as_ref ( ) ) ;
540571
541572 let ( pallet_name, extrinsic_name) = identifier. names :: < T , I > ( ) ?;
542573 let pallet = Vec :: from ( pallet_name. as_bytes ( ) ) ;
0 commit comments