mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 07:01:05 +00:00
Aggregate all liquidity restrictions in a single place (#1921)
* Clean up session key rotation * Fix build * Bump version * Introduce feature to balances. * Move staking locking logic over to central point * ^^^ rest * First part of assimilation * More assimilation * More assimilation * Fix most tests * Fix build * Move Balances to new locking system * :q! * Bump runtime version * Build runtime * Convenience function * Test fix. * Whitespace * Improve type legibility. * Fix comment. * More tests. * More tests. * Bump version * Caps * Whitespace * Whitespace * Remove unneeded function.
This commit is contained in:
@@ -6,7 +6,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
hex-literal = { version = "0.1.0", optional = true }
|
||||
serde = { version = "1.0", default-features = false }
|
||||
serde = { version = "1.0", optional = true }
|
||||
serde_derive = { version = "1.0", optional = true }
|
||||
parity-codec = { version = "3.1", default-features = false, features = ["derive"] }
|
||||
srml-metadata = { path = "../metadata", default-features = false }
|
||||
@@ -17,6 +17,7 @@ inherents = { package = "substrate-inherents", path = "../../core/inherents", de
|
||||
srml-support-procedural = { path = "./procedural" }
|
||||
paste = "0.1"
|
||||
once_cell = { version = "0.1.6", default-features = false, optional = true }
|
||||
bitmask = { git = "https://github.com/paritytech/bitmask", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.5.1"
|
||||
@@ -26,7 +27,8 @@ default = ["std"]
|
||||
std = [
|
||||
"hex-literal",
|
||||
"once_cell",
|
||||
"serde/std",
|
||||
"bitmask/std",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"runtime_io/std",
|
||||
"parity-codec/std",
|
||||
|
||||
@@ -232,9 +232,9 @@ fn decl_store_extra_genesis(
|
||||
use #scrate::rstd::{cell::RefCell, marker::PhantomData};
|
||||
use #scrate::codec::{Encode, Decode};
|
||||
|
||||
let storage = (RefCell::new(&mut r), PhantomData::<Self>::default());
|
||||
let v = (#builder)(&self);
|
||||
<#name<#traitinstance> as #scrate::storage::generator::StorageValue<#typ>>::put(&v, &storage);
|
||||
|
||||
}}
|
||||
},
|
||||
DeclStorageTypeInfosKind::Map { key_type, .. } => {
|
||||
@@ -242,7 +242,6 @@ fn decl_store_extra_genesis(
|
||||
use #scrate::rstd::{cell::RefCell, marker::PhantomData};
|
||||
use #scrate::codec::{Encode, Decode};
|
||||
|
||||
let storage = (RefCell::new(&mut r), PhantomData::<Self>::default());
|
||||
let data = (#builder)(&self);
|
||||
for (k, v) in data.into_iter() {
|
||||
<#name<#traitinstance> as #scrate::storage::generator::StorageMap<#key_type, #typ>>::insert(&k, &v, &storage);
|
||||
@@ -382,12 +381,28 @@ fn decl_store_extra_genesis(
|
||||
let mut r: #scrate::runtime_primitives::StorageOverlay = Default::default();
|
||||
let mut c: #scrate::runtime_primitives::ChildrenStorageOverlay = Default::default();
|
||||
|
||||
#builders
|
||||
{
|
||||
use #scrate::rstd::{cell::RefCell, marker::PhantomData};
|
||||
let storage = (RefCell::new(&mut r), PhantomData::<Self>::default());
|
||||
#builders
|
||||
}
|
||||
|
||||
#scall(&mut r, &mut c, &self);
|
||||
|
||||
Ok((r, c))
|
||||
}
|
||||
fn assimilate_storage(self, r: &mut #scrate::runtime_primitives::StorageOverlay, c: &mut #scrate::runtime_primitives::ChildrenStorageOverlay) -> ::std::result::Result<(), String> {
|
||||
use #scrate::rstd::{cell::RefCell, marker::PhantomData};
|
||||
let storage = (RefCell::new(r), PhantomData::<Self>::default());
|
||||
|
||||
#builders
|
||||
|
||||
let r = storage.0.into_inner();
|
||||
|
||||
#scall(r, c, &self);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![cfg_attr(not(feature = "std"), feature(alloc))]
|
||||
|
||||
#[macro_use]
|
||||
extern crate bitmask;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use serde;
|
||||
#[doc(hidden)]
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
//! Traits for SRML
|
||||
|
||||
use crate::rstd::result;
|
||||
use crate::codec::Codec;
|
||||
use crate::codec::{Codec, Encode, Decode};
|
||||
use crate::runtime_primitives::traits::{
|
||||
MaybeSerializeDebug, SimpleArithmetic, As
|
||||
};
|
||||
@@ -53,61 +53,6 @@ impl<Balance> OnDilution<Balance> for () {
|
||||
fn on_dilution(_minted: Balance, _portion: Balance) {}
|
||||
}
|
||||
|
||||
/// Determinator for whether a given account is able to use its **free** balance.
|
||||
///
|
||||
/// By convention, `ensure_account_liquid` overrules `ensure_account_can_withdraw`. If a
|
||||
/// caller gets `Ok` from the former, then they do not need to call the latter.
|
||||
///
|
||||
/// This implies that if you define the latter away from its default of replicating the
|
||||
/// former, then ensure you also redefine the former to return an `Err` in corresponding
|
||||
/// situations, otherwise you'll end up giving inconsistent information.
|
||||
// TODO: Remove in favour of explicit functionality in balances module: #1896
|
||||
pub trait EnsureAccountLiquid<AccountId, Balance> {
|
||||
/// Ensures that the account is completely unencumbered. If this is `Ok` then there's no need to
|
||||
/// check any other items. If it's an `Err`, then you must use one pair of the other items.
|
||||
fn ensure_account_liquid(who: &AccountId) -> result::Result<(), &'static str>;
|
||||
|
||||
/// Returns `Ok` iff the account is able to make a withdrawal of the given amount
|
||||
/// for the given reason.
|
||||
///
|
||||
/// `Err(...)` with the reason why not otherwise.
|
||||
///
|
||||
/// By default this just reflects the results of `ensure_account_liquid`.
|
||||
///
|
||||
/// @warning If you redefine this away from the default, ensure that you define
|
||||
/// `ensure_account_liquid` in accordance.
|
||||
fn ensure_account_can_withdraw(
|
||||
who: &AccountId,
|
||||
_amount: Balance,
|
||||
_reason: WithdrawReason
|
||||
) -> result::Result<(), &'static str> {
|
||||
Self::ensure_account_liquid(who)
|
||||
}
|
||||
}
|
||||
impl<
|
||||
AccountId,
|
||||
Balance: Copy,
|
||||
X: EnsureAccountLiquid<AccountId, Balance>,
|
||||
Y: EnsureAccountLiquid<AccountId, Balance>,
|
||||
> EnsureAccountLiquid<AccountId, Balance> for (X, Y) {
|
||||
fn ensure_account_liquid(who: &AccountId) -> result::Result<(), &'static str> {
|
||||
X::ensure_account_liquid(who)?;
|
||||
Y::ensure_account_liquid(who)
|
||||
}
|
||||
|
||||
fn ensure_account_can_withdraw(
|
||||
who: &AccountId,
|
||||
amount: Balance,
|
||||
reason: WithdrawReason
|
||||
) -> result::Result<(), &'static str> {
|
||||
X::ensure_account_can_withdraw(who, amount, reason)?;
|
||||
Y::ensure_account_can_withdraw(who, amount, reason)
|
||||
}
|
||||
}
|
||||
impl<AccountId, Balance> EnsureAccountLiquid<AccountId, Balance> for () {
|
||||
fn ensure_account_liquid(_who: &AccountId) -> result::Result<(), &'static str> { Ok(()) }
|
||||
}
|
||||
|
||||
/// Outcome of a balance update.
|
||||
pub enum UpdateBalanceOutcome {
|
||||
/// Account balance was simply updated.
|
||||
@@ -227,6 +172,41 @@ pub trait Currency<AccountId> {
|
||||
) -> result::Result<Option<Self::Balance>, &'static str>;
|
||||
}
|
||||
|
||||
/// An identifier for a lock. Used for disambiguating different locks so that
|
||||
/// they can be individually replaced or removed.
|
||||
pub type LockIdentifier = [u8; 8];
|
||||
|
||||
/// A currency whose accounts can have liquidity restructions.
|
||||
pub trait LockableCurrency<AccountId>: Currency<AccountId> {
|
||||
/// The quantity used to denote time; usually just a `BlockNumber`.
|
||||
type Moment;
|
||||
|
||||
/// Introduce a new lock or change an existing one.
|
||||
fn set_lock(
|
||||
id: LockIdentifier,
|
||||
who: &AccountId,
|
||||
amount: Self::Balance,
|
||||
until: Self::Moment,
|
||||
reasons: WithdrawReasons,
|
||||
);
|
||||
|
||||
/// Change any existing lock so that it becomes strictly less liquid in all
|
||||
/// respects to the given parameters.
|
||||
fn extend_lock(
|
||||
id: LockIdentifier,
|
||||
who: &AccountId,
|
||||
amount: Self::Balance,
|
||||
until: Self::Moment,
|
||||
reasons: WithdrawReasons,
|
||||
);
|
||||
|
||||
/// Remove an existing lock.
|
||||
fn remove_lock(
|
||||
id: LockIdentifier,
|
||||
who: &AccountId,
|
||||
);
|
||||
}
|
||||
|
||||
/// Charge bytes fee trait
|
||||
pub trait ChargeBytesFee<AccountId> {
|
||||
/// Charge fees from `transactor` for an extrinsic (transaction) of encoded length
|
||||
@@ -246,16 +226,21 @@ pub trait ChargeFee<AccountId>: ChargeBytesFee<AccountId> {
|
||||
fn refund_fee(transactor: &AccountId, amount: Self::Amount) -> Result<(), &'static str>;
|
||||
}
|
||||
|
||||
/// Reason for moving funds out of an account.
|
||||
#[derive(Copy, Clone, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum WithdrawReason {
|
||||
/// In order to pay for (system) transaction costs.
|
||||
TransactionPayment,
|
||||
/// In order to transfer ownership.
|
||||
Transfer,
|
||||
/// In order to reserve some funds for a later return or repatriation
|
||||
Reserve,
|
||||
bitmask! {
|
||||
/// Reasons for moving funds out of an account.
|
||||
#[derive(Encode, Decode)]
|
||||
pub mask WithdrawReasons: i8 where
|
||||
|
||||
/// Reason for moving funds out of an account.
|
||||
#[derive(Encode, Decode)]
|
||||
flags WithdrawReason {
|
||||
/// In order to pay for (system) transaction costs.
|
||||
TransactionPayment = 0b00000001,
|
||||
/// In order to transfer ownership.
|
||||
Transfer = 0b00000010,
|
||||
/// In order to reserve some funds for a later return or repatriation
|
||||
Reserve = 0b00000100,
|
||||
}
|
||||
}
|
||||
|
||||
/// Transfer fungible asset trait
|
||||
|
||||
Reference in New Issue
Block a user