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

feat: make fixed point flexible #1452

Merged
merged 5 commits into from
Jul 13, 2023
Merged

Conversation

mustermeiszer
Copy link
Collaborator

Description

This is a non breaking change of our fixed point integer logic. It allows to use our logic with variable decimals. This is especially useful for places where we want to reduce the max decimals compared to 27 decimals.

While 27 decimals are great for interest calculation in some place they are limiting to the maximum value that can be represented. I.e. roughly 1 billion in the 27 decimal case.

Changes and Descriptions

  • change struct Rate to struct FixedU128<const DIV: u128>
  • create type Rate = FixedU128<DECIMAL_27>

Checklist:

  • I have added Rust doc comments to structs, enums, traits and functions
  • I have made corresponding changes to the documentation
  • I have performed a self-review of my code
  • I have added tests that prove my fix is effective or that my feature works

Copy link
Contributor

@lemunozm lemunozm left a comment

Choose a reason for hiding this comment

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

I like the generalization!

A note about maintaining our fixed_point file: I think this can be a sucurity issue in the way that we are not merging updates in this section from Substrate. What if tomorrow Substrate fixes an issue in the fixed point multiplication or similar? How can we receive these changes and update accordinly? Is there no way to reuse the Substrate FixedU128 type and add the rounding capabilities on top of that type?
Adding traits as extensions or wrapping the FixedU128 from Substrate internally should work.

I mean, I think there is two things here.

  1. We need a Rate with 27 decimals for accruing interest. (This could lead to having our own type)
  2. We need rounding capabilities. (This not need a new type)

So for a Rate with rounding capabilities with 18 decimals, I think we could use the Substrate FixedU128 because using the FixedPointNumberExtension it inherents to those capabilities.

@@ -1,4 +1,4 @@
// This file is part of Substrate.
// This file is part of SubstFixedU128.
Copy link
Contributor

Choose a reason for hiding this comment

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

Funny name after rename "rate" 😆

/// A fixed point number representation with 27 decimals. Used for
/// representing a rate, mostly interest rate.
#[doc = "_Fixed Point 128 bits unsigned with 27 decimals precision"]
pub type Rate = FixedU128<DECIMALS_27>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Knowing that the purpose of this is accruing rates. I would call it AccrualRate or something similar to denote in its name the purpose and avoid confusion

/// A fixed point number representation with 18 decimals. Used for
/// representing a ratio between two things.
#[doc = "_Fixed Point 128 bits unsigned with 18 decimals precision"]
pub type Ratio = FixedU128<DECIMALS_18>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Then, it can be a "normal" Rate, a Ratio, or a simple number with decimals I guess

type Inner = u128;

const DIV: Self::Inner = 1_000_000_000_000_000_000_000_000_000;
const DIV: Self::Inner = DIV;
const SIGNED: bool = false;
Copy link
Contributor

@lemunozm lemunozm Jul 12, 2023

Choose a reason for hiding this comment

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

What if I want to hold negative numbers? i.e. Right now, I'm using a FixedI128 for rewards without this rounding capabilities.

Copy link
Contributor

@wischli wischli left a comment

Choose a reason for hiding this comment

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

Code changes LGTM. Let's hope all tests succeed.

There are bunch of undesired replacements of rate to FixedU128 in the comments, e.g.

  • Substrate --> SubstFixedU128.
  • Saturates --> ~SatuFixedU128s`

libs/types/src/fixed_point.rs Outdated Show resolved Hide resolved
libs/types/src/fixed_point.rs Outdated Show resolved Hide resolved
libs/types/src/fixed_point.rs Outdated Show resolved Hide resolved
/// A fixed point number representation with 18 decimals. Used for
/// representing a quantity of something.
#[doc = "_Fixed Point 128 bits unsigned with 18 decimals precision"]
pub type Quantity = FixedU128<DECIMALS_18>;
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, where is this expected to be used?

Copy link
Contributor

Choose a reason for hiding this comment

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

When you want to express an absolute number value with decimals. Ratio should represent instead a proportion of a value. Both are represented in the same way and are the same.

Maybe these "aliases" could be moved to our runtime definition, because they are how we are using them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am not keen on moving them now as this means adapting all imports of Rate. Lets do in a follow up if wanted.

@mustermeiszer
Copy link
Collaborator Author

A note about maintaining our fixed_point file: I think this can be a sucurity issue in the way that we are not merging updates in this section from Substrate. What if tomorrow Substrate fixes an issue in the fixed point multiplication or similar? How can we receive these changes and update accordinly? Is there no way to reuse the Substrate FixedU128 type and add the rounding capabilities on top of that type?

I do not think this will be an issue. We are using the core methods which are not provided by the trait but by the arithmetics of Substrate. If they fix something there, we will receive the change.

The problem with rounding is not solvable by that as checked_from_rational and checked_mul_int are the core problems here and we must override them to get the right stuff.

@mustermeiszer
Copy link
Collaborator Author

@wischli and @lemunozm udpated all

@lemunozm
Copy link
Contributor

The problem with rounding is not solvable by that as checked_from_rational and checked_mul_int are the core problems here and we must override them to get the right stuff.

And we could not create a FixedU128(sp_runtime::FixedU128) that implements FixedPointNumber calling the inner fixed rate except for checked_from_rational and checked_mul_int methods where we add our custom logic?

wischli
wischli previously approved these changes Jul 12, 2023
Copy link
Contributor

@wischli wischli left a comment

Choose a reason for hiding this comment

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

Thanks, LGTM!

@mustermeiszer mustermeiszer enabled auto-merge (squash) July 12, 2023 10:19
@mustermeiszer
Copy link
Collaborator Author

And we could not create a FixedU128(sp_runtime::FixedU128) that implements FixedPointNumber calling the inner fixed rate except for checked_from_rational and checked_mul_int methods where we add our custom logic?

Do not see the advantage. We are essentialy doing just that ^^

@lemunozm
Copy link
Contributor

The advantage I see is we are less error-prone in our code. Instead of adding simple calculations by us, we call the underlying type to do it. But it's true that the layer is quite quite slim 👍🏻, so maybe not needed. Ideally should be Substrate who maintains all this 😞

lemunozm
lemunozm previously approved these changes Jul 12, 2023
Copy link
Contributor

@lemunozm lemunozm left a comment

Choose a reason for hiding this comment

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

LGTM!

@wischli wischli dismissed stale reviews from lemunozm and themself via 0ba64b2 July 13, 2023 08:15
@mustermeiszer mustermeiszer merged commit 10e23ec into main Jul 13, 2023
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants