From 95c1d9b1b32c7d19647f3d78847419ddd2123690 Mon Sep 17 00:00:00 2001 From: Shaun Wang Date: Wed, 24 Mar 2021 21:07:07 +1300 Subject: [PATCH 1/4] Migrate pallet-vesting to pallet attribute macro. --- frame/vesting/src/lib.rs | 165 ++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 71 deletions(-) diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index 98f6067a687ec..d7e05f9b32fff 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -15,15 +15,15 @@ // See the License for the specific language governing permissions and // limitations under the License. -//! # Vesting Module +//! # Vesting Pallet //! //! - [`Config`] //! - [`Call`] //! //! ## Overview //! -//! A simple module providing a means of placing a linear curve on an account's locked balance. This -//! module ensures that there is a lock in place preventing the balance to drop below the *unvested* +//! A simple pallet providing a means of placing a linear curve on an account's locked balance. This +//! pallet ensures that there is a lock in place preventing the balance to drop below the *unvested* //! amount for any reason other than transaction fee payment. //! //! As the amount vested increases over time, the amount unvested reduces. However, locks remain in @@ -34,7 +34,7 @@ //! //! ## Interface //! -//! This module implements the `VestingSchedule` trait. +//! This pallet implements the `VestingSchedule` trait. //! //! ### Dispatchable Functions //! @@ -50,37 +50,21 @@ pub mod weights; use sp_std::prelude::*; use sp_std::fmt::Debug; use codec::{Encode, Decode}; -use sp_runtime::{DispatchResult, RuntimeDebug, traits::{ +use sp_runtime::{RuntimeDebug, traits::{ StaticLookup, Zero, AtLeast32BitUnsigned, MaybeSerializeDeserialize, Convert }}; -use frame_support::{decl_module, decl_event, decl_storage, decl_error, ensure}; +use frame_support::{ensure, pallet_prelude::*}; use frame_support::traits::{ Currency, LockableCurrency, VestingSchedule, WithdrawReasons, LockIdentifier, ExistenceRequirement, Get, }; -use frame_system::{ensure_signed, ensure_root}; +use frame_system::{ensure_signed, ensure_root, pallet_prelude::*}; pub use weights::WeightInfo; +pub use pallet::*; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; type MaxLocksOf = <::Currency as LockableCurrency<::AccountId>>::MaxLocks; -pub trait Config: frame_system::Config { - /// The overarching event type. - type Event: From> + Into<::Event>; - - /// The currency trait. - type Currency: LockableCurrency; - - /// Convert the block number into a balance. - type BlockNumberToBalance: Convert>; - - /// The minimum amount transferred to call `vested_transfer`. - type MinVestedTransfer: Get>; - - /// Weight information for extrinsics in this pallet. - type WeightInfo: WeightInfo; -} - const VESTING_ID: LockIdentifier = *b"vesting "; /// Struct to encode the vesting schedule of an individual account. @@ -116,23 +100,68 @@ impl< } } -decl_storage! { - trait Store for Module as Vesting { - /// Information regarding the vesting of a given account. - pub Vesting get(fn vesting): - map hasher(blake2_128_concat) T::AccountId - => Option, T::BlockNumber>>; +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type Event: From> + IsType<::Event>; + + /// The currency trait. + type Currency: LockableCurrency; + + /// Convert the block number into a balance. + type BlockNumberToBalance: Convert>; + + /// The minimum amount transferred to call `vested_transfer`. + #[pallet::constant] + type MinVestedTransfer: Get>; + + /// Weight information for extrinsics in this pallet. + type WeightInfo: WeightInfo; + } + + /// Information regarding the vesting of a given account. + #[pallet::storage] + #[pallet::getter(fn vesting)] + pub type Vesting = StorageMap< + _, + Blake2_128Concat, + T::AccountId, + VestingInfo, T::BlockNumber>, + >; + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub vesting: Vec<(T::AccountId, T::BlockNumber, T::BlockNumber, BalanceOf)>, } - add_extra_genesis { - config(vesting): Vec<(T::AccountId, T::BlockNumber, T::BlockNumber, BalanceOf)>; - build(|config: &GenesisConfig| { + + #[cfg(feature = "std")] + impl Default for GenesisConfig { + fn default() -> Self { + GenesisConfig { + vesting: Default::default(), + } + } + } + + #[pallet::genesis_build] + impl GenesisBuild for GenesisConfig { + fn build(&self) { use sp_runtime::traits::Saturating; + // Generate initial vesting configuration // * who - Account which we are generating vesting configuration for // * begin - Block when the account will start to vest // * length - Number of blocks from `begin` until fully vested // * liquid - Number of units which can be spent before vesting begins - for &(ref who, begin, length, liquid) in config.vesting.iter() { + for &(ref who, begin, length, liquid) in self.vesting.iter() { let balance = T::Currency::free_balance(who); assert!(!balance.is_zero(), "Currencies must be init'd before vesting"); // Total genesis `balance` minus `liquid` equals funds locked for vesting @@ -148,24 +177,24 @@ decl_storage! { let reasons = WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE; T::Currency::set_lock(VESTING_ID, who, locked, reasons); } - }) + } } -} -decl_event!( - pub enum Event where AccountId = ::AccountId, Balance = BalanceOf { + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + #[pallet::metadata(T::AccountId = "AccountId", T::Balance = "Balance")] + pub enum Event { /// The amount vested has been updated. This could indicate more funds are available. The /// balance given is the amount which is left unvested (and thus locked). /// \[account, unvested\] - VestingUpdated(AccountId, Balance), + VestingUpdated(T::AccountId, BalanceOf), /// An \[account\] has become fully vested. No further vesting can happen. - VestingCompleted(AccountId), + VestingCompleted(T::AccountId), } -); -decl_error! { - /// Error for the vesting module. - pub enum Error for Module { + /// Error for the vesting pallet. + #[pallet::error] + pub enum Error { /// The account given is not vesting. NotVesting, /// An existing vesting schedule already exists for this account that cannot be clobbered. @@ -173,22 +202,16 @@ decl_error! { /// Amount being transferred is too low to create a vesting schedule. AmountLow, } -} - -decl_module! { - /// Vesting module declaration. - pub struct Module for enum Call where origin: T::Origin { - type Error = Error; - - /// The minimum amount to be transferred to create a new vesting schedule. - const MinVestedTransfer: BalanceOf = T::MinVestedTransfer::get(); - fn deposit_event() = default; + #[pallet::hooks] + impl Hooks> for Pallet {} + #[pallet::call] + impl Pallet { /// Unlock any vested funds of the sender account. /// /// The dispatch origin for this call must be _Signed_ and the sender must have funds still - /// locked under this module. + /// locked under this pallet. /// /// Emits either `VestingCompleted` or `VestingUpdated`. /// @@ -198,10 +221,10 @@ decl_module! { /// - Reads: Vesting Storage, Balances Locks, [Sender Account] /// - Writes: Vesting Storage, Balances Locks, [Sender Account] /// # - #[weight = T::WeightInfo::vest_locked(MaxLocksOf::::get()) + #[pallet::weight(T::WeightInfo::vest_locked(MaxLocksOf::::get()) .max(T::WeightInfo::vest_unlocked(MaxLocksOf::::get())) - ] - fn vest(origin) -> DispatchResult { + )] + pub fn vest(origin: OriginFor) -> DispatchResult { let who = ensure_signed(origin)?; Self::update_lock(who) } @@ -211,7 +234,7 @@ decl_module! { /// The dispatch origin for this call must be _Signed_. /// /// - `target`: The account whose vested funds should be unlocked. Must have funds still - /// locked under this module. + /// locked under this pallet. /// /// Emits either `VestingCompleted` or `VestingUpdated`. /// @@ -221,10 +244,10 @@ decl_module! { /// - Reads: Vesting Storage, Balances Locks, Target Account /// - Writes: Vesting Storage, Balances Locks, Target Account /// # - #[weight = T::WeightInfo::vest_other_locked(MaxLocksOf::::get()) + #[pallet::weight(T::WeightInfo::vest_other_locked(MaxLocksOf::::get()) .max(T::WeightInfo::vest_other_unlocked(MaxLocksOf::::get())) - ] - fn vest_other(origin, target: ::Source) -> DispatchResult { + )] + pub fn vest_other(origin: OriginFor, target: ::Source) -> DispatchResult { ensure_signed(origin)?; Self::update_lock(T::Lookup::lookup(target)?) } @@ -245,9 +268,9 @@ decl_module! { /// - Reads: Vesting Storage, Balances Locks, Target Account, [Sender Account] /// - Writes: Vesting Storage, Balances Locks, Target Account, [Sender Account] /// # - #[weight = T::WeightInfo::vested_transfer(MaxLocksOf::::get())] + #[pallet::weight(T::WeightInfo::vested_transfer(MaxLocksOf::::get()))] pub fn vested_transfer( - origin, + origin: OriginFor, target: ::Source, schedule: VestingInfo, T::BlockNumber>, ) -> DispatchResult { @@ -282,9 +305,9 @@ decl_module! { /// - Reads: Vesting Storage, Balances Locks, Target Account, Source Account /// - Writes: Vesting Storage, Balances Locks, Target Account, Source Account /// # - #[weight = T::WeightInfo::force_vested_transfer(MaxLocksOf::::get())] + #[pallet::weight(T::WeightInfo::force_vested_transfer(MaxLocksOf::::get()))] pub fn force_vested_transfer( - origin, + origin: OriginFor, source: ::Source, target: ::Source, schedule: VestingInfo, T::BlockNumber>, @@ -306,8 +329,8 @@ decl_module! { } } -impl Module { - /// (Re)set or remove the module's currency lock on `who`'s account in accordance with their +impl Pallet { + /// (Re)set or remove the pallet's currency lock on `who`'s account in accordance with their /// current unvested amount. fn update_lock(who: T::AccountId) -> DispatchResult { let vesting = Self::vesting(&who).ok_or(Error::::NotVesting)?; @@ -317,17 +340,17 @@ impl Module { if locked_now.is_zero() { T::Currency::remove_lock(VESTING_ID, &who); Vesting::::remove(&who); - Self::deposit_event(RawEvent::VestingCompleted(who)); + Self::deposit_event(Event::::VestingCompleted(who)); } else { let reasons = WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE; T::Currency::set_lock(VESTING_ID, &who, locked_now, reasons); - Self::deposit_event(RawEvent::VestingUpdated(who, locked_now)); + Self::deposit_event(Event::::VestingUpdated(who, locked_now)); } Ok(()) } } -impl VestingSchedule for Module where +impl VestingSchedule for Pallet where BalanceOf: MaybeSerializeDeserialize + Debug { type Moment = T::BlockNumber; From f9fe546b5dca5e820f67d9bd2daa405b6f4ab734 Mon Sep 17 00:00:00 2001 From: Shaun Wang Date: Wed, 24 Mar 2021 21:20:10 +1300 Subject: [PATCH 2/4] Update metadata type alias. --- frame/vesting/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/vesting/src/lib.rs b/frame/vesting/src/lib.rs index d7e05f9b32fff..483e734fe4ca6 100644 --- a/frame/vesting/src/lib.rs +++ b/frame/vesting/src/lib.rs @@ -182,7 +182,7 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] - #[pallet::metadata(T::AccountId = "AccountId", T::Balance = "Balance")] + #[pallet::metadata(T::AccountId = "AccountId", BalanceOf = "Balance")] pub enum Event { /// The amount vested has been updated. This could indicate more funds are available. The /// balance given is the amount which is left unvested (and thus locked). From a74a97d618e24952d79bd4a7e1dee3a1f5c4f29b Mon Sep 17 00:00:00 2001 From: Shaun Wang Date: Wed, 24 Mar 2021 21:56:36 +1300 Subject: [PATCH 3/4] Replace 'Module' with 'Pallet' in benchmarking. --- frame/vesting/src/benchmarking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frame/vesting/src/benchmarking.rs b/frame/vesting/src/benchmarking.rs index 0a882157ab38a..8d16a53fba2c1 100644 --- a/frame/vesting/src/benchmarking.rs +++ b/frame/vesting/src/benchmarking.rs @@ -25,7 +25,7 @@ use frame_system::{RawOrigin, Pallet as System}; use frame_benchmarking::{benchmarks, account, whitelisted_caller, impl_benchmark_test_suite}; use sp_runtime::traits::Bounded; -use crate::Module as Vesting; +use crate::Pallet as Vesting; const SEED: u32 = 0; From 40e26a99ac7545f9c100547dbec2e62000d4ec94 Mon Sep 17 00:00:00 2001 From: Shaun Wang Date: Wed, 24 Mar 2021 23:39:27 +1300 Subject: [PATCH 4/4] Trigger CI.