Pallet-Multisig to framev2 (#8741)

* the great migration

* benchmarks to work

* unnecessary T: Config

* Update frame/multisig/src/lib.rs

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>

* Update frame/multisig/src/lib.rs

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>

* Update frame/multisig/src/lib.rs

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>

* Update frame/multisig/src/lib.rs

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>

* Update frame/multisig/src/lib.rs

* line width

* get to compile

Co-authored-by: Keith Yeung <kungfukeith11@gmail.com>
Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com>
This commit is contained in:
ferrell-code
2021-05-21 02:40:19 -04:00
committed by GitHub
parent 06d87ba464
commit 39a7decd1c
3 changed files with 117 additions and 101 deletions
+115 -99
View File
@@ -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<T> = <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
/// Just a bunch of bytes, but they should decode to a valid `Call`.
pub type OpaqueCall = Vec<u8>;
/// Configuration trait.
pub trait Config: frame_system::Config {
/// The overarching event type.
type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;
/// The overarching call type.
type Call: Parameter + Dispatchable<Origin=Self::Origin, PostInfo=PostDispatchInfo>
+ GetDispatchInfo + From<frame_system::Call<Self>>;
/// The currency mechanism.
type Currency: ReservableCurrency<Self::AccountId>;
/// 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<BalanceOf<Self>>;
/// 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<BalanceOf<Self>>;
/// The maximum amount of signatories allowed in the multisig.
type MaxSignatories: Get<u16>;
/// 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<BlockNumber, Balance, AccountId> {
approvals: Vec<AccountId>,
}
decl_storage! {
trait Store for Module<T: Config> 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<Multisig<T::BlockNumber, BalanceOf<T>, T::AccountId>>;
type CallHash = [u8; 32];
pub Calls: map hasher(identity) [u8; 32] => Option<(OpaqueCall, T::AccountId, BalanceOf<T>)>;
}
enum CallOrHash {
Call(OpaqueCall, bool),
Hash([u8; 32]),
}
decl_error! {
pub enum Error for Module<T: Config> {
#[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<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
/// The overarching call type.
type Call: Parameter + Dispatchable<Origin=Self::Origin, PostInfo=PostDispatchInfo>
+ GetDispatchInfo + From<frame_system::Call<Self>>;
/// The currency mechanism.
type Currency: ReservableCurrency<Self::AccountId>;
/// 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<BalanceOf<Self>>;
/// 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<BalanceOf<Self>>;
/// The maximum amount of signatories allowed in the multisig.
#[pallet::constant]
type MaxSignatories: Get<u16>;
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
}
#[pallet::pallet]
#[pallet::generate_store(pub(super) trait Store)]
pub struct Pallet<T>(_);
/// The set of open multisig operations.
#[pallet::storage]
pub type Multisigs<T: Config> = StorageDoubleMap<
_,
Twox64Concat,
T::AccountId,
Blake2_128Concat,
[u8; 32],
Multisig<T::BlockNumber, BalanceOf<T>, T::AccountId>,
>;
#[pallet::storage]
pub type Calls<T: Config> = StorageMap<
_,
Identity,
[u8; 32],
(OpaqueCall, T::AccountId, BalanceOf<T>),
>;
#[pallet::error]
pub enum Error<T> {
/// 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<T> where
AccountId = <T as system::Config>::AccountId,
BlockNumber = <T as system::Config>::BlockNumber,
CallHash = [u8; 32]
{
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
#[pallet::metadata(
T::AccountId = "AccountId",
T::BlockNumber = "BlockNumber",
Timepoint<T::BlockNumber> = "Timepoint<BlockNumber>"
)]
pub enum Event<T: Config> {
/// 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<BlockNumber>, AccountId, CallHash),
MultisigApproval(T::AccountId, Timepoint<T::BlockNumber>, T::AccountId, CallHash),
/// A multisig operation has been executed. \[approving, timepoint, multisig, call_hash\]
MultisigExecuted(AccountId, Timepoint<BlockNumber>, AccountId, CallHash, DispatchResult),
MultisigExecuted(T::AccountId, Timepoint<T::BlockNumber>, T::AccountId, CallHash, DispatchResult),
/// A multisig operation has been cancelled. \[cancelling, timepoint, multisig, call_hash\]
MultisigCancelled(AccountId, Timepoint<BlockNumber>, AccountId, CallHash),
MultisigCancelled(T::AccountId, Timepoint<T::BlockNumber>, T::AccountId, CallHash)
}
}
enum CallOrHash {
Call(OpaqueCall, bool),
Hash([u8; 32]),
}
decl_module! {
pub struct Module<T: Config> 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;
/// 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> = T::DepositBase::get();
/// The amount of currency needed per unit threshold when creating a multisig execution.
const DepositFactor: BalanceOf<T> = T::DepositFactor::get();
/// The maximum amount of signatories allowed for a given multisig.
const MaxSignatories: u16 = T::MaxSignatories::get();
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// 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>
#[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<T>,
other_signatories: Vec<T::AccountId>,
call: Box<<T as Config>::Call>,
) -> DispatchResultWithPostInfo {
@@ -312,7 +325,7 @@ decl_module! {
/// - Writes: Multisig Storage, [Caller Account], Calls (if `store_call`)
/// - Plus Call Weight
/// # </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<T>,
threshold: u16,
other_signatories: Vec<T::AccountId>,
maybe_timepoint: Option<Timepoint<T::BlockNumber>>,
@@ -370,15 +384,16 @@ decl_module! {
/// - Read: Multisig Storage, [Caller Account]
/// - Write: Multisig Storage, [Caller Account]
/// # </weight>
#[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<T>,
threshold: u16,
other_signatories: Vec<T::AccountId>,
maybe_timepoint: Option<Timepoint<T::BlockNumber>>,
@@ -415,8 +430,9 @@ decl_module! {
/// - Read: Multisig Storage, [Caller Account], Refund Account, Calls
/// - Write: Multisig Storage, [Caller Account], Refund Account, Calls
/// # </weight>
#[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<T>,
threshold: u16,
other_signatories: Vec<T::AccountId>,
timepoint: Timepoint<T::BlockNumber>,
@@ -441,13 +457,13 @@ decl_module! {
<Multisigs<T>>::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<T: Config> Module<T> {
impl<T: Config> Pallet<T> {
/// Derive a multi-account ID from the sorted list of accounts and the threshold that are
/// required.
///
@@ -513,7 +529,7 @@ impl<T: Config> Module<T> {
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<T: Config> Module<T> {
// Record approval.
m.approvals.insert(pos, who.clone());
<Multisigs<T>>::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<T: Config> Module<T> {
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(