Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Aggregate all liquidity restrictions in a single place #1921

Merged
merged 32 commits into from
Mar 6, 2019

Conversation

gavofyork
Copy link
Member

@gavofyork gavofyork commented Mar 4, 2019

Fixes #1896

Removes a bunch of serde dependencies, too.

Breaking changes

EnsureAccountLiquid has been removed from balances::Trait and Democracy no longer implements OnFreeBalanceZero. Simply remove Democracy from impl balances::Trait for Runtime's OnFreeBalanceZero type entry and remove EnsureAccountLiquid altogether.

If you use EnsureAccountLiquid in an SRML module, you'll need to refactor it to use LockableCurrency instead. See the documentation for more details.

@gavofyork gavofyork added A0-please_review Pull request needs code review. A3-in_progress Pull request is in progress. No review needed at this stage. and removed A0-please_review Pull request needs code review. labels Mar 4, 2019
@xlc
Copy link
Contributor

xlc commented Mar 4, 2019

It will be good if this logic can be abstracted into its own module so I can reuse it in my multi asset currency module. But otherwise I can just copy and adapt the logic in my module.

@gavofyork
Copy link
Member Author

I'll leave it like this for now - feel free to make a PR which pulls it out into its own module.

@gavofyork gavofyork added A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. B2-breaksapi labels Mar 4, 2019
use srml_support::{assert_noop, assert_ok, assert_err};
use srml_support::{
assert_noop, assert_ok, assert_err,
traits::{LockableCurrency, LockIdentifier, WithdrawReason, WithdrawReasons, TransferAsset}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WithdrawReason unused.

|| {
Balances::set_lock(ID_1, &1, 1280, u64::max_value(), WithdrawReasons::all());
Balances::set_lock(ID_2, &1, 1280, u64::max_value(), WithdrawReasons::all());
assert_ok!(<Balances as TransferAsset<_>>::transfer(&1, &2, 100));
Copy link
Contributor

@kianenigma kianenigma Mar 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think I am missing something about the nature of the lock here that this strikes me as counter-intuitive. To me, this account should now have all of its 2*1280 units of fund locked and the transfer should fail. The implementation of ensure_account_can_withdraw seems also close to what I assumed but something is missing in my mind here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

following up on the above: shouldn't a lock affect free-vesting balance?
In other words what would have made this test (of course for me) more understandable was to see the operation and then a query afterwards on how it affected the different balance storage items corresponding to 1:

Balances::set_lock(ID_1, &1, 1280, u64::max_value(), WithdrawReasons::all());
Balances::set_lock(ID_2, &1, 1280, u64::max_value(), WithdrawReasons::all());

// knowing that initially free = 2580 and vesting = 0
assert_eq!(Balances::free_balance(&1), XXX); 
assert_eq!(Balances::vesting_balance(&1), YYY); 

Copy link
Contributor

@kianenigma kianenigma Mar 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@joepetrowski since I see that you are assigned to the documentation of this module this might also be related to you.

Given that we decided to put as much doc as possible into the code files, documenting these might also be helpful.

kianenigma
kianenigma previously approved these changes Mar 5, 2019
Copy link
Contributor

@kianenigma kianenigma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a few questions (more might be added) but I don't see any of them as things to hold back the PR and they are mostly to put my own mind at peace.

Edit: except for this if we want to be concise and strict on code merged to master.

@gavofyork
Copy link
Member Author

@kianenigma could do with a final review as quite a bit changed.

@kianenigma kianenigma self-requested a review March 6, 2019 11:35
@kianenigma kianenigma dismissed their stale review March 6, 2019 11:35

new changes pushed.

@gavofyork gavofyork merged commit b825e26 into master Mar 6, 2019
@gavofyork gavofyork deleted the gav-central-locking branch March 6, 2019 11:46
/// for the given reason.
///
/// `Err(...)` with the reason why not otherwise.
pub fn ensure_account_can_withdraw(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be moved to Currency trait or LockableCurrency trait?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because it is used within the module (pub fn make_transfer) to ensure that there is enough unvested balance. All chains using the balances module allow vesting, so this check makes sense.

Regarding the use of locks, Locks is a storage item of the entire module. If the logic makes it past the vesting check and the chain does not implement Currency or LockableCurrency then the locks getter will return empty and the function will return Ok(()).

let locks = Self::locks(who);
if locks.is_empty() {
	return Ok(())    // <--- Will return here
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean it is better to also expose ensure_account_can_withdraw in the Currency or LockableCurrency trait so other modules are able to check this liquidity before calling mutate method offered by Currency trait.

/// `Err(...)` with the reason why not otherwise.
pub fn ensure_account_can_withdraw(
who: &T::AccountId,
_amount: T::Balance,
Copy link
Contributor

@xlc xlc Mar 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the reason to include this unused amount as well as new_balance?
it should be able to calculate one from other so why passing it twice?
also it doesn't query user free balance and check amount is greater than that.
I found it is awkward to use this call. I need to check free balance is more than amount, and calculate the new amount, and call this method check to check if a transfer is allowed.
Shouldn't this does all the check and query for me?

Some(b) => b,
};
if would_create && value < Self::existential_deposit() {
return Err("value too low to create account");
}
T::EnsureAccountLiquid::ensure_account_can_withdraw(transactor, value, WithdrawReason::Transfer)?;
Self::ensure_account_can_withdraw(transactor, value, WithdrawReason::Transfer, new_from_balance)?;
Copy link
Contributor

@xlc xlc Mar 11, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing check?
Self::ensure_account_can_withdraw(transactor, fee, WithdrawReason::TransactionPayment, new_from_balance)?
fee is used for transaction payment and value is used for transfer.
This means ensure_account_can_withdraw needs to be able to designed to be able to query multiple reasons at once?
Something like
Self::ensure_account_can_withdraw(transactor, vec![(fee, WithdrawReason::TransactionPayment), (value, WithdrawReason::Transfer)])?

Copy link
Contributor

@gui1117 gui1117 Mar 12, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or Self::ensure_account_can_withdraw(transactor, WithdrawReason::TransactionPayment | WithdrawReason::Transfer, new_from_balance)?

MTDK1 pushed a commit to bdevux/substrate that referenced this pull request Apr 12, 2019
* 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.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-please_review Pull request needs code review.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants