diff --git a/substrate/frame/proxy/src/tests.rs b/substrate/frame/proxy/src/tests.rs index 72c9c0d577c2a45a91b9180a2e84076ce2b7f5dd..63d5c9e575d9cf81c9189237f52a6da1db60e15a 100644 --- a/substrate/frame/proxy/src/tests.rs +++ b/substrate/frame/proxy/src/tests.rs @@ -201,19 +201,11 @@ fn filtering_works() { assert_ok!(Proxy::proxy(Origin::signed(4), 1, None, call.clone())); expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); - let sub_id = Utility::sub_account_id(1, 0); - Balances::mutate_account(&sub_id, |a| a.free = 1000); + let derivative_id = Utility::derivative_account_id(1, 0); + Balances::mutate_account(&derivative_id, |a| a.free = 1000); let inner = Box::new(Call::Balances(BalancesCall::transfer(6, 1))); - let call = Box::new(Call::Utility(UtilityCall::as_sub(0, inner.clone()))); - assert_ok!(Proxy::proxy(Origin::signed(2), 1, None, call.clone())); - expect_event(RawEvent::ProxyExecuted(Ok(()))); - assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); - expect_event(RawEvent::ProxyExecuted(Err(DispatchError::BadOrigin))); - assert_ok!(Proxy::proxy(Origin::signed(4), 1, None, call.clone())); - expect_event(RawEvent::ProxyExecuted(Ok(()))); - - let call = Box::new(Call::Utility(UtilityCall::as_limited_sub(0, inner.clone()))); + let call = Box::new(Call::Utility(UtilityCall::as_derivative(0, inner.clone()))); assert_ok!(Proxy::proxy(Origin::signed(2), 1, None, call.clone())); expect_event(RawEvent::ProxyExecuted(Ok(()))); assert_ok!(Proxy::proxy(Origin::signed(3), 1, None, call.clone())); diff --git a/substrate/frame/utility/src/benchmarking.rs b/substrate/frame/utility/src/benchmarking.rs index 27696404bf4a286ddcd58d0aab72d018e65c66a9..8d9817895766d0ddb36bf46e2786768af4a2bf61 100644 --- a/substrate/frame/utility/src/benchmarking.rs +++ b/substrate/frame/utility/src/benchmarking.rs @@ -38,13 +38,7 @@ benchmarks! { let caller = account("caller", 0, SEED); }: _(RawOrigin::Signed(caller), calls) - as_sub { - let u in 0 .. 1000; - let caller = account("caller", u, SEED); - let call = Box::new(frame_system::Call::remark(vec![]).into()); - }: _(RawOrigin::Signed(caller), u as u16, call) - - as_limited_sub { + as_derivative { let u in 0 .. 1000; let caller = account("caller", u, SEED); let call = Box::new(frame_system::Call::remark(vec![]).into()); @@ -61,8 +55,7 @@ mod tests { fn test_benchmarks() { new_test_ext().execute_with(|| { assert_ok!(test_benchmark_batch::<Test>()); - assert_ok!(test_benchmark_as_sub::<Test>()); - assert_ok!(test_benchmark_as_limited_sub::<Test>()); + assert_ok!(test_benchmark_as_derivative::<Test>()); }); } } diff --git a/substrate/frame/utility/src/lib.rs b/substrate/frame/utility/src/lib.rs index 3759a2afcd814ce0afe443f683679d7d486f400e..47ca4f13e7c55ae5ab28e06678af4ea03a3818b6 100644 --- a/substrate/frame/utility/src/lib.rs +++ b/substrate/frame/utility/src/lib.rs @@ -16,7 +16,7 @@ // limitations under the License. //! # Utility Module -//! A stateless module with helpers for dispatch management. +//! A stateless module with helpers for dispatch management which does no re-authentication. //! //! - [`utility::Trait`](./trait.Trait.html) //! - [`Call`](./enum.Call.html) @@ -29,10 +29,15 @@ //! corresponding `set_storage`s, for efficient multiple payouts with just a single signature //! verify, or in combination with one of the other two dispatch functionality. //! - Pseudonymal dispatch: A stateless operation, allowing a signed origin to execute a call from -//! an alternative signed origin. Each account has 2**16 possible "pseudonyms" (alternative +//! an alternative signed origin. Each account has 2 * 2**16 possible "pseudonyms" (alternative //! account IDs) and these can be stacked. This can be useful as a key management tool, where you //! need multiple distinct accounts (e.g. as controllers for many staking accounts), but where //! it's perfectly fine to have each of them controlled by the same underlying keypair. +//! Derivative accounts are, for the purposes of proxy filtering considered exactly the same as +//! the oigin and are thus hampered with the origin's filters. +//! +//! Since proxy filters are respected in all dispatches of this module, it should never need to be +//! filtered by any proxy. //! //! ## Interface //! @@ -42,7 +47,7 @@ //! * `batch` - Dispatch multiple calls from the sender's origin. //! //! #### For pseudonymal dispatch -//! * `as_sub` - Dispatch a call from a secondary ("sub") signed origin. +//! * `as_derivative` - Dispatch a call from a derivative signed origin. //! //! [`Call`]: ./enum.Call.html //! [`Trait`]: ./trait.Trait.html @@ -155,31 +160,6 @@ decl_module! { Self::deposit_event(Event::BatchCompleted); } - /// Send a call through an indexed pseudonym of the sender. - /// - /// 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. - /// - /// The dispatch origin for this call must be _Signed_. - /// - /// # <weight> - /// - Base weight: 2.861 µs - /// - Plus the weight of the `call` - /// # </weight> - #[weight = ( - call.get_dispatch_info().weight.saturating_add(3_000_000), - call.get_dispatch_info().class, - )] - fn as_sub(origin, index: u16, call: Box<<T as Trait>::Call>) -> DispatchResult { - let who = ensure_signed(origin)?; - - // 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. /// /// Filter from origin are passed along. The call will be dispatched with an origin which @@ -187,7 +167,10 @@ decl_module! { /// /// 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 - /// the call restrictions to apply to any sub-accounts), then use `as_sub` instead. + /// the call restrictions to apply to any sub-accounts), then use `as_multi_threshold_1` + /// in the Multisig pallet instead. + /// + /// NOTE: Prior to version *12, this was called `as_limited_sub`. /// /// The dispatch origin for this call must be _Signed_. /// @@ -199,10 +182,10 @@ decl_module! { call.get_dispatch_info().weight.saturating_add(3_000_000), call.get_dispatch_info().class, )] - fn as_limited_sub(origin, index: u16, call: Box<<T as Trait>::Call>) -> DispatchResult { + fn as_derivative(origin, index: u16, call: Box<<T as Trait>::Call>) -> DispatchResult { let mut origin = origin; let who = ensure_signed(origin.clone())?; - let pseudonym = Self::sub_account_id(who, index); + let pseudonym = Self::derivative_account_id(who, index); origin.set_caller_from(frame_system::RawOrigin::Signed(pseudonym)); call.dispatch(origin).map(|_| ()).map_err(|e| e.error) } @@ -210,8 +193,8 @@ decl_module! { } impl<T: Trait> Module<T> { - /// Derive a sub-account ID from the owner account and the sub-account index. - pub fn sub_account_id(who: T::AccountId, index: u16) -> T::AccountId { + /// Derive a derivative account ID from the owner account and the sub-account index. + pub fn derivative_account_id(who: T::AccountId, index: u16) -> T::AccountId { let entropy = (b"modlpy/utilisuba", who, index).using_encoded(blake2_256); T::AccountId::decode(&mut &entropy[..]).unwrap_or_default() } diff --git a/substrate/frame/utility/src/tests.rs b/substrate/frame/utility/src/tests.rs index e0f8426d289412e41c33d9b747504dd31c169c83..c0a64992508ae9d6499a546493585aa27c0012e8 100644 --- a/substrate/frame/utility/src/tests.rs +++ b/substrate/frame/utility/src/tests.rs @@ -138,16 +138,16 @@ fn expect_event<E: Into<TestEvent>>(e: E) { } #[test] -fn as_sub_works() { +fn as_derivative_works() { new_test_ext().execute_with(|| { - let sub_1_0 = Utility::sub_account_id(1, 0); + let sub_1_0 = Utility::derivative_account_id(1, 0); assert_ok!(Balances::transfer(Origin::signed(1), sub_1_0, 5)); - assert_noop!(Utility::as_sub( + assert_noop!(Utility::as_derivative( Origin::signed(1), 1, Box::new(Call::Balances(BalancesCall::transfer(6, 3))), ), BalancesError::<Test, _>::InsufficientBalance); - assert_ok!(Utility::as_sub( + assert_ok!(Utility::as_derivative( Origin::signed(1), 0, Box::new(Call::Balances(BalancesCall::transfer(2, 3))), @@ -158,9 +158,9 @@ fn as_sub_works() { } #[test] -fn as_sub_filters() { +fn as_derivative_filters() { new_test_ext().execute_with(|| { - assert_noop!(Utility::as_sub( + assert_noop!(Utility::as_derivative( Origin::signed(1), 1, Box::new(Call::System(frame_system::Call::remark(vec![]))),