-
Notifications
You must be signed in to change notification settings - Fork 2.7k
extend ensure_account_can_withdraw and fix transfer check #1978
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -302,7 +302,11 @@ impl<T: Trait> Module<T> { | |
| if would_create && value < Self::existential_deposit() { | ||
| return Err("value too low to create account"); | ||
| } | ||
| Self::ensure_account_can_withdraw(transactor, value, WithdrawReason::Transfer, new_from_balance)?; | ||
| Self::ensure_account_can_withdraw( | ||
| transactor, | ||
| WithdrawReason::Transfer | WithdrawReason::TransactionPayment, | ||
| new_from_balance, | ||
| )?; | ||
|
|
||
| // NOTE: total stake being stored in the same type means that this could never overflow | ||
| // but better to be safe than sorry. | ||
|
|
@@ -370,26 +374,26 @@ impl<T: Trait> Module<T> { | |
|
|
||
| /// 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. | ||
| pub fn ensure_account_can_withdraw( | ||
| who: &T::AccountId, | ||
| _amount: T::Balance, | ||
| reason: WithdrawReason, | ||
| reasons: impl Into<WithdrawReasons>, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I never encounter this syntax before. Can I know where I can read more about this syntax?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in parameter as far as I know it is same as if I have a generic in function
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incorrect - there should be just one
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's say I want to create a runtime module that allow user to reserve and transfer in a single runtime call. How can do it? Call
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually calling ensure_account_can_withdraw(who, Reserve | Transfer, new_free_balance)is equivalent to ensure_account_can_withdraw(who, Transfer, new_free_balance)
ensure_account_can_withdraw(who, Reserve, new_free_balance) |
||
| new_balance: T::Balance, | ||
| ) -> Result { | ||
| match reason { | ||
| WithdrawReason::Reserve | WithdrawReason::Transfer if Self::vesting_balance(who) > new_balance => | ||
| return Err("vesting balance too high to send value"), | ||
| _ => {} | ||
| let reasons = reasons.into(); | ||
| if reasons.intersects(WithdrawReason::Reserve | WithdrawReason::Transfer) | ||
| && Self::vesting_balance(who) > new_balance | ||
| { | ||
| return Err("vesting balance too high to send value"); | ||
| } | ||
| let locks = Self::locks(who); | ||
| if locks.is_empty() { | ||
| return Ok(()) | ||
| } | ||
| let now = <system::Module<T>>::block_number(); | ||
| if Self::locks(who).into_iter() | ||
| .all(|l| now >= l.until || new_balance >= l.amount || !l.reasons.contains(reason)) | ||
| .all(|l| now >= l.until || new_balance >= l.amount || !l.reasons.intersects(reasons)) | ||
| { | ||
| Ok(()) | ||
| } else { | ||
|
|
@@ -416,7 +420,7 @@ where | |
| Self::free_balance(who) | ||
| .checked_sub(&value) | ||
| .map_or(false, |new_balance| | ||
| Self::ensure_account_can_withdraw(who, value, WithdrawReason::Reserve, new_balance).is_ok() | ||
| Self::ensure_account_can_withdraw(who, WithdrawReason::Reserve, new_balance).is_ok() | ||
| ) | ||
| } | ||
|
|
||
|
|
@@ -467,7 +471,7 @@ where | |
| return Err("not enough free funds") | ||
| } | ||
| let new_balance = b - value; | ||
| Self::ensure_account_can_withdraw(who, value, WithdrawReason::Reserve, new_balance)?; | ||
| Self::ensure_account_can_withdraw(who, WithdrawReason::Reserve, new_balance)?; | ||
| Self::set_reserved_balance(who, Self::reserved_balance(who) + value); | ||
| Self::set_free_balance(who, new_balance); | ||
| Ok(()) | ||
|
|
@@ -602,7 +606,7 @@ impl<T: Trait> TransferAsset<T::AccountId> for Module<T> { | |
| let b = Self::free_balance(who); | ||
| ensure!(b >= value, "account has too few funds"); | ||
| let new_balance = b - value; | ||
| Self::ensure_account_can_withdraw(who, value, reason, new_balance)?; | ||
| Self::ensure_account_can_withdraw(who, reason, new_balance)?; | ||
| Self::set_free_balance(who, new_balance); | ||
| Self::decrease_total_stake_by(value); | ||
| Ok(()) | ||
|
|
||
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.
This is not a transaction payment. Transaction payments happen specifically for inclusion of a transaction in the chain.