mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 23:21:06 +00:00
Rewrap all comments to 100 line width (#9490)
* reformat everything again * manual formatting * last manual fix * Fix build
This commit is contained in:
@@ -439,7 +439,8 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
|
||||
// Burn any dust if needed.
|
||||
if let Some(burn) = maybe_burn {
|
||||
// Debit dust from supply; this will not saturate since it's already checked in prep.
|
||||
// Debit dust from supply; this will not saturate since it's already checked in
|
||||
// prep.
|
||||
debug_assert!(details.supply >= burn, "checked in prep; qed");
|
||||
details.supply = details.supply.saturating_sub(burn);
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
//! account that issues the asset. This is a privileged operation.
|
||||
//! * **Asset transfer**: The reduction of the balance of an asset of one account with the
|
||||
//! corresponding increase in the balance of another.
|
||||
//! * **Asset destruction**: The process of reduce the balance of an asset of one account. This is
|
||||
//! a privileged operation.
|
||||
//! * **Asset destruction**: The process of reduce the balance of an asset of one account. This is a
|
||||
//! privileged operation.
|
||||
//! * **Fungible asset**: An asset whose units are interchangeable.
|
||||
//! * **Issuer**: An account ID uniquely privileged to be able to mint a particular class of assets.
|
||||
//! * **Freezer**: An account ID uniquely privileged to be able to freeze an account from
|
||||
@@ -54,8 +54,8 @@
|
||||
//! * **Non-fungible asset**: An asset for which each unit has unique characteristics.
|
||||
//! * **Owner**: An account ID uniquely privileged to be able to destroy a particular asset class,
|
||||
//! or to set the Issuer, Freezer or Admin of that asset class.
|
||||
//! * **Approval**: The act of allowing an account the permission to transfer some
|
||||
//! balance of asset from the approving account into some third-party destination account.
|
||||
//! * **Approval**: The act of allowing an account the permission to transfer some balance of asset
|
||||
//! from the approving account into some third-party destination account.
|
||||
//! * **Sufficiency**: The idea of a minimum-balance of an asset being sufficient to allow the
|
||||
//! account's existence on the system without requiring any other existential-deposit.
|
||||
//!
|
||||
@@ -104,7 +104,8 @@
|
||||
//! * `set_team`: Changes an asset class's Admin, Freezer and Issuer; called by the asset class's
|
||||
//! Owner.
|
||||
//!
|
||||
//! Please refer to the [`Call`] enum and its associated variants for documentation on each function.
|
||||
//! Please refer to the [`Call`] enum and its associated variants for documentation on each
|
||||
//! function.
|
||||
//!
|
||||
//! ### Public Functions
|
||||
//! <!-- Original author of descriptions: @gavofyork -->
|
||||
@@ -339,7 +340,8 @@ pub mod pallet {
|
||||
BadWitness,
|
||||
/// Minimum balance should be non-zero.
|
||||
MinBalanceZero,
|
||||
/// No provider reference exists to allow a non-zero balance of a non-self-sufficient asset.
|
||||
/// No provider reference exists to allow a non-zero balance of a non-self-sufficient
|
||||
/// asset.
|
||||
NoProvider,
|
||||
/// Invalid metadata given.
|
||||
BadMetadata,
|
||||
@@ -418,8 +420,8 @@ pub mod pallet {
|
||||
/// - `id`: The identifier of the new asset. This must not be currently in use to identify
|
||||
/// an existing asset.
|
||||
/// - `owner`: The owner of this class of assets. The owner has full superuser permissions
|
||||
/// over this asset, but may later change and configure the permissions using `transfer_ownership`
|
||||
/// and `set_team`.
|
||||
/// over this asset, but may later change and configure the permissions using
|
||||
/// `transfer_ownership` and `set_team`.
|
||||
/// - `min_balance`: The minimum balance of this new asset that any single account must
|
||||
/// have. If an account's balance is reduced below this, then it collapses to zero.
|
||||
///
|
||||
|
||||
@@ -183,7 +183,8 @@ pub enum ConversionError {
|
||||
MinBalanceZero,
|
||||
/// The asset is not present in storage.
|
||||
AssetMissing,
|
||||
/// The asset is not sufficient and thus does not have a reliable `min_balance` so it cannot be converted.
|
||||
/// The asset is not sufficient and thus does not have a reliable `min_balance` so it cannot be
|
||||
/// converted.
|
||||
AssetNotSufficient,
|
||||
}
|
||||
|
||||
@@ -210,10 +211,11 @@ where
|
||||
{
|
||||
type Error = ConversionError;
|
||||
|
||||
/// Convert the given balance value into an asset balance based on the ratio between the fungible's
|
||||
/// minimum balance and the minimum asset balance.
|
||||
/// Convert the given balance value into an asset balance based on the ratio between the
|
||||
/// fungible's minimum balance and the minimum asset balance.
|
||||
///
|
||||
/// Will return `Err` if the asset is not found, not sufficient or the fungible's minimum balance is zero.
|
||||
/// Will return `Err` if the asset is not found, not sufficient or the fungible's minimum
|
||||
/// balance is zero.
|
||||
fn to_asset_balance(
|
||||
balance: BalanceOf<F, T>,
|
||||
asset_id: AssetIdOf<T, I>,
|
||||
|
||||
@@ -165,14 +165,14 @@ pub mod pallet {
|
||||
type SwapAction: SwapAction<Self::AccountId, Self> + Parameter;
|
||||
/// Limit of proof size.
|
||||
///
|
||||
/// Atomic swap is only atomic if once the proof is revealed, both parties can submit the proofs
|
||||
/// on-chain. If A is the one that generates the proof, then it requires that either:
|
||||
/// Atomic swap is only atomic if once the proof is revealed, both parties can submit the
|
||||
/// proofs on-chain. If A is the one that generates the proof, then it requires that either:
|
||||
/// - A's blockchain has the same proof length limit as B's blockchain.
|
||||
/// - Or A's blockchain has shorter proof length limit as B's blockchain.
|
||||
///
|
||||
/// If B sees A is on a blockchain with larger proof length limit, then it should kindly refuse
|
||||
/// to accept the atomic swap request if A generates the proof, and asks that B generates the
|
||||
/// proof instead.
|
||||
/// If B sees A is on a blockchain with larger proof length limit, then it should kindly
|
||||
/// refuse to accept the atomic swap request if A generates the proof, and asks that B
|
||||
/// generates the proof instead.
|
||||
#[pallet::constant]
|
||||
type ProofLimit: Get<u32>;
|
||||
}
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
//!
|
||||
//! ### Public Functions
|
||||
//!
|
||||
//! - `slot_duration` - Determine the Aura slot-duration based on the Timestamp module configuration.
|
||||
//! - `slot_duration` - Determine the Aura slot-duration based on the Timestamp module
|
||||
//! configuration.
|
||||
//!
|
||||
//! ## Related Modules
|
||||
//!
|
||||
@@ -99,7 +100,8 @@ pub mod pallet {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO [#3398] Generate offence report for all authorities that skipped their slots.
|
||||
// TODO [#3398] Generate offence report for all authorities that skipped their
|
||||
// slots.
|
||||
|
||||
T::DbWeight::get().reads_writes(2, 1)
|
||||
} else {
|
||||
|
||||
@@ -140,8 +140,8 @@ pub mod pallet {
|
||||
/// further constraints on what uncles can be included, other than their ancestry.
|
||||
///
|
||||
/// For PoW, as long as the seals are checked, there is no need to use anything
|
||||
/// but the `VerifySeal` implementation as the filter. This is because the cost of making many equivocating
|
||||
/// uncles is high.
|
||||
/// but the `VerifySeal` implementation as the filter. This is because the cost of making
|
||||
/// many equivocating uncles is high.
|
||||
///
|
||||
/// For PoS, there is no such limitation, so a further constraint must be imposed
|
||||
/// beyond a seal check in order to prevent an arbitrary number of
|
||||
|
||||
@@ -135,8 +135,8 @@ pub mod pallet {
|
||||
/// BABE requires some logic to be triggered on every block to query for whether an epoch
|
||||
/// has ended and to perform the transition to the next epoch.
|
||||
///
|
||||
/// Typically, the `ExternalTrigger` type should be used. An internal trigger should only be used
|
||||
/// when no other module is responsible for changing authority set.
|
||||
/// Typically, the `ExternalTrigger` type should be used. An internal trigger should only be
|
||||
/// used when no other module is responsible for changing authority set.
|
||||
type EpochChangeTrigger: EpochChangeTrigger;
|
||||
|
||||
/// A way to check whether a given validator is disabled and should not be authoring blocks.
|
||||
@@ -281,7 +281,8 @@ pub mod pallet {
|
||||
#[pallet::getter(fn lateness)]
|
||||
pub(super) type Lateness<T: Config> = StorageValue<_, T::BlockNumber, ValueQuery>;
|
||||
|
||||
/// The configuration for the current epoch. Should never be `None` as it is initialized in genesis.
|
||||
/// The configuration for the current epoch. Should never be `None` as it is initialized in
|
||||
/// genesis.
|
||||
#[pallet::storage]
|
||||
pub(super) type EpochConfig<T> = StorageValue<_, BabeEpochConfiguration>;
|
||||
|
||||
@@ -496,11 +497,11 @@ impl<T: Config> Pallet<T> {
|
||||
})
|
||||
}
|
||||
|
||||
/// DANGEROUS: Enact an epoch change. Should be done on every block where `should_epoch_change` has returned `true`,
|
||||
/// and the caller is the only caller of this function.
|
||||
/// DANGEROUS: Enact an epoch change. Should be done on every block where `should_epoch_change`
|
||||
/// has returned `true`, and the caller is the only caller of this function.
|
||||
///
|
||||
/// Typically, this is not handled directly by the user, but by higher-level validator-set manager logic like
|
||||
/// `pallet-session`.
|
||||
/// Typically, this is not handled directly by the user, but by higher-level validator-set
|
||||
/// manager logic like `pallet-session`.
|
||||
pub fn enact_epoch_change(
|
||||
authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
|
||||
next_authorities: Vec<(AuthorityId, BabeAuthorityWeight)>,
|
||||
|
||||
@@ -38,17 +38,18 @@
|
||||
//!
|
||||
//! ### Terminology
|
||||
//!
|
||||
//! - **Existential Deposit:** The minimum balance required to create or keep an account open. This prevents
|
||||
//! "dust accounts" from filling storage. When the free plus the reserved balance (i.e. the total balance)
|
||||
//! fall below this, then the account is said to be dead; and it loses its functionality as well as any
|
||||
//! prior history and all information on it is removed from the chain's state.
|
||||
//! No account should ever have a total balance that is strictly between 0 and the existential
|
||||
//! deposit (exclusive). If this ever happens, it indicates either a bug in this pallet or an
|
||||
//! erroneous raw mutation of storage.
|
||||
//! - **Existential Deposit:** The minimum balance required to create or keep an account open. This
|
||||
//! prevents "dust accounts" from filling storage. When the free plus the reserved balance (i.e.
|
||||
//! the total balance) fall below this, then the account is said to be dead; and it loses its
|
||||
//! functionality as well as any prior history and all information on it is removed from the
|
||||
//! chain's state. No account should ever have a total balance that is strictly between 0 and the
|
||||
//! existential deposit (exclusive). If this ever happens, it indicates either a bug in this
|
||||
//! pallet or an erroneous raw mutation of storage.
|
||||
//!
|
||||
//! - **Total Issuance:** The total number of units in existence in a system.
|
||||
//!
|
||||
//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after its
|
||||
//! - **Reaping an account:** The act of removing an account by resetting its nonce. Happens after
|
||||
//! its
|
||||
//! total balance has become zero (or, strictly speaking, less than the Existential Deposit).
|
||||
//!
|
||||
//! - **Free Balance:** The portion of a balance that is not reserved. The free balance is the only
|
||||
@@ -57,18 +58,21 @@
|
||||
//! - **Reserved Balance:** Reserved balance still belongs to the account holder, but is suspended.
|
||||
//! Reserved balance can still be slashed, but only after all the free balance has been slashed.
|
||||
//!
|
||||
//! - **Imbalance:** A condition when some funds were credited or debited without equal and opposite accounting
|
||||
//! (i.e. a difference between total issuance and account balances). Functions that result in an imbalance will
|
||||
//! return an object of the `Imbalance` trait that can be managed within your runtime logic. (If an imbalance is
|
||||
//! simply dropped, it should automatically maintain any book-keeping such as total issuance.)
|
||||
//! - **Imbalance:** A condition when some funds were credited or debited without equal and opposite
|
||||
//! accounting
|
||||
//! (i.e. a difference between total issuance and account balances). Functions that result in an
|
||||
//! imbalance will return an object of the `Imbalance` trait that can be managed within your runtime
|
||||
//! logic. (If an imbalance is simply dropped, it should automatically maintain any book-keeping
|
||||
//! such as total issuance.)
|
||||
//!
|
||||
//! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block number. Multiple
|
||||
//! - **Lock:** A freeze on a specified amount of an account's free balance until a specified block
|
||||
//! number. Multiple
|
||||
//! locks always operate over the same funds, so they "overlay" rather than "stack".
|
||||
//!
|
||||
//! ### Implementations
|
||||
//!
|
||||
//! The Balances pallet provides implementations for the following traits. If these traits provide the functionality
|
||||
//! that you need, then you can avoid coupling with the Balances pallet.
|
||||
//! The Balances pallet provides implementations for the following traits. If these traits provide
|
||||
//! the functionality that you need, then you can avoid coupling with the Balances pallet.
|
||||
//!
|
||||
//! - [`Currency`](frame_support::traits::Currency): Functions for dealing with a
|
||||
//! fungible assets system.
|
||||
@@ -78,8 +82,8 @@
|
||||
//! - [`LockableCurrency`](frame_support::traits::LockableCurrency): Functions for
|
||||
//! dealing with accounts that allow liquidity restrictions.
|
||||
//! - [`Imbalance`](frame_support::traits::Imbalance): Functions for handling
|
||||
//! imbalances between total issuance in the system and account balances. Must be used when a function
|
||||
//! creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee).
|
||||
//! imbalances between total issuance in the system and account balances. Must be used when a
|
||||
//! function creates new funds (e.g. a reward) or destroys some funds (e.g. a system fee).
|
||||
//!
|
||||
//! ## Interface
|
||||
//!
|
||||
@@ -94,7 +98,8 @@
|
||||
//!
|
||||
//! ### Examples from the FRAME
|
||||
//!
|
||||
//! The Contract pallet uses the `Currency` trait to handle gas payment, and its types inherit from `Currency`:
|
||||
//! The Contract pallet uses the `Currency` trait to handle gas payment, and its types inherit from
|
||||
//! `Currency`:
|
||||
//!
|
||||
//! ```
|
||||
//! use frame_support::traits::Currency;
|
||||
@@ -249,18 +254,19 @@ pub mod pallet {
|
||||
/// The dispatch origin for this call must be `Signed` by the transactor.
|
||||
///
|
||||
/// # <weight>
|
||||
/// - Dependent on arguments but not critical, given proper implementations for
|
||||
/// input config types. See related functions below.
|
||||
/// - It contains a limited number of reads and writes internally and no complex computation.
|
||||
/// - Dependent on arguments but not critical, given proper implementations for input config
|
||||
/// types. See related functions below.
|
||||
/// - It contains a limited number of reads and writes internally and no complex
|
||||
/// computation.
|
||||
///
|
||||
/// Related functions:
|
||||
///
|
||||
/// - `ensure_can_withdraw` is always called internally but has a bounded complexity.
|
||||
/// - Transferring balances to accounts that did not exist before will cause
|
||||
/// `T::OnNewAccount::on_new_account` to be called.
|
||||
/// `T::OnNewAccount::on_new_account` to be called.
|
||||
/// - Removing enough funds from an account will trigger `T::DustRemoval::on_unbalanced`.
|
||||
/// - `transfer_keep_alive` works the same way as `transfer`, but has an additional
|
||||
/// check that the transfer will not kill the origin account.
|
||||
/// - `transfer_keep_alive` works the same way as `transfer`, but has an additional check
|
||||
/// that the transfer will not kill the origin account.
|
||||
/// ---------------------------------
|
||||
/// - Base Weight: 73.64 µs, worst case scenario (account created, account removed)
|
||||
/// - DB Weight: 1 Read and 1 Write to destination account
|
||||
@@ -344,8 +350,8 @@ pub mod pallet {
|
||||
/// Exactly as `transfer`, except the origin must be root and the source account may be
|
||||
/// specified.
|
||||
/// # <weight>
|
||||
/// - Same as transfer, but additional read and write because the source account is
|
||||
/// not assumed to be in the overlay.
|
||||
/// - Same as transfer, but additional read and write because the source account is not
|
||||
/// assumed to be in the overlay.
|
||||
/// # </weight>
|
||||
#[pallet::weight(T::WeightInfo::force_transfer())]
|
||||
pub fn force_transfer(
|
||||
@@ -403,8 +409,7 @@ pub mod pallet {
|
||||
/// - `keep_alive`: A boolean to determine if the `transfer_all` operation should send all
|
||||
/// of the funds the account has, causing the sender account to be killed (false), or
|
||||
/// transfer everything except at least the existential deposit, which will guarantee to
|
||||
/// keep the sender account alive (true).
|
||||
/// # <weight>
|
||||
/// keep the sender account alive (true). # <weight>
|
||||
/// - O(1). Just like transfer, but reading the user's transferable balance first.
|
||||
/// #</weight>
|
||||
#[pallet::weight(T::WeightInfo::transfer_all())]
|
||||
@@ -1052,8 +1057,8 @@ impl<T: Config<I>, I: 'static> fungible::Inspect<T::AccountId> for Pallet<T, I>
|
||||
if frame_system::Pallet::<T>::can_dec_provider(who) && !keep_alive {
|
||||
liquid
|
||||
} else {
|
||||
// `must_remain_to_exist` is the part of liquid balance which must remain to keep total over
|
||||
// ED.
|
||||
// `must_remain_to_exist` is the part of liquid balance which must remain to keep total
|
||||
// over ED.
|
||||
let must_remain_to_exist =
|
||||
T::ExistentialDeposit::get().saturating_sub(a.total() - liquid);
|
||||
liquid.saturating_sub(must_remain_to_exist)
|
||||
@@ -1464,8 +1469,8 @@ where
|
||||
.checked_sub(&value)
|
||||
.ok_or(Error::<T, I>::InsufficientBalance)?;
|
||||
|
||||
// NOTE: total stake being stored in the same type means that this could never overflow
|
||||
// but better to be safe than sorry.
|
||||
// NOTE: total stake being stored in the same type means that this could
|
||||
// never overflow but better to be safe than sorry.
|
||||
to_account.free =
|
||||
to_account.free.checked_add(&value).ok_or(ArithmeticError::Overflow)?;
|
||||
|
||||
@@ -1480,8 +1485,8 @@ where
|
||||
)
|
||||
.map_err(|_| Error::<T, I>::LiquidityRestrictions)?;
|
||||
|
||||
// TODO: This is over-conservative. There may now be other providers, and this pallet
|
||||
// may not even be a provider.
|
||||
// TODO: This is over-conservative. There may now be other providers, and
|
||||
// this pallet may not even be a provider.
|
||||
let allow_death = existence_requirement == ExistenceRequirement::AllowDeath;
|
||||
let allow_death =
|
||||
allow_death && system::Pallet::<T>::can_dec_provider(transactor);
|
||||
@@ -1509,9 +1514,9 @@ where
|
||||
/// Is a no-op if `value` to be slashed is zero or the account does not exist.
|
||||
///
|
||||
/// NOTE: `slash()` prefers free balance, but assumes that reserve balance can be drawn
|
||||
/// from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid having
|
||||
/// to draw from reserved funds, however we err on the side of punishment if things are inconsistent
|
||||
/// or `can_slash` wasn't used appropriately.
|
||||
/// from in extreme circumstances. `can_slash()` should be used prior to `slash()` to avoid
|
||||
/// having to draw from reserved funds, however we err on the side of punishment if things are
|
||||
/// inconsistent or `can_slash` wasn't used appropriately.
|
||||
fn slash(who: &T::AccountId, value: Self::Balance) -> (Self::NegativeImbalance, Self::Balance) {
|
||||
if value.is_zero() {
|
||||
return (NegativeImbalance::zero(), Zero::zero())
|
||||
@@ -1528,7 +1533,8 @@ where
|
||||
-> Result<(Self::NegativeImbalance, Self::Balance), DispatchError> {
|
||||
// Best value is the most amount we can slash following liveness rules.
|
||||
let best_value = match attempt {
|
||||
// First attempt we try to slash the full amount, and see if liveness issues happen.
|
||||
// First attempt we try to slash the full amount, and see if liveness issues
|
||||
// happen.
|
||||
0 => value,
|
||||
// If acting as a critical provider (i.e. first attempt failed), then slash
|
||||
// as much as possible while leaving at least at ED.
|
||||
@@ -1548,7 +1554,8 @@ where
|
||||
account.reserved -= reserved_slash; // Safe because of above check
|
||||
Ok((
|
||||
NegativeImbalance::new(free_slash + reserved_slash),
|
||||
value - free_slash - reserved_slash, /* Safe because value is gt or eq total slashed */
|
||||
value - free_slash - reserved_slash, /* Safe because value is gt or
|
||||
* eq total slashed */
|
||||
))
|
||||
} else {
|
||||
// Else we are done!
|
||||
@@ -1593,8 +1600,10 @@ where
|
||||
///
|
||||
/// This function is a no-op if:
|
||||
/// - the `value` to be deposited is zero; or
|
||||
/// - the `value` to be deposited is less than the required ED and the account does not yet exist; or
|
||||
/// - the deposit would necessitate the account to exist and there are no provider references; or
|
||||
/// - the `value` to be deposited is less than the required ED and the account does not yet
|
||||
/// exist; or
|
||||
/// - the deposit would necessitate the account to exist and there are no provider references;
|
||||
/// or
|
||||
/// - `value` is so large it would cause the balance of `who` to overflow.
|
||||
fn deposit_creating(who: &T::AccountId, value: Self::Balance) -> Self::PositiveImbalance {
|
||||
if value.is_zero() {
|
||||
@@ -1744,8 +1753,8 @@ where
|
||||
let actual = match Self::mutate_account(who, |account| {
|
||||
let actual = cmp::min(account.reserved, value);
|
||||
account.reserved -= actual;
|
||||
// defensive only: this can never fail since total issuance which is at least free+reserved
|
||||
// fits into the same data type.
|
||||
// defensive only: this can never fail since total issuance which is at least
|
||||
// free+reserved fits into the same data type.
|
||||
account.free = account.free.saturating_add(actual);
|
||||
actual
|
||||
}) {
|
||||
@@ -1991,7 +2000,8 @@ where
|
||||
status,
|
||||
)?;
|
||||
|
||||
// remain should always be zero but just to be defensive here
|
||||
// remain should always be zero but just to be defensive
|
||||
// here
|
||||
let actual = to_change.saturating_sub(remain);
|
||||
|
||||
// this add can't overflow but just to be defensive.
|
||||
@@ -2009,7 +2019,8 @@ where
|
||||
status,
|
||||
)?;
|
||||
|
||||
// remain should always be zero but just to be defensive here
|
||||
// remain should always be zero but just to be defensive
|
||||
// here
|
||||
let actual = to_change.saturating_sub(remain);
|
||||
|
||||
reserves
|
||||
|
||||
@@ -74,8 +74,8 @@ impl TryFrom<Option<String>> for AnalysisChoice {
|
||||
}
|
||||
|
||||
impl Analysis {
|
||||
// Useful for when there are no components, and we just need an median value of the benchmark results.
|
||||
// Note: We choose the median value because it is more robust to outliers.
|
||||
// Useful for when there are no components, and we just need an median value of the benchmark
|
||||
// results. Note: We choose the median value because it is more robust to outliers.
|
||||
fn median_value(r: &Vec<BenchmarkResults>, selector: BenchmarkSelector) -> Option<Self> {
|
||||
if r.is_empty() {
|
||||
return None
|
||||
|
||||
@@ -675,7 +675,7 @@ macro_rules! benchmark_backend {
|
||||
// Every variant must implement [`BenchmarkingSetup`].
|
||||
//
|
||||
// ```nocompile
|
||||
//
|
||||
//
|
||||
// struct Transfer;
|
||||
// impl BenchmarkingSetup for Transfer { ... }
|
||||
//
|
||||
@@ -1032,11 +1032,12 @@ macro_rules! impl_benchmark_test {
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// There is an optional fourth argument, with keyword syntax: `benchmarks_path = path_to_benchmarks_invocation`.
|
||||
/// In the typical case in which this macro is in the same module as the `benchmarks!` invocation,
|
||||
/// you don't need to supply this. However, if the `impl_benchmark_test_suite!` invocation is in a
|
||||
/// different module than the `benchmarks!` invocation, then you should provide the path to the
|
||||
/// module containing the `benchmarks!` invocation:
|
||||
/// There is an optional fourth argument, with keyword syntax: `benchmarks_path =
|
||||
/// path_to_benchmarks_invocation`. In the typical case in which this macro is in the same module as
|
||||
/// the `benchmarks!` invocation, you don't need to supply this. However, if the
|
||||
/// `impl_benchmark_test_suite!` invocation is in a different module than the `benchmarks!`
|
||||
/// invocation, then you should provide the path to the module containing the `benchmarks!`
|
||||
/// invocation:
|
||||
///
|
||||
/// ```rust,ignore
|
||||
/// mod benches {
|
||||
@@ -1065,7 +1066,8 @@ macro_rules! impl_benchmark_test {
|
||||
/// to these restrictions:
|
||||
///
|
||||
/// - It must be the name of a method applied to the output of the `new_test_ext` argument.
|
||||
/// - That method must have a signature capable of receiving a single argument of the form `impl FnOnce()`.
|
||||
/// - That method must have a signature capable of receiving a single argument of the form `impl
|
||||
/// FnOnce()`.
|
||||
// ## Notes (not for rustdoc)
|
||||
//
|
||||
// The biggest challenge for this macro is communicating the actual test functions to be run. We
|
||||
@@ -1258,8 +1260,8 @@ pub fn show_benchmark_debug_info(
|
||||
/// ```
|
||||
///
|
||||
/// The `whitelist` is a parameter you pass to control the DB read/write tracking.
|
||||
/// We use a vector of [TrackedStorageKey](./struct.TrackedStorageKey.html), which is a simple struct used to set
|
||||
/// if a key has been read or written to.
|
||||
/// We use a vector of [TrackedStorageKey](./struct.TrackedStorageKey.html), which is a simple
|
||||
/// struct used to set if a key has been read or written to.
|
||||
///
|
||||
/// For values that should be skipped entirely, we can just pass `key.into()`. For example:
|
||||
///
|
||||
|
||||
@@ -202,7 +202,8 @@ pub trait Benchmarking {
|
||||
fn add_to_whitelist(&mut self, add: TrackedStorageKey) {
|
||||
let mut whitelist = self.get_whitelist();
|
||||
match whitelist.iter_mut().find(|x| x.key == add.key) {
|
||||
// If we already have this key in the whitelist, update to be the most constrained value.
|
||||
// If we already have this key in the whitelist, update to be the most constrained
|
||||
// value.
|
||||
Some(item) => {
|
||||
item.reads += add.reads;
|
||||
item.writes += add.writes;
|
||||
@@ -239,8 +240,8 @@ pub trait Benchmarking<T> {
|
||||
/// extrinsic, so these are sometimes just called "extrinsics".
|
||||
///
|
||||
/// Parameters
|
||||
/// - `extra`: Also return benchmarks marked "extra" which would otherwise not be
|
||||
/// needed for weight calculation.
|
||||
/// - `extra`: Also return benchmarks marked "extra" which would otherwise not be needed for
|
||||
/// weight calculation.
|
||||
fn benchmarks(extra: bool) -> Vec<BenchmarkMetadata>;
|
||||
|
||||
/// Run the benchmarks for this pallet.
|
||||
|
||||
@@ -161,7 +161,8 @@ pub enum BountyStatus<AccountId, BlockNumber> {
|
||||
Approved,
|
||||
/// The bounty is funded and waiting for curator assignment.
|
||||
Funded,
|
||||
/// A curator has been proposed by the `ApproveOrigin`. Waiting for acceptance from the curator.
|
||||
/// A curator has been proposed by the `ApproveOrigin`. Waiting for acceptance from the
|
||||
/// curator.
|
||||
CuratorProposed {
|
||||
/// The assigned curator of this bounty.
|
||||
curator: AccountId,
|
||||
|
||||
@@ -774,7 +774,8 @@ fn cancel_and_refund() {
|
||||
|
||||
assert_ok!(Bounties::close_bounty(Origin::root(), 0));
|
||||
|
||||
assert_eq!(Treasury::pot(), 85); // - 25 + 10
|
||||
// `- 25 + 10`
|
||||
assert_eq!(Treasury::pot(), 85);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -114,7 +114,8 @@ where
|
||||
Endow::CollectRent => {
|
||||
// storage_size cannot be zero because otherwise a contract that is just above
|
||||
// the subsistence threshold does not pay rent given a large enough subsistence
|
||||
// threshold. But we need rent payments to occur in order to benchmark for worst cases.
|
||||
// threshold. But we need rent payments to occur in order to benchmark for worst
|
||||
// cases.
|
||||
let storage_size = u32::MAX / 10;
|
||||
|
||||
// Endowment should be large but not as large to inhibit rent payments.
|
||||
|
||||
@@ -86,8 +86,8 @@ pub trait ChainExtension<C: Config> {
|
||||
/// imported wasm function.
|
||||
///
|
||||
/// # Parameters
|
||||
/// - `func_id`: The first argument to `seal_call_chain_extension`. Usually used to
|
||||
/// determine which function to realize.
|
||||
/// - `func_id`: The first argument to `seal_call_chain_extension`. Usually used to determine
|
||||
/// which function to realize.
|
||||
/// - `env`: Access to the remaining arguments and the execution environment.
|
||||
///
|
||||
/// # Return
|
||||
|
||||
@@ -173,8 +173,8 @@ pub trait Ext: sealing::Sealed {
|
||||
/// Instantiate a contract from the given code.
|
||||
///
|
||||
/// Returns the original code size of the called contract.
|
||||
/// The newly created account will be associated with `code`. `value` specifies the amount of value
|
||||
/// transferred from this to the newly created account (also known as endowment).
|
||||
/// The newly created account will be associated with `code`. `value` specifies the amount of
|
||||
/// value transferred from this to the newly created account (also known as endowment).
|
||||
///
|
||||
/// # Return Value
|
||||
///
|
||||
@@ -190,8 +190,8 @@ pub trait Ext: sealing::Sealed {
|
||||
|
||||
/// Transfer all funds to `beneficiary` and delete the contract.
|
||||
///
|
||||
/// Since this function removes the self contract eagerly, if succeeded, no further actions should
|
||||
/// be performed on this `Ext` instance.
|
||||
/// Since this function removes the self contract eagerly, if succeeded, no further actions
|
||||
/// should be performed on this `Ext` instance.
|
||||
///
|
||||
/// This function will fail if the same contract is present on the contract
|
||||
/// call stack.
|
||||
@@ -199,8 +199,8 @@ pub trait Ext: sealing::Sealed {
|
||||
|
||||
/// Restores the given destination contract sacrificing the current one.
|
||||
///
|
||||
/// Since this function removes the self contract eagerly, if succeeded, no further actions should
|
||||
/// be performed on this `Ext` instance.
|
||||
/// Since this function removes the self contract eagerly, if succeeded, no further actions
|
||||
/// should be performed on this `Ext` instance.
|
||||
///
|
||||
/// This function will fail if the same contract is present
|
||||
/// on the contract call stack.
|
||||
@@ -1283,8 +1283,8 @@ mod sealing {
|
||||
|
||||
/// These tests exercise the executive layer.
|
||||
///
|
||||
/// In these tests the VM/loader are mocked. Instead of dealing with wasm bytecode they use simple closures.
|
||||
/// This allows you to tackle executive logic more thoroughly without writing a
|
||||
/// In these tests the VM/loader are mocked. Instead of dealing with wasm bytecode they use simple
|
||||
/// closures. This allows you to tackle executive logic more thoroughly without writing a
|
||||
/// wasm VM code.
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -17,43 +17,47 @@
|
||||
|
||||
//! # Contract Pallet
|
||||
//!
|
||||
//! The Contract module provides functionality for the runtime to deploy and execute WebAssembly smart-contracts.
|
||||
//! The Contract module provides functionality for the runtime to deploy and execute WebAssembly
|
||||
//! smart-contracts.
|
||||
//!
|
||||
//! - [`Config`]
|
||||
//! - [`Call`]
|
||||
//!
|
||||
//! ## Overview
|
||||
//!
|
||||
//! This module extends accounts based on the [`Currency`] trait to have smart-contract functionality. It can
|
||||
//! be used with other modules that implement accounts based on [`Currency`]. These "smart-contract accounts"
|
||||
//! have the ability to instantiate smart-contracts and make calls to other contract and non-contract accounts.
|
||||
//! This module extends accounts based on the [`Currency`] trait to have smart-contract
|
||||
//! functionality. It can be used with other modules that implement accounts based on [`Currency`].
|
||||
//! These "smart-contract accounts" have the ability to instantiate smart-contracts and make calls
|
||||
//! to other contract and non-contract accounts.
|
||||
//!
|
||||
//! The smart-contract code is stored once in a code cache, and later retrievable via its hash.
|
||||
//! This means that multiple smart-contracts can be instantiated from the same hash, without replicating
|
||||
//! the code each time.
|
||||
//! This means that multiple smart-contracts can be instantiated from the same hash, without
|
||||
//! replicating the code each time.
|
||||
//!
|
||||
//! When a smart-contract is called, its associated code is retrieved via the code hash and gets executed.
|
||||
//! This call can alter the storage entries of the smart-contract account, instantiate new smart-contracts,
|
||||
//! or call other smart-contracts.
|
||||
//! When a smart-contract is called, its associated code is retrieved via the code hash and gets
|
||||
//! executed. This call can alter the storage entries of the smart-contract account, instantiate new
|
||||
//! smart-contracts, or call other smart-contracts.
|
||||
//!
|
||||
//! Finally, when an account is reaped, its associated code and storage of the smart-contract account
|
||||
//! will also be deleted.
|
||||
//! Finally, when an account is reaped, its associated code and storage of the smart-contract
|
||||
//! account will also be deleted.
|
||||
//!
|
||||
//! ### Gas
|
||||
//!
|
||||
//! Senders must specify a gas limit with every call, as all instructions invoked by the smart-contract require gas.
|
||||
//! Unused gas is refunded after the call, regardless of the execution outcome.
|
||||
//! Senders must specify a gas limit with every call, as all instructions invoked by the
|
||||
//! smart-contract require gas. Unused gas is refunded after the call, regardless of the execution
|
||||
//! outcome.
|
||||
//!
|
||||
//! If the gas limit is reached, then all calls and state changes (including balance transfers) are only
|
||||
//! reverted at the current call's contract level. For example, if contract A calls B and B runs out of gas mid-call,
|
||||
//! then all of B's calls are reverted. Assuming correct error handling by contract A, A's other calls and state
|
||||
//! changes still persist.
|
||||
//! If the gas limit is reached, then all calls and state changes (including balance transfers) are
|
||||
//! only reverted at the current call's contract level. For example, if contract A calls B and B
|
||||
//! runs out of gas mid-call, then all of B's calls are reverted. Assuming correct error handling by
|
||||
//! contract A, A's other calls and state changes still persist.
|
||||
//!
|
||||
//! ### Notable Scenarios
|
||||
//!
|
||||
//! Contract call failures are not always cascading. When failures occur in a sub-call, they do not "bubble up",
|
||||
//! and the call will only revert at the specific contract level. For example, if contract A calls contract B, and B
|
||||
//! fails, A can decide how to handle that failure, either proceeding or reverting A's changes.
|
||||
//! Contract call failures are not always cascading. When failures occur in a sub-call, they do not
|
||||
//! "bubble up", and the call will only revert at the specific contract level. For example, if
|
||||
//! contract A calls contract B, and B fails, A can decide how to handle that failure, either
|
||||
//! proceeding or reverting A's changes.
|
||||
//!
|
||||
//! ## Interface
|
||||
//!
|
||||
@@ -226,17 +230,18 @@ pub mod pallet {
|
||||
/// deposited while the contract is alive. Costs for additional storage are added to
|
||||
/// this base cost.
|
||||
///
|
||||
/// This is a simple way to ensure that contracts with empty storage eventually get deleted by
|
||||
/// making them pay rent. This creates an incentive to remove them early in order to save rent.
|
||||
/// This is a simple way to ensure that contracts with empty storage eventually get deleted
|
||||
/// by making them pay rent. This creates an incentive to remove them early in order to save
|
||||
/// rent.
|
||||
#[pallet::constant]
|
||||
type DepositPerContract: Get<BalanceOf<Self>>;
|
||||
|
||||
/// The balance a contract needs to deposit per storage byte to stay alive indefinitely.
|
||||
///
|
||||
/// Let's suppose the deposit is 1,000 BU (balance units)/byte and the rent is 1 BU/byte/day,
|
||||
/// then a contract with 1,000,000 BU that uses 1,000 bytes of storage would pay no rent.
|
||||
/// But if the balance reduced to 500,000 BU and the storage stayed the same at 1,000,
|
||||
/// then it would pay 500 BU/day.
|
||||
/// Let's suppose the deposit is 1,000 BU (balance units)/byte and the rent is 1
|
||||
/// BU/byte/day, then a contract with 1,000,000 BU that uses 1,000 bytes of storage would
|
||||
/// pay no rent. But if the balance reduced to 500,000 BU and the storage stayed the same at
|
||||
/// 1,000, then it would pay 500 BU/day.
|
||||
#[pallet::constant]
|
||||
type DepositPerStorageByte: Get<BalanceOf<Self>>;
|
||||
|
||||
@@ -353,7 +358,8 @@ pub mod pallet {
|
||||
///
|
||||
/// Instantiation is executed as follows:
|
||||
///
|
||||
/// - The supplied `code` is instrumented, deployed, and a `code_hash` is created for that code.
|
||||
/// - The supplied `code` is instrumented, deployed, and a `code_hash` is created for that
|
||||
/// code.
|
||||
/// - If the `code_hash` already exists on the chain the underlying `code` will be shared.
|
||||
/// - The destination address is computed based on the sender, code_hash and the salt.
|
||||
/// - The smart-contract account is created at the computed address.
|
||||
@@ -458,7 +464,8 @@ pub mod pallet {
|
||||
|
||||
// Add some advantage for block producers (who send unsigned extrinsics) by
|
||||
// adding a handicap: for signed extrinsics we use a slightly older block number
|
||||
// for the eviction check. This can be viewed as if we pushed regular users back in past.
|
||||
// for the eviction check. This can be viewed as if we pushed regular users back in
|
||||
// past.
|
||||
let handicap = if signed { T::SignedClaimHandicap::get() } else { Zero::zero() };
|
||||
|
||||
// If poking the contract has lead to eviction of the contract, give out the rewards.
|
||||
@@ -530,8 +537,8 @@ pub mod pallet {
|
||||
/// # Params
|
||||
///
|
||||
/// - `contract`: The contract that emitted the event.
|
||||
/// - `data`: Data supplied by the contract. Metadata generated during contract
|
||||
/// compilation is needed to decode it.
|
||||
/// - `data`: Data supplied by the contract. Metadata generated during contract compilation
|
||||
/// is needed to decode it.
|
||||
ContractEmitted(T::AccountId, Vec<u8>),
|
||||
|
||||
/// A code with the specified hash was removed.
|
||||
|
||||
@@ -96,8 +96,8 @@ where
|
||||
///
|
||||
/// The `handicap` parameter gives a way to check the rent to a moment in the past instead
|
||||
/// of current block. E.g. if the contract is going to be evicted at the current block,
|
||||
/// `handicap = 1` can defer the eviction for 1 block. This is useful to handicap certain snitchers
|
||||
/// relative to others.
|
||||
/// `handicap = 1` can defer the eviction for 1 block. This is useful to handicap certain
|
||||
/// snitchers relative to others.
|
||||
///
|
||||
/// NOTE this function performs eviction eagerly. All changes are read and written directly to
|
||||
/// storage.
|
||||
@@ -148,12 +148,12 @@ where
|
||||
/// accessed at the beginning of the current block. Returns `None` in case if the contract was
|
||||
/// evicted before or as a result of the rent collection.
|
||||
///
|
||||
/// The returned value is only an estimation. It doesn't take into account any top ups, changing the
|
||||
/// rent allowance, or any problems coming from withdrawing the dues.
|
||||
/// The returned value is only an estimation. It doesn't take into account any top ups, changing
|
||||
/// the rent allowance, or any problems coming from withdrawing the dues.
|
||||
///
|
||||
/// NOTE that this is not a side-effect free function! It will actually collect rent and then
|
||||
/// compute the projection. This function is only used for implementation of an RPC method through
|
||||
/// `RuntimeApi` meaning that the changes will be discarded anyway.
|
||||
/// compute the projection. This function is only used for implementation of an RPC method
|
||||
/// through `RuntimeApi` meaning that the changes will be discarded anyway.
|
||||
pub fn compute_projection(account: &T::AccountId) -> RentProjectionResult<T::BlockNumber> {
|
||||
use ContractAccessError::IsTombstone;
|
||||
|
||||
@@ -357,8 +357,8 @@ where
|
||||
|
||||
/// Returns amount of funds available to consume by rent mechanism.
|
||||
///
|
||||
/// Rent mechanism cannot consume more than `rent_allowance` set by the contract and it cannot make
|
||||
/// the balance lower than [`subsistence_threshold`].
|
||||
/// Rent mechanism cannot consume more than `rent_allowance` set by the contract and it cannot
|
||||
/// make the balance lower than [`subsistence_threshold`].
|
||||
///
|
||||
/// In case the toal_balance is below the subsistence threshold, this function returns `None`.
|
||||
fn rent_budget(
|
||||
@@ -381,8 +381,8 @@ where
|
||||
|
||||
/// Consider the case for rent payment of the given account and returns a `Verdict`.
|
||||
///
|
||||
/// Use `handicap` in case you want to change the reference block number. (To get more details see
|
||||
/// `try_eviction` ).
|
||||
/// Use `handicap` in case you want to change the reference block number. (To get more details
|
||||
/// see `try_eviction` ).
|
||||
fn consider_case(
|
||||
account: &T::AccountId,
|
||||
current_block_number: T::BlockNumber,
|
||||
@@ -435,8 +435,8 @@ where
|
||||
.unwrap_or_else(|| <BalanceOf<T>>::max_value());
|
||||
let insufficient_rent = rent_budget < dues;
|
||||
|
||||
// If the rent payment cannot be withdrawn due to locks on the account balance, then evict the
|
||||
// account.
|
||||
// If the rent payment cannot be withdrawn due to locks on the account balance, then evict
|
||||
// the account.
|
||||
//
|
||||
// NOTE: This seems problematic because it provides a way to tombstone an account while
|
||||
// avoiding the last rent payment. In effect, someone could retroactively set rent_allowance
|
||||
@@ -566,8 +566,8 @@ impl<T: Config> OutstandingAmount<T> {
|
||||
enum Verdict<T: Config> {
|
||||
/// The contract is exempted from paying rent.
|
||||
///
|
||||
/// For example, it already paid its rent in the current block, or it has enough deposit for not
|
||||
/// paying rent at all.
|
||||
/// For example, it already paid its rent in the current block, or it has enough deposit for
|
||||
/// not paying rent at all.
|
||||
Exempt,
|
||||
/// The contract cannot afford payment within its rent budget so it gets evicted. However,
|
||||
/// because its balance is greater than the subsistence threshold it leaves a tombstone.
|
||||
|
||||
@@ -167,8 +167,8 @@ where
|
||||
{
|
||||
/// Reads a storage kv pair of a contract.
|
||||
///
|
||||
/// The read is performed from the `trie_id` only. The `address` is not necessary. If the contract
|
||||
/// doesn't store under the given `key` `None` is returned.
|
||||
/// The read is performed from the `trie_id` only. The `address` is not necessary. If the
|
||||
/// contract doesn't store under the given `key` `None` is returned.
|
||||
pub fn read(trie_id: &TrieId, key: &StorageKey) -> Option<Vec<u8>> {
|
||||
child::get_raw(&child_trie_info(&trie_id), &blake2_256(key))
|
||||
}
|
||||
@@ -230,7 +230,8 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Creates a new contract descriptor in the storage with the given code hash at the given address.
|
||||
/// Creates a new contract descriptor in the storage with the given code hash at the given
|
||||
/// address.
|
||||
///
|
||||
/// Returns `Err` if there is already a contract (or a tombstone) exists at the given address.
|
||||
pub fn new_contract(
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
//! - Before running contract code we check if the cached code has the schedule version that
|
||||
//! is equal to the current saved schedule.
|
||||
//! If it is equal then run the code, if it isn't reinstrument with the current schedule.
|
||||
//! - When we update the schedule we want it to have strictly greater version than the current saved one:
|
||||
//! this guarantees that every instrumented contract code in cache cannot have the version equal to the current one.
|
||||
//! Thus, before executing a contract it should be reinstrument with new schedule.
|
||||
//! - When we update the schedule we want it to have strictly greater version than the current saved
|
||||
//! one:
|
||||
//! this guarantees that every instrumented contract code in cache cannot have the version equal to
|
||||
//! the current one. Thus, before executing a contract it should be reinstrument with new schedule.
|
||||
|
||||
#[cfg(feature = "runtime-benchmarks")]
|
||||
pub use self::private::reinstrument;
|
||||
|
||||
@@ -279,8 +279,7 @@ impl<'a, T: Config> ContractModule<'a, T> {
|
||||
///
|
||||
/// This accomplishes two tasks:
|
||||
///
|
||||
/// - checks any imported function against defined host functions set, incl.
|
||||
/// their signatures.
|
||||
/// - checks any imported function against defined host functions set, incl. their signatures.
|
||||
/// - if there is a memory import, returns it's descriptor
|
||||
/// `import_fn_banlist`: list of function names that are disallowed to be imported
|
||||
fn scan_imports<C: ImportSatisfyCheck>(
|
||||
|
||||
@@ -534,8 +534,8 @@ where
|
||||
/// when the caller is not interested in the result.
|
||||
///
|
||||
/// `create_token` can optionally instruct this function to charge the gas meter with the token
|
||||
/// it returns. `create_token` receives the variable amount of bytes that are about to be copied by
|
||||
/// this function.
|
||||
/// it returns. `create_token` receives the variable amount of bytes that are about to be copied
|
||||
/// by this function.
|
||||
///
|
||||
/// In addition to the error conditions of `write_sandbox_memory` this functions returns
|
||||
/// `Err` if the size of the buffer located at `out_ptr` is too small to fit `buf`.
|
||||
|
||||
@@ -46,12 +46,12 @@
|
||||
//! - **Conviction:** An indication of a voter's strength of belief in their vote. An increase
|
||||
//! of one in conviction indicates that a token holder is willing to lock their tokens for twice
|
||||
//! as many lock periods after enactment.
|
||||
//! - **Vote:** A value that can either be in approval ("Aye") or rejection ("Nay")
|
||||
//! of a particular referendum.
|
||||
//! - **Vote:** A value that can either be in approval ("Aye") or rejection ("Nay") of a particular
|
||||
//! referendum.
|
||||
//! - **Proposal:** A submission to the chain that represents an action that a proposer (either an
|
||||
//! account or an external origin) suggests that the system adopt.
|
||||
//! - **Referendum:** A proposal that is in the process of being voted on for
|
||||
//! either acceptance or rejection as a change to the system.
|
||||
//! - **Referendum:** A proposal that is in the process of being voted on for either acceptance or
|
||||
//! rejection as a change to the system.
|
||||
//! - **Delegation:** The act of granting your voting power to the decisions of another account for
|
||||
//! up to a certain conviction.
|
||||
//!
|
||||
@@ -92,50 +92,50 @@
|
||||
//! - `unlock` - Redetermine the account's balance lock, potentially making tokens available.
|
||||
//!
|
||||
//! Preimage actions:
|
||||
//! - `note_preimage` - Registers the preimage for an upcoming proposal, requires
|
||||
//! a deposit that is returned once the proposal is enacted.
|
||||
//! - `note_preimage` - Registers the preimage for an upcoming proposal, requires a deposit that is
|
||||
//! returned once the proposal is enacted.
|
||||
//! - `note_preimage_operational` - same but provided by `T::OperationalPreimageOrigin`.
|
||||
//! - `note_imminent_preimage` - Registers the preimage for an upcoming proposal.
|
||||
//! Does not require a deposit, but the proposal must be in the dispatch queue.
|
||||
//! - `note_imminent_preimage` - Registers the preimage for an upcoming proposal. Does not require a
|
||||
//! deposit, but the proposal must be in the dispatch queue.
|
||||
//! - `note_imminent_preimage_operational` - same but provided by `T::OperationalPreimageOrigin`.
|
||||
//! - `reap_preimage` - Removes the preimage for an expired proposal. Will only
|
||||
//! work under the condition that it's the same account that noted it and
|
||||
//! after the voting period, OR it's a different account after the enactment period.
|
||||
//! - `reap_preimage` - Removes the preimage for an expired proposal. Will only work under the
|
||||
//! condition that it's the same account that noted it and after the voting period, OR it's a
|
||||
//! different account after the enactment period.
|
||||
//!
|
||||
//! #### Cancellation Origin
|
||||
//!
|
||||
//! This call can only be made by the `CancellationOrigin`.
|
||||
//!
|
||||
//! - `emergency_cancel` - Schedules an emergency cancellation of a referendum.
|
||||
//! Can only happen once to a specific referendum.
|
||||
//! - `emergency_cancel` - Schedules an emergency cancellation of a referendum. Can only happen once
|
||||
//! to a specific referendum.
|
||||
//!
|
||||
//! #### ExternalOrigin
|
||||
//!
|
||||
//! This call can only be made by the `ExternalOrigin`.
|
||||
//!
|
||||
//! - `external_propose` - Schedules a proposal to become a referendum once it is is legal
|
||||
//! for an externally proposed referendum.
|
||||
//! - `external_propose` - Schedules a proposal to become a referendum once it is is legal for an
|
||||
//! externally proposed referendum.
|
||||
//!
|
||||
//! #### External Majority Origin
|
||||
//!
|
||||
//! This call can only be made by the `ExternalMajorityOrigin`.
|
||||
//!
|
||||
//! - `external_propose_majority` - Schedules a proposal to become a majority-carries
|
||||
//! referendum once it is legal for an externally proposed referendum.
|
||||
//! - `external_propose_majority` - Schedules a proposal to become a majority-carries referendum
|
||||
//! once it is legal for an externally proposed referendum.
|
||||
//!
|
||||
//! #### External Default Origin
|
||||
//!
|
||||
//! This call can only be made by the `ExternalDefaultOrigin`.
|
||||
//!
|
||||
//! - `external_propose_default` - Schedules a proposal to become a negative-turnout-bias
|
||||
//! referendum once it is legal for an externally proposed referendum.
|
||||
//! - `external_propose_default` - Schedules a proposal to become a negative-turnout-bias referendum
|
||||
//! once it is legal for an externally proposed referendum.
|
||||
//!
|
||||
//! #### Fast Track Origin
|
||||
//!
|
||||
//! This call can only be made by the `FastTrackOrigin`.
|
||||
//!
|
||||
//! - `fast_track` - Schedules the current externally proposed proposal that
|
||||
//! is "majority-carries" to become a referendum immediately.
|
||||
//! - `fast_track` - Schedules the current externally proposed proposal that is "majority-carries"
|
||||
//! to become a referendum immediately.
|
||||
//!
|
||||
//! #### Veto Origin
|
||||
//!
|
||||
@@ -263,11 +263,12 @@ pub mod pallet {
|
||||
type Currency: ReservableCurrency<Self::AccountId>
|
||||
+ LockableCurrency<Self::AccountId, Moment = Self::BlockNumber>;
|
||||
|
||||
/// The minimum period of locking and the period between a proposal being approved and enacted.
|
||||
/// The minimum period of locking and the period between a proposal being approved and
|
||||
/// enacted.
|
||||
///
|
||||
/// It should generally be a little more than the unstake period to ensure that
|
||||
/// voting stakers have an opportunity to remove themselves from the system in the case where
|
||||
/// they are on the losing side of a vote.
|
||||
/// voting stakers have an opportunity to remove themselves from the system in the case
|
||||
/// where they are on the losing side of a vote.
|
||||
#[pallet::constant]
|
||||
type EnactmentPeriod: Get<Self::BlockNumber>;
|
||||
|
||||
@@ -287,27 +288,27 @@ pub mod pallet {
|
||||
/// "super-majority-required" referendum.
|
||||
type ExternalOrigin: EnsureOrigin<Self::Origin>;
|
||||
|
||||
/// Origin from which the next tabled referendum may be forced; this allows for the tabling of
|
||||
/// a majority-carries referendum.
|
||||
/// Origin from which the next tabled referendum may be forced; this allows for the tabling
|
||||
/// of a majority-carries referendum.
|
||||
type ExternalMajorityOrigin: EnsureOrigin<Self::Origin>;
|
||||
|
||||
/// Origin from which the next tabled referendum may be forced; this allows for the tabling of
|
||||
/// a negative-turnout-bias (default-carries) referendum.
|
||||
/// Origin from which the next tabled referendum may be forced; this allows for the tabling
|
||||
/// of a negative-turnout-bias (default-carries) referendum.
|
||||
type ExternalDefaultOrigin: EnsureOrigin<Self::Origin>;
|
||||
|
||||
/// Origin from which the next majority-carries (or more permissive) referendum may be tabled to
|
||||
/// vote according to the `FastTrackVotingPeriod` asynchronously in a similar manner to the
|
||||
/// emergency origin. It retains its threshold method.
|
||||
/// Origin from which the next majority-carries (or more permissive) referendum may be
|
||||
/// tabled to vote according to the `FastTrackVotingPeriod` asynchronously in a similar
|
||||
/// manner to the emergency origin. It retains its threshold method.
|
||||
type FastTrackOrigin: EnsureOrigin<Self::Origin>;
|
||||
|
||||
/// Origin from which the next majority-carries (or more permissive) referendum may be tabled to
|
||||
/// vote immediately and asynchronously in a similar manner to the emergency origin. It retains
|
||||
/// its threshold method.
|
||||
/// Origin from which the next majority-carries (or more permissive) referendum may be
|
||||
/// tabled to vote immediately and asynchronously in a similar manner to the emergency
|
||||
/// origin. It retains its threshold method.
|
||||
type InstantOrigin: EnsureOrigin<Self::Origin>;
|
||||
|
||||
/// Indicator for whether an emergency origin is even allowed to happen. Some chains may want
|
||||
/// to set this permanently to `false`, others may want to condition it on things such as
|
||||
/// an upgrade having happened recently.
|
||||
/// Indicator for whether an emergency origin is even allowed to happen. Some chains may
|
||||
/// want to set this permanently to `false`, others may want to condition it on things such
|
||||
/// as an upgrade having happened recently.
|
||||
#[pallet::constant]
|
||||
type InstantAllowed: Get<bool>;
|
||||
|
||||
@@ -446,8 +447,8 @@ pub mod pallet {
|
||||
|
||||
/// True if the last referendum tabled was submitted externally. False if it was a public
|
||||
/// proposal.
|
||||
// TODO: There should be any number of tabling origins, not just public and "external" (council).
|
||||
// https://github.com/paritytech/substrate/issues/5322
|
||||
// TODO: There should be any number of tabling origins, not just public and "external"
|
||||
// (council). https://github.com/paritytech/substrate/issues/5322
|
||||
#[pallet::storage]
|
||||
pub type LastTabledWasExternal<T> = StorageValue<_, bool, ValueQuery>;
|
||||
|
||||
@@ -508,7 +509,8 @@ pub mod pallet {
|
||||
pub enum Event<T: Config> {
|
||||
/// A motion has been proposed by a public account. \[proposal_index, deposit\]
|
||||
Proposed(PropIndex, BalanceOf<T>),
|
||||
/// A public proposal has been tabled for referendum vote. \[proposal_index, deposit, depositors\]
|
||||
/// A public proposal has been tabled for referendum vote. \[proposal_index, deposit,
|
||||
/// depositors\]
|
||||
Tabled(PropIndex, BalanceOf<T>, Vec<T::AccountId>),
|
||||
/// An external proposal has been tabled.
|
||||
ExternalTabled,
|
||||
@@ -824,7 +826,8 @@ pub mod pallet {
|
||||
delay: T::BlockNumber,
|
||||
) -> DispatchResult {
|
||||
// Rather complicated bit of code to ensure that either:
|
||||
// - `voting_period` is at least `FastTrackVotingPeriod` and `origin` is `FastTrackOrigin`; or
|
||||
// - `voting_period` is at least `FastTrackVotingPeriod` and `origin` is
|
||||
// `FastTrackOrigin`; or
|
||||
// - `InstantAllowed` is `true` and `origin` is `InstantOrigin`.
|
||||
let maybe_ensure_instant = if voting_period < T::FastTrackVotingPeriod::get() {
|
||||
Some(origin)
|
||||
@@ -932,8 +935,8 @@ pub mod pallet {
|
||||
/// - `to`: The account whose voting the `target` account's voting power will follow.
|
||||
/// - `conviction`: The conviction that will be attached to the delegated votes. When the
|
||||
/// account is undelegated, the funds will be locked for the corresponding period.
|
||||
/// - `balance`: The amount of the account's balance to be used in delegating. This must
|
||||
/// not be more than the account's current balance.
|
||||
/// - `balance`: The amount of the account's balance to be used in delegating. This must not
|
||||
/// be more than the account's current balance.
|
||||
///
|
||||
/// Emits `Delegated`.
|
||||
///
|
||||
@@ -1035,8 +1038,9 @@ pub mod pallet {
|
||||
encoded_proposal: Vec<u8>,
|
||||
) -> DispatchResultWithPostInfo {
|
||||
Self::note_imminent_preimage_inner(ensure_signed(origin)?, encoded_proposal)?;
|
||||
// We check that this preimage was not uploaded before in `note_imminent_preimage_inner`,
|
||||
// thus this call can only be successful once. If successful, user does not pay a fee.
|
||||
// We check that this preimage was not uploaded before in
|
||||
// `note_imminent_preimage_inner`, thus this call can only be successful once. If
|
||||
// successful, user does not pay a fee.
|
||||
Ok(Pays::No.into())
|
||||
}
|
||||
|
||||
@@ -1051,8 +1055,9 @@ pub mod pallet {
|
||||
) -> DispatchResultWithPostInfo {
|
||||
let who = T::OperationalPreimageOrigin::ensure_origin(origin)?;
|
||||
Self::note_imminent_preimage_inner(who, encoded_proposal)?;
|
||||
// We check that this preimage was not uploaded before in `note_imminent_preimage_inner`,
|
||||
// thus this call can only be successful once. If successful, user does not pay a fee.
|
||||
// We check that this preimage was not uploaded before in
|
||||
// `note_imminent_preimage_inner`, thus this call can only be successful once. If
|
||||
// successful, user does not pay a fee.
|
||||
Ok(Pays::No.into())
|
||||
}
|
||||
|
||||
@@ -1061,8 +1066,8 @@ pub mod pallet {
|
||||
/// The dispatch origin of this call must be _Signed_.
|
||||
///
|
||||
/// - `proposal_hash`: The preimage hash of a proposal.
|
||||
/// - `proposal_length_upper_bound`: an upper bound on length of the proposal.
|
||||
/// Extrinsic is weighted according to this value with no refund.
|
||||
/// - `proposal_length_upper_bound`: an upper bound on length of the proposal. Extrinsic is
|
||||
/// weighted according to this value with no refund.
|
||||
///
|
||||
/// This will only work after `VotingPeriod` blocks from the time that the preimage was
|
||||
/// noted, if it's the same account doing it. If it's a different account, then it'll only
|
||||
@@ -1620,11 +1625,10 @@ impl<T: Config> Pallet<T> {
|
||||
/// Table the waiting public proposal with the highest backing for a vote.
|
||||
fn launch_public(now: T::BlockNumber) -> DispatchResult {
|
||||
let mut public_props = Self::public_props();
|
||||
if let Some((winner_index, _)) = public_props.iter()
|
||||
.enumerate()
|
||||
.max_by_key(|x| Self::backing_for((x.1).0).unwrap_or_else(Zero::zero)
|
||||
/* ^^ defensive only: All current public proposals have an amount locked*/)
|
||||
{
|
||||
if let Some((winner_index, _)) = public_props.iter().enumerate().max_by_key(
|
||||
// defensive only: All current public proposals have an amount locked
|
||||
|x| Self::backing_for((x.1).0).unwrap_or_else(Zero::zero),
|
||||
) {
|
||||
let (prop_index, proposal, _) = public_props.swap_remove(winner_index);
|
||||
<PublicProps<T>>::put(public_props);
|
||||
|
||||
|
||||
@@ -334,8 +334,8 @@ pub enum Phase<Bn> {
|
||||
/// number.
|
||||
///
|
||||
/// We do not yet check whether the unsigned phase is active or passive. The intent is for the
|
||||
/// blockchain to be able to declare: "I believe that there exists an adequate signed solution,"
|
||||
/// advising validators not to bother running the unsigned offchain worker.
|
||||
/// blockchain to be able to declare: "I believe that there exists an adequate signed
|
||||
/// solution," advising validators not to bother running the unsigned offchain worker.
|
||||
///
|
||||
/// As validator nodes are free to edit their OCW code, they could simply ignore this advisory
|
||||
/// and always compute their own solution. However, by default, when the unsigned phase is
|
||||
@@ -716,20 +716,23 @@ pub mod pallet {
|
||||
Phase::Signed | Phase::Off
|
||||
if remaining <= unsigned_deadline && remaining > Zero::zero() =>
|
||||
{
|
||||
// our needs vary according to whether or not the unsigned phase follows a signed phase
|
||||
// our needs vary according to whether or not the unsigned phase follows a
|
||||
// signed phase
|
||||
let (need_snapshot, enabled, signed_weight) = if current_phase == Phase::Signed
|
||||
{
|
||||
// there was previously a signed phase: close the signed phase, no need for snapshot.
|
||||
// there was previously a signed phase: close the signed phase, no need for
|
||||
// snapshot.
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
// - `Self::finalize_signed_phase()` also appears in `fn do_elect`. This is
|
||||
// a guard against the case that `elect` is called prematurely. This adds
|
||||
// a small amount of overhead, but that is unfortunately unavoidable.
|
||||
// - `Self::finalize_signed_phase()` also appears in `fn do_elect`. This
|
||||
// is a guard against the case that `elect` is called prematurely. This
|
||||
// adds a small amount of overhead, but that is unfortunately
|
||||
// unavoidable.
|
||||
let (_success, weight) = Self::finalize_signed_phase();
|
||||
// In the future we can consider disabling the unsigned phase if the signed
|
||||
// phase completes successfully, but for now we're enabling it unconditionally
|
||||
// as a defensive measure.
|
||||
// phase completes successfully, but for now we're enabling it
|
||||
// unconditionally as a defensive measure.
|
||||
(false, true, weight)
|
||||
} else {
|
||||
// No signed phase: create a new snapshot, definitely `enable` the unsigned
|
||||
@@ -1068,6 +1071,7 @@ pub mod pallet {
|
||||
|
||||
#[pallet::origin]
|
||||
pub struct Origin<T>(PhantomData<T>);
|
||||
|
||||
#[pallet::validate_unsigned]
|
||||
impl<T: Config> ValidateUnsigned for Pallet<T> {
|
||||
type Call = Call<T>;
|
||||
@@ -1320,7 +1324,8 @@ impl<T: Config> Pallet<T> {
|
||||
<DesiredTargets<T>>::put(desired_targets);
|
||||
|
||||
// instead of using storage APIs, we do a manual encoding into a fixed-size buffer.
|
||||
// `encoded_size` encodes it without storing it anywhere, this should not cause any allocation.
|
||||
// `encoded_size` encodes it without storing it anywhere, this should not cause any
|
||||
// allocation.
|
||||
let snapshot = RoundSnapshot { voters, targets };
|
||||
let size = snapshot.encoded_size();
|
||||
log!(info, "snapshot pre-calculated size {:?}", size);
|
||||
@@ -1473,7 +1478,8 @@ impl<T: Config> Pallet<T> {
|
||||
// We have to unconditionally try finalizing the signed phase here. There are only two
|
||||
// possibilities:
|
||||
//
|
||||
// - signed phase was open, in which case this is essential for correct functioning of the system
|
||||
// - signed phase was open, in which case this is essential for correct functioning of the
|
||||
// system
|
||||
// - signed phase was complete or not started, in which case finalization is idempotent and
|
||||
// inexpensive (1 read of an empty vector).
|
||||
let (_, signed_finalize_weight) = Self::finalize_signed_phase();
|
||||
|
||||
@@ -401,9 +401,9 @@ pub mod pallet {
|
||||
/// origin is removed as a runner-up.
|
||||
/// - `origin` is a current member. In this case, the deposit is unreserved and origin is
|
||||
/// removed as a member, consequently not being a candidate for the next round anymore.
|
||||
/// Similar to [`remove_member`](Self::remove_member), if replacement runners exists,
|
||||
/// they are immediately used. If the prime is renouncing, then no prime will exist until
|
||||
/// the next round.
|
||||
/// Similar to [`remove_member`](Self::remove_member), if replacement runners exists, they
|
||||
/// are immediately used. If the prime is renouncing, then no prime will exist until the
|
||||
/// next round.
|
||||
///
|
||||
/// The dispatch origin of this call must be signed, and have one of the above roles.
|
||||
///
|
||||
@@ -673,9 +673,10 @@ pub mod pallet {
|
||||
"Genesis member does not have enough stake.",
|
||||
);
|
||||
|
||||
// Note: all members will only vote for themselves, hence they must be given exactly
|
||||
// their own stake as total backing. Any sane election should behave as such.
|
||||
// Nonetheless, stakes will be updated for term 1 onwards according to the election.
|
||||
// Note: all members will only vote for themselves, hence they must be given
|
||||
// exactly their own stake as total backing. Any sane election should behave as
|
||||
// such. Nonetheless, stakes will be updated for term 1 onwards according to the
|
||||
// election.
|
||||
Members::<T>::mutate(|members| {
|
||||
match members.binary_search_by(|m| m.who.cmp(member)) {
|
||||
Ok(_) =>
|
||||
@@ -692,9 +693,9 @@ pub mod pallet {
|
||||
});
|
||||
|
||||
// set self-votes to make persistent. Genesis voters don't have any bond, nor do
|
||||
// they have any lock. NOTE: this means that we will still try to remove a lock once
|
||||
// this genesis voter is removed, and for now it is okay because remove_lock is noop
|
||||
// if lock is not there.
|
||||
// they have any lock. NOTE: this means that we will still try to remove a lock
|
||||
// once this genesis voter is removed, and for now it is okay because
|
||||
// remove_lock is noop if lock is not there.
|
||||
<Voting<T>>::insert(
|
||||
&member,
|
||||
Voter { votes: vec![member.clone()], stake: *stake, deposit: Zero::zero() },
|
||||
|
||||
@@ -73,8 +73,8 @@ mod tests;
|
||||
// - remove inactive voter (either you or the target is removed; if the target, you get their
|
||||
// "voter" bond back; O(1); one fewer DB entry, one DB change)
|
||||
// - submit candidacy (you pay a "candidate" bond; O(1); one extra DB entry, two DB changes)
|
||||
// - present winner/runner-up (you may pay a "presentation" bond of O(voters) if the presentation
|
||||
// is invalid; O(voters) compute; ) protected operations:
|
||||
// - present winner/runner-up (you may pay a "presentation" bond of O(voters) if the presentation is
|
||||
// invalid; O(voters) compute; ) protected operations:
|
||||
// - remove candidacy (remove all votes for a candidate) (one fewer DB entry, two DB changes)
|
||||
|
||||
// to avoid a potentially problematic case of not-enough approvals prior to voting causing a
|
||||
@@ -128,8 +128,8 @@ pub struct VoterInfo<Balance> {
|
||||
/// Used to demonstrate the status of a particular index in the global voter list.
|
||||
#[derive(PartialEq, Eq, RuntimeDebug)]
|
||||
pub enum CellStatus {
|
||||
/// Any out of bound index. Means a push a must happen to the chunk pointed by `NextVoterSet<T>`.
|
||||
/// Voting fee is applied in case a new chunk is created.
|
||||
/// Any out of bound index. Means a push a must happen to the chunk pointed by
|
||||
/// `NextVoterSet<T>`. Voting fee is applied in case a new chunk is created.
|
||||
Head,
|
||||
/// Already occupied by another voter. Voting fee is applied.
|
||||
Occupied,
|
||||
@@ -850,13 +850,14 @@ impl<T: Config> Pallet<T> {
|
||||
None
|
||||
} else {
|
||||
let c = Self::members();
|
||||
let (next_possible, count, coming) =
|
||||
if let Some((tally_end, comers, leavers)) = Self::next_finalize() {
|
||||
// if there's a tally in progress, then next tally can begin immediately afterwards
|
||||
(tally_end, c.len() - leavers.len() + comers as usize, comers)
|
||||
} else {
|
||||
(<frame_system::Pallet<T>>::block_number(), c.len(), 0)
|
||||
};
|
||||
let (next_possible, count, coming) = if let Some((tally_end, comers, leavers)) =
|
||||
Self::next_finalize()
|
||||
{
|
||||
// if there's a tally in progress, then next tally can begin immediately afterwards
|
||||
(tally_end, c.len() - leavers.len() + comers as usize, comers)
|
||||
} else {
|
||||
(<frame_system::Pallet<T>>::block_number(), c.len(), 0)
|
||||
};
|
||||
if count < desired_seats as usize {
|
||||
Some(next_possible)
|
||||
} else {
|
||||
|
||||
@@ -131,7 +131,8 @@ pub mod pallet {
|
||||
|
||||
/// Number of blocks of cooldown after unsigned transaction is included.
|
||||
///
|
||||
/// This ensures that we only accept unsigned transactions once, every `UnsignedInterval` blocks.
|
||||
/// This ensures that we only accept unsigned transactions once, every `UnsignedInterval`
|
||||
/// blocks.
|
||||
#[pallet::constant]
|
||||
type UnsignedInterval: Get<Self::BlockNumber>;
|
||||
|
||||
@@ -439,9 +440,9 @@ impl<T: Config> Pallet<T> {
|
||||
// Submit signed will return a vector of results for all accounts that were found in the
|
||||
// local keystore with expected `KEY_TYPE`.
|
||||
let results = signer.send_signed_transaction(|_account| {
|
||||
// Received price is wrapped into a call to `submit_price` public function of this pallet.
|
||||
// This means that the transaction, when executed, will simply call that function passing
|
||||
// `price` as an argument.
|
||||
// Received price is wrapped into a call to `submit_price` public function of this
|
||||
// pallet. This means that the transaction, when executed, will simply call that
|
||||
// function passing `price` as an argument.
|
||||
Call::submit_price(price)
|
||||
});
|
||||
|
||||
|
||||
@@ -26,27 +26,35 @@
|
||||
//!
|
||||
//! ### Documentation Guidelines:
|
||||
//!
|
||||
//! <!-- Original author of paragraph: Various. Based on collation of review comments to PRs addressing issues with -->
|
||||
//! <!-- label 'S3-FRAME' in https://github.com/paritytech/substrate-developer-hub/issues -->
|
||||
//! <!-- Original author of paragraph: Various. Based on collation of review comments to PRs
|
||||
//! addressing issues with --> <!-- label 'S3-FRAME' in https://github.com/paritytech/substrate-developer-hub/issues -->
|
||||
//! <ul>
|
||||
//! <li>Documentation comments (i.e. <code>/// comment</code>) - should
|
||||
//! accompany pallet functions and be restricted to the pallet interface,
|
||||
//! not the internals of the pallet implementation. Only state inputs,
|
||||
//! outputs, and a brief description that mentions whether calling it
|
||||
//! requires root, but without repeating the source code details.
|
||||
//! Capitalize the first word of each documentation comment and end it with
|
||||
//! a full stop. See
|
||||
//! <a href="https://github.com/paritytech/substrate#72-contributing-to-documentation-for-substrate-packages"
|
||||
//! target="_blank"> Generic example of annotating source code with documentation comments</a></li>
|
||||
//! <li>Self-documenting code - Try to refactor code to be self-documenting.</li>
|
||||
//! <li>Code comments - Supplement complex code with a brief explanation, not every line of code.</li>
|
||||
//! <li>Identifiers - surround by backticks (i.e. <code>INHERENT_IDENTIFIER</code>, <code>InherentType</code>,
|
||||
//! <code>u64</code>)</li>
|
||||
//! <li>Usage scenarios - should be simple doctests. The compiler should ensure they stay valid.</li>
|
||||
//! <li>Extended tutorials - should be moved to external files and refer to.</li>
|
||||
//! <!-- Original author of paragraph: @AmarRSingh -->
|
||||
//! <li>Mandatory - include all of the sections/subsections where <b>MUST</b> is specified.</li>
|
||||
//! <li>Optional - optionally include sections/subsections where <b>CAN</b> is specified.</li>
|
||||
//! <li>Documentation comments (i.e. <code>/// comment</code>) - should
|
||||
//! accompany pallet functions and be restricted to the pallet interface,
|
||||
//! not the internals of the pallet implementation. Only state inputs,
|
||||
//! outputs, and a brief description that mentions whether calling it
|
||||
//! requires root, but without repeating the source code details.
|
||||
//! Capitalize the first word of each documentation comment and end it with
|
||||
//! a full stop. See
|
||||
//! <a href="https://github.com/paritytech/substrate#72-contributing-to-documentation-for-substrate-packages"
|
||||
//! target="_blank"> Generic example of annotating source code with documentation comments</a></li>
|
||||
//!
|
||||
//! <li>Self-documenting code - Try to refactor code to be self-documenting.</li>
|
||||
//!
|
||||
//! <li>Code comments - Supplement complex code with a brief explanation, not every line of
|
||||
//! code.</li>
|
||||
//!
|
||||
//! <li>Identifiers - surround by backticks (i.e. <code>INHERENT_IDENTIFIER</code>,
|
||||
//! <code>InherentType</code>, <code>u64</code>)</li>
|
||||
//!
|
||||
//! <li>Usage scenarios - should be simple doctests. The compiler should ensure they stay
|
||||
//! valid.</li>
|
||||
//!
|
||||
//! <li>Extended tutorials - should be moved to external files and refer to.</li>
|
||||
//!
|
||||
//! <li>Mandatory - include all of the sections/subsections where <b>MUST</b> is specified.</li>
|
||||
//!
|
||||
//! <li>Optional - optionally include sections/subsections where <b>CAN</b> is specified.</li>
|
||||
//! </ul>
|
||||
//!
|
||||
//! ### Documentation Template:<br>
|
||||
@@ -84,12 +92,13 @@
|
||||
//!
|
||||
//! \## Terminology
|
||||
//!
|
||||
//! // Add terminology used in the custom pallet. Include concepts, storage items, or actions that you think
|
||||
//! // deserve to be noted to give context to the rest of the documentation or pallet usage. The author needs to
|
||||
//! // use some judgment about what is included. We don't want a list of every storage item nor types - the user
|
||||
//! // can go to the code for that. For example, "transfer fee" is obvious and should not be included, but
|
||||
//! // "free balance" and "reserved balance" should be noted to give context to the pallet.
|
||||
//! // Please do not link to outside resources. The reference docs should be the ultimate source of truth.
|
||||
//! // Add terminology used in the custom pallet. Include concepts, storage items, or actions that
|
||||
//! you think // deserve to be noted to give context to the rest of the documentation or pallet
|
||||
//! usage. The author needs to // use some judgment about what is included. We don't want a list of
|
||||
//! every storage item nor types - the user // can go to the code for that. For example, "transfer
|
||||
//! fee" is obvious and should not be included, but // "free balance" and "reserved balance" should
|
||||
//! be noted to give context to the pallet. // Please do not link to outside resources. The
|
||||
//! reference docs should be the ultimate source of truth.
|
||||
//!
|
||||
//! <!-- Original author of heading: @Kianenigma in PR https://github.com/paritytech/substrate/pull/1951 -->
|
||||
//!
|
||||
@@ -106,7 +115,8 @@
|
||||
//! \#### <INSERT_SCENARIO_NAME>
|
||||
//!
|
||||
//! // Describe requirements prior to interacting with the custom pallet.
|
||||
//! // Describe the process of interacting with the custom pallet for this scenario and public API functions used.
|
||||
//! // Describe the process of interacting with the custom pallet for this scenario and public API
|
||||
//! functions used.
|
||||
//!
|
||||
//! \## Interface
|
||||
//!
|
||||
@@ -130,14 +140,16 @@
|
||||
//!
|
||||
//! <!-- Original author of paragraph: ??? -->
|
||||
//!
|
||||
//! // Reference documentation of aspects such as `storageItems` and `dispatchable` functions should only be
|
||||
//! // included in the <https://docs.rs> Rustdocs for Substrate and not repeated in the README file.
|
||||
//! // Reference documentation of aspects such as `storageItems` and `dispatchable` functions should
|
||||
//! // only be included in the <https://docs.rs> Rustdocs for Substrate and not repeated in the
|
||||
//! // README file.
|
||||
//!
|
||||
//! \### Dispatchable Functions
|
||||
//!
|
||||
//! <!-- Original author of paragraph: @AmarRSingh & @joepetrowski -->
|
||||
//!
|
||||
//! // A brief description of dispatchable functions and a link to the rustdoc with their actual documentation.
|
||||
//! // A brief description of dispatchable functions and a link to the rustdoc with their actual
|
||||
//! documentation.
|
||||
//!
|
||||
//! // <b>MUST</b> have link to Call enum
|
||||
//! // <b>MUST</b> have origin information included in function doc
|
||||
@@ -154,7 +166,8 @@
|
||||
//!
|
||||
//! <!-- Original author of paragraph: @AmarRSingh -->
|
||||
//!
|
||||
//! // It is up to the writer of the respective pallet (with respect to how much information to provide).
|
||||
//! // It is up to the writer of the respective pallet (with respect to how much information to
|
||||
//! provide).
|
||||
//!
|
||||
//! \#### Public Inspection functions - Immutable (getters)
|
||||
//!
|
||||
@@ -217,7 +230,8 @@
|
||||
//!
|
||||
//! \### Simple Code Snippet
|
||||
//!
|
||||
//! // Show a simple example (e.g. how to query a public getter function of <INSERT_CUSTOM_PALLET_NAME>)
|
||||
//! // Show a simple example (e.g. how to query a public getter function of
|
||||
//! <INSERT_CUSTOM_PALLET_NAME>)
|
||||
//!
|
||||
//! \### Example from FRAME
|
||||
//!
|
||||
@@ -408,10 +422,10 @@ pub mod pallet {
|
||||
// - Public calls that are signed by an external account.
|
||||
// - Root calls that are allowed to be made only by the governance system.
|
||||
// - Unsigned calls that can be of two kinds:
|
||||
// * "Inherent extrinsics" that are opinions generally held by the block
|
||||
// authors that build child blocks.
|
||||
// * Unsigned Transactions that are of intrinsic recognizable utility to the
|
||||
// network, and are validated by the runtime.
|
||||
// * "Inherent extrinsics" that are opinions generally held by the block authors that build
|
||||
// child blocks.
|
||||
// * Unsigned Transactions that are of intrinsic recognizable utility to the network, and are
|
||||
// validated by the runtime.
|
||||
//
|
||||
// Information about where this dispatch initiated from is provided as the first argument
|
||||
// "origin". As such functions must always look like:
|
||||
@@ -466,10 +480,10 @@ pub mod pallet {
|
||||
//
|
||||
// If you don't respect these rules, it is likely that your chain will be attackable.
|
||||
//
|
||||
// Each transaction must define a `#[pallet::weight(..)]` attribute to convey a set of static
|
||||
// information about its dispatch. FRAME System and FRAME Executive pallet then use this
|
||||
// information to properly execute the transaction, whilst keeping the total load of the
|
||||
// chain in a moderate rate.
|
||||
// Each transaction must define a `#[pallet::weight(..)]` attribute to convey a set of
|
||||
// static information about its dispatch. FRAME System and FRAME Executive pallet then use
|
||||
// this information to properly execute the transaction, whilst keeping the total load of
|
||||
// the chain in a moderate rate.
|
||||
//
|
||||
// The parenthesized value of the `#[pallet::weight(..)]` attribute can be any type that
|
||||
// implements a set of traits, namely [`WeighData`] and [`ClassifyDispatch`].
|
||||
@@ -478,8 +492,8 @@ pub mod pallet {
|
||||
// call. A higher weight means a larger transaction (less of which can be placed in a
|
||||
// single block).
|
||||
//
|
||||
// The weight for this extrinsic we rely on the auto-generated `WeightInfo` from the benchmark
|
||||
// toolchain.
|
||||
// The weight for this extrinsic we rely on the auto-generated `WeightInfo` from the
|
||||
// benchmark toolchain.
|
||||
#[pallet::weight(
|
||||
<T as pallet::Config>::WeightInfo::accumulate_dummy((*increase_by).saturated_into())
|
||||
)]
|
||||
@@ -522,8 +536,8 @@ pub mod pallet {
|
||||
// assume it's a one-off operation and substantial processing/storage/memory can be used
|
||||
// without worrying about gameability or attack scenarios.
|
||||
//
|
||||
// The weight for this extrinsic we use our own weight object `WeightForSetDummy` to determine
|
||||
// its weight
|
||||
// The weight for this extrinsic we use our own weight object `WeightForSetDummy` to
|
||||
// determine its weight
|
||||
#[pallet::weight(WeightForSetDummy::<T>(<BalanceOf<T>>::from(100u32)))]
|
||||
pub fn set_dummy(
|
||||
origin: OriginFor<T>,
|
||||
@@ -531,8 +545,8 @@ pub mod pallet {
|
||||
) -> DispatchResult {
|
||||
ensure_root(origin)?;
|
||||
|
||||
// Print out log or debug message in the console via log::{error, warn, info, debug, trace},
|
||||
// accepting format strings similar to `println!`.
|
||||
// Print out log or debug message in the console via log::{error, warn, info, debug,
|
||||
// trace}, accepting format strings similar to `println!`.
|
||||
// https://substrate.dev/rustdocs/v3.0.0/log/index.html
|
||||
info!("New value is now: {:?}", new_value);
|
||||
|
||||
@@ -631,7 +645,8 @@ impl<T: Config> Pallet<T> {
|
||||
let _sender = ensure_signed(origin)?;
|
||||
|
||||
let prev = <Foo<T>>::get();
|
||||
// Because Foo has 'default', the type of 'foo' in closure is the raw type instead of an Option<> type.
|
||||
// Because Foo has 'default', the type of 'foo' in closure is the raw type instead of an
|
||||
// Option<> type.
|
||||
let result = <Foo<T>>::mutate(|foo| {
|
||||
*foo = foo.saturating_add(increase_by);
|
||||
*foo
|
||||
|
||||
@@ -150,8 +150,7 @@ pub type OriginOf<E, C> = <CallOf<E, C> as Dispatchable>::Origin;
|
||||
/// - `UnsignedValidator`: The unsigned transaction validator of the runtime.
|
||||
/// - `AllPallets`: Tuple that contains all modules. Will be used to call e.g. `on_initialize`.
|
||||
/// - `OnRuntimeUpgrade`: Custom logic that should be called after a runtime upgrade. Modules are
|
||||
/// already called by `AllPallets`. It will be called before all modules will
|
||||
/// be called.
|
||||
/// already called by `AllPallets`. It will be called before all modules will be called.
|
||||
pub struct Executive<System, Block, Context, UnsignedValidator, AllPallets, OnRuntimeUpgrade = ()>(
|
||||
PhantomData<(System, Block, Context, UnsignedValidator, AllPallets, OnRuntimeUpgrade)>,
|
||||
);
|
||||
@@ -479,7 +478,8 @@ where
|
||||
}
|
||||
|
||||
/// Check a given signed transaction for validity. This doesn't execute any
|
||||
/// side-effects; it merely checks whether the transaction would panic if it were included or not.
|
||||
/// side-effects; it merely checks whether the transaction would panic if it were included or
|
||||
/// not.
|
||||
///
|
||||
/// Changes made to storage should be discarded.
|
||||
pub fn validate_transaction(
|
||||
|
||||
@@ -294,8 +294,8 @@ pub mod pallet {
|
||||
DurationTooBig,
|
||||
/// The amount of the bid is less than the minimum allowed.
|
||||
AmountTooSmall,
|
||||
/// The queue for the bid's duration is full and the amount bid is too low to get in through
|
||||
/// replacing an existing bid.
|
||||
/// The queue for the bid's duration is full and the amount bid is too low to get in
|
||||
/// through replacing an existing bid.
|
||||
BidTooLow,
|
||||
/// Gilt index is unknown.
|
||||
Unknown,
|
||||
@@ -506,8 +506,8 @@ pub mod pallet {
|
||||
pub struct IssuanceInfo<Balance> {
|
||||
/// The balance held in reserve over all active gilts.
|
||||
pub reserved: Balance,
|
||||
/// The issuance not held in reserve for active gilts. Together with `reserved` this sums to
|
||||
/// `Currency::total_issuance`.
|
||||
/// The issuance not held in reserve for active gilts. Together with `reserved` this sums
|
||||
/// to `Currency::total_issuance`.
|
||||
pub non_gilt: Balance,
|
||||
/// The balance that `reserved` is effectively worth, at present. This is not issued funds
|
||||
/// and could be less than `reserved` (though in most cases should be greater).
|
||||
@@ -586,8 +586,8 @@ pub mod pallet {
|
||||
let amount = bid.amount;
|
||||
// Can never overflow due to block above.
|
||||
remaining -= amount;
|
||||
// Should never underflow since it should track the total of the bids
|
||||
// exactly, but we'll be defensive.
|
||||
// Should never underflow since it should track the total of the
|
||||
// bids exactly, but we'll be defensive.
|
||||
qs[queue_index].1 = qs[queue_index].1.saturating_sub(bid.amount);
|
||||
|
||||
// Now to activate the bid...
|
||||
|
||||
@@ -118,8 +118,8 @@ pub mod pallet {
|
||||
type FieldDeposit: Get<BalanceOf<Self>>;
|
||||
|
||||
/// The amount held on deposit for a registered subaccount. This should account for the fact
|
||||
/// that one storage item's value will increase by the size of an account ID, and there will be
|
||||
/// another trie item whose value is the size of an account ID plus 32 bytes.
|
||||
/// that one storage item's value will increase by the size of an account ID, and there will
|
||||
/// be another trie item whose value is the size of an account ID plus 32 bytes.
|
||||
#[pallet::constant]
|
||||
type SubAccountDeposit: Get<BalanceOf<Self>>;
|
||||
|
||||
@@ -451,7 +451,8 @@ pub mod pallet {
|
||||
|
||||
Ok(Some(
|
||||
T::WeightInfo::set_subs_old(old_ids.len() as u32) // P: Real number of old accounts removed.
|
||||
.saturating_add(T::WeightInfo::set_subs_new(new_subs as u32)), /* S: New subs added. */
|
||||
// S: New subs added
|
||||
.saturating_add(T::WeightInfo::set_subs_new(new_subs as u32)),
|
||||
)
|
||||
.into())
|
||||
}
|
||||
|
||||
@@ -222,7 +222,8 @@ pub type ValidatorId<T> = <<T as Config>::ValidatorSet as ValidatorSet<
|
||||
<T as frame_system::Config>::AccountId,
|
||||
>>::ValidatorId;
|
||||
|
||||
/// A tuple of (ValidatorId, Identification) where `Identification` is the full identification of `ValidatorId`.
|
||||
/// A tuple of (ValidatorId, Identification) where `Identification` is the full identification of
|
||||
/// `ValidatorId`.
|
||||
pub type IdentificationTuple<T> = (
|
||||
ValidatorId<T>,
|
||||
<<T as Config>::ValidatorSet as ValidatorSetWithIdentification<
|
||||
@@ -375,8 +376,8 @@ pub mod pallet {
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// # <weight>
|
||||
/// - Complexity: `O(K + E)` where K is length of `Keys` (heartbeat.validators_len)
|
||||
/// and E is length of `heartbeat.network_state.external_address`
|
||||
/// - Complexity: `O(K + E)` where K is length of `Keys` (heartbeat.validators_len) and E is
|
||||
/// length of `heartbeat.network_state.external_address`
|
||||
/// - `O(K)`: decoding of length `K`
|
||||
/// - `O(E)`: decoding/encoding of length `E`
|
||||
/// - DbReads: pallet_session `Validators`, pallet_session `CurrentIndex`, `Keys`,
|
||||
@@ -447,7 +448,8 @@ pub mod pallet {
|
||||
}
|
||||
}
|
||||
|
||||
/// Invalid transaction custom error. Returned when validators_len field in heartbeat is incorrect.
|
||||
/// Invalid transaction custom error. Returned when validators_len field in heartbeat is
|
||||
/// incorrect.
|
||||
pub(crate) const INVALID_VALIDATORS_LEN: u8 = 10;
|
||||
|
||||
#[pallet::validate_unsigned]
|
||||
|
||||
@@ -48,8 +48,8 @@ pub mod pallet {
|
||||
/// The module's config trait.
|
||||
#[pallet::config]
|
||||
pub trait Config: frame_system::Config {
|
||||
/// Type used for storing an account's index; implies the maximum number of accounts the system
|
||||
/// can hold.
|
||||
/// Type used for storing an account's index; implies the maximum number of accounts the
|
||||
/// system can hold.
|
||||
type AccountIndex: Parameter
|
||||
+ Member
|
||||
+ MaybeSerializeDeserialize
|
||||
@@ -223,7 +223,8 @@ pub mod pallet {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Freeze an index so it will always point to the sender account. This consumes the deposit.
|
||||
/// Freeze an index so it will always point to the sender account. This consumes the
|
||||
/// deposit.
|
||||
///
|
||||
/// The dispatch origin for this call must be _Signed_ and the signing account must have a
|
||||
/// non-frozen account `index`.
|
||||
|
||||
@@ -266,9 +266,9 @@ pub mod pallet {
|
||||
*lottery = None;
|
||||
return T::WeightInfo::on_initialize_end()
|
||||
}
|
||||
// We choose not need to kill Participants and Tickets to avoid a large number
|
||||
// of writes at one time. Instead, data persists between lotteries, but is not used
|
||||
// if it is not relevant.
|
||||
// We choose not need to kill Participants and Tickets to avoid a large
|
||||
// number of writes at one time. Instead, data persists between lotteries,
|
||||
// but is not used if it is not relevant.
|
||||
}
|
||||
}
|
||||
return T::DbWeight::get().reads(1)
|
||||
|
||||
@@ -96,14 +96,14 @@ pub mod pallet {
|
||||
/// and some of the inner mmr nodes might be pruned from on-chain storage.
|
||||
/// The latter will contain all the entries in their full form.
|
||||
///
|
||||
/// Each node is stored in the Off-chain DB under key derived from the [`Self::INDEXING_PREFIX`] and
|
||||
/// it's in-tree index (MMR position).
|
||||
/// Each node is stored in the Off-chain DB under key derived from the
|
||||
/// [`Self::INDEXING_PREFIX`] and it's in-tree index (MMR position).
|
||||
const INDEXING_PREFIX: &'static [u8];
|
||||
|
||||
/// A hasher type for MMR.
|
||||
///
|
||||
/// To construct trie nodes that result in merging (bagging) two peaks, depending on the node
|
||||
/// kind we take either:
|
||||
/// To construct trie nodes that result in merging (bagging) two peaks, depending on the
|
||||
/// node kind we take either:
|
||||
/// - The node (hash) itself if it's an inner node.
|
||||
/// - The hash of SCALE-encoding of the leaf data if it's a leaf node.
|
||||
///
|
||||
@@ -128,22 +128,22 @@ pub mod pallet {
|
||||
|
||||
/// Data stored in the leaf nodes.
|
||||
///
|
||||
/// The [LeafData](primitives::LeafDataProvider) is responsible for returning the entire leaf
|
||||
/// data that will be inserted to the MMR.
|
||||
/// The [LeafData](primitives::LeafDataProvider) is responsible for returning the entire
|
||||
/// leaf data that will be inserted to the MMR.
|
||||
/// [LeafDataProvider](primitives::LeafDataProvider)s can be composed into tuples to put
|
||||
/// multiple elements into the tree. In such a case it might be worth using [primitives::Compact]
|
||||
/// to make MMR proof for one element of the tuple leaner.
|
||||
/// multiple elements into the tree. In such a case it might be worth using
|
||||
/// [primitives::Compact] to make MMR proof for one element of the tuple leaner.
|
||||
///
|
||||
/// Note that the leaf at each block MUST be unique. You may want to include a block hash or block
|
||||
/// number as an easiest way to ensure that.
|
||||
/// Note that the leaf at each block MUST be unique. You may want to include a block hash or
|
||||
/// block number as an easiest way to ensure that.
|
||||
type LeafData: primitives::LeafDataProvider;
|
||||
|
||||
/// A hook to act on the new MMR root.
|
||||
///
|
||||
/// For some applications it might be beneficial to make the MMR root available externally
|
||||
/// apart from having it in the storage. For instance you might output it in the header digest
|
||||
/// (see [`frame_system::Pallet::deposit_log`]) to make it available for Light Clients.
|
||||
/// Hook complexity should be `O(1)`.
|
||||
/// apart from having it in the storage. For instance you might output it in the header
|
||||
/// digest (see [`frame_system::Pallet::deposit_log`]) to make it available for Light
|
||||
/// Clients. Hook complexity should be `O(1)`.
|
||||
type OnNewRoot: primitives::OnNewRoot<<Self as Config<I>>::Hash>;
|
||||
|
||||
/// Weights for this pallet.
|
||||
|
||||
@@ -127,8 +127,8 @@ pub mod pallet {
|
||||
/// 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.
|
||||
/// 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
|
||||
@@ -333,9 +333,8 @@ pub mod pallet {
|
||||
/// - I/O: 1 read `O(S)`, up to 1 mutate `O(S)`. Up to one remove.
|
||||
/// - One event.
|
||||
/// - The weight of the `call`.
|
||||
/// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a
|
||||
/// deposit taken for its lifetime of
|
||||
/// `DepositBase + threshold * DepositFactor`.
|
||||
/// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a deposit
|
||||
/// taken for its lifetime of `DepositBase + threshold * DepositFactor`.
|
||||
/// -------------------------------
|
||||
/// - DB Weight:
|
||||
/// - Reads: Multisig Storage, [Caller Account], Calls (if `store_call`)
|
||||
@@ -400,9 +399,8 @@ pub mod pallet {
|
||||
/// - Up to one binary search and insert (`O(logS + S)`).
|
||||
/// - I/O: 1 read `O(S)`, up to 1 mutate `O(S)`. Up to one remove.
|
||||
/// - One event.
|
||||
/// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a
|
||||
/// deposit taken for its lifetime of
|
||||
/// `DepositBase + threshold * DepositFactor`.
|
||||
/// - Storage: inserts one item, value size bounded by `MaxSignatories`, with a deposit
|
||||
/// taken for its lifetime of `DepositBase + threshold * DepositFactor`.
|
||||
/// ----------------------------------
|
||||
/// - DB Weight:
|
||||
/// - Read: Multisig Storage, [Caller Account]
|
||||
|
||||
@@ -812,8 +812,9 @@ fn weight_check_works() {
|
||||
|
||||
#[test]
|
||||
fn multisig_handles_no_preimage_after_all_approve() {
|
||||
// This test checks the situation where everyone approves a multi-sig, but no-one provides the call data.
|
||||
// In the end, any of the multisig callers can approve again with the call data and the call will go through.
|
||||
// This test checks the situation where everyone approves a multi-sig, but no-one provides the
|
||||
// call data. In the end, any of the multisig callers can approve again with the call data and
|
||||
// the call will go through.
|
||||
new_test_ext().execute_with(|| {
|
||||
let multi = Multisig::multi_account_id(&[1, 2, 3][..], 3);
|
||||
assert_ok!(Balances::transfer(Origin::signed(1), multi, 5));
|
||||
|
||||
@@ -67,8 +67,8 @@ pub struct ProxyDefinition<AccountId, ProxyType, BlockNumber> {
|
||||
pub delegate: AccountId,
|
||||
/// A value defining the subset of calls that it is allowed to make.
|
||||
pub proxy_type: ProxyType,
|
||||
/// The number of blocks that an announcement must be in place for before the corresponding call
|
||||
/// may be dispatched. If zero, then no announcement is needed.
|
||||
/// The number of blocks that an announcement must be in place for before the corresponding
|
||||
/// call may be dispatched. If zero, then no announcement is needed.
|
||||
pub delay: BlockNumber,
|
||||
}
|
||||
|
||||
@@ -132,9 +132,9 @@ pub mod pallet {
|
||||
|
||||
/// The amount of currency needed per proxy added.
|
||||
///
|
||||
/// This is held for adding 32 bytes plus an instance of `ProxyType` more into a pre-existing
|
||||
/// storage value. Thus, when configuring `ProxyDepositFactor` one should take into account
|
||||
/// `32 + proxy_type.encode().len()` bytes of data.
|
||||
/// This is held for adding 32 bytes plus an instance of `ProxyType` more into a
|
||||
/// pre-existing storage value. Thus, when configuring `ProxyDepositFactor` one should take
|
||||
/// into account `32 + proxy_type.encode().len()` bytes of data.
|
||||
#[pallet::constant]
|
||||
type ProxyDepositFactor: Get<BalanceOf<Self>>;
|
||||
|
||||
@@ -154,7 +154,8 @@ pub mod pallet {
|
||||
|
||||
/// The base amount of currency needed to reserve for creating an announcement.
|
||||
///
|
||||
/// This is held when a new storage item holding a `Balance` is created (typically 16 bytes).
|
||||
/// This is held when a new storage item holding a `Balance` is created (typically 16
|
||||
/// bytes).
|
||||
#[pallet::constant]
|
||||
type AnnouncementDepositBase: Get<BalanceOf<Self>>;
|
||||
|
||||
@@ -539,7 +540,8 @@ pub mod pallet {
|
||||
/// A proxy was executed correctly, with the given \[result\].
|
||||
ProxyExecuted(DispatchResult),
|
||||
/// Anonymous account has been created by new proxy with given
|
||||
/// disambiguation index and proxy type. \[anonymous, who, proxy_type, disambiguation_index\]
|
||||
/// disambiguation index and proxy type. \[anonymous, who, proxy_type,
|
||||
/// disambiguation_index\]
|
||||
AnonymousCreated(T::AccountId, T::AccountId, T::ProxyType, u16),
|
||||
/// An announcement was placed to make a call in the future. \[real, proxy, call_hash\]
|
||||
Announced(T::AccountId, T::AccountId, CallHashOf<T>),
|
||||
@@ -761,11 +763,13 @@ impl<T: Config> Pallet<T> {
|
||||
let c = <T as Config>::Call::from_ref(c);
|
||||
// We make sure the proxy call does access this pallet to change modify proxies.
|
||||
match c.is_sub_type() {
|
||||
// Proxy call cannot add or remove a proxy with more permissions than it already has.
|
||||
// Proxy call cannot add or remove a proxy with more permissions than it already
|
||||
// has.
|
||||
Some(Call::add_proxy(_, ref pt, _)) | Some(Call::remove_proxy(_, ref pt, _))
|
||||
if !def.proxy_type.is_superset(&pt) =>
|
||||
false,
|
||||
// Proxy call cannot remove all proxies or kill anonymous proxies unless it has full permissions.
|
||||
// Proxy call cannot remove all proxies or kill anonymous proxies unless it has full
|
||||
// permissions.
|
||||
Some(Call::remove_proxies(..)) | Some(Call::kill_anonymous(..))
|
||||
if def.proxy_type != T::ProxyType::default() =>
|
||||
false,
|
||||
|
||||
@@ -33,12 +33,12 @@
|
||||
//!
|
||||
//! The recovery process for each recoverable account can be configured by the account owner.
|
||||
//! They are able to choose:
|
||||
//! * `friends` - The list of friends that the account owner trusts to protect the
|
||||
//! recovery process for their account.
|
||||
//! * `threshold` - The number of friends that need to approve a recovery process for
|
||||
//! the account to be successfully recovered.
|
||||
//! * `delay_period` - The minimum number of blocks after the beginning of the recovery
|
||||
//! process that need to pass before the account can be successfully recovered.
|
||||
//! * `friends` - The list of friends that the account owner trusts to protect the recovery process
|
||||
//! for their account.
|
||||
//! * `threshold` - The number of friends that need to approve a recovery process for the account to
|
||||
//! be successfully recovered.
|
||||
//! * `delay_period` - The minimum number of blocks after the beginning of the recovery process that
|
||||
//! need to pass before the account can be successfully recovered.
|
||||
//!
|
||||
//! There is a configurable deposit that all users need to pay to create a recovery
|
||||
//! configuration. This deposit is composed of a base deposit plus a multiplier for
|
||||
@@ -101,25 +101,23 @@
|
||||
//! security of an account if used incorrectly. Some recommended practices for users
|
||||
//! of this pallet are:
|
||||
//!
|
||||
//! * Configure a significant `delay_period` for your recovery process: As long as you
|
||||
//! have access to your recoverable account, you need only check the blockchain once
|
||||
//! every `delay_period` blocks to ensure that no recovery attempt is successful
|
||||
//! against your account. Using off-chain notification systems can help with this,
|
||||
//! but ultimately, setting a large `delay_period` means that even the most skilled
|
||||
//! attacker will need to wait this long before they can access your account.
|
||||
//! * Use a high threshold of approvals: Setting a value of 1 for the threshold means
|
||||
//! that any of your friends would be able to recover your account. They would
|
||||
//! simply need to start a recovery process and approve their own process. Similarly,
|
||||
//! a threshold of 2 would mean that any 2 friends could work together to gain
|
||||
//! access to your account. The only way to prevent against these kinds of attacks
|
||||
//! is to choose a high threshold of approvals and select from a diverse friend
|
||||
//! group that would not be able to reasonably coordinate with one another.
|
||||
//! * Reset your configuration over time: Since the entire deposit of creating a
|
||||
//! recovery configuration is returned to the user, the only cost of updating
|
||||
//! your recovery configuration is the transaction fees for the calls. Thus,
|
||||
//! it is strongly encouraged to regularly update your recovery configuration
|
||||
//! as your life changes and your relationship with new and existing friends
|
||||
//! change as well.
|
||||
//! * Configure a significant `delay_period` for your recovery process: As long as you have access
|
||||
//! to your recoverable account, you need only check the blockchain once every `delay_period`
|
||||
//! blocks to ensure that no recovery attempt is successful against your account. Using off-chain
|
||||
//! notification systems can help with this, but ultimately, setting a large `delay_period` means
|
||||
//! that even the most skilled attacker will need to wait this long before they can access your
|
||||
//! account.
|
||||
//! * Use a high threshold of approvals: Setting a value of 1 for the threshold means that any of
|
||||
//! your friends would be able to recover your account. They would simply need to start a recovery
|
||||
//! process and approve their own process. Similarly, a threshold of 2 would mean that any 2
|
||||
//! friends could work together to gain access to your account. The only way to prevent against
|
||||
//! these kinds of attacks is to choose a high threshold of approvals and select from a diverse
|
||||
//! friend group that would not be able to reasonably coordinate with one another.
|
||||
//! * Reset your configuration over time: Since the entire deposit of creating a recovery
|
||||
//! configuration is returned to the user, the only cost of updating your recovery configuration
|
||||
//! is the transaction fees for the calls. Thus, it is strongly encouraged to regularly update
|
||||
//! your recovery configuration as your life changes and your relationship with new and existing
|
||||
//! friends change as well.
|
||||
//!
|
||||
//! ## Interface
|
||||
//!
|
||||
@@ -131,22 +129,27 @@
|
||||
//! * `initiate_recovery` - Start the recovery process for a recoverable account.
|
||||
//!
|
||||
//! #### For Friends of a Recoverable Account
|
||||
//! * `vouch_recovery` - As a `friend` of a recoverable account, vouch for a recovery attempt on the account.
|
||||
//! * `vouch_recovery` - As a `friend` of a recoverable account, vouch for a recovery attempt on the
|
||||
//! account.
|
||||
//!
|
||||
//! #### For a User Who Successfully Recovered an Account
|
||||
//!
|
||||
//! * `claim_recovery` - Claim access to the account that you have successfully completed the recovery process for.
|
||||
//! * `as_recovered` - Send a transaction as an account that you have recovered. See other functions below.
|
||||
//! * `claim_recovery` - Claim access to the account that you have successfully completed the
|
||||
//! recovery process for.
|
||||
//! * `as_recovered` - Send a transaction as an account that you have recovered. See other functions
|
||||
//! below.
|
||||
//!
|
||||
//! #### For the Recoverable Account
|
||||
//!
|
||||
//! * `close_recovery` - Close an active recovery process for your account and reclaim the recovery deposit.
|
||||
//! * `remove_recovery` - Remove the recovery configuration from the account, making it un-recoverable.
|
||||
//! * `close_recovery` - Close an active recovery process for your account and reclaim the recovery
|
||||
//! deposit.
|
||||
//! * `remove_recovery` - Remove the recovery configuration from the account, making it
|
||||
//! un-recoverable.
|
||||
//!
|
||||
//! #### For Super Users
|
||||
//!
|
||||
//! * `set_recovered` - The ROOT origin is able to skip the recovery process and directly allow
|
||||
//! one account to access another.
|
||||
//! * `set_recovered` - The ROOT origin is able to skip the recovery process and directly allow one
|
||||
//! account to access another.
|
||||
|
||||
// Ensure we're `no_std` when compiling for Wasm.
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
@@ -231,9 +234,11 @@ pub mod pallet {
|
||||
#[pallet::constant]
|
||||
type ConfigDepositBase: Get<BalanceOf<Self>>;
|
||||
|
||||
/// The amount of currency needed per additional user when creating a recovery configuration.
|
||||
/// The amount of currency needed per additional user when creating a recovery
|
||||
/// configuration.
|
||||
///
|
||||
/// This is held for adding `sizeof(AccountId)` bytes more into a pre-existing storage value.
|
||||
/// This is held for adding `sizeof(AccountId)` bytes more into a pre-existing storage
|
||||
/// value.
|
||||
#[pallet::constant]
|
||||
type FriendDepositFactor: Get<BalanceOf<Self>>;
|
||||
|
||||
@@ -417,13 +422,13 @@ pub mod pallet {
|
||||
/// The dispatch origin for this call must be _Signed_.
|
||||
///
|
||||
/// Parameters:
|
||||
/// - `friends`: A list of friends you trust to vouch for recovery attempts.
|
||||
/// Should be ordered and contain no duplicate values.
|
||||
/// - `threshold`: The number of friends that must vouch for a recovery attempt
|
||||
/// before the account can be recovered. Should be less than or equal to
|
||||
/// the length of the list of friends.
|
||||
/// - `delay_period`: The number of blocks after a recovery attempt is initialized
|
||||
/// that needs to pass before the account can be recovered.
|
||||
/// - `friends`: A list of friends you trust to vouch for recovery attempts. Should be
|
||||
/// ordered and contain no duplicate values.
|
||||
/// - `threshold`: The number of friends that must vouch for a recovery attempt before the
|
||||
/// account can be recovered. Should be less than or equal to the length of the list of
|
||||
/// friends.
|
||||
/// - `delay_period`: The number of blocks after a recovery attempt is initialized that
|
||||
/// needs to pass before the account can be recovered.
|
||||
///
|
||||
/// # <weight>
|
||||
/// - Key: F (len of friends)
|
||||
@@ -480,8 +485,8 @@ pub mod pallet {
|
||||
/// The dispatch origin for this call must be _Signed_.
|
||||
///
|
||||
/// Parameters:
|
||||
/// - `account`: The lost account that you want to recover. This account
|
||||
/// needs to be recoverable (i.e. have a recovery configuration).
|
||||
/// - `account`: The lost account that you want to recover. This account needs to be
|
||||
/// recoverable (i.e. have a recovery configuration).
|
||||
///
|
||||
/// # <weight>
|
||||
/// - One storage read to check that account is recoverable. O(F)
|
||||
@@ -526,8 +531,7 @@ pub mod pallet {
|
||||
///
|
||||
/// Parameters:
|
||||
/// - `lost`: The lost account that you want to recover.
|
||||
/// - `rescuer`: The account trying to rescue the lost account that you
|
||||
/// want to vouch for.
|
||||
/// - `rescuer`: The account trying to rescue the lost account that you want to vouch for.
|
||||
///
|
||||
/// The combination of these two parameters must point to an active recovery
|
||||
/// process.
|
||||
@@ -575,8 +579,8 @@ pub mod pallet {
|
||||
/// `threshold` or more vouches, waited `delay_period` blocks since initiation.
|
||||
///
|
||||
/// Parameters:
|
||||
/// - `account`: The lost account that you want to claim has been successfully
|
||||
/// recovered by you.
|
||||
/// - `account`: The lost account that you want to claim has been successfully recovered by
|
||||
/// you.
|
||||
///
|
||||
/// # <weight>
|
||||
/// Key: F (len of friends in config), V (len of vouching friends)
|
||||
|
||||
@@ -64,7 +64,8 @@ fn recovery_life_cycle_works() {
|
||||
run_to_block(10);
|
||||
// Using account 1, the user begins the recovery process to recover the lost account
|
||||
assert_ok!(Recovery::initiate_recovery(Origin::signed(1), 5));
|
||||
// Off chain, the user contacts their friends and asks them to vouch for the recovery attempt
|
||||
// Off chain, the user contacts their friends and asks them to vouch for the recovery
|
||||
// attempt
|
||||
assert_ok!(Recovery::vouch_recovery(Origin::signed(2), 5, 1));
|
||||
assert_ok!(Recovery::vouch_recovery(Origin::signed(3), 5, 1));
|
||||
assert_ok!(Recovery::vouch_recovery(Origin::signed(4), 5, 1));
|
||||
|
||||
@@ -40,12 +40,11 @@
|
||||
//!
|
||||
//! ### Dispatchable Functions
|
||||
//!
|
||||
//! * `schedule` - schedule a dispatch, which may be periodic, to occur at a
|
||||
//! specified block and with a specified priority.
|
||||
//! * `cancel` - cancel a scheduled dispatch, specified by block number and
|
||||
//! index.
|
||||
//! * `schedule_named` - augments the `schedule` interface with an additional
|
||||
//! `Vec<u8>` parameter that can be used for identification.
|
||||
//! * `schedule` - schedule a dispatch, which may be periodic, to occur at a specified block and
|
||||
//! with a specified priority.
|
||||
//! * `cancel` - cancel a scheduled dispatch, specified by block number and index.
|
||||
//! * `schedule_named` - augments the `schedule` interface with an additional `Vec<u8>` parameter
|
||||
//! that can be used for identification.
|
||||
//! * `cancel_named` - the named complement to the cancel function.
|
||||
|
||||
// Ensure we're `no_std` when compiling for Wasm.
|
||||
@@ -152,8 +151,8 @@ pub mod pallet {
|
||||
+ GetDispatchInfo
|
||||
+ From<system::Call<Self>>;
|
||||
|
||||
/// The maximum weight that may be scheduled per block for any dispatchables of less priority
|
||||
/// than `schedule::HARD_DEADLINE`.
|
||||
/// The maximum weight that may be scheduled per block for any dispatchables of less
|
||||
/// priority than `schedule::HARD_DEADLINE`.
|
||||
#[pallet::constant]
|
||||
type MaximumWeight: Get<Weight>;
|
||||
|
||||
@@ -1321,7 +1320,8 @@ mod tests {
|
||||
root(),
|
||||
Call::Logger(LoggerCall::log(69, MaximumSchedulerWeight::get() / 2))
|
||||
));
|
||||
// With base weights, 69 and 42 should not fit together, but do because of hard deadlines
|
||||
// With base weights, 69 and 42 should not fit together, but do because of hard
|
||||
// deadlines
|
||||
run_to_block(4);
|
||||
assert_eq!(logger::log(), vec![(root(), 42u32), (root(), 69u32)]);
|
||||
});
|
||||
|
||||
@@ -269,7 +269,8 @@ pub trait SessionHandler<ValidatorId> {
|
||||
/// All the key type ids this session handler can process.
|
||||
///
|
||||
/// The order must be the same as it expects them in
|
||||
/// [`on_new_session`](Self::on_new_session<Ks>) and [`on_genesis_session`](Self::on_genesis_session<Ks>).
|
||||
/// [`on_new_session`](Self::on_new_session<Ks>) and
|
||||
/// [`on_genesis_session`](Self::on_genesis_session<Ks>).
|
||||
const KEY_TYPE_IDS: &'static [KeyTypeId];
|
||||
|
||||
/// The given validator set will be used for the genesis session.
|
||||
@@ -490,8 +491,8 @@ decl_storage! {
|
||||
|
||||
decl_event!(
|
||||
pub enum Event {
|
||||
/// New session has happened. Note that the argument is the \[session_index\], not the block
|
||||
/// number as the type might suggest.
|
||||
/// New session has happened. Note that the argument is the \[session_index\], not the
|
||||
/// block number as the type might suggest.
|
||||
NewSession(SessionIndex),
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1332,8 +1332,9 @@ impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
// we assume there's at least one member or this logic won't work.
|
||||
if !members.is_empty() {
|
||||
let candidates = <Candidates<T, I>>::take();
|
||||
// NOTE: This may cause member length to surpass `MaxMembers`, but results in no consensus
|
||||
// critical issues or side-effects. This is auto-correcting as members fall out of society.
|
||||
// NOTE: This may cause member length to surpass `MaxMembers`, but results in no
|
||||
// consensus critical issues or side-effects. This is auto-correcting as members fall
|
||||
// out of society.
|
||||
members.reserve(candidates.len());
|
||||
|
||||
let maturity =
|
||||
@@ -1369,8 +1370,9 @@ impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
let matching_vote = if is_accepted { Vote::Approve } else { Vote::Reject };
|
||||
|
||||
let bad_vote = |m: &T::AccountId| {
|
||||
// Voter voted wrong way (or was just a lazy skeptic) then reduce their payout
|
||||
// and increase their strikes. after MaxStrikes then they go into suspension.
|
||||
// Voter voted wrong way (or was just a lazy skeptic) then reduce their
|
||||
// payout and increase their strikes. after MaxStrikes then they go into
|
||||
// suspension.
|
||||
let amount = Self::slash_payout(m, T::WrongSideDeduction::get());
|
||||
|
||||
let strikes = <Strikes<T, I>>::mutate(m, |s| {
|
||||
@@ -1405,9 +1407,10 @@ impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
|
||||
Self::pay_accepted_candidate(&candidate, value, kind, maturity);
|
||||
|
||||
// We track here the total_approvals so that every candidate has a unique range
|
||||
// of numbers from 0 to `total_approvals` with length `approval_count` so each
|
||||
// candidate is proportionally represented when selecting a "primary" below.
|
||||
// We track here the total_approvals so that every candidate has a unique
|
||||
// range of numbers from 0 to `total_approvals` with length `approval_count`
|
||||
// so each candidate is proportionally represented when selecting a
|
||||
// "primary" below.
|
||||
Some((candidate, total_approvals, value))
|
||||
} else {
|
||||
// Suspend Candidate
|
||||
@@ -1474,8 +1477,9 @@ impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
|
||||
// Then write everything back out, signal the changed membership and leave an event.
|
||||
members.sort();
|
||||
// NOTE: This may cause member length to surpass `MaxMembers`, but results in no consensus
|
||||
// critical issues or side-effects. This is auto-correcting as members fall out of society.
|
||||
// NOTE: This may cause member length to surpass `MaxMembers`, but results in no
|
||||
// consensus critical issues or side-effects. This is auto-correcting as members
|
||||
// fall out of society.
|
||||
<Members<T, I>>::put(&members[..]);
|
||||
<Head<T, I>>::put(&primary);
|
||||
|
||||
@@ -1565,7 +1569,8 @@ impl<T: Config<I>, I: Instance> Module<T, I> {
|
||||
value
|
||||
},
|
||||
BidKind::Vouch(voucher, tip) => {
|
||||
// Check that the voucher is still vouching, else some other logic may have removed their status.
|
||||
// Check that the voucher is still vouching, else some other logic may have removed
|
||||
// their status.
|
||||
if <Vouching<T, I>>::take(&voucher) == Some(VouchingStatus::Vouching) {
|
||||
// In the case that a vouched-for bid is accepted we unset the
|
||||
// vouching status and transfer the tip over to the voucher.
|
||||
|
||||
@@ -32,28 +32,27 @@ use syn::parse::{Parse, ParseStream};
|
||||
/// [here](https://research.web3.foundation/en/latest/polkadot/Token%20Economics.html#inflation-model))
|
||||
/// for those parameters. Parameters are:
|
||||
/// - `min_inflation`: the minimal amount to be rewarded between validators, expressed as a fraction
|
||||
/// of total issuance. Known as `I_0` in the literature.
|
||||
/// Expressed in millionth, must be between 0 and 1_000_000.
|
||||
/// of total issuance. Known as `I_0` in the literature. Expressed in millionth, must be between 0
|
||||
/// and 1_000_000.
|
||||
///
|
||||
/// - `max_inflation`: the maximum amount to be rewarded between validators, expressed as a fraction
|
||||
/// of total issuance. This is attained only when `ideal_stake` is achieved.
|
||||
/// Expressed in millionth, must be between min_inflation and 1_000_000.
|
||||
/// of total issuance. This is attained only when `ideal_stake` is achieved. Expressed in
|
||||
/// millionth, must be between min_inflation and 1_000_000.
|
||||
///
|
||||
/// - `ideal_stake`: the fraction of total issued tokens that should be actively staked behind
|
||||
/// validators. Known as `x_ideal` in the literature.
|
||||
/// Expressed in millionth, must be between 0_100_000 and 0_900_000.
|
||||
/// validators. Known as `x_ideal` in the literature. Expressed in millionth, must be between
|
||||
/// 0_100_000 and 0_900_000.
|
||||
///
|
||||
/// - `falloff`: Known as `decay_rate` in the literature. A co-efficient dictating the strength of
|
||||
/// the global incentivization to get the `ideal_stake`. A higher number results in less typical
|
||||
/// inflation at the cost of greater volatility for validators.
|
||||
/// Expressed in millionth, must be between 0 and 1_000_000.
|
||||
/// inflation at the cost of greater volatility for validators. Expressed in millionth, must be
|
||||
/// between 0 and 1_000_000.
|
||||
///
|
||||
/// - `max_piece_count`: The maximum number of pieces in the curve. A greater number uses more
|
||||
/// resources but results in higher accuracy.
|
||||
/// Must be between 2 and 1_000.
|
||||
/// resources but results in higher accuracy. Must be between 2 and 1_000.
|
||||
///
|
||||
/// - `test_precision`: The maximum error allowed in the generated test.
|
||||
/// Expressed in millionth, must be between 0 and 1_000_000.
|
||||
/// - `test_precision`: The maximum error allowed in the generated test. Expressed in millionth,
|
||||
/// must be between 0 and 1_000_000.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
||||
@@ -45,19 +45,13 @@ use sp_arithmetic::{
|
||||
/// [here](https://research.web3.foundation/en/latest/polkadot/economics/1-token-economics.html#inflation-model-with-parachains))
|
||||
///
|
||||
/// Arguments are:
|
||||
/// * `stake`:
|
||||
/// The fraction of total issued tokens that actively staked behind
|
||||
/// validators. Known as `x` in the literature.
|
||||
/// Must be between 0 and 1.
|
||||
/// * `ideal_stake`:
|
||||
/// The fraction of total issued tokens that should be actively staked behind
|
||||
/// validators. Known as `x_ideal` in the literature.
|
||||
/// Must be between 0 and 1.
|
||||
/// * `falloff`:
|
||||
/// Known as `decay_rate` in the literature. A co-efficient dictating the strength of
|
||||
/// * `stake`: The fraction of total issued tokens that actively staked behind validators. Known as
|
||||
/// `x` in the literature. Must be between 0 and 1.
|
||||
/// * `ideal_stake`: The fraction of total issued tokens that should be actively staked behind
|
||||
/// validators. Known as `x_ideal` in the literature. Must be between 0 and 1.
|
||||
/// * `falloff`: Known as `decay_rate` in the literature. A co-efficient dictating the strength of
|
||||
/// the global incentivization to get the `ideal_stake`. A higher number results in less typical
|
||||
/// inflation at the cost of greater volatility for validators.
|
||||
/// Must be more than 0.01.
|
||||
/// inflation at the cost of greater volatility for validators. Must be more than 0.01.
|
||||
pub fn compute_inflation<P: PerThing>(stake: P, ideal_stake: P, falloff: P) -> P {
|
||||
if stake < ideal_stake {
|
||||
// ideal_stake is more than 0 because it is strictly more than stake
|
||||
|
||||
@@ -25,8 +25,8 @@ use sp_runtime::{curve::PiecewiseLinear, traits::AtLeast32BitUnsigned, Perbill};
|
||||
/// The total payout to all validators (and their nominators) per era and maximum payout.
|
||||
///
|
||||
/// Defined as such:
|
||||
/// `staker-payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens / era_per_year`
|
||||
/// `maximum-payout = max_yearly_inflation * total_tokens / era_per_year`
|
||||
/// `staker-payout = yearly_inflation(npos_token_staked / total_tokens) * total_tokens /
|
||||
/// era_per_year` `maximum-payout = max_yearly_inflation * total_tokens / era_per_year`
|
||||
///
|
||||
/// `era_duration` is expressed in millisecond.
|
||||
pub fn compute_total_payout<N>(
|
||||
|
||||
@@ -163,8 +163,9 @@ impl<T: Config> Pallet<T> {
|
||||
Self::deposit_event(Event::<T>::Rewarded(ledger.stash, imbalance.peek()));
|
||||
}
|
||||
|
||||
// Track the number of payout ops to nominators. Note: `WeightInfo::payout_stakers_alive_staked`
|
||||
// always assumes at least a validator is paid out, so we do not need to count their payout op.
|
||||
// Track the number of payout ops to nominators. Note:
|
||||
// `WeightInfo::payout_stakers_alive_staked` always assumes at least a validator is paid
|
||||
// out, so we do not need to count their payout op.
|
||||
let mut nominator_payout_count: u32 = 0;
|
||||
|
||||
// Lets now calculate how this is split to the nominators.
|
||||
@@ -306,6 +307,7 @@ impl<T: Config> Pallet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// * Increment `active_era.index`,
|
||||
/// * reset `active_era.start`,
|
||||
/// * update `BondedEras` and apply slashes.
|
||||
@@ -674,7 +676,8 @@ impl<T: Config> Pallet<T> {
|
||||
all_voters
|
||||
}
|
||||
|
||||
/// This is a very expensive function and result should be cached versus being called multiple times.
|
||||
/// This is a very expensive function and result should be cached versus being called multiple
|
||||
/// times.
|
||||
pub fn get_npos_targets() -> Vec<T::AccountId> {
|
||||
Validators::<T>::iter().map(|(v, _)| v).collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
@@ -62,12 +62,12 @@ pub mod pallet {
|
||||
|
||||
/// Time used for computing era duration.
|
||||
///
|
||||
/// It is guaranteed to start being called from the first `on_finalize`. Thus value at genesis
|
||||
/// is not used.
|
||||
/// It is guaranteed to start being called from the first `on_finalize`. Thus value at
|
||||
/// genesis is not used.
|
||||
type UnixTime: UnixTime;
|
||||
|
||||
/// Convert a balance into a number used for election calculation. This must fit into a `u64`
|
||||
/// but is allowed to be sensibly lossy. The `u64` is used to communicate with the
|
||||
/// Convert a balance into a number used for election calculation. This must fit into a
|
||||
/// `u64` but is allowed to be sensibly lossy. The `u64` is used to communicate with the
|
||||
/// [`sp_npos_elections`] crate which accepts u64 numbers and does operations in 128.
|
||||
/// Consequently, the backward convert is used convert the u128s from sp-elections back to a
|
||||
/// [`BalanceOf`].
|
||||
@@ -129,13 +129,14 @@ pub mod pallet {
|
||||
/// See [Era payout](./index.html#era-payout).
|
||||
type EraPayout: EraPayout<BalanceOf<Self>>;
|
||||
|
||||
/// Something that can estimate the next session change, accurately or as a best effort guess.
|
||||
/// Something that can estimate the next session change, accurately or as a best effort
|
||||
/// guess.
|
||||
type NextNewSession: EstimateNextNewSession<Self::BlockNumber>;
|
||||
|
||||
/// The maximum number of nominators rewarded for each validator.
|
||||
///
|
||||
/// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can claim
|
||||
/// their reward. This used to limit the i/o cost for the nominator payout.
|
||||
/// For each validator only the `$MaxNominatorRewardedPerValidator` biggest stakers can
|
||||
/// claim their reward. This used to limit the i/o cost for the nominator payout.
|
||||
#[pallet::constant]
|
||||
type MaxNominatorRewardedPerValidator: Get<u32>;
|
||||
|
||||
@@ -437,9 +438,9 @@ pub mod pallet {
|
||||
#[pallet::storage]
|
||||
pub(crate) type StorageVersion<T: Config> = StorageValue<_, Releases, ValueQuery>;
|
||||
|
||||
/// The threshold for when users can start calling `chill_other` for other validators / nominators.
|
||||
/// The threshold is compared to the actual number of validators / nominators (`CountFor*`) in
|
||||
/// the system compared to the configured max (`Max*Count`).
|
||||
/// The threshold for when users can start calling `chill_other` for other validators /
|
||||
/// nominators. The threshold is compared to the actual number of validators / nominators
|
||||
/// (`CountFor*`) in the system compared to the configured max (`Max*Count`).
|
||||
#[pallet::storage]
|
||||
pub(crate) type ChillThreshold<T: Config> = StorageValue<_, Percent, OptionQuery>;
|
||||
|
||||
@@ -598,11 +599,11 @@ pub mod pallet {
|
||||
BadTarget,
|
||||
/// The user has enough bond and thus cannot be chilled forcefully by an external person.
|
||||
CannotChillOther,
|
||||
/// There are too many nominators in the system. Governance needs to adjust the staking settings
|
||||
/// to keep things safe for the runtime.
|
||||
/// There are too many nominators in the system. Governance needs to adjust the staking
|
||||
/// settings to keep things safe for the runtime.
|
||||
TooManyNominators,
|
||||
/// There are too many validators in the system. Governance needs to adjust the staking settings
|
||||
/// to keep things safe for the runtime.
|
||||
/// There are too many validators in the system. Governance needs to adjust the staking
|
||||
/// settings to keep things safe for the runtime.
|
||||
TooManyValidators,
|
||||
}
|
||||
|
||||
@@ -636,7 +637,8 @@ pub mod pallet {
|
||||
if active_era.start.is_none() {
|
||||
let now_as_millis_u64 = T::UnixTime::now().as_millis().saturated_into::<u64>();
|
||||
active_era.start = Some(now_as_millis_u64);
|
||||
// This write only ever happens once, we don't include it in the weight in general
|
||||
// This write only ever happens once, we don't include it in the weight in
|
||||
// general
|
||||
ActiveEra::<T>::put(active_era);
|
||||
}
|
||||
}
|
||||
@@ -731,8 +733,8 @@ pub mod pallet {
|
||||
/// The dispatch origin for this call must be _Signed_ by the stash, not the controller.
|
||||
///
|
||||
/// Use this if there are additional funds in your stash account that you wish to bond.
|
||||
/// Unlike [`bond`](Self::bond) or [`unbond`](Self::unbond) this function does not impose any limitation
|
||||
/// on the amount that can be added.
|
||||
/// Unlike [`bond`](Self::bond) or [`unbond`](Self::unbond) this function does not impose
|
||||
/// any limitation on the amount that can be added.
|
||||
///
|
||||
/// Emits `Bonded`.
|
||||
///
|
||||
@@ -854,23 +856,24 @@ pub mod pallet {
|
||||
ledger = ledger.consolidate_unlocked(current_era)
|
||||
}
|
||||
|
||||
let post_info_weight =
|
||||
if ledger.unlocking.is_empty() && ledger.active < T::Currency::minimum_balance() {
|
||||
// This account must have called `unbond()` with some value that caused the active
|
||||
// portion to fall below existential deposit + will have no more unlocking chunks
|
||||
// left. We can now safely remove all staking-related information.
|
||||
Self::kill_stash(&stash, num_slashing_spans)?;
|
||||
// Remove the lock.
|
||||
T::Currency::remove_lock(STAKING_ID, &stash);
|
||||
// This is worst case scenario, so we use the full weight and return None
|
||||
None
|
||||
} else {
|
||||
// This was the consequence of a partial unbond. just update the ledger and move on.
|
||||
Self::update_ledger(&controller, &ledger);
|
||||
let post_info_weight = if ledger.unlocking.is_empty() &&
|
||||
ledger.active < T::Currency::minimum_balance()
|
||||
{
|
||||
// This account must have called `unbond()` with some value that caused the active
|
||||
// portion to fall below existential deposit + will have no more unlocking chunks
|
||||
// left. We can now safely remove all staking-related information.
|
||||
Self::kill_stash(&stash, num_slashing_spans)?;
|
||||
// Remove the lock.
|
||||
T::Currency::remove_lock(STAKING_ID, &stash);
|
||||
// This is worst case scenario, so we use the full weight and return None
|
||||
None
|
||||
} else {
|
||||
// This was the consequence of a partial unbond. just update the ledger and move on.
|
||||
Self::update_ledger(&controller, &ledger);
|
||||
|
||||
// This is only an update, so we use less overall weight.
|
||||
Some(T::WeightInfo::withdraw_unbonded_update(num_slashing_spans))
|
||||
};
|
||||
// This is only an update, so we use less overall weight.
|
||||
Some(T::WeightInfo::withdraw_unbonded_update(num_slashing_spans))
|
||||
};
|
||||
|
||||
// `old_total` should never be less than the new total because
|
||||
// `consolidate_unlocked` strictly subtracts balance.
|
||||
@@ -898,8 +901,9 @@ pub mod pallet {
|
||||
|
||||
// Only check limits if they are not already a validator.
|
||||
if !Validators::<T>::contains_key(stash) {
|
||||
// If this error is reached, we need to adjust the `MinValidatorBond` and start calling `chill_other`.
|
||||
// Until then, we explicitly block new validators to protect the runtime.
|
||||
// If this error is reached, we need to adjust the `MinValidatorBond` and start
|
||||
// calling `chill_other`. Until then, we explicitly block new validators to protect
|
||||
// the runtime.
|
||||
if let Some(max_validators) = MaxValidatorsCount::<T>::get() {
|
||||
ensure!(
|
||||
CounterForValidators::<T>::get() < max_validators,
|
||||
@@ -937,8 +941,9 @@ pub mod pallet {
|
||||
|
||||
// Only check limits if they are not already a nominator.
|
||||
if !Nominators::<T>::contains_key(stash) {
|
||||
// If this error is reached, we need to adjust the `MinNominatorBond` and start calling `chill_other`.
|
||||
// Until then, we explicitly block new nominators to protect the runtime.
|
||||
// If this error is reached, we need to adjust the `MinNominatorBond` and start
|
||||
// calling `chill_other`. Until then, we explicitly block new nominators to protect
|
||||
// the runtime.
|
||||
if let Some(max_nominators) = MaxNominatorsCount::<T>::get() {
|
||||
ensure!(
|
||||
CounterForNominators::<T>::get() < max_nominators,
|
||||
@@ -1180,8 +1185,8 @@ pub mod pallet {
|
||||
/// # <weight>
|
||||
/// O(S) where S is the number of slashing spans to be removed
|
||||
/// Reads: Bonded, Slashing Spans, Account, Locks
|
||||
/// Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators, Account, Locks
|
||||
/// Writes Each: SpanSlash * S
|
||||
/// Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators,
|
||||
/// Account, Locks Writes Each: SpanSlash * S
|
||||
/// # </weight>
|
||||
#[pallet::weight(T::WeightInfo::force_unstake(*num_slashing_spans))]
|
||||
pub fn force_unstake(
|
||||
@@ -1327,10 +1332,10 @@ pub mod pallet {
|
||||
///
|
||||
/// Parameters:
|
||||
/// - `new_history_depth`: The new history depth you would like to set.
|
||||
/// - `era_items_deleted`: The number of items that will be deleted by this dispatch.
|
||||
/// This should report all the storage items that will be deleted by clearing old
|
||||
/// era history. Needed to report an accurate weight for the dispatch. Trusted by
|
||||
/// `Root` to report an accurate number.
|
||||
/// - `era_items_deleted`: The number of items that will be deleted by this dispatch. This
|
||||
/// should report all the storage items that will be deleted by clearing old era history.
|
||||
/// Needed to report an accurate weight for the dispatch. Trusted by `Root` to report an
|
||||
/// accurate number.
|
||||
///
|
||||
/// Origin must be root.
|
||||
///
|
||||
@@ -1341,7 +1346,8 @@ pub mod pallet {
|
||||
/// - Reads: Current Era, History Depth
|
||||
/// - Writes: History Depth
|
||||
/// - Clear Prefix Each: Era Stakers, EraStakersClipped, ErasValidatorPrefs
|
||||
/// - Writes Each: ErasValidatorReward, ErasRewardPoints, ErasTotalStake, ErasStartSessionIndex
|
||||
/// - Writes Each: ErasValidatorReward, ErasRewardPoints, ErasTotalStake,
|
||||
/// ErasStartSessionIndex
|
||||
/// # </weight>
|
||||
#[pallet::weight(T::WeightInfo::set_history_depth(*_era_items_deleted))]
|
||||
pub fn set_history_depth(
|
||||
@@ -1375,7 +1381,8 @@ pub mod pallet {
|
||||
/// Complexity: O(S) where S is the number of slashing spans on the account.
|
||||
/// DB Weight:
|
||||
/// - Reads: Stash Account, Bonded, Slashing Spans, Locks
|
||||
/// - Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators, Stash Account, Locks
|
||||
/// - Writes: Bonded, Slashing Spans (if S > 0), Ledger, Payee, Validators, Nominators,
|
||||
/// Stash Account, Locks
|
||||
/// - Writes Each: SpanSlash * S
|
||||
/// # </weight>
|
||||
#[pallet::weight(T::WeightInfo::reap_stash(*num_slashing_spans))]
|
||||
@@ -1437,10 +1444,10 @@ pub mod pallet {
|
||||
///
|
||||
/// * `min_nominator_bond`: The minimum active bond needed to be a nominator.
|
||||
/// * `min_validator_bond`: The minimum active bond needed to be a validator.
|
||||
/// * `max_nominator_count`: The max number of users who can be a nominator at once.
|
||||
/// When set to `None`, no limit is enforced.
|
||||
/// * `max_validator_count`: The max number of users who can be a validator at once.
|
||||
/// When set to `None`, no limit is enforced.
|
||||
/// * `max_nominator_count`: The max number of users who can be a nominator at once. When
|
||||
/// set to `None`, no limit is enforced.
|
||||
/// * `max_validator_count`: The max number of users who can be a validator at once. When
|
||||
/// set to `None`, no limit is enforced.
|
||||
///
|
||||
/// Origin must be Root to call this function.
|
||||
///
|
||||
|
||||
@@ -572,13 +572,15 @@ fn nominating_and_rewards_should_work() {
|
||||
mock::make_all_reward_payment(1);
|
||||
let payout_for_10 = total_payout_1 / 3;
|
||||
let payout_for_20 = 2 * total_payout_1 / 3;
|
||||
// Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11
|
||||
// Nominator 2: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==>
|
||||
// 2/9 + 3/11
|
||||
assert_eq_error_rate!(
|
||||
Balances::total_balance(&2),
|
||||
initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11),
|
||||
2,
|
||||
);
|
||||
// Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==> 2/9 + 3/11
|
||||
// Nominator 4: has [400/1800 ~ 2/9 from 10] + [600/2200 ~ 3/11 from 20]'s reward. ==>
|
||||
// 2/9 + 3/11
|
||||
assert_eq_error_rate!(
|
||||
Balances::total_balance(&4),
|
||||
initial_balance + (2 * payout_for_10 / 9 + 3 * payout_for_20 / 11),
|
||||
@@ -591,7 +593,8 @@ fn nominating_and_rewards_should_work() {
|
||||
initial_balance + 5 * payout_for_10 / 9,
|
||||
2,
|
||||
);
|
||||
// Validator 20: got `1200/2200` external stake => 12/22 =? 6/11 => Validator's share = 5/11
|
||||
// Validator 20: got 1200 / 2200 external stake => 12/22 =? 6/11 => Validator's share =
|
||||
// 5/11
|
||||
assert_eq_error_rate!(
|
||||
Balances::total_balance(&20),
|
||||
initial_balance_20 + 5 * payout_for_20 / 11,
|
||||
@@ -684,7 +687,8 @@ fn double_staking_should_fail() {
|
||||
#[test]
|
||||
fn double_controlling_should_fail() {
|
||||
// should test (in the same order):
|
||||
// * an account already bonded as controller CANNOT be reused as the controller of another account.
|
||||
// * an account already bonded as controller CANNOT be reused as the controller of another
|
||||
// account.
|
||||
ExtBuilder::default().build_and_execute(|| {
|
||||
let arbitrary_value = 5;
|
||||
// 2 = controller, 1 stashed => ok
|
||||
@@ -1116,6 +1120,7 @@ fn bond_extra_works() {
|
||||
|
||||
#[test]
|
||||
fn bond_extra_and_withdraw_unbonded_works() {
|
||||
//
|
||||
// * Should test
|
||||
// * Given an account being bonded [and chosen as a validator](not mandatory)
|
||||
// * It can add extra funds to the bonded account.
|
||||
@@ -1282,6 +1287,7 @@ fn too_many_unbond_calls_should_not_work() {
|
||||
|
||||
#[test]
|
||||
fn rebond_works() {
|
||||
//
|
||||
// * Should test
|
||||
// * Given an account being bonded [and chosen as a validator](not mandatory)
|
||||
// * it can unbond a portion of its funds from the stash account.
|
||||
@@ -1683,7 +1689,8 @@ fn on_free_balance_zero_stash_removes_nominator() {
|
||||
|
||||
#[test]
|
||||
fn switching_roles() {
|
||||
// Test that it should be possible to switch between roles (nominator, validator, idle) with minimal overhead.
|
||||
// Test that it should be possible to switch between roles (nominator, validator, idle) with
|
||||
// minimal overhead.
|
||||
ExtBuilder::default().nominate(false).build_and_execute(|| {
|
||||
// Reset reward destination
|
||||
for i in &[10, 20] {
|
||||
@@ -3354,7 +3361,8 @@ fn payout_stakers_handles_weight_refund() {
|
||||
assert_ok!(result);
|
||||
assert_eq!(extract_actual_weight(&result, &info), zero_nom_payouts_weight);
|
||||
|
||||
// The validator is not rewarded in this era; so there will be zero payouts to claim for this era.
|
||||
// The validator is not rewarded in this era; so there will be zero payouts to claim for
|
||||
// this era.
|
||||
|
||||
// Era 3
|
||||
start_active_era(3);
|
||||
@@ -4118,7 +4126,8 @@ fn chill_other_works() {
|
||||
assert_eq!(CounterForNominators::<Test>::get(), 15 + initial_nominators);
|
||||
assert_eq!(CounterForValidators::<Test>::get(), 15 + initial_validators);
|
||||
|
||||
// Users can now be chilled down to 7 people, so we try to remove 9 of them (starting with 16)
|
||||
// Users can now be chilled down to 7 people, so we try to remove 9 of them (starting
|
||||
// with 16)
|
||||
for i in 6..15 {
|
||||
let b = 4 * i + 1;
|
||||
let d = 4 * i + 3;
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
//! ### Executing Privileged Functions
|
||||
//!
|
||||
//! The Sudo pallet itself is not intended to be used within other pallets.
|
||||
//! Instead, you can build "privileged functions" (i.e. functions that require `Root` origin) in other pallets.
|
||||
//! You can execute these privileged functions by calling `sudo` with the sudo key account.
|
||||
//! Privileged functions cannot be directly executed via an extrinsic.
|
||||
//! Instead, you can build "privileged functions" (i.e. functions that require `Root` origin) in
|
||||
//! other pallets. You can execute these privileged functions by calling `sudo` with the sudo key
|
||||
//! account. Privileged functions cannot be directly executed via an extrinsic.
|
||||
//!
|
||||
//! Learn more about privileged functions and `Root` origin in the [`Origin`] type documentation.
|
||||
//!
|
||||
@@ -52,7 +52,7 @@
|
||||
//! This is an example of a pallet that exposes a privileged function:
|
||||
//!
|
||||
//! ```
|
||||
//!
|
||||
//!
|
||||
//! #[frame_support::pallet]
|
||||
//! pub mod logger {
|
||||
//! use frame_support::pallet_prelude::*;
|
||||
@@ -181,7 +181,8 @@ pub mod pallet {
|
||||
Ok(Pays::No.into())
|
||||
}
|
||||
|
||||
/// Authenticates the current sudo key and sets the given AccountId (`new`) as the new sudo key.
|
||||
/// Authenticates the current sudo key and sets the given AccountId (`new`) as the new sudo
|
||||
/// key.
|
||||
///
|
||||
/// The dispatch origin for this call must be _Signed_.
|
||||
///
|
||||
|
||||
@@ -109,7 +109,8 @@ fn set_key_basics() {
|
||||
});
|
||||
|
||||
new_test_ext(1).execute_with(|| {
|
||||
// A non-root `key` will trigger a `RequireSudo` error and a non-root `key` cannot change the root `key`.
|
||||
// A non-root `key` will trigger a `RequireSudo` error and a non-root `key` cannot change
|
||||
// the root `key`.
|
||||
assert_noop!(Sudo::set_key(Origin::signed(2), 3), Error::<Test>::RequireSudo);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -92,23 +92,24 @@ impl Counter {
|
||||
/// ```
|
||||
///
|
||||
/// * Map: `Foo: map hasher($hash) type => type`: Implements the
|
||||
/// [`StorageMap`](../frame_support/storage/trait.StorageMap.html) trait using the
|
||||
/// [`StorageMap generator`](../frame_support/storage/generator/trait.StorageMap.html).
|
||||
/// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html).
|
||||
/// [`StorageMap`](../frame_support/storage/trait.StorageMap.html) trait using the [`StorageMap
|
||||
/// generator`](../frame_support/storage/generator/trait.StorageMap.html). And
|
||||
/// [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html).
|
||||
///
|
||||
/// `$hash` representing a choice of hashing algorithms available in the
|
||||
/// [`Hashable`](../frame_support/trait.Hashable.html) trait. You will generally want to use one
|
||||
/// of three hashers:
|
||||
/// * `blake2_128_concat`: The default, safe choice. Use if you are unsure or don't care. It is
|
||||
/// secure against user-tainted keys, fairly fast and memory-efficient and supports
|
||||
/// iteration over its keys and values. This must be used if the keys of your map can be
|
||||
/// selected *en masse* by untrusted users.
|
||||
/// secure against user-tainted keys, fairly fast and memory-efficient and supports iteration
|
||||
/// over its keys and values. This must be used if the keys of your map can be selected *en
|
||||
/// masse* by untrusted users.
|
||||
/// * `twox_64_concat`: This is an insecure hasher and can only be used safely if you know that
|
||||
/// the preimages cannot be chosen at will by untrusted users. It is memory-efficient, extremely
|
||||
/// performant and supports iteration over its keys and values. You can safely use this is the
|
||||
/// key is:
|
||||
/// - A (slowly) incrementing index.
|
||||
/// - Known to be the result of a cryptographic hash (though `identity` is a better choice here).
|
||||
/// - Known to be the result of a cryptographic hash (though `identity` is a better choice
|
||||
/// here).
|
||||
/// - Known to be the public key of a cryptographic key pair in existence.
|
||||
/// * `identity`: This is not a hasher at all, and just uses the key material directly. Since it
|
||||
/// does no hashing or appending, it's the fastest possible hasher, however, it's also the least
|
||||
@@ -132,8 +133,9 @@ impl Counter {
|
||||
///
|
||||
/// * Double map: `Foo: double_map hasher($hash1) u32, hasher($hash2) u32 => u32`: Implements the
|
||||
/// [`StorageDoubleMap`](../frame_support/storage/trait.StorageDoubleMap.html) trait using the
|
||||
/// [`StorageDoubleMap generator`](../frame_support/storage/generator/trait.StorageDoubleMap.html).
|
||||
/// And [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html).
|
||||
/// [`StorageDoubleMap
|
||||
/// generator`](../frame_support/storage/generator/trait.StorageDoubleMap.html). And
|
||||
/// [`StoragePrefixedMap`](../frame_support/storage/trait.StoragePrefixedMap.html).
|
||||
///
|
||||
/// `$hash1` and `$hash2` representing choices of hashing algorithms available in the
|
||||
/// [`Hashable`](../frame_support/trait.Hashable.html) trait. They must be chosen with care, see
|
||||
@@ -147,8 +149,8 @@ impl Counter {
|
||||
///
|
||||
/// Thus keys are stored at:
|
||||
/// ```nocompile
|
||||
/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++ Hasher2(encode(key2))
|
||||
/// ```
|
||||
/// Twox128(module_prefix) ++ Twox128(storage_prefix) ++ Hasher1(encode(key1)) ++
|
||||
/// Hasher2(encode(key2)) ```
|
||||
///
|
||||
/// Supported hashers (ordered from least to best security):
|
||||
///
|
||||
@@ -176,8 +178,8 @@ impl Counter {
|
||||
/// Will include the item in `GenesisConfig`.
|
||||
/// * \[optional\] `build(#closure)`: Closure called with storage overlays.
|
||||
/// * \[optional\] `max_values(#expr)`: `expr` is an expression returning a `u32`. It is used to
|
||||
/// implement `StorageInfoTrait`. Note this attribute is not available for storage value as the maximum
|
||||
/// number of values is 1.
|
||||
/// implement `StorageInfoTrait`. Note this attribute is not available for storage value as the
|
||||
/// maximum number of values is 1.
|
||||
/// * `#type`: Storage type.
|
||||
/// * \[optional\] `#default`: Value returned when none.
|
||||
///
|
||||
@@ -339,8 +341,8 @@ pub fn decl_storage(input: TokenStream) -> TokenStream {
|
||||
///
|
||||
/// # Type definitions
|
||||
///
|
||||
/// * The macro generates a type alias for each pallet to their `Module` (or `Pallet`).
|
||||
/// E.g. `type System = frame_system::Pallet<Runtime>`
|
||||
/// * The macro generates a type alias for each pallet to their `Module` (or `Pallet`). E.g. `type
|
||||
/// System = frame_system::Pallet<Runtime>`
|
||||
#[proc_macro]
|
||||
pub fn construct_runtime(input: TokenStream) -> TokenStream {
|
||||
construct_runtime::construct_runtime(input)
|
||||
|
||||
@@ -19,6 +19,7 @@ use crate::{pallet::Def, COUNTER};
|
||||
use frame_support_procedural_tools::clean_type_string;
|
||||
use syn::spanned::Spanned;
|
||||
|
||||
///
|
||||
/// * Generate enum call and implement various trait on it.
|
||||
/// * Implement Callable and call_function on `Pallet`
|
||||
pub fn expand_call(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
use crate::pallet::{parse::helper::get_doc_literals, Def};
|
||||
|
||||
///
|
||||
/// * Generate default rust doc
|
||||
pub fn expand_config(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
let config = &def.config;
|
||||
|
||||
@@ -30,6 +30,7 @@ struct ConstDef {
|
||||
pub default_byte_impl: proc_macro2::TokenStream,
|
||||
}
|
||||
|
||||
///
|
||||
/// * Impl fn module_constant_metadata for pallet.
|
||||
pub fn expand_constants(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
let frame_support = &def.frame_support;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
use crate::pallet::{parse::helper::get_doc_literals, Def};
|
||||
|
||||
///
|
||||
/// * impl various trait on Error
|
||||
/// * impl ModuleErrorMetadata for Error
|
||||
pub fn expand_error(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::{
|
||||
};
|
||||
use syn::{spanned::Spanned, Ident};
|
||||
|
||||
///
|
||||
/// * Add __Ignore variant on Event
|
||||
/// * Impl various trait on Event including metadata
|
||||
/// * if deposit_event is defined, implement deposit_event on module.
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
use crate::pallet::Def;
|
||||
|
||||
///
|
||||
/// * implement the trait `sp_runtime::BuildModuleGenesisStorage`
|
||||
/// * add #[cfg(features = "std")] to GenesisBuild implementation.
|
||||
pub fn expand_genesis_build(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::{
|
||||
};
|
||||
use syn::{spanned::Spanned, Ident};
|
||||
|
||||
///
|
||||
/// * add various derive trait on GenesisConfig struct.
|
||||
pub fn expand_genesis_config(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
let count = COUNTER.with(|counter| counter.borrow_mut().inc());
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
use crate::pallet::Def;
|
||||
|
||||
///
|
||||
/// * implement the individual traits using the Hooks trait
|
||||
pub fn expand_hooks(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
let (where_clause, span, has_runtime_upgrade) = match def.hooks.as_ref() {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
use crate::{pallet::Def, NUMBER_OF_INSTANCE};
|
||||
use proc_macro2::Span;
|
||||
|
||||
///
|
||||
/// * Provide inherent instance to be used by construct_runtime
|
||||
/// * Provide Instance1 ..= Instance16 for instantiable pallet
|
||||
pub fn expand_instances(def: &mut Def) -> proc_macro2::TokenStream {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
use crate::pallet::{expand::merge_where_clauses, parse::helper::get_doc_literals, Def};
|
||||
|
||||
///
|
||||
/// * Add derive trait on Pallet
|
||||
/// * Implement GetStorageVersion on Pallet
|
||||
/// * Implement OnGenesis on Pallet
|
||||
|
||||
@@ -46,6 +46,7 @@ fn check_prefix_duplicates(storage_def: &StorageDef, set: &mut HashSet<String>)
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
/// * if generics are unnamed: replace the first generic `_` by the generated prefix structure
|
||||
/// * if generics are named: reorder the generic, remove their name, and add the missing ones.
|
||||
/// * Add `#[allow(type_alias_bounds)]`
|
||||
@@ -150,6 +151,7 @@ pub fn process_generics(def: &mut Def) -> syn::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
///
|
||||
/// * generate StoragePrefix structs (e.g. for a storage `MyStorage` a struct with the name
|
||||
/// `_GeneratedPrefixForStorage$NameOfStorage` is generated) and implements StorageInstance trait.
|
||||
/// * if generics are unnamed: replace the first generic `_` by the generated prefix structure
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
use crate::pallet::Def;
|
||||
|
||||
///
|
||||
/// * Generate the struct
|
||||
/// * implement the `Get<..>` on it
|
||||
/// * Rename the name of the function to internal name
|
||||
|
||||
@@ -112,7 +112,8 @@ pub struct StorageDef {
|
||||
pub instances: Vec<helper::InstanceUsage>,
|
||||
/// Optional getter to generate. If some then query_kind is ensured to be some as well.
|
||||
pub getter: Option<syn::Ident>,
|
||||
/// Optional expression that evaluates to a type that can be used as StoragePrefix instead of ident.
|
||||
/// Optional expression that evaluates to a type that can be used as StoragePrefix instead of
|
||||
/// ident.
|
||||
pub rename_as: Option<syn::LitStr>,
|
||||
/// Whereas the querytype of the storage is OptionQuery or ValueQuery.
|
||||
/// Note that this is best effort as it can't be determined when QueryKind is generic, and
|
||||
|
||||
@@ -271,10 +271,10 @@ macro_rules! generate_storage_alias {
|
||||
///
|
||||
/// `twox_128(":" ++ NAME ++ ":")` where `NAME` is the name that is passed as type name.
|
||||
///
|
||||
/// - Using `static` to create a static parameter type. Its value is
|
||||
/// being provided by a static variable with the equivalent name in `UPPER_SNAKE_CASE`. An
|
||||
/// additional `set` function is provided in this case to alter the static variable.
|
||||
/// **This is intended for testing ONLY and is ONLY available when `std` is enabled.**
|
||||
/// - Using `static` to create a static parameter type. Its value is being provided by a static
|
||||
/// variable with the equivalent name in `UPPER_SNAKE_CASE`. An additional `set` function is
|
||||
/// provided in this case to alter the static variable. **This is intended for testing ONLY and is
|
||||
/// ONLY available when `std` is enabled.**
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
@@ -1314,11 +1314,11 @@ pub mod pallet_prelude {
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Inside the module the macro will parse item with the attribute: `#[pallet::*]`, some attributes
|
||||
/// are mandatory, some other optional.
|
||||
/// Inside the module the macro will parse item with the attribute: `#[pallet::*]`, some
|
||||
/// attributes are mandatory, some other optional.
|
||||
///
|
||||
/// The attribute are explained with the syntax of non instantiable pallets, to see how pallet with
|
||||
/// instance work see below example.
|
||||
/// The attribute are explained with the syntax of non instantiable pallets, to see how pallet
|
||||
/// with instance work see below example.
|
||||
///
|
||||
/// Note various type can be automatically imported using pallet_prelude in frame_support and
|
||||
/// frame_system:
|
||||
@@ -1348,7 +1348,8 @@ pub mod pallet_prelude {
|
||||
/// optionally other supertrait and where clause.
|
||||
///
|
||||
/// The associated type `Event` is reserved, if defined it must bounds `From<Event>` and
|
||||
/// `IsType<<Self as frame_system::Config>::Event>`, see `#[pallet::event]` for more information.
|
||||
/// `IsType<<Self as frame_system::Config>::Event>`, see `#[pallet::event]` for more
|
||||
/// information.
|
||||
///
|
||||
/// To put `Get` associated type into metadatas, use the attribute `#[pallet::constant]`, e.g.:
|
||||
/// ```ignore
|
||||
@@ -1369,7 +1370,8 @@ pub mod pallet_prelude {
|
||||
///
|
||||
/// ### Macro expansion:
|
||||
///
|
||||
/// The macro expand pallet constant metadata with the information given by `#[pallet::constant]`.
|
||||
/// The macro expand pallet constant metadata with the information given by
|
||||
/// `#[pallet::constant]`.
|
||||
///
|
||||
/// # Pallet struct placeholder: `#[pallet::pallet]` mandatory
|
||||
///
|
||||
@@ -1389,8 +1391,8 @@ pub mod pallet_prelude {
|
||||
/// #[pallet::generate_store(pub(super) trait Store)]
|
||||
/// pub struct Pallet<T>(_);
|
||||
/// ```
|
||||
/// More precisely the store trait contains an associated type for each storage. It is implemented
|
||||
/// for `Pallet` allowing to access the storage from pallet struct.
|
||||
/// More precisely the store trait contains an associated type for each storage. It is
|
||||
/// implemented for `Pallet` allowing to access the storage from pallet struct.
|
||||
///
|
||||
/// Thus when defining a storage named `Foo`, it can later be accessed from `Pallet` using
|
||||
/// `<Pallet as Store>::Foo`.
|
||||
@@ -1406,8 +1408,8 @@ pub mod pallet_prelude {
|
||||
/// This require all storage to implement the trait [`traits::StorageInfoTrait`], thus all keys
|
||||
/// and value types must bound [`pallet_prelude::MaxEncodedLen`].
|
||||
///
|
||||
/// As the macro implements [`traits::GetStorageVersion`], the current storage version needs to be
|
||||
/// communicated to the macro. This can be done by using the `storage_version` attribute:
|
||||
/// As the macro implements [`traits::GetStorageVersion`], the current storage version needs to
|
||||
/// be communicated to the macro. This can be done by using the `storage_version` attribute:
|
||||
///
|
||||
/// ```ignore
|
||||
/// const STORAGE_VERSION: StorageVersion = StorageVersion::new(5);
|
||||
@@ -1439,14 +1441,15 @@ pub mod pallet_prelude {
|
||||
///
|
||||
/// It declare `type Module` type alias for `Pallet`, used by [`construct_runtime`].
|
||||
///
|
||||
/// It implements [`traits::PalletInfoAccess`] on `Pallet` to ease access to pallet informations
|
||||
/// given by [`frame_support::traits::PalletInfo`].
|
||||
/// It implements [`traits::PalletInfoAccess`] on `Pallet` to ease access to pallet
|
||||
/// informations given by [`frame_support::traits::PalletInfo`].
|
||||
/// (The implementation use the associated type `frame_system::Config::PalletInfo`).
|
||||
///
|
||||
/// It implements [`traits::StorageInfoTrait`] on `Pallet` which give information about all storages.
|
||||
/// It implements [`traits::StorageInfoTrait`] on `Pallet` which give information about all
|
||||
/// storages.
|
||||
///
|
||||
/// If the attribute generate_store is set then the macro creates the trait `Store` and implements
|
||||
/// it on `Pallet`.
|
||||
/// If the attribute generate_store is set then the macro creates the trait `Store` and
|
||||
/// implements it on `Pallet`.
|
||||
///
|
||||
/// If the attribute set_storage_max_encoded_len is set then the macro call
|
||||
/// [`traits::StorageInfoTrait`] for each storage in the implementation of
|
||||
@@ -1468,8 +1471,8 @@ pub mod pallet_prelude {
|
||||
/// `Hooks<BlockNumberFor<T>>` (they are defined in preludes), for the type `Pallet<T>`
|
||||
/// and with an optional where clause.
|
||||
///
|
||||
/// If no `#[pallet::hooks]` exists, then a default implementation corresponding to the following
|
||||
/// code is automatically generated:
|
||||
/// If no `#[pallet::hooks]` exists, then a default implementation corresponding to the
|
||||
/// following code is automatically generated:
|
||||
/// ```ignore
|
||||
/// #[pallet::hooks]
|
||||
/// impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
|
||||
@@ -1483,8 +1486,8 @@ pub mod pallet_prelude {
|
||||
/// NOTE: OnRuntimeUpgrade is implemented with `Hooks::on_runtime_upgrade` and some additional
|
||||
/// logic. E.g. logic to write pallet version into storage.
|
||||
///
|
||||
/// NOTE: The macro also adds some tracing logic when implementing the above traits. The following
|
||||
/// hooks emit traces: `on_initialize`, `on_finalize` and `on_runtime_upgrade`.
|
||||
/// NOTE: The macro also adds some tracing logic when implementing the above traits. The
|
||||
/// following hooks emit traces: `on_initialize`, `on_finalize` and `on_runtime_upgrade`.
|
||||
///
|
||||
/// # Call: `#[pallet::call]` optional
|
||||
///
|
||||
@@ -1511,30 +1514,30 @@ pub mod pallet_prelude {
|
||||
/// optional where clause.
|
||||
///
|
||||
/// Each dispatchable needs to define a weight with `#[pallet::weight($expr)]` attribute,
|
||||
/// the first argument must be `origin: OriginFor<T>`, compact encoding for argument can be used
|
||||
/// using `#[pallet::compact]`, function must return `DispatchResultWithPostInfo` or
|
||||
/// the first argument must be `origin: OriginFor<T>`, compact encoding for argument can be
|
||||
/// used using `#[pallet::compact]`, function must return `DispatchResultWithPostInfo` or
|
||||
/// `DispatchResult`.
|
||||
///
|
||||
/// All arguments must implement `Debug`, `PartialEq`, `Eq`, `Decode`, `Encode`, `Clone`. For ease
|
||||
/// of use, bound the trait `Member` available in frame_support::pallet_prelude.
|
||||
/// All arguments must implement `Debug`, `PartialEq`, `Eq`, `Decode`, `Encode`, `Clone`. For
|
||||
/// ease of use, bound the trait `Member` available in frame_support::pallet_prelude.
|
||||
///
|
||||
/// If no `#[pallet::call]` exists, then a default implementation corresponding to the following
|
||||
/// code is automatically generated:
|
||||
/// If no `#[pallet::call]` exists, then a default implementation corresponding to the
|
||||
/// following code is automatically generated:
|
||||
/// ```ignore
|
||||
/// #[pallet::call]
|
||||
/// impl<T: Config> Pallet<T> {}
|
||||
/// ```
|
||||
///
|
||||
/// **WARNING**: modifying dispatchables, changing their order, removing some must be done with
|
||||
/// care. Indeed this will change the outer runtime call type (which is an enum with one variant
|
||||
/// per pallet), this outer runtime call can be stored on-chain (e.g. in pallet-scheduler).
|
||||
/// Thus migration might be needed.
|
||||
/// care. Indeed this will change the outer runtime call type (which is an enum with one
|
||||
/// variant per pallet), this outer runtime call can be stored on-chain (e.g. in
|
||||
/// pallet-scheduler). Thus migration might be needed.
|
||||
///
|
||||
/// ### Macro expansion
|
||||
///
|
||||
/// The macro create an enum `Call` with one variant per dispatchable. This enum implements:
|
||||
/// `Clone`, `Eq`, `PartialEq`, `Debug` (with stripped implementation in `not("std")`), `Encode`,
|
||||
/// `Decode`, `GetDispatchInfo`, `GetCallName`, `UnfilteredDispatchable`.
|
||||
/// `Clone`, `Eq`, `PartialEq`, `Debug` (with stripped implementation in `not("std")`),
|
||||
/// `Encode`, `Decode`, `GetDispatchInfo`, `GetCallName`, `UnfilteredDispatchable`.
|
||||
///
|
||||
/// The macro implement on `Pallet`, the `Callable` trait and a function `call_functions` which
|
||||
/// returns the dispatchable metadatas.
|
||||
@@ -1554,8 +1557,8 @@ pub mod pallet_prelude {
|
||||
/// ...
|
||||
/// }
|
||||
/// ```
|
||||
/// I.e. a regular rust implement block with some optional where clause and functions with 0 args,
|
||||
/// 0 generics, and some return type.
|
||||
/// I.e. a regular rust implement block with some optional where clause and functions with 0
|
||||
/// args, 0 generics, and some return type.
|
||||
///
|
||||
/// ### Macro expansion
|
||||
///
|
||||
@@ -1576,13 +1579,13 @@ pub mod pallet_prelude {
|
||||
/// }
|
||||
/// ```
|
||||
/// I.e. a regular rust enum named `Error`, with generic `T` and fieldless variants.
|
||||
/// The generic `T` mustn't bound anything and where clause is not allowed. But bounds and where
|
||||
/// clause shouldn't be needed for any usecase.
|
||||
/// The generic `T` mustn't bound anything and where clause is not allowed. But bounds and
|
||||
/// where clause shouldn't be needed for any usecase.
|
||||
///
|
||||
/// ### Macro expansion
|
||||
///
|
||||
/// The macro implements `Debug` trait and functions `as_u8` using variant position, and `as_str`
|
||||
/// using variant doc.
|
||||
/// The macro implements `Debug` trait and functions `as_u8` using variant position, and
|
||||
/// `as_str` using variant doc.
|
||||
///
|
||||
/// The macro implements `From<Error<T>>` for `&'static str`.
|
||||
/// The macro implements `From<Error<T>>` for `DispatchError`.
|
||||
@@ -1592,8 +1595,8 @@ pub mod pallet_prelude {
|
||||
///
|
||||
/// # Event: `#[pallet::event]` optional
|
||||
///
|
||||
/// Allow to define pallet events, pallet events are stored in the block when they deposited (and
|
||||
/// removed in next block).
|
||||
/// Allow to define pallet events, pallet events are stored in the block when they deposited
|
||||
/// (and removed in next block).
|
||||
///
|
||||
/// Item is defined as:
|
||||
/// ```ignore
|
||||
@@ -1606,15 +1609,16 @@ pub mod pallet_prelude {
|
||||
/// ...
|
||||
/// }
|
||||
/// ```
|
||||
/// I.e. an enum (with named or unnamed fields variant), named Event, with generic: none or `T` or
|
||||
/// `T: Config`, and optional where clause.
|
||||
/// I.e. an enum (with named or unnamed fields variant), named Event, with generic: none or `T`
|
||||
/// or `T: Config`, and optional where clause.
|
||||
///
|
||||
/// Each field must implement `Clone`, `Eq`, `PartialEq`, `Encode`, `Decode`, and `Debug` (on std
|
||||
/// only).
|
||||
/// Each field must implement `Clone`, `Eq`, `PartialEq`, `Encode`, `Decode`, and `Debug` (on
|
||||
/// std only).
|
||||
/// For ease of use, bound the trait `Member` available in frame_support::pallet_prelude.
|
||||
///
|
||||
/// Variant documentations and field types are put into metadata.
|
||||
/// The attribute `#[pallet::metadata(..)]` allows to specify the metadata to put for some types.
|
||||
/// The attribute `#[pallet::metadata(..)]` allows to specify the metadata to put for some
|
||||
/// types.
|
||||
///
|
||||
/// The metadata of a type is defined by:
|
||||
/// * if matching a type in `#[pallet::metadata(..)]`, then the corresponding metadata.
|
||||
@@ -1676,16 +1680,16 @@ pub mod pallet_prelude {
|
||||
/// For named generic argument: the name for each argument is the one as define on the storage
|
||||
/// struct:
|
||||
/// * [`pallet_prelude::StorageValue`] expect `Value` and optionally `QueryKind` and `OnEmpty`,
|
||||
/// * [`pallet_prelude::StorageMap`] expect `Hasher`, `Key`, `Value` and optionally `QueryKind` and
|
||||
/// `OnEmpty`,
|
||||
/// * [`pallet_prelude::StorageDoubleMap`] expect `Hasher1`, `Key1`, `Hasher2`, `Key2`, `Value` and
|
||||
/// optionally `QueryKind` and `OnEmpty`.
|
||||
/// * [`pallet_prelude::StorageMap`] expect `Hasher`, `Key`, `Value` and optionally `QueryKind`
|
||||
/// and `OnEmpty`,
|
||||
/// * [`pallet_prelude::StorageDoubleMap`] expect `Hasher1`, `Key1`, `Hasher2`, `Key2`, `Value`
|
||||
/// and optionally `QueryKind` and `OnEmpty`.
|
||||
///
|
||||
/// For unnamed generic argument: Their first generic must be `_` as it is replaced by the macro
|
||||
/// and other generic must declared as a normal declaration of type generic in rust.
|
||||
/// For unnamed generic argument: Their first generic must be `_` as it is replaced by the
|
||||
/// macro and other generic must declared as a normal declaration of type generic in rust.
|
||||
///
|
||||
/// The Prefix generic written by the macro is generated using `PalletInfo::name::<Pallet<..>>()`
|
||||
/// and the name of the storage type.
|
||||
/// The Prefix generic written by the macro is generated using
|
||||
/// `PalletInfo::name::<Pallet<..>>()` and the name of the storage type.
|
||||
/// E.g. if runtime names the pallet "MyExample" then the storage `type Foo<T> = ...` use the
|
||||
/// prefix: `Twox128(b"MyExample") ++ Twox128(b"Foo")`.
|
||||
///
|
||||
@@ -1714,12 +1718,12 @@ pub mod pallet_prelude {
|
||||
/// pub(super) type MyStorage<T> = StorageValue<Value = u32>;
|
||||
/// ```
|
||||
///
|
||||
/// All the `cfg` attributes are automatically copied to the items generated for the storage, i.e. the
|
||||
/// getter, storage prefix, and the metadata element etc.
|
||||
/// All the `cfg` attributes are automatically copied to the items generated for the storage,
|
||||
/// i.e. the getter, storage prefix, and the metadata element etc.
|
||||
///
|
||||
/// NOTE: If the `QueryKind` generic parameter is still generic at this stage or is using some type
|
||||
/// alias then the generation of the getter might fail. In this case the getter can be implemented
|
||||
/// manually.
|
||||
/// NOTE: If the `QueryKind` generic parameter is still generic at this stage or is using some
|
||||
/// type alias then the generation of the getter might fail. In this case the getter can be
|
||||
/// implemented manually.
|
||||
///
|
||||
/// NOTE: The generic `Hasher` must implement the [`StorageHasher`] trait (or the type is not
|
||||
/// usable at all). We use [`StorageHasher::METADATA`] for the metadata of the hasher of the
|
||||
@@ -1729,17 +1733,17 @@ pub mod pallet_prelude {
|
||||
///
|
||||
/// For each storage item the macro generates a struct named
|
||||
/// `_GeneratedPrefixForStorage$NameOfStorage`, and implements
|
||||
/// [`StorageInstance`](traits::StorageInstance) on it using the pallet and storage name. It then
|
||||
/// uses it as the first generic of the aliased type.
|
||||
/// [`StorageInstance`](traits::StorageInstance) on it using the pallet and storage name. It
|
||||
/// then uses it as the first generic of the aliased type.
|
||||
///
|
||||
/// For named generic, the macro will reorder the generics, and remove the names.
|
||||
///
|
||||
/// The macro implements the function `storage_metadata` on `Pallet` implementing the metadata for
|
||||
/// all storage items based on their kind:
|
||||
/// The macro implements the function `storage_metadata` on `Pallet` implementing the metadata
|
||||
/// for all storage items based on their kind:
|
||||
/// * for a storage value, the type of the value is copied into the metadata
|
||||
/// * for a storage map, the type of the values and the key's type is copied into the metadata
|
||||
/// * for a storage double map, the type of the values, and the types of key1 and key2 are copied into
|
||||
/// the metadata.
|
||||
/// * for a storage double map, the type of the values, and the types of key1 and key2 are
|
||||
/// copied into the metadata.
|
||||
///
|
||||
/// # Type value: `#[pallet::type_value]` optional
|
||||
///
|
||||
@@ -1764,9 +1768,9 @@ pub mod pallet_prelude {
|
||||
///
|
||||
/// ### Macro expansion
|
||||
///
|
||||
/// Macro renames the function to some internal name, generate a struct with the original name of
|
||||
/// the function and its generic, and implement `Get<$ReturnType>` by calling the user defined
|
||||
/// function.
|
||||
/// Macro renames the function to some internal name, generate a struct with the original name
|
||||
/// of the function and its generic, and implement `Get<$ReturnType>` by calling the user
|
||||
/// defined function.
|
||||
///
|
||||
/// # Genesis config: `#[pallet::genesis_config]` optional
|
||||
///
|
||||
@@ -1805,8 +1809,8 @@ pub mod pallet_prelude {
|
||||
/// fn build(&self) { $expr }
|
||||
/// }
|
||||
/// ```
|
||||
/// I.e. a rust trait implementation with generic `T: Config`, of trait `GenesisBuild<T>` on type
|
||||
/// `GenesisConfig` with generics none or `T`.
|
||||
/// I.e. a rust trait implementation with generic `T: Config`, of trait `GenesisBuild<T>` on
|
||||
/// type `GenesisConfig` with generics none or `T`.
|
||||
///
|
||||
/// E.g.:
|
||||
/// ```ignore
|
||||
@@ -1821,8 +1825,8 @@ pub mod pallet_prelude {
|
||||
/// Macro will add the following attribute on it:
|
||||
/// * `#[cfg(feature = "std")]`
|
||||
///
|
||||
/// Macro will implement `sp_runtime::BuildModuleGenesisStorage` using `()` as second generic for
|
||||
/// non-instantiable pallets.
|
||||
/// Macro will implement `sp_runtime::BuildModuleGenesisStorage` using `()` as second generic
|
||||
/// for non-instantiable pallets.
|
||||
///
|
||||
/// # Inherent: `#[pallet::inherent]` optional
|
||||
///
|
||||
@@ -1857,8 +1861,8 @@ pub mod pallet_prelude {
|
||||
/// I.e. a trait implementation with bound `T: Config`, of trait `ValidateUnsigned` for type
|
||||
/// `Pallet<T>`, and some optional where clause.
|
||||
///
|
||||
/// NOTE: There is also `sp_runtime::traits::SignedExtension` that can be used to add some specific
|
||||
/// logic for transaction validation.
|
||||
/// NOTE: There is also `sp_runtime::traits::SignedExtension` that can be used to add some
|
||||
/// specific logic for transaction validation.
|
||||
///
|
||||
/// ### Macro expansion
|
||||
///
|
||||
@@ -1877,19 +1881,19 @@ pub mod pallet_prelude {
|
||||
/// pub struct Origin<T>(PhantomData<(T)>);
|
||||
/// ```
|
||||
///
|
||||
/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin can
|
||||
/// be stored on-chain (e.g. in pallet-scheduler), thus any change must be done with care as it
|
||||
/// might require some migration.
|
||||
/// **WARNING**: modifying origin changes the outer runtime origin. This outer runtime origin
|
||||
/// can be stored on-chain (e.g. in pallet-scheduler), thus any change must be done with care
|
||||
/// as it might require some migration.
|
||||
///
|
||||
/// NOTE: for instantiable pallet, origin must be generic over T and I.
|
||||
///
|
||||
/// # General notes on instantiable pallet
|
||||
///
|
||||
/// An instantiable pallet is one where Config is generic, i.e. `Config<I>`. This allow runtime to
|
||||
/// implement multiple instance of the pallet, by using different type for the generic.
|
||||
/// An instantiable pallet is one where Config is generic, i.e. `Config<I>`. This allow runtime
|
||||
/// to implement multiple instance of the pallet, by using different type for the generic.
|
||||
/// This is the sole purpose of the generic `I`.
|
||||
/// But because `PalletInfo` requires `Pallet` placeholder to be static it is important to bound
|
||||
/// `'static` whenever `PalletInfo` can be used.
|
||||
/// But because `PalletInfo` requires `Pallet` placeholder to be static it is important to
|
||||
/// bound `'static` whenever `PalletInfo` can be used.
|
||||
/// And in order to have instantiable pallet usable as a regular pallet without instance, it is
|
||||
/// important to bound `= ()` on every types.
|
||||
///
|
||||
@@ -2226,8 +2230,8 @@ pub mod pallet_prelude {
|
||||
///
|
||||
/// 1. Export the metadata of the pallet for later checks
|
||||
/// - run your node with the pallet active
|
||||
/// - query the metadata using the `state_getMetadata` RPC and curl, or use
|
||||
/// `subsee -p <PALLET_NAME> > meta.json`
|
||||
/// - query the metadata using the `state_getMetadata` RPC and curl, or use `subsee -p
|
||||
/// <PALLET_NAME> > meta.json`
|
||||
/// 2. generate the template upgrade for the pallet provided by decl_storage
|
||||
/// with environment variable `PRINT_PALLET_UPGRADE`:
|
||||
/// `PRINT_PALLET_UPGRADE=1 cargo check -p my_pallet` This template can be
|
||||
@@ -2271,7 +2275,8 @@ pub mod pallet_prelude {
|
||||
/// impl<T: Config> Hooks for Pallet<T> {
|
||||
/// }
|
||||
/// ```
|
||||
/// and write inside on_initialize/on_finalize/on_runtime_upgrade/offchain_worker/integrity_test
|
||||
/// and write inside
|
||||
/// `on_initialize`, `on_finalize`, `on_runtime_upgrade`, `offchain_worker`, `integrity_test`.
|
||||
///
|
||||
/// then write:
|
||||
/// ```ignore
|
||||
@@ -2281,7 +2286,8 @@ pub mod pallet_prelude {
|
||||
/// ```
|
||||
/// and write inside all the calls in decl_module with a few changes in the signature:
|
||||
/// - origin must now be written completely, e.g. `origin: OriginFor<T>`
|
||||
/// - result type must be `DispatchResultWithPostInfo`, you need to write it and also you might
|
||||
/// - result type must be `DispatchResultWithPostInfo`, you need to write it and also you
|
||||
/// might
|
||||
/// need to put `Ok(().into())` at the end or the function.
|
||||
/// - `#[compact]` must now be written `#[pallet::compact]`
|
||||
/// - `#[weight = ..]` must now be written `#[pallet::weight(..)]`
|
||||
@@ -2289,8 +2295,8 @@ pub mod pallet_prelude {
|
||||
/// 7. **migrate event**:
|
||||
/// rewrite as a simple enum under with the attribute `#[pallet::event]`,
|
||||
/// use `#[pallet::generate_deposit($vis fn deposit_event)]` to generate deposit_event,
|
||||
/// use `#[pallet::metadata(...)]` to configure the metadata for types in order not to break them.
|
||||
/// 8. **migrate error**: rewrite it with attribute `#[pallet::error]`.
|
||||
/// use `#[pallet::metadata(...)]` to configure the metadata for types in order not to break
|
||||
/// them. 8. **migrate error**: rewrite it with attribute `#[pallet::error]`.
|
||||
/// 9. **migrate storage**:
|
||||
/// decl_storage provide an upgrade template (see 3.). All storages, genesis config, genesis
|
||||
/// build and default implementation of genesis config can be taken from it directly.
|
||||
@@ -2308,7 +2314,8 @@ pub mod pallet_prelude {
|
||||
/// }
|
||||
/// #[pallet::genesis_build]
|
||||
/// impl<T: Config> GenesisBuild<T> for GenesisConfig {
|
||||
/// // impl<T: Config, I: 'static> GenesisBuild<T, I> for GenesisConfig { for instantiable pallet
|
||||
/// // for instantiable pallet:
|
||||
/// // `impl<T: Config, I: 'static> GenesisBuild<T, I> for GenesisConfig {
|
||||
/// fn build() {
|
||||
/// // The add_extra_genesis build logic
|
||||
/// }
|
||||
@@ -2325,10 +2332,12 @@ pub mod pallet_prelude {
|
||||
/// Once this is done you can migrate storage individually, a few notes:
|
||||
/// - for private storage use `pub(crate) type ` or `pub(super) type` or nothing,
|
||||
/// - for storage with `get(fn ..)` use `#[pallet::getter(fn ...)]`
|
||||
/// - for storage with value being `Option<$something>` make generic `Value` being `$something`
|
||||
/// - for storage with value being `Option<$something>` make generic `Value` being
|
||||
/// `$something`
|
||||
/// and generic `QueryKind` being `OptionQuery` (note: this is default). Otherwise make
|
||||
/// `Value` the complete value type and `QueryKind` being `ValueQuery`.
|
||||
/// - for storage with default value: `= $expr;` provide some specific OnEmpty generic. To do so
|
||||
/// - for storage with default value: `= $expr;` provide some specific OnEmpty generic. To do
|
||||
/// so
|
||||
/// use of `#[pallet::type_value]` to generate the wanted struct to put.
|
||||
/// example: `MyStorage: u32 = 3u32` would be written:
|
||||
/// ```ignore
|
||||
@@ -2361,9 +2370,11 @@ pub mod pallet_prelude {
|
||||
/// * error , error, constant,
|
||||
/// * manually check that:
|
||||
/// * `Origin` is moved inside the macro under `#[pallet::origin]` if it exists
|
||||
/// * `ValidateUnsigned` is moved inside the macro under `#[pallet::validate_unsigned)]` if it exists
|
||||
/// * `ValidateUnsigned` is moved inside the macro under `#[pallet::validate_unsigned)]` if it
|
||||
/// exists
|
||||
/// * `ProvideInherent` is moved inside macro under `#[pallet::inherent)]` if it exists
|
||||
/// * `on_initialize`/`on_finalize`/`on_runtime_upgrade`/`offchain_worker` are moved to `Hooks`
|
||||
/// * `on_initialize`/`on_finalize`/`on_runtime_upgrade`/`offchain_worker` are moved to
|
||||
/// `Hooks`
|
||||
/// implementation
|
||||
/// * storages with `config(..)` are converted to `GenesisConfig` field, and their default is
|
||||
/// `= $expr;` if the storage have default value
|
||||
@@ -2380,8 +2391,9 @@ pub mod pallet_prelude {
|
||||
/// as the name the pallet was giving to `decl_storage`,
|
||||
/// * or do a storage migration from the old prefix used to the new prefix used.
|
||||
///
|
||||
/// NOTE: The prefixes used by storage items are in the metadata. Thus, ensuring the metadata hasn't
|
||||
/// changed does ensure that the `pallet_prefix`s used by the storage items haven't changed.
|
||||
/// NOTE: The prefixes used by storage items are in the metadata. Thus, ensuring the metadata
|
||||
/// hasn't changed does ensure that the `pallet_prefix`s used by the storage items haven't
|
||||
/// changed.
|
||||
///
|
||||
/// # Notes when macro fails to show proper error message spans:
|
||||
///
|
||||
|
||||
@@ -125,7 +125,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove a key from the map, returning the value at the key if the key was previously in the map.
|
||||
/// Remove a key from the map, returning the value at the key if the key was previously in the
|
||||
/// map.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but the ordering on the borrowed
|
||||
/// form _must_ match the ordering on the key type.
|
||||
@@ -137,7 +138,8 @@ where
|
||||
self.0.remove(key)
|
||||
}
|
||||
|
||||
/// Remove a key from the map, returning the value at the key if the key was previously in the map.
|
||||
/// Remove a key from the map, returning the value at the key if the key was previously in the
|
||||
/// map.
|
||||
///
|
||||
/// The key may be any borrowed form of the map's key type, but the ordering on the borrowed
|
||||
/// form _must_ match the ordering on the key type.
|
||||
|
||||
@@ -160,8 +160,8 @@ pub trait StorageValue<T: FullCodec> {
|
||||
/// # Usage
|
||||
///
|
||||
/// This would typically be called inside the module implementation of on_runtime_upgrade, while
|
||||
/// ensuring **no usage of this storage are made before the call to `on_runtime_upgrade`**. (More
|
||||
/// precisely prior initialized modules doesn't make use of this storage).
|
||||
/// ensuring **no usage of this storage are made before the call to `on_runtime_upgrade`**.
|
||||
/// (More precisely prior initialized modules doesn't make use of this storage).
|
||||
fn translate<O: Decode, F: FnOnce(Option<O>) -> Option<T>>(f: F) -> Result<Option<T>, ()>;
|
||||
|
||||
/// Store a value under this key into the provided storage instance.
|
||||
@@ -989,7 +989,8 @@ impl<T> ChildTriePrefixIterator<T> {
|
||||
}
|
||||
|
||||
impl<T: Decode + Sized> ChildTriePrefixIterator<(Vec<u8>, T)> {
|
||||
/// Construct iterator to iterate over child trie items in `child_info` with the prefix `prefix`.
|
||||
/// Construct iterator to iterate over child trie items in `child_info` with the prefix
|
||||
/// `prefix`.
|
||||
///
|
||||
/// NOTE: Iterator with [`Self::drain`] will remove any value who failed to decode
|
||||
pub fn with_prefix(child_info: &ChildInfo, prefix: &[u8]) -> Self {
|
||||
@@ -1012,7 +1013,8 @@ impl<T: Decode + Sized> ChildTriePrefixIterator<(Vec<u8>, T)> {
|
||||
}
|
||||
|
||||
impl<K: Decode + Sized, T: Decode + Sized> ChildTriePrefixIterator<(K, T)> {
|
||||
/// Construct iterator to iterate over child trie items in `child_info` with the prefix `prefix`.
|
||||
/// Construct iterator to iterate over child trie items in `child_info` with the prefix
|
||||
/// `prefix`.
|
||||
///
|
||||
/// NOTE: Iterator with [`Self::drain`] will remove any key or value who failed to decode
|
||||
pub fn with_prefix_over_key<H: ReversibleStorageHasher>(
|
||||
|
||||
@@ -58,7 +58,8 @@ pub trait KeyGeneratorMaxEncodedLen: KeyGenerator {
|
||||
fn key_max_encoded_len() -> usize;
|
||||
}
|
||||
|
||||
/// A trait containing methods that are only implemented on the Key struct instead of the entire tuple.
|
||||
/// A trait containing methods that are only implemented on the Key struct instead of the entire
|
||||
/// tuple.
|
||||
pub trait KeyGeneratorInner: KeyGenerator {
|
||||
type Hasher: StorageHasher;
|
||||
|
||||
|
||||
@@ -39,10 +39,10 @@ pub use value::{StorageValue, StorageValueMetadata};
|
||||
/// Trait implementing how the storage optional value is converted into the queried type.
|
||||
///
|
||||
/// It is implemented by:
|
||||
/// * `OptionQuery` which convert an optional value to an optional value, user when querying
|
||||
/// storage will get an optional value.
|
||||
/// * `ValueQuery` which convert an optional value to a value, user when querying storage will get
|
||||
/// a value.
|
||||
/// * `OptionQuery` which convert an optional value to an optional value, user when querying storage
|
||||
/// will get an optional value.
|
||||
/// * `ValueQuery` which convert an optional value to a value, user when querying storage will get a
|
||||
/// value.
|
||||
pub trait QueryKindTrait<Value, OnEmpty> {
|
||||
/// Metadata for the storage kind.
|
||||
const METADATA: StorageEntryModifier;
|
||||
|
||||
@@ -270,8 +270,8 @@ impl<T, S> codec::DecodeLength for WeakBoundedVec<T, S> {
|
||||
}
|
||||
|
||||
// NOTE: we could also implement this as:
|
||||
// impl<T: Value, S1: Get<u32>, S2: Get<u32>> PartialEq<WeakBoundedVec<T, S2>> for WeakBoundedVec<T, S1>
|
||||
// to allow comparison of bounded vectors with different bounds.
|
||||
// impl<T: Value, S1: Get<u32>, S2: Get<u32>> PartialEq<WeakBoundedVec<T, S2>> for WeakBoundedVec<T,
|
||||
// S1> to allow comparison of bounded vectors with different bounds.
|
||||
impl<T, S> PartialEq for WeakBoundedVec<T, S>
|
||||
where
|
||||
T: PartialEq,
|
||||
|
||||
@@ -185,8 +185,8 @@ pub trait ChangeMembers<AccountId: Clone + Ord> {
|
||||
sorted_new: &[AccountId],
|
||||
);
|
||||
|
||||
/// Set the new members; they **must already be sorted**. This will compute the diff and use it to
|
||||
/// call `change_members_sorted`.
|
||||
/// Set the new members; they **must already be sorted**. This will compute the diff and use it
|
||||
/// to call `change_members_sorted`.
|
||||
///
|
||||
/// This resets any previous value of prime.
|
||||
fn set_members_sorted(new_members: &[AccountId], old_members: &[AccountId]) {
|
||||
|
||||
@@ -277,7 +277,8 @@ pub trait IsSubType<T> {
|
||||
pub trait ExecuteBlock<Block: BlockT> {
|
||||
/// Execute the given `block`.
|
||||
///
|
||||
/// This will execute all extrinsics in the block and check that the resulting header is correct.
|
||||
/// This will execute all extrinsics in the block and check that the resulting header is
|
||||
/// correct.
|
||||
///
|
||||
/// # Panic
|
||||
///
|
||||
|
||||
@@ -42,8 +42,8 @@ pub enum DispatchTime<BlockNumber> {
|
||||
/// The highest priority. We invert the value so that normal sorting will place the highest
|
||||
/// priority at the beginning of the list.
|
||||
pub const HIGHEST_PRIORITY: Priority = 0;
|
||||
/// Anything of this value or lower will definitely be scheduled on the block that they ask for, even
|
||||
/// if it breaches the `MaximumWeight` limitation.
|
||||
/// Anything of this value or lower will definitely be scheduled on the block that they ask for,
|
||||
/// even if it breaches the `MaximumWeight` limitation.
|
||||
pub const HARD_DEADLINE: Priority = 63;
|
||||
/// The lowest priority. Most stuff should be around here.
|
||||
pub const LOWEST_PRIORITY: Priority = 255;
|
||||
|
||||
@@ -21,7 +21,8 @@ use sp_std::prelude::*;
|
||||
|
||||
/// An instance of a pallet in the storage.
|
||||
///
|
||||
/// It is required that these instances are unique, to support multiple instances per pallet in the same runtime!
|
||||
/// It is required that these instances are unique, to support multiple instances per pallet in the
|
||||
/// same runtime!
|
||||
///
|
||||
/// E.g. for module MyModule default instance will have prefix "MyModule" and other instances
|
||||
/// "InstanceNMyModule".
|
||||
|
||||
@@ -56,8 +56,8 @@ pub trait Currency<AccountId> {
|
||||
/// The total amount of issuance in the system.
|
||||
fn total_issuance() -> Self::Balance;
|
||||
|
||||
/// The minimum balance any single account may have. This is equivalent to the `Balances` module's
|
||||
/// `ExistentialDeposit`.
|
||||
/// The minimum balance any single account may have. This is equivalent to the `Balances`
|
||||
/// module's `ExistentialDeposit`.
|
||||
fn minimum_balance() -> Self::Balance;
|
||||
|
||||
/// Reduce the total issuance by `amount` and return the according imbalance. The imbalance will
|
||||
@@ -192,8 +192,8 @@ pub trait Currency<AccountId> {
|
||||
/// Ensure an account's free balance equals some value; this will create the account
|
||||
/// if needed.
|
||||
///
|
||||
/// Returns a signed imbalance and status to indicate if the account was successfully updated or update
|
||||
/// has led to killing of the account.
|
||||
/// Returns a signed imbalance and status to indicate if the account was successfully updated or
|
||||
/// update has led to killing of the account.
|
||||
fn make_free_balance_be(
|
||||
who: &AccountId,
|
||||
balance: Self::Balance,
|
||||
|
||||
@@ -193,8 +193,8 @@ pub trait NamedReservableCurrency<AccountId>: ReservableCurrency<AccountId> {
|
||||
Self::slash_reserved_named(id, who, value).0
|
||||
}
|
||||
|
||||
/// Move all the named reserved balance of one account into the balance of another, according to `status`.
|
||||
/// If `status` is `Reserved`, the balance will be reserved with given `id`.
|
||||
/// Move all the named reserved balance of one account into the balance of another, according to
|
||||
/// `status`. If `status` is `Reserved`, the balance will be reserved with given `id`.
|
||||
///
|
||||
/// Is a no-op if:
|
||||
/// - the value to be moved is zero; or
|
||||
|
||||
@@ -198,7 +198,8 @@ pub trait Unbalanced<AccountId>: Inspect<AccountId> {
|
||||
}
|
||||
let mut r = Self::set_balance(who, new_balance);
|
||||
if r.is_err() {
|
||||
// Some error, probably because we tried to destroy an account which cannot be destroyed.
|
||||
// Some error, probably because we tried to destroy an account which cannot be
|
||||
// destroyed.
|
||||
if new_balance.is_zero() && amount >= minimum_balance {
|
||||
new_balance = minimum_balance;
|
||||
amount -= minimum_balance;
|
||||
|
||||
@@ -142,7 +142,8 @@ pub type DebtOf<AccountId, B> = Imbalance<
|
||||
<B as Balanced<AccountId>>::OnDropCredit,
|
||||
>;
|
||||
|
||||
/// Imbalance implying that the total_issuance value is greater than the sum of all account balances.
|
||||
/// Imbalance implying that the total_issuance value is greater than the sum of all account
|
||||
/// balances.
|
||||
pub type CreditOf<AccountId, B> = Imbalance<
|
||||
<B as Inspect<AccountId>>::Balance,
|
||||
// This will generally be implemented by decreasing the total_issuance value.
|
||||
|
||||
@@ -223,7 +223,8 @@ pub trait Unbalanced<AccountId>: Inspect<AccountId> {
|
||||
}
|
||||
let mut r = Self::set_balance(asset, who, new_balance);
|
||||
if r.is_err() {
|
||||
// Some error, probably because we tried to destroy an account which cannot be destroyed.
|
||||
// Some error, probably because we tried to destroy an account which cannot be
|
||||
// destroyed.
|
||||
if new_balance.is_zero() && amount >= minimum_balance {
|
||||
new_balance = minimum_balance;
|
||||
amount -= minimum_balance;
|
||||
|
||||
@@ -168,7 +168,8 @@ pub type DebtOf<AccountId, B> = Imbalance<
|
||||
<B as Balanced<AccountId>>::OnDropCredit,
|
||||
>;
|
||||
|
||||
/// Imbalance implying that the total_issuance value is greater than the sum of all account balances.
|
||||
/// Imbalance implying that the total_issuance value is greater than the sum of all account
|
||||
/// balances.
|
||||
pub type CreditOf<AccountId, B> = Imbalance<
|
||||
<B as Inspect<AccountId>>::AssetId,
|
||||
<B as Inspect<AccountId>>::Balance,
|
||||
|
||||
@@ -51,8 +51,8 @@ pub enum WithdrawConsequence<Balance> {
|
||||
}
|
||||
|
||||
impl<Balance: Zero> WithdrawConsequence<Balance> {
|
||||
/// Convert the type into a `Result` with `DispatchError` as the error or the additional `Balance`
|
||||
/// by which the account will be reduced.
|
||||
/// Convert the type into a `Result` with `DispatchError` as the error or the additional
|
||||
/// `Balance` by which the account will be reduced.
|
||||
pub fn into_result(self) -> Result<Balance, DispatchError> {
|
||||
use WithdrawConsequence::*;
|
||||
match self {
|
||||
|
||||
@@ -238,7 +238,8 @@ impl<N: Zero> Lateness<N> for () {
|
||||
}
|
||||
|
||||
/// Implementors of this trait provide information about whether or not some validator has
|
||||
/// been registered with them. The [Session module](../../pallet_session/index.html) is an implementor.
|
||||
/// been registered with them. The [Session module](../../pallet_session/index.html) is an
|
||||
/// implementor.
|
||||
pub trait ValidatorRegistration<ValidatorId> {
|
||||
/// Returns true if the provided validator ID has been registered with the implementing runtime
|
||||
/// module
|
||||
|
||||
@@ -229,8 +229,9 @@ pub enum DispatchClass {
|
||||
Operational,
|
||||
/// A mandatory dispatch. These kinds of dispatch are always included regardless of their
|
||||
/// weight, therefore it is critical that they are separately validated to ensure that a
|
||||
/// malicious validator cannot craft a valid but impossibly heavy block. Usually this just means
|
||||
/// ensuring that the extrinsic can only be included once and that it is always very light.
|
||||
/// malicious validator cannot craft a valid but impossibly heavy block. Usually this just
|
||||
/// means ensuring that the extrinsic can only be included once and that it is always very
|
||||
/// light.
|
||||
///
|
||||
/// Do *NOT* use it for extrinsics that can be heavy.
|
||||
///
|
||||
@@ -528,12 +529,12 @@ impl<T> PaysFee<T> for (Weight, Pays) {
|
||||
/// A struct to represent a weight which is a function of the input arguments. The given items have
|
||||
/// the following types:
|
||||
///
|
||||
/// - `WD`: a raw `Weight` value or a closure that returns a `Weight` with the same
|
||||
/// - `WD`: a raw `Weight` value or a closure that returns a `Weight` with the same argument list as
|
||||
/// the dispatched, wrapped in a tuple.
|
||||
/// - `CD`: a raw `DispatchClass` value or a closure that returns a `DispatchClass` with the same
|
||||
/// argument list as the dispatched, wrapped in a tuple.
|
||||
/// - `CD`: a raw `DispatchClass` value or a closure that returns a `DispatchClass`
|
||||
/// with the same argument list as the dispatched, wrapped in a tuple.
|
||||
/// - `PF`: a `Pays` variant for whether this dispatch pays fee or not or a closure that
|
||||
/// returns a `Pays` variant with the same argument list as the dispatched, wrapped in a tuple.
|
||||
/// - `PF`: a `Pays` variant for whether this dispatch pays fee or not or a closure that returns a
|
||||
/// `Pays` variant with the same argument list as the dispatched, wrapped in a tuple.
|
||||
#[deprecated = "Function arguments are available directly inside the annotation now."]
|
||||
pub struct FunctionOf<WD, CD, PF>(pub WD, pub CD, pub PF);
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@ impl frame_support::traits::PalletInfo for PanicPalletInfo {
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides an implementation of [`frame_support::traits::Randomness`] that should only be used in tests!
|
||||
/// Provides an implementation of [`frame_support::traits::Randomness`] that should only be used in
|
||||
/// tests!
|
||||
pub struct TestRandomness<T>(sp_std::marker::PhantomData<T>);
|
||||
|
||||
impl<Output: codec::Decode + Default, T> frame_support::traits::Randomness<Output, T::BlockNumber>
|
||||
|
||||
@@ -456,7 +456,8 @@ mod tests {
|
||||
CheckWeight::<Test>::do_pre_dispatch(&dispatch_normal, len),
|
||||
InvalidTransaction::ExhaustsResources
|
||||
);
|
||||
// Thank goodness we can still do an operational transaction to possibly save the blockchain.
|
||||
// Thank goodness we can still do an operational transaction to possibly save the
|
||||
// blockchain.
|
||||
assert_ok!(CheckWeight::<Test>::do_pre_dispatch(&dispatch_operational, len));
|
||||
// Not too much though
|
||||
assert_err!(
|
||||
|
||||
@@ -27,8 +27,8 @@
|
||||
//! The System pallet defines the core data types used in a Substrate runtime.
|
||||
//! It also provides several utility functions (see [`Pallet`]) for other FRAME pallets.
|
||||
//!
|
||||
//! In addition, it manages the storage items for extrinsics data, indexes, event records, and digest items,
|
||||
//! among other things that support the execution of the current block.
|
||||
//! In addition, it manages the storage items for extrinsics data, indexes, event records, and
|
||||
//! digest items, among other things that support the execution of the current block.
|
||||
//!
|
||||
//! It also handles low-level tasks like depositing logs, basic set up and take down of
|
||||
//! temporary storage entries, and access to previous block hashes.
|
||||
@@ -54,10 +54,10 @@
|
||||
//! - [`CheckEra`]: Checks the era of the transaction. Contains a single payload of type `Era`.
|
||||
//! - [`CheckGenesis`]: Checks the provided genesis hash of the transaction. Must be a part of the
|
||||
//! signed payload of the transaction.
|
||||
//! - [`CheckSpecVersion`]: Checks that the runtime version is the same as the one used to sign the
|
||||
//! transaction.
|
||||
//! - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign the
|
||||
//! transaction.
|
||||
//! - [`CheckSpecVersion`]: Checks that the runtime version is the same as the one used to sign
|
||||
//! the transaction.
|
||||
//! - [`CheckTxVersion`]: Checks that the transaction version is the same as the one used to sign
|
||||
//! the transaction.
|
||||
//!
|
||||
//! Lookup the runtime aggregator file (e.g. `node/runtime`) to see the full list of signed
|
||||
//! extensions included in a chain.
|
||||
@@ -180,8 +180,8 @@ pub mod pallet {
|
||||
/// The aggregated `Call` type.
|
||||
type Call: Dispatchable + Debug;
|
||||
|
||||
/// Account index (aka nonce) type. This stores the number of previous transactions associated
|
||||
/// with a sender account.
|
||||
/// Account index (aka nonce) type. This stores the number of previous transactions
|
||||
/// associated with a sender account.
|
||||
type Index: Parameter
|
||||
+ Member
|
||||
+ MaybeSerializeDeserialize
|
||||
@@ -238,10 +238,10 @@ pub mod pallet {
|
||||
|
||||
/// Converting trait to take a source type and convert to `AccountId`.
|
||||
///
|
||||
/// Used to define the type and conversion mechanism for referencing accounts in transactions.
|
||||
/// It's perfectly reasonable for this to be an identity conversion (with the source type being
|
||||
/// `AccountId`), but other pallets (e.g. Indices pallet) may provide more functional/efficient
|
||||
/// alternatives.
|
||||
/// Used to define the type and conversion mechanism for referencing accounts in
|
||||
/// transactions. It's perfectly reasonable for this to be an identity conversion (with the
|
||||
/// source type being `AccountId`), but other pallets (e.g. Indices pallet) may provide more
|
||||
/// functional/efficient alternatives.
|
||||
type Lookup: StaticLookup<Target = Self::AccountId>;
|
||||
|
||||
/// The block header.
|
||||
@@ -363,10 +363,11 @@ pub mod pallet {
|
||||
/// # <weight>
|
||||
/// - `O(C + S)` where `C` length of `code` and `S` complexity of `can_set_code`
|
||||
/// - 1 storage write (codec `O(C)`).
|
||||
/// - 1 call to `can_set_code`: `O(S)` (calls `sp_io::misc::runtime_version` which is expensive).
|
||||
/// - 1 call to `can_set_code`: `O(S)` (calls `sp_io::misc::runtime_version` which is
|
||||
/// expensive).
|
||||
/// - 1 event.
|
||||
/// The weight of this function is dependent on the runtime, but generally this is very expensive.
|
||||
/// We will treat this as a full block.
|
||||
/// The weight of this function is dependent on the runtime, but generally this is very
|
||||
/// expensive. We will treat this as a full block.
|
||||
/// # </weight>
|
||||
#[pallet::weight((T::BlockWeights::get().max_block, DispatchClass::Operational))]
|
||||
pub fn set_code(origin: OriginFor<T>, code: Vec<u8>) -> DispatchResultWithPostInfo {
|
||||
@@ -384,8 +385,8 @@ pub mod pallet {
|
||||
/// - `O(C)` where `C` length of `code`
|
||||
/// - 1 storage write (codec `O(C)`).
|
||||
/// - 1 event.
|
||||
/// The weight of this function is dependent on the runtime. We will treat this as a full block.
|
||||
/// # </weight>
|
||||
/// The weight of this function is dependent on the runtime. We will treat this as a full
|
||||
/// block. # </weight>
|
||||
#[pallet::weight((T::BlockWeights::get().max_block, DispatchClass::Operational))]
|
||||
pub fn set_code_without_checks(
|
||||
origin: OriginFor<T>,
|
||||
|
||||
@@ -27,13 +27,14 @@
|
||||
//!
|
||||
//! The Timestamp pallet allows the validators to set and validate a timestamp with each block.
|
||||
//!
|
||||
//! It uses inherents for timestamp data, which is provided by the block author and validated/verified
|
||||
//! by other validators. The timestamp can be set only once per block and must be set each block.
|
||||
//! There could be a constraint on how much time must pass before setting the new timestamp.
|
||||
//! It uses inherents for timestamp data, which is provided by the block author and
|
||||
//! validated/verified by other validators. The timestamp can be set only once per block and must be
|
||||
//! set each block. There could be a constraint on how much time must pass before setting the new
|
||||
//! timestamp.
|
||||
//!
|
||||
//! **NOTE:** The Timestamp pallet is the recommended way to query the on-chain time instead of using
|
||||
//! an approach based on block numbers. The block number based time measurement can cause issues
|
||||
//! because of cumulative calculation errors and hence should be avoided.
|
||||
//! **NOTE:** The Timestamp pallet is the recommended way to query the on-chain time instead of
|
||||
//! using an approach based on block numbers. The block number based time measurement can cause
|
||||
//! issues because of cumulative calculation errors and hence should be avoided.
|
||||
//!
|
||||
//! ## Interface
|
||||
//!
|
||||
@@ -52,7 +53,8 @@
|
||||
//!
|
||||
//! ## Usage
|
||||
//!
|
||||
//! The following example shows how to use the Timestamp pallet in your custom pallet to query the current timestamp.
|
||||
//! The following example shows how to use the Timestamp pallet in your custom pallet to query the
|
||||
//! current timestamp.
|
||||
//!
|
||||
//! ### Prerequisites
|
||||
//!
|
||||
@@ -120,13 +122,14 @@ pub mod pallet {
|
||||
+ Copy
|
||||
+ MaxEncodedLen;
|
||||
|
||||
/// Something which can be notified when the timestamp is set. Set this to `()` if not needed.
|
||||
/// Something which can be notified when the timestamp is set. Set this to `()` if not
|
||||
/// needed.
|
||||
type OnTimestampSet: OnTimestampSet<Self::Moment>;
|
||||
|
||||
/// The minimum period between blocks. Beware that this is different to the *expected* period
|
||||
/// that the block production apparatus provides. Your chosen consensus system will generally
|
||||
/// work with this to determine a sensible block time. e.g. For Aura, it will be double this
|
||||
/// period on default settings.
|
||||
/// The minimum period between blocks. Beware that this is different to the *expected*
|
||||
/// period that the block production apparatus provides. Your chosen consensus system will
|
||||
/// generally work with this to determine a sensible block time. e.g. For Aura, it will be
|
||||
/// double this period on default settings.
|
||||
#[pallet::constant]
|
||||
type MinimumPeriod: Get<Self::Moment>;
|
||||
|
||||
@@ -179,7 +182,8 @@ pub mod pallet {
|
||||
///
|
||||
/// # <weight>
|
||||
/// - `O(1)` (Note that implementations of `OnTimestampSet` must also be `O(1)`)
|
||||
/// - 1 storage read and 1 storage mutation (codec `O(1)`). (because of `DidUpdate::take` in `on_finalize`)
|
||||
/// - 1 storage read and 1 storage mutation (codec `O(1)`). (because of `DidUpdate::take` in
|
||||
/// `on_finalize`)
|
||||
/// - 1 event handler `on_timestamp_set`. Must be `O(1)`.
|
||||
/// # </weight>
|
||||
#[pallet::weight((
|
||||
|
||||
@@ -22,11 +22,11 @@
|
||||
//! A subsystem to allow for an agile "tipping" process, whereby a reward may be given without first
|
||||
//! having a pre-determined stakeholder group come to consensus on how much should be paid.
|
||||
//!
|
||||
//! A group of `Tippers` is determined through the config `Config`. After half of these have declared
|
||||
//! some amount that they believe a particular reported reason deserves, then a countdown period is
|
||||
//! entered where any remaining members can declare their tip amounts also. After the close of the
|
||||
//! countdown period, the median of all declared tips is paid to the reported beneficiary, along
|
||||
//! with any finders fee, in case of a public (and bonded) original report.
|
||||
//! A group of `Tippers` is determined through the config `Config`. After half of these have
|
||||
//! declared some amount that they believe a particular reported reason deserves, then a countdown
|
||||
//! period is entered where any remaining members can declare their tip amounts also. After the
|
||||
//! close of the countdown period, the median of all declared tips is paid to the reported
|
||||
//! beneficiary, along with any finders fee, in case of a public (and bonded) original report.
|
||||
//!
|
||||
//!
|
||||
//! ### Terminology
|
||||
@@ -114,8 +114,8 @@ pub struct OpenTip<
|
||||
BlockNumber: Parameter,
|
||||
Hash: Parameter,
|
||||
> {
|
||||
/// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be
|
||||
/// sensible.
|
||||
/// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded
|
||||
/// string. A URL would be sensible.
|
||||
reason: Hash,
|
||||
/// The account to be tipped.
|
||||
who: AccountId,
|
||||
@@ -530,8 +530,8 @@ impl<T: Config> Module<T> {
|
||||
}
|
||||
|
||||
pub fn migrate_retract_tip_for_tip_new() {
|
||||
/// An open tipping "motion". Retains all details of a tip including information on the finder
|
||||
/// and the members who have voted.
|
||||
/// An open tipping "motion". Retains all details of a tip including information on the
|
||||
/// finder and the members who have voted.
|
||||
#[derive(Clone, Eq, PartialEq, Encode, Decode, RuntimeDebug)]
|
||||
pub struct OldOpenTip<
|
||||
AccountId: Parameter,
|
||||
@@ -539,15 +539,15 @@ impl<T: Config> Module<T> {
|
||||
BlockNumber: Parameter,
|
||||
Hash: Parameter,
|
||||
> {
|
||||
/// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be
|
||||
/// sensible.
|
||||
/// The hash of the reason for the tip. The reason should be a human-readable UTF-8
|
||||
/// encoded string. A URL would be sensible.
|
||||
reason: Hash,
|
||||
/// The account to be tipped.
|
||||
who: AccountId,
|
||||
/// The account who began this tip and the amount held on deposit.
|
||||
finder: Option<(AccountId, Balance)>,
|
||||
/// The block number at which this tip will close if `Some`. If `None`, then no closing is
|
||||
/// scheduled.
|
||||
/// The block number at which this tip will close if `Some`. If `None`, then no closing
|
||||
/// is scheduled.
|
||||
closes: Option<BlockNumber>,
|
||||
/// The members who have voted for this tip. Sorted by AccountId.
|
||||
tips: Vec<(AccountId, Balance)>,
|
||||
|
||||
@@ -412,8 +412,8 @@ fn test_last_reward_migration() {
|
||||
BlockNumber: Parameter,
|
||||
Hash: Parameter,
|
||||
> {
|
||||
/// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded string. A URL would be
|
||||
/// sensible.
|
||||
/// The hash of the reason for the tip. The reason should be a human-readable UTF-8 encoded
|
||||
/// string. A URL would be sensible.
|
||||
reason: Hash,
|
||||
/// The account to be tipped.
|
||||
who: AccountId,
|
||||
|
||||
@@ -117,8 +117,8 @@ type BalanceOf<T> = <<T as Config>::OnChargeTransaction as OnChargeTransaction<T
|
||||
/// - in a fully congested chain: `p >= v * k * (1 - s')`.
|
||||
/// - in an empty chain: `p >= v * k * (-s')`.
|
||||
///
|
||||
/// For example, when all blocks are full and there are 28800 blocks per day (default in `substrate-node`)
|
||||
/// and v == 0.00001, s' == 0.1875, we'd have:
|
||||
/// For example, when all blocks are full and there are 28800 blocks per day (default in
|
||||
/// `substrate-node`) and v == 0.00001, s' == 0.1875, we'd have:
|
||||
///
|
||||
/// p >= 0.00001 * 28800 * 0.8125
|
||||
/// p >= 0.234
|
||||
|
||||
@@ -36,8 +36,9 @@ pub struct InclusionFee<Balance> {
|
||||
pub base_fee: Balance,
|
||||
/// The length fee, the amount paid for the encoded length (in bytes) of the transaction.
|
||||
pub len_fee: Balance,
|
||||
/// - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on
|
||||
/// the congestion of the network.
|
||||
///
|
||||
/// - `targeted_fee_adjustment`: This is a multiplier that can tune the final fee based on the
|
||||
/// congestion of the network.
|
||||
/// - `weight_fee`: This amount is computed based on the weight of the transaction. Weight
|
||||
/// accounts for the execution time of a transaction.
|
||||
///
|
||||
@@ -60,8 +61,8 @@ impl<Balance: AtLeast32BitUnsigned + Copy> InclusionFee<Balance> {
|
||||
|
||||
/// The `FeeDetails` is composed of:
|
||||
/// - (Optional) `inclusion_fee`: Only the `Pays::Yes` transaction can have the inclusion fee.
|
||||
/// - `tip`: If included in the transaction, the tip will be added on top. Only
|
||||
/// signed transactions can have a tip.
|
||||
/// - `tip`: If included in the transaction, the tip will be added on top. Only signed
|
||||
/// transactions can have a tip.
|
||||
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
@@ -88,7 +89,8 @@ impl<Balance: AtLeast32BitUnsigned + Copy> FeeDetails<Balance> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Information related to a dispatchable's class, weight, and fee that can be queried from the runtime.
|
||||
/// Information related to a dispatchable's class, weight, and fee that can be queried from the
|
||||
/// runtime.
|
||||
#[derive(Eq, PartialEq, Encode, Decode, Default)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
|
||||
@@ -169,9 +169,9 @@ pub mod pallet {
|
||||
|
||||
#[pallet::call]
|
||||
impl<T: Config> Pallet<T> {
|
||||
/// Index and store data on chain. Minimum data size is 1 bytes, maximum is `MaxTransactionSize`.
|
||||
/// Data will be removed after `STORAGE_PERIOD` blocks, unless `renew` is called.
|
||||
/// # <weight>
|
||||
/// Index and store data on chain. Minimum data size is 1 bytes, maximum is
|
||||
/// `MaxTransactionSize`. Data will be removed after `STORAGE_PERIOD` blocks, unless `renew`
|
||||
/// is called. # <weight>
|
||||
/// - n*log(n) of data size, as all data is pushed to an in-memory trie.
|
||||
/// Additionally contains a DB write.
|
||||
/// # </weight>
|
||||
@@ -258,7 +258,8 @@ pub mod pallet {
|
||||
/// Check storage proof for block number `block_number() - StoragePeriod`.
|
||||
/// If such block does not exist the proof is expected to be `None`.
|
||||
/// # <weight>
|
||||
/// - Linear w.r.t the number of indexed transactions in the proved block for random probing.
|
||||
/// - Linear w.r.t the number of indexed transactions in the proved block for random
|
||||
/// probing.
|
||||
/// There's a DB read for each transaction.
|
||||
/// Here we assume a maximum of 100 probed transactions.
|
||||
/// # </weight>
|
||||
|
||||
@@ -95,15 +95,14 @@ pub type NegativeImbalanceOf<T, I = ()> = <<T as Config<I>>::Currency as Currenc
|
||||
/// A trait to allow the Treasury Pallet to spend it's funds for other purposes.
|
||||
/// There is an expectation that the implementer of this trait will correctly manage
|
||||
/// the mutable variables passed to it:
|
||||
/// * `budget_remaining`: How much available funds that can be spent by the treasury.
|
||||
/// As funds are spent, you must correctly deduct from this value.
|
||||
/// * `imbalance`: Any imbalances that you create should be subsumed in here to
|
||||
/// maximize efficiency of updating the total issuance. (i.e. `deposit_creating`)
|
||||
/// * `total_weight`: Track any weight that your `spend_fund` implementation uses by
|
||||
/// updating this value.
|
||||
/// * `missed_any`: If there were items that you want to spend on, but there were
|
||||
/// not enough funds, mark this value as `true`. This will prevent the treasury
|
||||
/// from burning the excess funds.
|
||||
/// * `budget_remaining`: How much available funds that can be spent by the treasury. As funds are
|
||||
/// spent, you must correctly deduct from this value.
|
||||
/// * `imbalance`: Any imbalances that you create should be subsumed in here to maximize efficiency
|
||||
/// of updating the total issuance. (i.e. `deposit_creating`)
|
||||
/// * `total_weight`: Track any weight that your `spend_fund` implementation uses by updating this
|
||||
/// value.
|
||||
/// * `missed_any`: If there were items that you want to spend on, but there were not enough funds,
|
||||
/// mark this value as `true`. This will prevent the treasury from burning the excess funds.
|
||||
#[impl_trait_for_tuples::impl_for_tuples(30)]
|
||||
pub trait SpendFunds<T: Config<I>, I: 'static = ()> {
|
||||
fn spend_funds(
|
||||
@@ -293,8 +292,8 @@ pub mod pallet {
|
||||
/// # <weight>
|
||||
/// - Complexity: `O(A)` where `A` is the number of approvals
|
||||
/// - Db reads and writes: `Approvals`, `pot account data`
|
||||
/// - Db reads and writes per approval:
|
||||
/// `Proposals`, `proposer account data`, `beneficiary account data`
|
||||
/// - Db reads and writes per approval: `Proposals`, `proposer account data`, `beneficiary
|
||||
/// account data`
|
||||
/// - The weight is overestimated if some approvals got missed.
|
||||
/// # </weight>
|
||||
fn on_initialize(n: T::BlockNumber) -> Weight {
|
||||
|
||||
@@ -413,7 +413,8 @@ pub mod pallet {
|
||||
|
||||
Self::deposit_event(Event::Destroyed(class));
|
||||
|
||||
// NOTE: could use postinfo to reflect the actual number of accounts/sufficient/approvals
|
||||
// NOTE: could use postinfo to reflect the actual number of
|
||||
// accounts/sufficient/approvals
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -32,9 +32,9 @@
|
||||
//! 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 origin and are thus hampered with the origin's filters.
|
||||
//! 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 origin
|
||||
//! and are thus hampered with the origin's filters.
|
||||
//!
|
||||
//! Since proxy filters are respected in all dispatches of this pallet, it should never need to be
|
||||
//! filtered by any proxy.
|
||||
|
||||
@@ -579,7 +579,8 @@ fn batch_all_does_not_nest() {
|
||||
);
|
||||
|
||||
// And for those who want to get a little fancy, we check that the filter persists across
|
||||
// other kinds of dispatch wrapping functions... in this case `batch_all(batch(batch_all(..)))`
|
||||
// other kinds of dispatch wrapping functions... in this case
|
||||
// `batch_all(batch(batch_all(..)))`
|
||||
let batch_nested = Call::Utility(UtilityCall::batch(vec![batch_all]));
|
||||
// Batch will end with `Ok`, but does not actually execute as we can see from the event
|
||||
// and balances.
|
||||
|
||||
Reference in New Issue
Block a user