Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make on_unbalanceds work with fungibles imbalances #4564

Merged
merged 8 commits into from
Jul 23, 2024

Conversation

muharem
Copy link
Contributor

@muharem muharem commented May 24, 2024

Make on_unbalanceds work with fungibles imbalances.

The fungibles imbalances cannot be handled by the default implementation of on_unbalanceds from the OnUnbalanced trait. This is because the fungibles imbalances types do not implement the Imbalance trait (and cannot with its current semantics). The on_unbalanceds function requires only the merge function for the imbalance type. In this PR, we provide the TryMerge trait, which can be implemented by all imbalance types and make OnUnbalanced require it instead Imbalance.

Migration for OnUnbalanced trait implementations:

In case if you have a custom implementation of on_unbalanceds trait function, remove it's <B> type argument.

Migration for custom imbalance types:

If you have your own imbalance types implementations, implement the TryMerge trait for it introduced with this update.

The applicability of the on_unbalanceds function to fungibles imbalances is useful in cases like - link from #4488.

@muharem muharem requested a review from a team as a code owner May 24, 2024 09:57
@muharem muharem added the T1-FRAME This PR/Issue is related to core FRAME, the framework. label May 24, 2024
@@ -132,6 +132,12 @@ mod imbalances {
}
}

impl<T: Config<I>, I: 'static> TryMerge for PositiveImbalance<T, I> {
fn try_merge(self, other: Self) -> Result<Self, (Self, Self)> {
Ok(self.merge(other))
Copy link
Member

@ggwpez ggwpez Jul 15, 2024

Choose a reason for hiding this comment

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

I think conceptually it makes more sense to call try_merge from merge and just ignore the return value there. Then try-merge would fail on overflow instead of saturating.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Can you explain why? It feels less correct to me to ignore an error from try_merge within merge. In the scope of merge we wont know for sure, that the try_merge wont return an error.
We probably fine with saturation since we do not expect it to overflow the max supply type. It may happened only if you create imbalances in some hacky way, and do not use fungibles api.

Then try-merge would fail on overflow instead of saturating.

To handle this we would need a separate impl for try_merge, since merge is infallible

Copy link
Member

Choose a reason for hiding this comment

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

The difference is that we explicitly ignore the error - instead of merge pretending to be infallible. We already have messed up TI on production, so i think saturation could happen.
Anyway, i dont care so much in this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I see, but I think that would be a bigger change, a behaviour change, and if needed should be explored and addressed in different PR.

substrate/frame/support/src/traits/tokens/imbalance.rs Outdated Show resolved Hide resolved
}
}
if let Some(sum) = sum {
Self::on_unbalanced(sum)
Copy link
Member

Choose a reason for hiding this comment

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

Where is the advantage of calling on_unbalanced on the merged result vs calling it on every balance individually?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We were merging tip and fee, to handle both with a single on_unbalanceds handler. This call would result a single deposit instead of two if the imbalances are identical.

Current open PR with impl of payment handler for the fees, requires two on unbalanced impl, because on_unbalanceds cannot handle fungibles iterator -


pr #4488

I do not like the breaking change, but also feel like this change needed, since we moving away from currency impls and using fungible and fungibles.

I also wanna have this decided, before I merge that PR to not break it again later.

Copy link
Member

Choose a reason for hiding this comment

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

Okay seems fine to me.

muharem and others added 2 commits July 16, 2024 10:56
Copy link
Contributor

@franciscoaguirre franciscoaguirre left a comment

Choose a reason for hiding this comment

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

Looks good

prdoc/pr_4564.prdoc Outdated Show resolved Hide resolved

crates:
- name: frame-support
bump: major
Copy link
Member

Choose a reason for hiding this comment

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

Hm the CI suggest minor here, but a public trait was change, so should be major IMHO.

muharem and others added 2 commits July 23, 2024 15:14
Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
@muharem muharem enabled auto-merge July 23, 2024 13:39
@muharem muharem added this pull request to the merge queue Jul 23, 2024
Merged via the queue into master with commit 6d0926e Jul 23, 2024
155 of 160 checks passed
@muharem muharem deleted the muharem-fungibles-on-unbalanceds branch July 23, 2024 15:10
TarekkMA pushed a commit to moonbeam-foundation/polkadot-sdk that referenced this pull request Aug 2, 2024
…4564)

Make `on_unbalanceds` work with `fungibles` `imbalances`.

The `fungibles` `imbalances` cannot be handled by the default
implementation of `on_unbalanceds` from the `OnUnbalanced` trait. This
is because the `fungibles` `imbalances` types do not implement the
`Imbalance` trait (and cannot with its current semantics). The
`on_unbalanceds` function requires only the `merge` function for the
imbalance type. In this PR, we provide the `TryMerge` trait, which can
be implemented by all imbalance types and make `OnUnbalanced` require it
instead `Imbalance`.

### Migration for `OnUnbalanced` trait implementations:
In case if you have a custom implementation of `on_unbalanceds` trait
function, remove it's `<B>` type argument.

### Migration for custom imbalance types:
If you have your own imbalance types implementations, implement the
`TryMerge` trait for it introduced with this update.
        
The applicability of the `on_unbalanceds` function to fungibles
imbalances is useful in cases like -
[link](https://github.com/paritytech/polkadot-sdk/blob/3a8e675e9f6f283514c00c14d3d1d90ed5bf59c0/substrate/frame/transaction-payment/asset-conversion-tx-payment/src/payment.rs#L267)
from paritytech#4488.

---------

Co-authored-by: Oliver Tale-Yazdi <oliver.tale-yazdi@parity.io>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T1-FRAME This PR/Issue is related to core FRAME, the framework.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants