-
Notifications
You must be signed in to change notification settings - Fork 79
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
Conversation
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.
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.
- We need a Rate with 27 decimals for accruing interest. (This could lead to having our own type)
- 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.
libs/types/src/fixed_point.rs
Outdated
@@ -1,4 +1,4 @@ | |||
// This file is part of Substrate. | |||
// This file is part of SubstFixedU128. |
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.
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>; |
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.
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>; |
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.
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; |
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.
What if I want to hold negative numbers? i.e. Right now, I'm using a FixedI128
for rewards without this rounding capabilities.
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.
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`
/// 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>; |
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.
Out of curiosity, where is this expected to be used?
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.
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.
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.
I am not keen on moving them now as this means adapting all imports of Rate
. Lets do in a follow up if wanted.
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 |
And we could not create a |
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.
Thanks, LGTM!
Do not see the advantage. We are essentialy doing just that ^^ |
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 😞 |
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.
LGTM!
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
struct Rate
tostruct FixedU128<const DIV: u128>
type Rate = FixedU128<DECIMAL_27>
Checklist: