-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Use can_hold instead of can_reserve in fn hold #12004
Conversation
Test? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks sensible to me
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
holding/reserving should never kill an account, so adding the keep_alive
arg doesn't make sense here.
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
.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_hold
rather thanReservableCurrency::can_reserve
, but perhaps due to merge conflicts, thecan_hold
call has been clobbered bycan_reserve
.Part of #8285 and paritytech/polkadot-sdk#327.