@@ -23,7 +23,7 @@ use super::*;
23
23
24
24
use frame_support:: {
25
25
assert_ok, assert_noop, impl_outer_origin, parameter_types, impl_outer_dispatch,
26
- weights:: Weight , impl_outer_event, RuntimeDebug , dispatch:: DispatchError
26
+ impl_filter_stack , weights:: Weight , impl_outer_event, RuntimeDebug , dispatch:: DispatchError
27
27
} ;
28
28
use codec:: { Encode , Decode } ;
29
29
use sp_core:: H256 ;
@@ -38,13 +38,15 @@ impl_outer_event! {
38
38
system<T >,
39
39
pallet_balances<T >,
40
40
proxy<T >,
41
+ pallet_utility,
41
42
}
42
43
}
43
44
impl_outer_dispatch ! {
44
45
pub enum Call for Test where origin: Origin {
45
46
frame_system:: System ,
46
47
pallet_balances:: Balances ,
47
48
proxy:: Proxy ,
49
+ pallet_utility:: Utility ,
48
50
}
49
51
}
50
52
@@ -94,30 +96,39 @@ impl pallet_balances::Trait for Test {
94
96
type ExistentialDeposit = ExistentialDeposit ;
95
97
type AccountStore = System ;
96
98
}
99
+ impl pallet_utility:: Trait for Test {
100
+ type Event = TestEvent ;
101
+ type Call = Call ;
102
+ type IsCallable = IsCallable ;
103
+ }
97
104
parameter_types ! {
98
105
pub const ProxyDepositBase : u64 = 1 ;
99
106
pub const ProxyDepositFactor : u64 = 1 ;
100
- pub const MaxProxies : u16 = 3 ;
107
+ pub const MaxProxies : u16 = 4 ;
101
108
}
109
+ pub struct IsCallable ;
110
+ impl_filter_stack ! ( crate :: tests:: IsCallable , crate :: tests:: BaseFilter , crate :: tests:: Call , is_callable) ;
102
111
#[ derive( Copy , Clone , Eq , PartialEq , Ord , PartialOrd , Encode , Decode , RuntimeDebug ) ]
103
112
pub enum ProxyType {
104
113
Any ,
105
114
JustTransfer ,
115
+ JustUtility ,
106
116
}
107
117
impl Default for ProxyType { fn default ( ) -> Self { Self :: Any } }
108
118
impl InstanceFilter < Call > for ProxyType {
109
119
fn filter ( & self , c : & Call ) -> bool {
110
120
match self {
111
121
ProxyType :: Any => true ,
112
- ProxyType :: JustTransfer => match c {
113
- Call :: Balances ( pallet_balances:: Call :: transfer( ..) ) => true ,
114
- _ => false ,
115
- }
122
+ ProxyType :: JustTransfer => matches ! ( c, Call :: Balances ( pallet_balances:: Call :: transfer( ..) ) ) ,
123
+ ProxyType :: JustUtility => matches ! ( c, Call :: Utility ( ..) ) ,
116
124
}
117
125
}
126
+ fn is_superset ( & self , o : & Self ) -> bool {
127
+ self == & ProxyType :: Any || self == o
128
+ }
118
129
}
119
- pub struct TestIsCallable ;
120
- impl Filter < Call > for TestIsCallable {
130
+ pub struct BaseFilter ;
131
+ impl Filter < Call > for BaseFilter {
121
132
fn filter ( c : & Call ) -> bool {
122
133
match * c {
123
134
// Remark is used as a no-op call in the benchmarking
@@ -131,7 +142,7 @@ impl Trait for Test {
131
142
type Event = TestEvent ;
132
143
type Call = Call ;
133
144
type Currency = Balances ;
134
- type IsCallable = TestIsCallable ;
145
+ type IsCallable = IsCallable ;
135
146
type ProxyType = ProxyType ;
136
147
type ProxyDepositBase = ProxyDepositBase ;
137
148
type ProxyDepositFactor = ProxyDepositFactor ;
@@ -140,11 +151,15 @@ impl Trait for Test {
140
151
141
152
type System = frame_system:: Module < Test > ;
142
153
type Balances = pallet_balances:: Module < Test > ;
154
+ type Utility = pallet_utility:: Module < Test > ;
143
155
type Proxy = Module < Test > ;
144
156
145
157
use frame_system:: Call as SystemCall ;
146
158
use pallet_balances:: Call as BalancesCall ;
147
159
use pallet_balances:: Error as BalancesError ;
160
+ use pallet_utility:: Call as UtilityCall ;
161
+ use pallet_utility:: Error as UtilityError ;
162
+ use pallet_utility:: Event as UtilityEvent ;
148
163
use super :: Call as ProxyCall ;
149
164
150
165
pub fn new_test_ext ( ) -> sp_io:: TestExternalities {
@@ -165,6 +180,65 @@ fn expect_event<E: Into<TestEvent>>(e: E) {
165
180
assert_eq ! ( last_event( ) , e. into( ) ) ;
166
181
}
167
182
183
+ fn last_events ( n : usize ) -> Vec < TestEvent > {
184
+ system:: Module :: < Test > :: events ( ) . into_iter ( ) . rev ( ) . take ( n) . rev ( ) . map ( |e| e. event ) . collect ( )
185
+ }
186
+
187
+ fn expect_events ( e : Vec < TestEvent > ) {
188
+ assert_eq ! ( last_events( e. len( ) ) , e) ;
189
+ }
190
+
191
+ #[ test]
192
+ fn filtering_works ( ) {
193
+ new_test_ext ( ) . execute_with ( || {
194
+ Balances :: mutate_account ( & 1 , |a| a. free = 1000 ) ;
195
+ assert_ok ! ( Proxy :: add_proxy( Origin :: signed( 1 ) , 2 , ProxyType :: Any ) ) ;
196
+ assert_ok ! ( Proxy :: add_proxy( Origin :: signed( 1 ) , 3 , ProxyType :: JustTransfer ) ) ;
197
+ assert_ok ! ( Proxy :: add_proxy( Origin :: signed( 1 ) , 4 , ProxyType :: JustUtility ) ) ;
198
+
199
+ let call = Box :: new ( Call :: Balances ( BalancesCall :: transfer ( 6 , 1 ) ) ) ;
200
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 2 ) , 1 , None , call. clone( ) ) ) ;
201
+ expect_event ( RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) ) ;
202
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 3 ) , 1 , None , call. clone( ) ) ) ;
203
+ expect_event ( RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) ) ;
204
+ assert_noop ! ( Proxy :: proxy( Origin :: signed( 4 ) , 1 , None , call. clone( ) ) , Error :: <Test >:: Uncallable ) ;
205
+
206
+ let sub_id = Utility :: sub_account_id ( 1 , 0 ) ;
207
+ Balances :: mutate_account ( & sub_id, |a| a. free = 1000 ) ;
208
+ let inner = Box :: new ( Call :: Balances ( BalancesCall :: transfer ( 6 , 1 ) ) ) ;
209
+
210
+ let call = Box :: new ( Call :: Utility ( UtilityCall :: as_sub ( 0 , inner. clone ( ) ) ) ) ;
211
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 2 ) , 1 , None , call. clone( ) ) ) ;
212
+ expect_event ( RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) ) ;
213
+ assert_noop ! ( Proxy :: proxy( Origin :: signed( 3 ) , 1 , None , call. clone( ) ) , Error :: <Test >:: Uncallable ) ;
214
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 4 ) , 1 , None , call. clone( ) ) ) ;
215
+ expect_event ( RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) ) ;
216
+
217
+ let call = Box :: new ( Call :: Utility ( UtilityCall :: as_limited_sub ( 0 , inner. clone ( ) ) ) ) ;
218
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 2 ) , 1 , None , call. clone( ) ) ) ;
219
+ expect_event ( RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) ) ;
220
+ assert_noop ! ( Proxy :: proxy( Origin :: signed( 3 ) , 1 , None , call. clone( ) ) , Error :: <Test >:: Uncallable ) ;
221
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 4 ) , 1 , None , call. clone( ) ) ) ;
222
+ let de = DispatchError :: from ( UtilityError :: < Test > :: Uncallable ) . stripped ( ) ;
223
+ expect_event ( RawEvent :: ProxyExecuted ( Err ( de) ) ) ;
224
+
225
+ let call = Box :: new ( Call :: Utility ( UtilityCall :: batch ( vec ! [ * inner] ) ) ) ;
226
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 2 ) , 1 , None , call. clone( ) ) ) ;
227
+ expect_events ( vec ! [ UtilityEvent :: BatchCompleted . into( ) , RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) . into( ) ] ) ;
228
+ assert_noop ! ( Proxy :: proxy( Origin :: signed( 3 ) , 1 , None , call. clone( ) ) , Error :: <Test >:: Uncallable ) ;
229
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 4 ) , 1 , None , call. clone( ) ) ) ;
230
+ expect_events ( vec ! [ UtilityEvent :: Uncallable ( 0 ) . into( ) , RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) . into( ) ] ) ;
231
+
232
+ let inner = Box :: new ( Call :: Proxy ( ProxyCall :: add_proxy ( 5 , ProxyType :: Any ) ) ) ;
233
+ let call = Box :: new ( Call :: Utility ( UtilityCall :: batch ( vec ! [ * inner] ) ) ) ;
234
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 2 ) , 1 , None , call. clone( ) ) ) ;
235
+ expect_events ( vec ! [ UtilityEvent :: BatchCompleted . into( ) , RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) . into( ) ] ) ;
236
+ assert_noop ! ( Proxy :: proxy( Origin :: signed( 3 ) , 1 , None , call. clone( ) ) , Error :: <Test >:: Uncallable ) ;
237
+ assert_ok ! ( Proxy :: proxy( Origin :: signed( 4 ) , 1 , None , call. clone( ) ) ) ;
238
+ expect_events ( vec ! [ UtilityEvent :: Uncallable ( 0 ) . into( ) , RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) . into( ) ] ) ;
239
+ } ) ;
240
+ }
241
+
168
242
#[ test]
169
243
fn add_remove_proxies_works ( ) {
170
244
new_test_ext ( ) . execute_with ( || {
@@ -175,8 +249,12 @@ fn add_remove_proxies_works() {
175
249
assert_eq ! ( Balances :: reserved_balance( 1 ) , 3 ) ;
176
250
assert_ok ! ( Proxy :: add_proxy( Origin :: signed( 1 ) , 3 , ProxyType :: Any ) ) ;
177
251
assert_eq ! ( Balances :: reserved_balance( 1 ) , 4 ) ;
252
+ assert_ok ! ( Proxy :: add_proxy( Origin :: signed( 1 ) , 4 , ProxyType :: JustUtility ) ) ;
253
+ assert_eq ! ( Balances :: reserved_balance( 1 ) , 5 ) ;
178
254
assert_noop ! ( Proxy :: add_proxy( Origin :: signed( 1 ) , 4 , ProxyType :: Any ) , Error :: <Test >:: TooMany ) ;
179
255
assert_noop ! ( Proxy :: remove_proxy( Origin :: signed( 1 ) , 3 , ProxyType :: JustTransfer ) , Error :: <Test >:: NotFound ) ;
256
+ assert_ok ! ( Proxy :: remove_proxy( Origin :: signed( 1 ) , 4 , ProxyType :: JustUtility ) ) ;
257
+ assert_eq ! ( Balances :: reserved_balance( 1 ) , 4 ) ;
180
258
assert_ok ! ( Proxy :: remove_proxy( Origin :: signed( 1 ) , 3 , ProxyType :: Any ) ) ;
181
259
assert_eq ! ( Balances :: reserved_balance( 1 ) , 3 ) ;
182
260
assert_ok ! ( Proxy :: remove_proxy( Origin :: signed( 1 ) , 2 , ProxyType :: Any ) ) ;
@@ -218,7 +296,7 @@ fn proxying_works() {
218
296
assert_noop ! ( Proxy :: proxy( Origin :: signed( 3 ) , 1 , None , call. clone( ) ) , Error :: <Test >:: Uncallable ) ;
219
297
220
298
let call = Box :: new ( Call :: Balances ( BalancesCall :: transfer_keep_alive ( 6 , 1 ) ) ) ;
221
- assert_noop ! ( Proxy :: proxy( Origin :: signed( 2 ) , 1 , None , call. clone( ) ) , Error :: <Test >:: Unproxyable ) ;
299
+ assert_noop ! ( Proxy :: proxy( Origin :: signed( 2 ) , 1 , None , call. clone( ) ) , Error :: <Test >:: Uncallable ) ;
222
300
assert_ok ! ( Proxy :: proxy( Origin :: signed( 3 ) , 1 , None , call. clone( ) ) ) ;
223
301
expect_event ( RawEvent :: ProxyExecuted ( Ok ( ( ) ) ) ) ;
224
302
assert_eq ! ( Balances :: free_balance( 6 ) , 2 ) ;
0 commit comments