Rewrap all comments to 100 line width (#9490)

* reformat everything again

* manual formatting

* last manual fix

* Fix build
This commit is contained in:
Kian Paimani
2021-08-11 16:56:55 +02:00
committed by GitHub
parent 8180c58700
commit abd08e29ce
258 changed files with 1776 additions and 1447 deletions
+2 -1
View File
@@ -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);
}
+10 -8
View File
@@ -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.
///
+6 -4
View File
@@ -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>,
+5 -5
View File
@@ -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>;
}
+4 -2
View File
@@ -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 {
+2 -2
View File
@@ -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
+8 -7
View File
@@ -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)>,
+56 -45
View File
@@ -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
+2 -2
View File
@@ -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
+11 -9
View File
@@ -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:
///
+4 -3
View File
@@ -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.
+2 -1
View File
@@ -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,
+2 -1
View File
@@ -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
+8 -8
View File
@@ -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 {
+37 -30
View File
@@ -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.
+14 -14
View File
@@ -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.
+4 -3
View File
@@ -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`.
+58 -54
View File
@@ -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();
+10 -9
View File
@@ -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() },
+12 -11
View File
@@ -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)
});
+62 -47
View File
@@ -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
+3 -3
View File
@@ -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(
+6 -6
View File
@@ -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...
+4 -3
View File
@@ -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())
}
+6 -4
View File
@@ -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]
+4 -3
View File
@@ -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`.
+3 -3
View File
@@ -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.
+6 -8
View File
@@ -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]
+3 -2
View File
@@ -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));
+13 -9
View File
@@ -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,
+51 -47
View File
@@ -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)
+2 -1
View File
@@ -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));
+9 -9
View File
@@ -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)]);
});
+4 -3
View File
@@ -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),
}
);
+15 -10
View File
@@ -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.
+11 -12
View File
@@ -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
///
+6 -12
View File
@@ -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
+2 -2
View File
@@ -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>(
+6 -3
View File
@@ -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<_>>()
}
+56 -49
View File
@@ -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.
///
+16 -7
View File
@@ -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;
+6 -5
View File
@@ -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_.
///
+2 -1
View File
@@ -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);
});
}
+17 -15
View File
@@ -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
+107 -95
View File
@@ -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.
+6 -4
View File
@@ -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]) {
+2 -1
View File
@@ -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
+8 -7
View File
@@ -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);
+2 -1
View File
@@ -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!(
+18 -17
View File
@@ -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>,
+17 -13
View File
@@ -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((
+13 -13
View File
@@ -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)>,
+2 -2
View File
@@ -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>
+10 -11
View File
@@ -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 {
+2 -1
View File
@@ -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(())
})
}
+3 -3
View File
@@ -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.
+2 -1
View File
@@ -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.