Use can_hold instead of can_reserve in fn hold#12004
Use can_hold instead of can_reserve in fn hold#12004
Conversation
|
Test? |
|
No test? |
|
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
…le-impl-in-balance
| })?; | ||
| Ok(()) | ||
| ensure!( | ||
| <Self as fungible::InspectHold<T::AccountId>>::can_hold(who, amount), |
There was a problem hiding this comment.
Okay, after writing unit tests, I found out that there is a difference between can_reserve and can_hold: the latter ensures that the reserved/held amount doesn't make the free balance go below the existential deposit. Should we still continue using can_hold here then? Or should we change can_hold to match the semantics of can_reserve?
There was a problem hiding this comment.
if we change can_hold what that mess up any existing code using can_hold / what are the tradeoffs?
There was a problem hiding this comment.
We want people to be able to use fungible traits instead of Currency in the future. See #8285 and #8453. We currently use Currency traits everywhere, and we'd like to change that.
sam0x17
left a comment
There was a problem hiding this comment.
Looks good to me once we have a definitive answer about the can_hold / can_reserve thing
|
7a6db84 Looks good. |
|
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
…le-impl-in-balance
gavofyork
left a comment
There was a problem hiding this comment.
holding/reserving should never kill an account, so adding the keep_alive arg doesn't make sense here.
|
bot rebase |
…le-impl-in-balance
|
Rebased |
As per this comment: #12004 (review) This reverts commit 7a6db84.
|
Would appreciate input in terms of logic soundness for The important differences between the current code and the last review:
What this basically means is that |
|
The CI pipeline was cancelled due to failure one of the required jobs. |
|
A bit stuck on this one while fixing other pallets, duplicating my post in FRAME Element room for posterity: Basically, after introducing the change to can_reserve and reserve we have to reserve here taking into account the ED..and_then(|_| T::Currency::reserve(contract, *amount - ED)); . I'm not sure it's the correct behaviour. Any insight would be much appreciated.This also then breaks the refund logic. |
|
This breaks the current implementation of |
|
Additional notes: Modify pallet-balances to take care of the below: But I'm not sure how this can solve the contracts issue. Because if we only transfer the ED - it will be unreserved and therefore there won't be a consumer ref. |
pallet-contracts transfers at least the ED on contract instantiation and then reserves it. |
Yeah, but we can't reserve the ED anymore due to the changes in can_reserve (which is called in reserve). Or rather we can, but we still need to have at least ED in free balance. |
|
I thought a while about this any my preferred solution would be that a contract can act as a sufficient for an account. It is a consumer because it depends on the existence of its account (and by extension its balance). But it is also a provider because it takes storage deposit which covers both the existential deposit and the data structures within pallet-contracts. Up until now this was achieved by transferring this deposit to the contract and reserving it there. This does no longer work with this PR as the existential deposit must be free balance. This issue arises because pallet-contracts is a sufficient only indirectly (by enforcing a certain balance). I think that should change and pallet-contracts should call
Step 4. is where it currently fails because we cannot reserve all the contract's balance as some of it needs to be free. We could work around this by partly leaving some balance free and creating a consumer to prevent the balance to be send away. However, I think that feels a bit weird when part of the deposit is free and some is reserved. Additionally, a storage migration is needed that changes all contract's accounts to have some free balance. This is why I suggest changing the Allow reserving the ED (as it was the case before this PR) but remove the provider created by pallet-balances when doing so. If this would reap the account (because there is no other provider) we won`t allow the reserve because we never want the reserve to kill an account. Not sure if this is a sound solution. Need some more thinking and debate. Another suggestion made by @gavofyork is to automatically add a consumer to an account whenever there is a non zero reserved balance. This would also work for contracts as we could send part of the initial balance as free balance as mentioned above. However, this also needs this big storage migration of all existing accounts with reserved balance. |
|
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
|
This has been stale for a while as we did not reach consensus on how to proceed with this as far as I understand. |
|
Hey, is anyone still working on this? Due to the inactivity this issue has been automatically marked as stale. It will be closed if no further activity occurs. Thank you for your contributions. |
|
Superseded by #12951. |
Per title, also tries to use safe math.
It seems to me that #8454 really intended the code to be calling
InspectHold::can_holdrather thanReservableCurrency::can_reserve, but perhaps due to merge conflicts, thecan_holdcall has been clobbered bycan_reserve.Part of #8285 and paritytech/polkadot-sdk#327.