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:
Gav Wood
2019-03-06 12:46:17 +01:00
committed by GitHub
parent 46541ec73c
commit ccc11974ee
62 changed files with 795 additions and 346 deletions
+4 -2
View File
@@ -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 {
+3
View File
@@ -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)]
+51 -66
View File
@@ -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