diff --git a/frame/multisig/src/benchmarking.rs b/frame/multisig/src/benchmarking.rs index b530a96396024..63a178313addd 100644 --- a/frame/multisig/src/benchmarking.rs +++ b/frame/multisig/src/benchmarking.rs @@ -25,7 +25,7 @@ use frame_benchmarking::{benchmarks, account, impl_benchmark_test_suite}; use sp_runtime::traits::Bounded; use core::convert::TryInto; -use crate::Module as Multisig; +use crate::Pallet as Multisig; const SEED: u32 = 0; diff --git a/frame/multisig/src/lib.rs b/frame/multisig/src/lib.rs index 8c8e1c0dbc436..bbb41e7a9287a 100644 --- a/frame/multisig/src/lib.rs +++ b/frame/multisig/src/lib.rs @@ -15,15 +15,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Multisig Module -//! A module for doing multisig dispatch. +//! # Multisig pallet +//! A pallet for doing multisig dispatch. //! //! - [`Config`] //! - [`Call`] //! //! ## Overview //! -//! This module contains functionality for multi-signature dispatch, a (potentially) stateful +//! This pallet contains functionality for multi-signature dispatch, a (potentially) stateful //! operation, allowing multiple signed //! origins (accounts) to coordinate and dispatch a call from a well-known origin, derivable //! deterministically from the set of account IDs and the threshold number of accounts from the @@ -53,51 +53,21 @@ pub mod weights; use sp_std::prelude::*; use codec::{Encode, Decode}; use sp_io::hashing::blake2_256; -use frame_support::{decl_module, decl_event, decl_error, decl_storage, Parameter, ensure, RuntimeDebug}; +use frame_support::{ensure, RuntimeDebug}; use frame_support::{traits::{Get, ReservableCurrency, Currency}, weights::{Weight, GetDispatchInfo}, - dispatch::{DispatchResultWithPostInfo, DispatchErrorWithPostInfo, PostDispatchInfo}, + dispatch::{DispatchResultWithPostInfo, DispatchResult, DispatchErrorWithPostInfo, PostDispatchInfo}, }; -use frame_system::{self as system, ensure_signed, RawOrigin}; -use sp_runtime::{DispatchError, DispatchResult, traits::{Dispatchable, Zero}}; +use frame_system::{self as system, RawOrigin}; +use sp_runtime::{DispatchError, traits::{Dispatchable, Zero}}; pub use weights::WeightInfo; +pub use pallet::*; + type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; /// Just a bunch of bytes, but they should decode to a valid `Call`. pub type OpaqueCall = Vec; -/// Configuration trait. -pub trait Config: frame_system::Config { - /// The overarching event type. - type Event: From> + Into<::Event>; - - /// The overarching call type. - type Call: Parameter + Dispatchable - + GetDispatchInfo + From>; - - /// The currency mechanism. - type Currency: ReservableCurrency; - - /// The base amount of currency needed to reserve for creating a multisig execution or to store - /// a dispatch call for later. - /// - /// This is held for an additional storage item whose value size is - /// `4 + sizeof((BlockNumber, Balance, AccountId))` bytes and whose key size is - /// `32 + sizeof(AccountId)` bytes. - type DepositBase: Get>; - - /// The amount of currency needed per unit threshold when creating a multisig execution. - /// - /// This is held for adding 32 bytes more into a pre-existing storage value. - type DepositFactor: Get>; - - /// The maximum amount of signatories allowed in the multisig. - type MaxSignatories: Get; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; -} - /// A global extrinsic index, formed as the extrinsic index within a block, together with that /// block's height. This allows a transaction in which a multisig operation of a particular /// composite was created to be uniquely identified. @@ -122,19 +92,79 @@ pub struct Multisig { approvals: Vec, } -decl_storage! { - trait Store for Module as Multisig { - /// The set of open multisig operations. - pub Multisigs: double_map - hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) [u8; 32] - => Option, T::AccountId>>; +type CallHash = [u8; 32]; - pub Calls: map hasher(identity) [u8; 32] => Option<(OpaqueCall, T::AccountId, BalanceOf)>; - } +enum CallOrHash { + Call(OpaqueCall, bool), + Hash([u8; 32]), } -decl_error! { - pub enum Error for Module { +#[frame_support::pallet] +pub mod pallet{ + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type Event: From> + IsType<::Event>; + + /// The overarching call type. + type Call: Parameter + Dispatchable + + GetDispatchInfo + From>; + + /// The currency mechanism. + type Currency: ReservableCurrency; + + /// The base amount of currency needed to reserve for creating a multisig execution or to store + /// a dispatch call for later. + /// + /// This is held for an additional storage item whose value size is + /// `4 + sizeof((BlockNumber, Balance, AccountId))` bytes and whose key size is + /// `32 + sizeof(AccountId)` bytes. + #[pallet::constant] + type DepositBase: Get>; + + /// The amount of currency needed per unit threshold when creating a multisig execution. + /// + /// This is held for adding 32 bytes more into a pre-existing storage value. + #[pallet::constant] + type DepositFactor: Get>; + + /// The maximum amount of signatories allowed in the multisig. + #[pallet::constant] + type MaxSignatories: Get; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + /// The set of open multisig operations. + #[pallet::storage] + pub type Multisigs = StorageDoubleMap< + _, + Twox64Concat, + T::AccountId, + Blake2_128Concat, + [u8; 32], + Multisig, T::AccountId>, + >; + + #[pallet::storage] + pub type Calls = StorageMap< + _, + Identity, + [u8; 32], + (OpaqueCall, T::AccountId, BalanceOf), + >; + + #[pallet::error] + pub enum Error { /// Threshold must be 2 or greater. MinimumThreshold, /// Call is already approved by this signatory. @@ -164,49 +194,31 @@ decl_error! { /// The data to be stored is already stored. AlreadyStored, } -} -decl_event! { - /// Events type. - pub enum Event where - AccountId = ::AccountId, - BlockNumber = ::BlockNumber, - CallHash = [u8; 32] - { + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + #[pallet::metadata( + T::AccountId = "AccountId", + T::BlockNumber = "BlockNumber", + Timepoint = "Timepoint" + )] + pub enum Event { /// A new multisig operation has begun. \[approving, multisig, call_hash\] - NewMultisig(AccountId, AccountId, CallHash), + NewMultisig(T::AccountId, T::AccountId, CallHash), /// A multisig operation has been approved by someone. /// \[approving, timepoint, multisig, call_hash\] - MultisigApproval(AccountId, Timepoint, AccountId, CallHash), + MultisigApproval(T::AccountId, Timepoint, T::AccountId, CallHash), /// A multisig operation has been executed. \[approving, timepoint, multisig, call_hash\] - MultisigExecuted(AccountId, Timepoint, AccountId, CallHash, DispatchResult), + MultisigExecuted(T::AccountId, Timepoint, T::AccountId, CallHash, DispatchResult), /// A multisig operation has been cancelled. \[cancelling, timepoint, multisig, call_hash\] - MultisigCancelled(AccountId, Timepoint, AccountId, CallHash), + MultisigCancelled(T::AccountId, Timepoint, T::AccountId, CallHash) } -} - -enum CallOrHash { - Call(OpaqueCall, bool), - Hash([u8; 32]), -} - -decl_module! { - pub struct Module for enum Call where origin: T::Origin { - type Error = Error; - - /// Deposit one of this module's events by using the default implementation. - fn deposit_event() = default; - - /// The base amount of currency needed to reserve for creating a multisig execution or to store - /// a dispatch call for later. - const DepositBase: BalanceOf = T::DepositBase::get(); - - /// The amount of currency needed per unit threshold when creating a multisig execution. - const DepositFactor: BalanceOf = T::DepositFactor::get(); - /// The maximum amount of signatories allowed for a given multisig. - const MaxSignatories: u16 = T::MaxSignatories::get(); + #[pallet::hooks] + impl Hooks> for Pallet {} + #[pallet::call] + impl Pallet { /// Immediately dispatch a multi-signature call using a single approval from the caller. /// /// The dispatch origin for this call must be _Signed_. @@ -223,7 +235,7 @@ decl_module! { /// - DB Weight: None /// - Plus Call Weight /// # - #[weight = { + #[pallet::weight({ let dispatch_info = call.get_dispatch_info(); ( T::WeightInfo::as_multi_threshold_1(call.using_encoded(|c| c.len() as u32)) @@ -232,8 +244,9 @@ decl_module! { .saturating_add(T::DbWeight::get().reads_writes(1, 1)), dispatch_info.class, ) - }] - fn as_multi_threshold_1(origin, + })] + pub(super) fn as_multi_threshold_1( + origin: OriginFor, other_signatories: Vec, call: Box<::Call>, ) -> DispatchResultWithPostInfo { @@ -312,7 +325,7 @@ decl_module! { /// - Writes: Multisig Storage, [Caller Account], Calls (if `store_call`) /// - Plus Call Weight /// # - #[weight = { + #[pallet::weight({ let s = other_signatories.len() as u32; let z = call.len() as u32; @@ -321,8 +334,9 @@ decl_module! { .max(T::WeightInfo::as_multi_approve(s, z)) .max(T::WeightInfo::as_multi_complete(s, z)) .saturating_add(*max_weight) - }] - fn as_multi(origin, + })] + pub(super) fn as_multi( + origin: OriginFor, threshold: u16, other_signatories: Vec, maybe_timepoint: Option>, @@ -370,15 +384,16 @@ decl_module! { /// - Read: Multisig Storage, [Caller Account] /// - Write: Multisig Storage, [Caller Account] /// # - #[weight = { + #[pallet::weight({ let s = other_signatories.len() as u32; T::WeightInfo::approve_as_multi_create(s) .max(T::WeightInfo::approve_as_multi_approve(s)) .max(T::WeightInfo::approve_as_multi_complete(s)) .saturating_add(*max_weight) - }] - fn approve_as_multi(origin, + })] + pub(super) fn approve_as_multi( + origin: OriginFor, threshold: u16, other_signatories: Vec, maybe_timepoint: Option>, @@ -415,8 +430,9 @@ decl_module! { /// - Read: Multisig Storage, [Caller Account], Refund Account, Calls /// - Write: Multisig Storage, [Caller Account], Refund Account, Calls /// # - #[weight = T::WeightInfo::cancel_as_multi(other_signatories.len() as u32)] - fn cancel_as_multi(origin, + #[pallet::weight(T::WeightInfo::cancel_as_multi(other_signatories.len() as u32))] + pub(super) fn cancel_as_multi( + origin: OriginFor, threshold: u16, other_signatories: Vec, timepoint: Timepoint, @@ -441,13 +457,13 @@ decl_module! { >::remove(&id, &call_hash); Self::clear_call(&call_hash); - Self::deposit_event(RawEvent::MultisigCancelled(who, timepoint, id, call_hash)); + Self::deposit_event(Event::MultisigCancelled(who, timepoint, id, call_hash)); Ok(()) } } } -impl Module { +impl Pallet { /// Derive a multi-account ID from the sorted list of accounts and the threshold that are /// required. /// @@ -513,7 +529,7 @@ impl Module { T::Currency::unreserve(&m.depositor, m.deposit); let result = call.dispatch(RawOrigin::Signed(id.clone()).into()); - Self::deposit_event(RawEvent::MultisigExecuted( + Self::deposit_event(Event::MultisigExecuted( who, timepoint, id, call_hash, result.map(|_| ()).map_err(|e| e.error) )); Ok(get_result_weight(result).map(|actual_weight| @@ -538,7 +554,7 @@ impl Module { // Record approval. m.approvals.insert(pos, who.clone()); >::insert(&id, call_hash, m); - Self::deposit_event(RawEvent::MultisigApproval(who, timepoint, id, call_hash)); + Self::deposit_event(Event::MultisigApproval(who, timepoint, id, call_hash)); } else { // If we already approved and didn't store the Call, then this was useless and // we report an error. @@ -581,7 +597,7 @@ impl Module { depositor: who.clone(), approvals: vec![who.clone()], }); - Self::deposit_event(RawEvent::NewMultisig(who, id, call_hash)); + Self::deposit_event(Event::NewMultisig(who, id, call_hash)); let final_weight = if stored { T::WeightInfo::as_multi_create_store( diff --git a/frame/multisig/src/tests.rs b/frame/multisig/src/tests.rs index d6eb949888d1a..cf457f6db6022 100644 --- a/frame/multisig/src/tests.rs +++ b/frame/multisig/src/tests.rs @@ -425,7 +425,7 @@ fn multisig_2_of_3_cannot_reissue_same_call() { assert_ok!(Multisig::as_multi(Origin::signed(3), 2, vec![1, 2], Some(now()), data.clone(), false, call_weight)); let err = DispatchError::from(BalancesError::::InsufficientBalance).stripped(); - System::assert_last_event(RawEvent::MultisigExecuted(3, now(), multi, hash, Err(err)).into()); + System::assert_last_event(pallet_multisig::Event::MultisigExecuted(3, now(), multi, hash, Err(err)).into()); }); }