mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 21:41:12 +00:00
Migrate crowdloan pallet to pallet attribute macro. (#3036)
This commit is contained in:
@@ -14,9 +14,9 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! # Parachain Crowdloaning module
|
||||
//! # Parachain Crowdloaning pallet
|
||||
//!
|
||||
//! The point of this module is to allow parachain projects to offer the ability to help fund a
|
||||
//! The point of this pallet is to allow parachain projects to offer the ability to help fund a
|
||||
//! deposit for the parachain. When the crowdloan has ended, the funds are returned.
|
||||
//!
|
||||
//! Each fund has a child-trie which stores all contributors account IDs together with the amount
|
||||
@@ -50,16 +50,15 @@
|
||||
//! returned to the crowdloan account.
|
||||
|
||||
use frame_support::{
|
||||
decl_module, decl_storage, decl_event, decl_error, ensure, Identity, PalletId,
|
||||
ensure, Identity, PalletId,
|
||||
storage::{child, ChildTriePrefixIterator},
|
||||
traits::{
|
||||
Currency, ReservableCurrency, Get, ExistenceRequirement::AllowDeath
|
||||
},
|
||||
pallet_prelude::{Weight, DispatchResultWithPostInfo},
|
||||
pallet_prelude::Weight,
|
||||
};
|
||||
use frame_system::{ensure_signed, ensure_root};
|
||||
use sp_runtime::{
|
||||
DispatchResult, RuntimeDebug, MultiSignature, MultiSigner,
|
||||
RuntimeDebug, MultiSignature, MultiSigner,
|
||||
traits::{
|
||||
AccountIdConversion, Hash, Saturating, Zero, One, CheckedAdd, Verify, IdentifyAccount,
|
||||
},
|
||||
@@ -69,6 +68,7 @@ use crate::slot_range::SlotRange;
|
||||
use parity_scale_codec::{Encode, Decode};
|
||||
use sp_std::vec::Vec;
|
||||
use primitives::v1::Id as ParaId;
|
||||
pub use pallet::*;
|
||||
|
||||
type CurrencyOf<T> = <<T as Config>::Auctioneer as Auctioneer>::Currency;
|
||||
type LeasePeriodOf<T> = <<T as Config>::Auctioneer as Auctioneer>::LeasePeriod;
|
||||
@@ -104,40 +104,6 @@ impl WeightInfo for TestWeightInfo {
|
||||
fn poke() -> Weight { 0 }
|
||||
}
|
||||
|
||||
pub trait Config: frame_system::Config {
|
||||
type Event: From<Event<Self>> + Into<<Self as frame_system::Config>::Event>;
|
||||
|
||||
/// PalletId for the crowdloan module. An appropriate value could be ```PalletId(*b"py/cfund")```
|
||||
type PalletId: Get<PalletId>;
|
||||
|
||||
/// The amount to be held on deposit by the depositor of a crowdloan.
|
||||
type SubmissionDeposit: Get<BalanceOf<Self>>;
|
||||
|
||||
/// The minimum amount that may be contributed into a crowdloan. Should almost certainly be at
|
||||
/// least ExistentialDeposit.
|
||||
type MinContribution: Get<BalanceOf<Self>>;
|
||||
|
||||
/// Max number of storage keys to remove per extrinsic call.
|
||||
type RemoveKeysLimit: Get<u32>;
|
||||
|
||||
/// The parachain registrar type. We jus use this to ensure that only the manager of a para is able to
|
||||
/// start a crowdloan for its slot.
|
||||
type Registrar: Registrar<AccountId=Self::AccountId>;
|
||||
|
||||
/// The type representing the auctioning system.
|
||||
type Auctioneer: Auctioneer<
|
||||
AccountId=Self::AccountId,
|
||||
BlockNumber=Self::BlockNumber,
|
||||
LeasePeriod=Self::BlockNumber,
|
||||
>;
|
||||
|
||||
/// The maximum length for the memo attached to a crowdloan contribution.
|
||||
type MaxMemoLength: Get<u8>;
|
||||
|
||||
/// Weight Information for the Extrinsics in the Pallet
|
||||
type WeightInfo: WeightInfo;
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug)]
|
||||
pub enum LastContribution<BlockNumber> {
|
||||
Never,
|
||||
@@ -180,36 +146,89 @@ pub struct FundInfo<AccountId, Balance, BlockNumber, LeasePeriod> {
|
||||
trie_index: TrieIndex,
|
||||
}
|
||||
|
||||
decl_storage! {
|
||||
trait Store for Module<T: Config> as Crowdloan {
|
||||
/// Info on all of the funds.
|
||||
Funds get(fn funds):
|
||||
map hasher(twox_64_concat) ParaId
|
||||
=> Option<FundInfo<T::AccountId, BalanceOf<T>, T::BlockNumber, LeasePeriodOf<T>>>;
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_system::{pallet_prelude::*, ensure_signed, ensure_root};
|
||||
use super::*;
|
||||
|
||||
/// The funds that have had additional contributions during the last block. This is used
|
||||
/// in order to determine which funds should submit new or updated bids.
|
||||
NewRaise get(fn new_raise): Vec<ParaId>;
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(super) trait Store)]
|
||||
pub struct Pallet<T>(_);
|
||||
|
||||
/// The number of auctions that have entered into their ending period so far.
|
||||
EndingsCount get(fn endings_count): u32;
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {
|
||||
type Event: From<Event<Self>> + IsType<<Self as frame_system::Config>::Event>;
|
||||
|
||||
/// Tracker for the next available trie index
|
||||
NextTrieIndex get(fn next_trie_index): u32;
|
||||
/// PalletId for the crowdloan pallet. An appropriate value could be ```PalletId(*b"py/cfund")```
|
||||
#[pallet::constant]
|
||||
type PalletId: Get<PalletId>;
|
||||
|
||||
/// The amount to be held on deposit by the depositor of a crowdloan.
|
||||
type SubmissionDeposit: Get<BalanceOf<Self>>;
|
||||
|
||||
/// The minimum amount that may be contributed into a crowdloan. Should almost certainly be at
|
||||
/// least ExistentialDeposit.
|
||||
#[pallet::constant]
|
||||
type MinContribution: Get<BalanceOf<Self>>;
|
||||
|
||||
/// Max number of storage keys to remove per extrinsic call.
|
||||
#[pallet::constant]
|
||||
type RemoveKeysLimit: Get<u32>;
|
||||
|
||||
/// The parachain registrar type. We jus use this to ensure that only the manager of a para is able to
|
||||
/// start a crowdloan for its slot.
|
||||
type Registrar: Registrar<AccountId=Self::AccountId>;
|
||||
|
||||
/// The type representing the auctioning system.
|
||||
type Auctioneer: Auctioneer<
|
||||
AccountId=Self::AccountId,
|
||||
BlockNumber=Self::BlockNumber,
|
||||
LeasePeriod=Self::BlockNumber,
|
||||
>;
|
||||
|
||||
/// The maximum length for the memo attached to a crowdloan contribution.
|
||||
type MaxMemoLength: Get<u8>;
|
||||
|
||||
/// Weight Information for the Extrinsics in the Pallet
|
||||
type WeightInfo: WeightInfo;
|
||||
}
|
||||
}
|
||||
|
||||
decl_event! {
|
||||
pub enum Event<T> where
|
||||
<T as frame_system::Config>::AccountId,
|
||||
Balance = BalanceOf<T>,
|
||||
{
|
||||
/// Info on all of the funds.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn funds)]
|
||||
pub(super) type Funds<T: Config> = StorageMap<
|
||||
_,
|
||||
Twox64Concat, ParaId,
|
||||
FundInfo<T::AccountId, BalanceOf<T>, T::BlockNumber, LeasePeriodOf<T>>,
|
||||
>;
|
||||
|
||||
/// The funds that have had additional contributions during the last block. This is used
|
||||
/// in order to determine which funds should submit new or updated bids.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn new_raise)]
|
||||
pub(super) type NewRaise<T> = StorageValue<_, Vec<ParaId>, ValueQuery>;
|
||||
|
||||
/// The number of auctions that have entered into their ending period so far.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn endings_count)]
|
||||
pub(super) type EndingsCount<T> = StorageValue<_, u32, ValueQuery>;
|
||||
|
||||
/// Tracker for the next available trie index
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn next_trie_index)]
|
||||
pub(super) type NextTrieIndex<T> = StorageValue<_, u32, ValueQuery>;
|
||||
|
||||
#[pallet::event]
|
||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||
#[pallet::metadata(T::AccountId = "AccountId", BalanceOf<T> = "Balance")]
|
||||
pub enum Event<T: Config> {
|
||||
/// Create a new crowdloaning campaign. [fund_index]
|
||||
Created(ParaId),
|
||||
/// Contributed to a crowd sale. [who, fund_index, amount]
|
||||
Contributed(AccountId, ParaId, Balance),
|
||||
Contributed(T::AccountId, ParaId, BalanceOf<T>),
|
||||
/// Withdrew full balance of a contributor. [who, fund_index, amount]
|
||||
Withdrew(AccountId, ParaId, Balance),
|
||||
Withdrew(T::AccountId, ParaId, BalanceOf<T>),
|
||||
/// The loans in a fund have been partially dissolved, i.e. there are some left
|
||||
/// over child keys that still need to be killed. [fund_index]
|
||||
PartiallyRefunded(ParaId),
|
||||
@@ -226,14 +245,13 @@ decl_event! {
|
||||
/// The configuration to a crowdloan has been edited. [fund_index]
|
||||
Edited(ParaId),
|
||||
/// A memo has been updated. [who, fund_index, memo]
|
||||
MemoUpdated(AccountId, ParaId, Vec<u8>),
|
||||
MemoUpdated(T::AccountId, ParaId, Vec<u8>),
|
||||
/// A parachain has been moved to NewRaise
|
||||
AddedToNewRaise(ParaId),
|
||||
}
|
||||
}
|
||||
|
||||
decl_error! {
|
||||
pub enum Error for Module<T: Config> {
|
||||
#[pallet::error]
|
||||
pub enum Error<T> {
|
||||
/// The current lease period is more than the first lease period.
|
||||
FirstPeriodInPast,
|
||||
/// The first lease period needs to at least be less than 3 `max_value`.
|
||||
@@ -281,31 +299,53 @@ decl_error! {
|
||||
/// The fund is already in NewRaise
|
||||
AlreadyInNewRaise
|
||||
}
|
||||
}
|
||||
|
||||
decl_module! {
|
||||
pub struct Module<T: Config> for enum Call where origin: <T as frame_system::Config>::Origin {
|
||||
type Error = Error<T>;
|
||||
#[pallet::hooks]
|
||||
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
|
||||
fn on_initialize(n: T::BlockNumber) -> frame_support::weights::Weight {
|
||||
if let Some(n) = T::Auctioneer::is_ending(n) {
|
||||
if n.is_zero() {
|
||||
// first block of ending period.
|
||||
EndingsCount::<T>::mutate(|c| *c += 1);
|
||||
}
|
||||
let new_raise = NewRaise::<T>::take();
|
||||
let new_raise_len = new_raise.len() as u32;
|
||||
for (fund, para_id) in new_raise.into_iter().filter_map(|i| Self::funds(i).map(|f| (f, i))) {
|
||||
// Care needs to be taken by the crowdloan creator that this function will succeed given
|
||||
// the crowdloaning configuration. We do some checks ahead of time in crowdloan `create`.
|
||||
let result = T::Auctioneer::place_bid(
|
||||
Self::fund_account_id(para_id),
|
||||
para_id,
|
||||
fund.first_period,
|
||||
fund.last_period,
|
||||
fund.raised,
|
||||
);
|
||||
|
||||
const PalletId: PalletId = T::PalletId::get();
|
||||
const MinContribution: BalanceOf<T> = T::MinContribution::get();
|
||||
const RemoveKeysLimit: u32 = T::RemoveKeysLimit::get();
|
||||
|
||||
fn deposit_event() = default;
|
||||
Self::deposit_event(Event::<T>::HandleBidResult(para_id, result));
|
||||
}
|
||||
T::WeightInfo::on_initialize(new_raise_len)
|
||||
} else {
|
||||
T::DbWeight::get().reads(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Create a new crowdloaning campaign for a parachain slot with the given lease period range.
|
||||
///
|
||||
/// This applies a lock to your parachain configuration, ensuring that it cannot be changed
|
||||
/// by the parachain manager.
|
||||
#[weight = T::WeightInfo::create()]
|
||||
pub fn create(origin,
|
||||
#[compact] index: ParaId,
|
||||
#[compact] cap: BalanceOf<T>,
|
||||
#[compact] first_period: LeasePeriodOf<T>,
|
||||
#[compact] last_period: LeasePeriodOf<T>,
|
||||
#[compact] end: T::BlockNumber,
|
||||
#[pallet::weight(T::WeightInfo::create())]
|
||||
pub fn create(
|
||||
origin: OriginFor<T>,
|
||||
#[pallet::compact] index: ParaId,
|
||||
#[pallet::compact] cap: BalanceOf<T>,
|
||||
#[pallet::compact] first_period: LeasePeriodOf<T>,
|
||||
#[pallet::compact] last_period: LeasePeriodOf<T>,
|
||||
#[pallet::compact] end: T::BlockNumber,
|
||||
verifier: Option<MultiSigner>,
|
||||
) {
|
||||
) -> DispatchResult {
|
||||
let depositor = ensure_signed(origin)?;
|
||||
|
||||
ensure!(first_period <= last_period, Error::<T>::LastPeriodBeforeFirstPeriod);
|
||||
@@ -345,21 +385,23 @@ decl_module! {
|
||||
trie_index,
|
||||
});
|
||||
|
||||
NextTrieIndex::put(new_trie_index);
|
||||
NextTrieIndex::<T>::put(new_trie_index);
|
||||
// Add a lock to the para so that the configuration cannot be changed.
|
||||
T::Registrar::apply_lock(index);
|
||||
|
||||
Self::deposit_event(RawEvent::Created(index));
|
||||
Self::deposit_event(Event::<T>::Created(index));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Contribute to a crowd sale. This will transfer some balance over to fund a parachain
|
||||
/// slot. It will be withdrawable when the crowdloan has ended and the funds are unused.
|
||||
#[weight = T::WeightInfo::contribute()]
|
||||
pub fn contribute(origin,
|
||||
#[compact] index: ParaId,
|
||||
#[compact] value: BalanceOf<T>,
|
||||
#[pallet::weight(T::WeightInfo::contribute())]
|
||||
pub fn contribute(
|
||||
origin: OriginFor<T>,
|
||||
#[pallet::compact] index: ParaId,
|
||||
#[pallet::compact] value: BalanceOf<T>,
|
||||
signature: Option<MultiSignature>,
|
||||
) {
|
||||
) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
ensure!(value >= T::MinContribution::get(), Error::<T>::ContributionTooSmall);
|
||||
@@ -400,7 +442,7 @@ decl_module! {
|
||||
// do nothing - already in NewRaise
|
||||
}
|
||||
_ => {
|
||||
NewRaise::append(index);
|
||||
NewRaise::<T>::append(index);
|
||||
fund.last_contribution = LastContribution::Ending(now);
|
||||
}
|
||||
}
|
||||
@@ -415,7 +457,7 @@ decl_module! {
|
||||
_ => {
|
||||
// Not in ending period; but an auction has been ending since our previous
|
||||
// bid, or we never had one to begin with. Add bid.
|
||||
NewRaise::append(index);
|
||||
NewRaise::<T>::append(index);
|
||||
fund.last_contribution = LastContribution::PreEnding(endings_count);
|
||||
}
|
||||
}
|
||||
@@ -423,7 +465,8 @@ decl_module! {
|
||||
|
||||
Funds::<T>::insert(index, &fund);
|
||||
|
||||
Self::deposit_event(RawEvent::Contributed(who, index, value));
|
||||
Self::deposit_event(Event::<T>::Contributed(who, index, value));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Withdraw full balance of a specific contributor.
|
||||
@@ -443,8 +486,12 @@ decl_module! {
|
||||
///
|
||||
/// - `who`: The account whose contribution should be withdrawn.
|
||||
/// - `index`: The parachain to whose crowdloan the contribution was made.
|
||||
#[weight = T::WeightInfo::withdraw()]
|
||||
pub fn withdraw(origin, who: T::AccountId, #[compact] index: ParaId) {
|
||||
#[pallet::weight(T::WeightInfo::withdraw())]
|
||||
pub fn withdraw(
|
||||
origin: OriginFor<T>,
|
||||
who: T::AccountId,
|
||||
#[pallet::compact] index: ParaId,
|
||||
) -> DispatchResult {
|
||||
ensure_signed(origin)?;
|
||||
|
||||
let mut fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
|
||||
@@ -462,7 +509,8 @@ decl_module! {
|
||||
|
||||
Funds::<T>::insert(index, &fund);
|
||||
|
||||
Self::deposit_event(RawEvent::Withdrew(who, index, balance));
|
||||
Self::deposit_event(Event::<T>::Withdrew(who, index, balance));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Automatically refund contributors of an ended crowdloan.
|
||||
@@ -470,8 +518,11 @@ decl_module! {
|
||||
/// times to fully refund all users. We will refund `RemoveKeysLimit` users at a time.
|
||||
///
|
||||
/// Origin must be signed, but can come from anyone.
|
||||
#[weight = T::WeightInfo::refund(T::RemoveKeysLimit::get())]
|
||||
pub fn refund(origin, #[compact] index: ParaId) -> DispatchResultWithPostInfo {
|
||||
#[pallet::weight(T::WeightInfo::refund(T::RemoveKeysLimit::get()))]
|
||||
pub fn refund(
|
||||
origin: OriginFor<T>,
|
||||
#[pallet::compact] index: ParaId,
|
||||
) -> DispatchResultWithPostInfo {
|
||||
ensure_signed(origin)?;
|
||||
|
||||
let mut fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
|
||||
@@ -500,19 +551,19 @@ decl_module! {
|
||||
Funds::<T>::insert(index, &fund);
|
||||
|
||||
if all_refunded {
|
||||
Self::deposit_event(RawEvent::AllRefunded(index));
|
||||
Self::deposit_event(Event::<T>::AllRefunded(index));
|
||||
// Refund for unused refund count.
|
||||
Ok(Some(T::WeightInfo::refund(refund_count)).into())
|
||||
} else {
|
||||
Self::deposit_event(RawEvent::PartiallyRefunded(index));
|
||||
Self::deposit_event(Event::<T>::PartiallyRefunded(index));
|
||||
// No weight to refund since we did not finish the loop.
|
||||
Ok(().into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove a fund after the retirement period has ended and all funds have been returned.
|
||||
#[weight = T::WeightInfo::dissolve()]
|
||||
pub fn dissolve(origin, #[compact] index: ParaId) -> DispatchResult {
|
||||
#[pallet::weight(T::WeightInfo::dissolve())]
|
||||
pub fn dissolve(origin: OriginFor<T>, #[pallet::compact] index: ParaId) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
let fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
|
||||
@@ -531,22 +582,23 @@ decl_module! {
|
||||
|
||||
CurrencyOf::<T>::unreserve(&fund.depositor, fund.deposit);
|
||||
Funds::<T>::remove(index);
|
||||
Self::deposit_event(RawEvent::Dissolved(index));
|
||||
Self::deposit_event(Event::<T>::Dissolved(index));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Edit the configuration for an in-progress crowdloan.
|
||||
///
|
||||
/// Can only be called by Root origin.
|
||||
#[weight = T::WeightInfo::edit()]
|
||||
pub fn edit(origin,
|
||||
#[compact] index: ParaId,
|
||||
#[compact] cap: BalanceOf<T>,
|
||||
#[compact] first_period: LeasePeriodOf<T>,
|
||||
#[compact] last_period: LeasePeriodOf<T>,
|
||||
#[compact] end: T::BlockNumber,
|
||||
#[pallet::weight(T::WeightInfo::edit())]
|
||||
pub fn edit(
|
||||
origin: OriginFor<T>,
|
||||
#[pallet::compact] index: ParaId,
|
||||
#[pallet::compact] cap: BalanceOf<T>,
|
||||
#[pallet::compact] first_period: LeasePeriodOf<T>,
|
||||
#[pallet::compact] last_period: LeasePeriodOf<T>,
|
||||
#[pallet::compact] end: T::BlockNumber,
|
||||
verifier: Option<MultiSigner>,
|
||||
) {
|
||||
) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
|
||||
let fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
|
||||
@@ -564,14 +616,15 @@ decl_module! {
|
||||
trie_index: fund.trie_index,
|
||||
});
|
||||
|
||||
Self::deposit_event(RawEvent::Edited(index));
|
||||
Self::deposit_event(Event::<T>::Edited(index));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add an optional memo to an existing crowdloan contribution.
|
||||
///
|
||||
/// Origin must be Signed, and the user must have contributed to the crowdloan.
|
||||
#[weight = T::WeightInfo::add_memo()]
|
||||
pub fn add_memo(origin, index: ParaId, memo: Vec<u8>) {
|
||||
#[pallet::weight(T::WeightInfo::add_memo())]
|
||||
pub fn add_memo(origin: OriginFor<T>, index: ParaId, memo: Vec<u8>) -> DispatchResult {
|
||||
let who = ensure_signed(origin)?;
|
||||
|
||||
ensure!(memo.len() <= T::MaxMemoLength::get().into(), Error::<T>::MemoTooLarge);
|
||||
@@ -581,52 +634,27 @@ decl_module! {
|
||||
ensure!(balance > Zero::zero(), Error::<T>::NoContributions);
|
||||
|
||||
Self::contribution_put(fund.trie_index, &who, &balance, &memo);
|
||||
Self::deposit_event(RawEvent::MemoUpdated(who, index, memo));
|
||||
}
|
||||
|
||||
fn on_initialize(n: T::BlockNumber) -> frame_support::weights::Weight {
|
||||
if let Some(n) = T::Auctioneer::is_ending(n) {
|
||||
if n.is_zero() {
|
||||
// first block of ending period.
|
||||
EndingsCount::mutate(|c| *c += 1);
|
||||
}
|
||||
let new_raise = NewRaise::take();
|
||||
let new_raise_len = new_raise.len() as u32;
|
||||
for (fund, para_id) in new_raise.into_iter().filter_map(|i| Self::funds(i).map(|f| (f, i))) {
|
||||
// Care needs to be taken by the crowdloan creator that this function will succeed given
|
||||
// the crowdloaning configuration. We do some checks ahead of time in crowdloan `create`.
|
||||
let result = T::Auctioneer::place_bid(
|
||||
Self::fund_account_id(para_id),
|
||||
para_id,
|
||||
fund.first_period,
|
||||
fund.last_period,
|
||||
fund.raised,
|
||||
);
|
||||
|
||||
Self::deposit_event(RawEvent::HandleBidResult(para_id, result));
|
||||
}
|
||||
T::WeightInfo::on_initialize(new_raise_len)
|
||||
} else {
|
||||
T::DbWeight::get().reads(1)
|
||||
}
|
||||
Self::deposit_event(Event::<T>::MemoUpdated(who, index, memo));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Poke the fund into NewRaise
|
||||
///
|
||||
/// Origin must be Signed, and the fund has non-zero raise.
|
||||
#[weight = T::WeightInfo::poke()]
|
||||
pub fn poke(origin, index: ParaId) {
|
||||
#[pallet::weight(T::WeightInfo::poke())]
|
||||
pub fn poke(origin: OriginFor<T>, index: ParaId) -> DispatchResult {
|
||||
ensure_signed(origin)?;
|
||||
let fund = Self::funds(index).ok_or(Error::<T>::InvalidParaId)?;
|
||||
ensure!(!fund.raised.is_zero(), Error::<T>::NoContributions);
|
||||
ensure!(!NewRaise::get().contains(&index), Error::<T>::AlreadyInNewRaise);
|
||||
NewRaise::append(index);
|
||||
Self::deposit_event(RawEvent::AddedToNewRaise(index));
|
||||
ensure!(!NewRaise::<T>::get().contains(&index), Error::<T>::AlreadyInNewRaise);
|
||||
NewRaise::<T>::append(index);
|
||||
Self::deposit_event(Event::<T>::AddedToNewRaise(index));
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> Module<T> {
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// The account ID of the fund pot.
|
||||
///
|
||||
/// This actually does computation. If you need to keep using it, then make sure you cache the
|
||||
@@ -675,7 +703,7 @@ impl<T: Config> Module<T> {
|
||||
now: T::BlockNumber,
|
||||
fund_account: &T::AccountId,
|
||||
fund: &FundInfo<T::AccountId, BalanceOf<T>, T::BlockNumber, LeasePeriodOf<T>>
|
||||
) -> DispatchResult {
|
||||
) -> sp_runtime::DispatchResult {
|
||||
// `fund.end` can represent the end of a failed crowdloan or the beginning of retirement
|
||||
// If the current lease period is past the first period they are trying to bid for, then
|
||||
// it is already too late to win the bid.
|
||||
@@ -689,7 +717,7 @@ impl<T: Config> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Config> crate::traits::OnSwap for Module<T> {
|
||||
impl<T: Config> crate::traits::OnSwap for Pallet<T> {
|
||||
fn on_swap(one: ParaId, other: ParaId) {
|
||||
Funds::<T>::mutate(one, |x|
|
||||
Funds::<T>::mutate(other, |y|
|
||||
@@ -734,7 +762,7 @@ mod tests {
|
||||
// The testing primitives are very useful for avoiding having to work with signatures
|
||||
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are requried.
|
||||
use sp_runtime::{
|
||||
testing::Header, traits::{BlakeTwo256, IdentityLookup},
|
||||
testing::Header, traits::{BlakeTwo256, IdentityLookup}, DispatchResult,
|
||||
};
|
||||
use crate::{
|
||||
mock::TestRegistrar,
|
||||
@@ -1335,14 +1363,14 @@ mod tests {
|
||||
// Move to the end of the crowdloan
|
||||
run_to_block(10);
|
||||
assert_ok!(Crowdloan::refund(Origin::signed(1337), para));
|
||||
assert_eq!(last_event(), super::RawEvent::PartiallyRefunded(para).into());
|
||||
assert_eq!(last_event(), super::Event::<Test>::PartiallyRefunded(para).into());
|
||||
|
||||
// Funds still left over
|
||||
assert!(!Balances::free_balance(account_id).is_zero());
|
||||
|
||||
// Call again
|
||||
assert_ok!(Crowdloan::refund(Origin::signed(1337), para));
|
||||
assert_eq!(last_event(), super::RawEvent::AllRefunded(para).into());
|
||||
assert_eq!(last_event(), super::Event::<Test>::AllRefunded(para).into());
|
||||
|
||||
// Funds are returned
|
||||
assert_eq!(Balances::free_balance(account_id), 0);
|
||||
@@ -1568,7 +1596,7 @@ mod tests {
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
mod benchmarking {
|
||||
use super::{*, Module as Crowdloan};
|
||||
use super::{*, Pallet as Crowdloan};
|
||||
use frame_system::RawOrigin;
|
||||
use frame_support::{
|
||||
assert_ok,
|
||||
@@ -1649,7 +1677,7 @@ mod benchmarking {
|
||||
|
||||
}: _(RawOrigin::Signed(caller), para_id, cap, first_period, last_period, end, Some(verifier))
|
||||
verify {
|
||||
assert_last_event::<T>(RawEvent::Created(para_id).into())
|
||||
assert_last_event::<T>(Event::<T>::Created(para_id).into())
|
||||
}
|
||||
|
||||
// Contribute has two arms: PreEnding and Ending, but both are equal complexity.
|
||||
@@ -1658,7 +1686,7 @@ mod benchmarking {
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
let contribution = T::MinContribution::get();
|
||||
CurrencyOf::<T>::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
|
||||
assert!(NewRaise::get().is_empty());
|
||||
assert!(NewRaise::<T>::get().is_empty());
|
||||
|
||||
let pubkey = crypto::create_ed25519_pubkey(b"//verifier".to_vec());
|
||||
let payload = (fund_index, &caller, BalanceOf::<T>::default(), contribution);
|
||||
@@ -1667,8 +1695,8 @@ mod benchmarking {
|
||||
}: _(RawOrigin::Signed(caller.clone()), fund_index, contribution, Some(sig))
|
||||
verify {
|
||||
// NewRaise is appended to, so we don't need to fill it up for worst case scenario.
|
||||
assert!(!NewRaise::get().is_empty());
|
||||
assert_last_event::<T>(RawEvent::Contributed(caller, fund_index, contribution).into());
|
||||
assert!(!NewRaise::<T>::get().is_empty());
|
||||
assert_last_event::<T>(Event::<T>::Contributed(caller, fund_index, contribution).into());
|
||||
}
|
||||
|
||||
withdraw {
|
||||
@@ -1679,7 +1707,7 @@ mod benchmarking {
|
||||
frame_system::Pallet::<T>::set_block_number(200u32.into());
|
||||
}: _(RawOrigin::Signed(caller), contributor.clone(), fund_index)
|
||||
verify {
|
||||
assert_last_event::<T>(RawEvent::Withdrew(contributor, fund_index, T::MinContribution::get()).into());
|
||||
assert_last_event::<T>(Event::<T>::Withdrew(contributor, fund_index, T::MinContribution::get()).into());
|
||||
}
|
||||
|
||||
// Worst case: Refund removes `RemoveKeysLimit` keys, and is fully refunded.
|
||||
@@ -1696,7 +1724,7 @@ mod benchmarking {
|
||||
frame_system::Pallet::<T>::set_block_number(200u32.into());
|
||||
}: _(RawOrigin::Signed(caller), fund_index)
|
||||
verify {
|
||||
assert_last_event::<T>(RawEvent::AllRefunded(fund_index).into());
|
||||
assert_last_event::<T>(Event::<T>::AllRefunded(fund_index).into());
|
||||
}
|
||||
|
||||
dissolve {
|
||||
@@ -1705,7 +1733,7 @@ mod benchmarking {
|
||||
frame_system::Pallet::<T>::set_block_number(T::BlockNumber::max_value());
|
||||
}: _(RawOrigin::Signed(caller.clone()), fund_index)
|
||||
verify {
|
||||
assert_last_event::<T>(RawEvent::Dissolved(fund_index).into());
|
||||
assert_last_event::<T>(Event::<T>::Dissolved(fund_index).into());
|
||||
}
|
||||
|
||||
edit {
|
||||
@@ -1733,7 +1761,7 @@ mod benchmarking {
|
||||
// Doesn't matter what we edit to, so use the same values.
|
||||
}: _(RawOrigin::Root, para_id, cap, first_period, last_period, end, Some(verifier))
|
||||
verify {
|
||||
assert_last_event::<T>(RawEvent::Edited(para_id).into())
|
||||
assert_last_event::<T>(Event::<T>::Edited(para_id).into())
|
||||
}
|
||||
|
||||
add_memo {
|
||||
@@ -1754,12 +1782,12 @@ mod benchmarking {
|
||||
let fund_index = create_fund::<T>(1, 100u32.into());
|
||||
let caller: T::AccountId = whitelisted_caller();
|
||||
contribute_fund::<T>(&caller, fund_index);
|
||||
NewRaise::kill();
|
||||
assert!(NewRaise::get().is_empty());
|
||||
NewRaise::<T>::kill();
|
||||
assert!(NewRaise::<T>::get().is_empty());
|
||||
}: _(RawOrigin::Signed(caller), fund_index)
|
||||
verify {
|
||||
assert!(!NewRaise::get().is_empty());
|
||||
assert_last_event::<T>(RawEvent::AddedToNewRaise(fund_index).into())
|
||||
assert!(!NewRaise::<T>::get().is_empty());
|
||||
assert_last_event::<T>(Event::<T>::AddedToNewRaise(fund_index).into())
|
||||
}
|
||||
|
||||
// Worst case scenario: N funds are all in the `NewRaise` list, we are
|
||||
@@ -1790,13 +1818,13 @@ mod benchmarking {
|
||||
T::Auctioneer::new_auction(duration, lease_period_index)?;
|
||||
|
||||
assert_eq!(T::Auctioneer::is_ending(end_block), Some(0u32.into()));
|
||||
assert_eq!(NewRaise::get().len(), n as usize);
|
||||
let old_endings_count = EndingsCount::get();
|
||||
assert_eq!(NewRaise::<T>::get().len(), n as usize);
|
||||
let old_endings_count = EndingsCount::<T>::get();
|
||||
}: {
|
||||
Crowdloan::<T>::on_initialize(end_block);
|
||||
} verify {
|
||||
assert_eq!(EndingsCount::get(), old_endings_count + 1);
|
||||
assert_last_event::<T>(RawEvent::HandleBidResult((n - 1).into(), Ok(())).into());
|
||||
assert_eq!(EndingsCount::<T>::get(), old_endings_count + 1);
|
||||
assert_last_event::<T>(Event::<T>::HandleBidResult((n - 1).into(), Ok(())).into());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -366,7 +366,7 @@ fn basic_end_to_end_works() {
|
||||
run_to_block(109);
|
||||
assert_eq!(
|
||||
last_event(),
|
||||
crowdloan::RawEvent::HandleBidResult(ParaId::from(para_2), Ok(())).into(),
|
||||
crowdloan::Event::<Test>::HandleBidResult(ParaId::from(para_2), Ok(())).into(),
|
||||
);
|
||||
run_to_block(110);
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user