-
Notifications
You must be signed in to change notification settings - Fork 2.7k
Introduce in-origin filtering #6318
Changes from 1 commit
97f9a31
705149d
a26b51c
2dae547
97c8f7e
49d759b
caec9f5
b444c5b
ae8ce23
9ce0ce9
cfbdaa4
faf13bc
b4a14e1
4ae8f9c
860396d
5c51b00
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
…ger bypass BasicCallFilter
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,12 +54,12 @@ use sp_std::prelude::*; | |
| use codec::{Encode, Decode}; | ||
| use sp_core::TypeId; | ||
| use sp_io::hashing::blake2_256; | ||
| use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure}; | ||
| use frame_support::{decl_module, decl_event, decl_storage, Parameter}; | ||
| use frame_support::{ | ||
| traits::{Filter, FilterStack, ClearFilterGuard, OriginTrait}, | ||
| traits::OriginTrait, | ||
| weights::{Weight, GetDispatchInfo, DispatchClass, FunctionOf, Pays}, dispatch::PostDispatchInfo, | ||
| }; | ||
| use frame_system::{self as system, ensure_signed, ensure_root}; | ||
| use frame_system::{self as system, ensure_signed}; | ||
| use sp_runtime::{DispatchError, DispatchResult, traits::Dispatchable}; | ||
|
|
||
| mod tests; | ||
|
|
@@ -73,22 +73,12 @@ pub trait Trait: frame_system::Trait { | |
| /// The overarching call type. | ||
| type Call: Parameter + Dispatchable<Origin=Self::Origin, PostInfo=PostDispatchInfo> | ||
| + GetDispatchInfo + From<frame_system::Call<Self>>; | ||
|
|
||
| /// Is a given call compatible with the proxying subsystem? | ||
| type IsCallable: FilterStack<<Self as Trait>::Call>; | ||
| } | ||
|
|
||
| decl_storage! { | ||
| trait Store for Module<T: Trait> as Utility {} | ||
| } | ||
|
|
||
| decl_error! { | ||
| pub enum Error for Module<T: Trait> { | ||
| /// A call with a `false` `IsCallable` filter was attempted. | ||
| Uncallable, | ||
| } | ||
| } | ||
|
|
||
| decl_event! { | ||
| /// Events type. | ||
| pub enum Event { | ||
|
|
@@ -97,8 +87,6 @@ decl_event! { | |
| BatchInterrupted(u32, DispatchError), | ||
| /// Batch of dispatches completed fully with no error. | ||
| BatchCompleted, | ||
| /// A call with a `false` IsCallable filter was attempted. | ||
| Uncallable(u32), | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -112,16 +100,11 @@ impl TypeId for IndexedUtilityModuleId { | |
|
|
||
| decl_module! { | ||
| pub struct Module<T: Trait> for enum Call where origin: T::Origin { | ||
| type Error = Error<T>; | ||
|
|
||
| /// Deposit one of this module's events by using the default implementation. | ||
| fn deposit_event() = default; | ||
|
|
||
| /// Send a batch of dispatch calls. | ||
| /// | ||
| /// This will execute until the first one fails and then stop. Calls must fulfil the | ||
| /// `IsCallable` filter unless the origin is `Root`. | ||
| /// | ||
| /// May be called from any origin. | ||
| /// | ||
| /// - `calls`: The calls to be dispatched from the same origin. | ||
|
|
@@ -156,12 +139,8 @@ decl_module! { | |
| Pays::Yes, | ||
| )] | ||
| fn batch(origin, calls: Vec<<T as Trait>::Call>) { | ||
| let is_root = ensure_root(origin.clone()).is_ok(); | ||
| for (index, call) in calls.into_iter().enumerate() { | ||
| if !is_root && !T::IsCallable::filter(&call) { | ||
| Self::deposit_event(Event::Uncallable(index as u32)); | ||
| return Ok(()) | ||
| } | ||
| // TODO TODO: root no longer bypass IsCallable filter. | ||
|
||
| let result = call.dispatch(origin.clone()); | ||
| if let Err(e) = result { | ||
| Self::deposit_event(Event::BatchInterrupted(index as u32, e.error)); | ||
|
|
@@ -173,9 +152,6 @@ decl_module! { | |
|
|
||
| /// Send a call through an indexed pseudonym of the sender. | ||
| /// | ||
| /// The call must fulfil only the pre-cleared `IsCallable` filter (i.e. only the level of | ||
| /// filtering that remains after calling `take()`). | ||
| /// | ||
| /// NOTE: If you need to ensure that any account-based filtering is honored (i.e. because | ||
| /// you expect `proxy` to have been used prior in the call stack and you want it to apply to | ||
| /// any sub-accounts), then use `as_limited_sub` instead. | ||
|
|
@@ -195,18 +171,17 @@ decl_module! { | |
| )] | ||
| fn as_sub(origin, index: u16, call: Box<<T as Trait>::Call>) -> DispatchResult { | ||
| let who = ensure_signed(origin)?; | ||
| // We're now executing as a freshly authenticated new account, so the previous call | ||
| // restrictions no longer apply. | ||
| let _guard = ClearFilterGuard::<T::IsCallable, <T as Trait>::Call>::new(); | ||
| ensure!(T::IsCallable::filter(&call), Error::<T>::Uncallable); | ||
|
|
||
| // This is a freshly authenticated new account, the origin restrictions doesn't apply. | ||
| let pseudonym = Self::sub_account_id(who, index); | ||
| call.dispatch(frame_system::RawOrigin::Signed(pseudonym).into()) | ||
| .map(|_| ()).map_err(|e| e.error) | ||
| } | ||
|
|
||
| /// Send a call through an indexed pseudonym of the sender. | ||
| /// | ||
| /// Calls must each fulfil the `IsCallable` filter; it is not cleared before. | ||
| /// Filter from origin are passed along. The call will be dispatched with an origin which | ||
| /// use the same filter as the origin of this call. | ||
| /// | ||
| /// NOTE: If you need to ensure that any account-based filtering is not honored (i.e. | ||
| /// because you expect `proxy` to have been used prior in the call stack and you do not want | ||
|
|
@@ -228,7 +203,6 @@ decl_module! { | |
| fn as_limited_sub(origin, index: u16, call: Box<<T as Trait>::Call>) -> DispatchResult { | ||
| let mut origin = origin; | ||
| let who = ensure_signed(origin.clone())?; | ||
| ensure!(T::IsCallable::filter(&call), Error::<T>::Uncallable); | ||
| let pseudonym = Self::sub_account_id(who, index); | ||
| origin.set_caller_from(frame_system::RawOrigin::Signed(pseudonym)); | ||
| call.dispatch(origin).map(|_| ()).map_err(|e| e.error) | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.