mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-13 05:51:02 +00:00
Stash/controller model for staking (#1782)
* First steps to stash/controller separation * More drafting * More drafting * Finish draft. * Optimisation * Remove accidental commit * Make it build. * Fix linked map for traits. * Fix Option<_> variant. * Improve naming a tad * Rebuild runtime * Builds! * First test. * Bump RT version * Minor fix * Update Mock * adds the correct reward testcase (+staking eras which was already ok) * fixes the basic staking testcase to work properly (along with a small fix in the module) * New logic to avoid controller transferring stash. * Fix some build issues. * adding some comments to tests * Fix impls. * adds a few more lines to explain the test case * More fixes. * gets the basic test up and running again * Fix rest of build * Rebuild wasm * Fix docs. * fix staking test with new chnages * updating some tests, pending questions * More working tests * adds double staking test * Docs * remove invalid slashing test * Payee stuff. * Fix build * Docs * Fix test * Fix a couple of tests * Layout plan for finishing tests before Pragmen * Add some working tests * re-build staking and reward tests * Add more tests * fix offline grace test * Nominator should have payee checked for cleanup * adds more nomination tets * adds validator prefs tests * Fix and clean up some TODOs * Fix a couple of issues * Fix tests * noting warnings from tests * final fix of local tests * Fix slot_stake bug * Half baked test * Add logic to limit `unstake_threshold` set in storage * Make sure to check before writing! Almost forgot this one * Move a couple of comments * fix last broken slot_stake test * Ignore broken test
This commit is contained in:
@@ -29,10 +29,13 @@ use rstd::{cmp, result};
|
||||
use parity_codec::Codec;
|
||||
use parity_codec_derive::{Encode, Decode};
|
||||
use srml_support::{StorageValue, StorageMap, Parameter, decl_event, decl_storage, decl_module, ensure};
|
||||
use srml_support::traits::{UpdateBalanceOutcome, Currency, EnsureAccountLiquid, OnFreeBalanceZero, ArithmeticType};
|
||||
use srml_support::traits::{
|
||||
UpdateBalanceOutcome, Currency, EnsureAccountLiquid, OnFreeBalanceZero, TransferAsset, WithdrawReason, ArithmeticType
|
||||
};
|
||||
use srml_support::dispatch::Result;
|
||||
use primitives::traits::{Zero, SimpleArithmetic,
|
||||
As, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug, TransferAsset};
|
||||
use primitives::traits::{
|
||||
Zero, SimpleArithmetic, As, StaticLookup, Member, CheckedAdd, CheckedSub, MaybeSerializeDebug
|
||||
};
|
||||
use system::{IsDeadAccount, OnNewAccount, ensure_signed};
|
||||
|
||||
mod mock;
|
||||
@@ -52,7 +55,7 @@ pub trait Trait: system::Trait {
|
||||
type OnNewAccount: OnNewAccount<Self::AccountId>;
|
||||
|
||||
/// A function that returns true iff a given account can transfer its funds to another account.
|
||||
type EnsureAccountLiquid: EnsureAccountLiquid<Self::AccountId>;
|
||||
type EnsureAccountLiquid: EnsureAccountLiquid<Self::AccountId, Self::Balance>;
|
||||
|
||||
/// The overarching event type.
|
||||
type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
|
||||
@@ -272,34 +275,6 @@ impl<T: Trait> Module<T> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds up to `value` to the free balance of `who`. If `who` doesn't exist, it is created.
|
||||
///
|
||||
/// This is a sensitive function since it circumvents any fees associated with account
|
||||
/// setup. Ensure it is only called by trusted code.
|
||||
///
|
||||
/// NOTE: This assumes that the total stake remains unchanged after this operation. If
|
||||
/// you mean to actually mint value into existence, then use `reward` instead.
|
||||
pub fn increase_free_balance_creating(who: &T::AccountId, value: T::Balance) -> UpdateBalanceOutcome {
|
||||
Self::set_free_balance_creating(who, Self::free_balance(who) + value)
|
||||
}
|
||||
|
||||
/// Substrates `value` from the free balance of `who`. If the whole amount cannot be
|
||||
/// deducted, an error is returned.
|
||||
///
|
||||
/// NOTE: This assumes that the total stake remains unchanged after this operation. If
|
||||
/// you mean to actually burn value out of existence, then use `slash` instead.
|
||||
pub fn decrease_free_balance(
|
||||
who: &T::AccountId,
|
||||
value: T::Balance
|
||||
) -> result::Result<UpdateBalanceOutcome, &'static str> {
|
||||
T::EnsureAccountLiquid::ensure_account_liquid(who)?;
|
||||
let b = Self::free_balance(who);
|
||||
if b < value {
|
||||
return Err("account has too few funds")
|
||||
}
|
||||
Ok(Self::set_free_balance(who, b - value))
|
||||
}
|
||||
|
||||
/// Transfer some liquid free balance to another staker.
|
||||
pub fn make_transfer(transactor: &T::AccountId, dest: &T::AccountId, value: T::Balance) -> Result {
|
||||
let from_balance = Self::free_balance(transactor);
|
||||
@@ -320,7 +295,7 @@ impl<T: Trait> Module<T> {
|
||||
if would_create && value < Self::existential_deposit() {
|
||||
return Err("value too low to create account");
|
||||
}
|
||||
T::EnsureAccountLiquid::ensure_account_liquid(transactor)?;
|
||||
T::EnsureAccountLiquid::ensure_account_can_withdraw(transactor, value, WithdrawReason::Transfer)?;
|
||||
|
||||
// NOTE: total stake being stored in the same type means that this could never overflow
|
||||
// but better to be safe than sorry.
|
||||
@@ -402,23 +377,27 @@ where
|
||||
}
|
||||
|
||||
fn can_reserve(who: &T::AccountId, value: Self::Balance) -> bool {
|
||||
if T::EnsureAccountLiquid::ensure_account_liquid(who).is_ok() {
|
||||
if T::EnsureAccountLiquid::ensure_account_can_withdraw(who, value, WithdrawReason::Reserve).is_ok() {
|
||||
Self::free_balance(who) >= value
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn total_issuance() -> Self:: Balance {
|
||||
Self::total_issuance()
|
||||
fn total_issuance() -> Self::Balance {
|
||||
<TotalIssuance<T>>::get()
|
||||
}
|
||||
|
||||
fn minimum_balance() -> Self::Balance {
|
||||
Self::existential_deposit()
|
||||
}
|
||||
|
||||
fn free_balance(who: &T::AccountId) -> Self::Balance {
|
||||
Self::free_balance(who)
|
||||
<FreeBalance<T>>::get(who)
|
||||
}
|
||||
|
||||
fn reserved_balance(who: &T::AccountId) -> Self::Balance {
|
||||
Self::reserved_balance(who)
|
||||
<ReservedBalance<T>>::get(who)
|
||||
}
|
||||
|
||||
fn slash(who: &T::AccountId, value: Self::Balance) -> Option<Self::Balance> {
|
||||
@@ -451,7 +430,7 @@ where
|
||||
if b < value {
|
||||
return Err("not enough free funds")
|
||||
}
|
||||
T::EnsureAccountLiquid::ensure_account_liquid(who)?;
|
||||
T::EnsureAccountLiquid::ensure_account_can_withdraw(who, value, WithdrawReason::Reserve)?;
|
||||
Self::set_reserved_balance(who, Self::reserved_balance(who) + value);
|
||||
Self::set_free_balance(who, b - value);
|
||||
Ok(())
|
||||
@@ -508,8 +487,8 @@ impl<T: Trait> TransferAsset<T::AccountId> for Module<T> {
|
||||
Self::make_transfer(from, to, amount)
|
||||
}
|
||||
|
||||
fn remove_from(who: &T::AccountId, value: T::Balance) -> Result {
|
||||
T::EnsureAccountLiquid::ensure_account_liquid(who)?;
|
||||
fn withdraw(who: &T::AccountId, value: T::Balance, reason: WithdrawReason) -> Result {
|
||||
T::EnsureAccountLiquid::ensure_account_can_withdraw(who, value, reason)?;
|
||||
let b = Self::free_balance(who);
|
||||
ensure!(b >= value, "account has too few funds");
|
||||
Self::set_free_balance(who, b - value);
|
||||
@@ -517,7 +496,7 @@ impl<T: Trait> TransferAsset<T::AccountId> for Module<T> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn add_to(who: &T::AccountId, value: T::Balance) -> Result {
|
||||
fn deposit(who: &T::AccountId, value: T::Balance) -> Result {
|
||||
Self::set_free_balance_creating(who, Self::free_balance(who) + value);
|
||||
Self::increase_total_stake_by(value);
|
||||
Ok(())
|
||||
|
||||
@@ -154,17 +154,6 @@ fn balance_transfer_works() {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn balance_reduction_works() {
|
||||
with_externalities(&mut ExtBuilder::default().build(), || {
|
||||
Balances::set_free_balance(&1, 111);
|
||||
Balances::increase_total_stake_by(111);
|
||||
assert_ok!(Balances::decrease_free_balance(&1, 69).map(|_| ()));
|
||||
assert_eq!(Balances::total_balance(&1), 42);
|
||||
assert_noop!(Balances::decrease_free_balance(&1, 69).map(|_| ()), "account has too few funds");
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reserving_balance_should_work() {
|
||||
with_externalities(&mut ExtBuilder::default().build(), || {
|
||||
|
||||
Reference in New Issue
Block a user