-
Notifications
You must be signed in to change notification settings - Fork 792
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
Support integer and decimal Nano amounts to raw conversion #3781
base: develop
Are you sure you want to change the base?
Support integer and decimal Nano amounts to raw conversion #3781
Conversation
We should look at a real number parser rather than manually slicing the string up. https://www.boost.org/doc/libs/1_75_0/libs/spirit/doc/html/spirit/qi/reference/numeric/real.html This also needs tests, specifically showing what it does to extreme values. |
I like this strategy better than a separate RPC, we just need to make sure rounding errors can't happen. |
I have added a bunch of testcases including all the edgecases I could think of. They run successfully with this implementation. |
@RickiNano Whats the status of this? Waiting on OK? I need this more than ever and the bounty is still waiting to be claimed! |
It's all up to @clemahieu if this gets approved. I've done a lot of testing on this and it's working correctly |
Nice @RickiNano @clemahieu Sorry for all the pings. Check this out when you get a chance. Nano Node shipping 🚢 with Floating point conversion RPC makes for super fast prototyping w/ Nano! |
I haven't looked at this closely but I agree with the idea that doing our own slicing of the string and parsing it ourselves is safer in short and medium term. |
nano/node/json_handler.cpp
Outdated
nano::amount wholeNumber (0); | ||
nano::amount decimalNumber (0); | ||
nano::amount result (0); | ||
if (!ec) |
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.
Let's make this a guard if and save a whole level of if nesting for better readability.
if (ec) return result;
@@ -283,6 +283,40 @@ nano::amount nano::json_handler::amount_impl () | |||
return result; | |||
} | |||
|
|||
nano::amount nano::json_handler::decimal_amount_impl () |
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.
Let's document the parsing rules. What are the parsing rules?
Let's make them very strict and very simple.
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.
Should ".5" be legal value to parse?
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.
Do we really want to parse negative numbers?
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 is the largest number we support?
What is smallest number?
What happens when a value is too small or too large?
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.
Do you want me to document the rules in the code as a comment or somewhere else?
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.
The rules will need to be in the documentation to the RPC call. In the mean time, you could add them to the code as a comment.
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 about whitespace? What are the rules, whitespace allowed?
I would lean on being strict on no whitespace allowed, for simplicity.
nano/node/json_handler.cpp
Outdated
{ | ||
std::string amount_text (request.get<std::string> ("amount")); | ||
|
||
int dotIndex = amount_text.find ("."); |
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.
Let's make sure that there is either zero or one dots. And no other possibility.
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.
dotIndex references the position of the dot. It's not the amount of dots. However if the input has multiple dots it will still output an error. Eg 5.3.6 will be converted into 5 as the wholenumber, but the remaining 3.6 can't be converted and the invalid_amount error is returned
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.
Can we have a test case for it? We also need a test cases for:
- empty string
- negative zero
- positive (with plus sign)
- number too large
- hex notation (should be rejected)
- scientific notation (should be rejected)
- use of comma character (should be rejected)
- use of comma as fractional part separator (not all countries use dot as separator, should be rejected)
In general I would favour removing support for negative numbers and plus sign to reduce complexity.
Hi @dsiganos |
I find the use of regex in this case over the top and a slight complication. |
This reverts commit c20ed43.
I have rolled back my attempt to convert the regex to c++ code |
@RickiNano , @nano2dev you could write a specification for the allowed incoming string to be converted. |
Changed maximum input to 340 million and changed unit tests to reflect this
@dsiganos
I think this description is concise but still addresses all input validations |
Just commenting to say Thank You everyone involved. I understand this PR may be controversial from an implementation standpoint. My hope is that it gets shipped sooner than later - and it gets better with time. I suspect, that I will be the only company to adopt this new feature immediately. As most bring their own Big Num library. My use case is Bash. Where no Big Num library exists. On that note. This PR will make the Node much more "self-sufficient". Specially in Low level language ecosystems, where user input is Decimals. |
@RickiNano Check this out when you get a chance: Thanks @marcusmmmz |
…-for-nano-to-raw-conversion convert regex to c++ code
@dsiganos |
Guys, I still do not see parsing rules. Where are the rules? What's allowed, what is not? |
@dsiganos They're intentionally very simple:
That's all the rules, no leading dots, no negative/positive signs, no hex, no scientific notation. |
How many characters are allowed in the whole number section? |
Is this legal? the current rules do not say. |
As 340 million is the max value (9 characters), and the maximum of decimals is 30, plus the "." character, that equals 40 characters, so that's the max string length. So yes, we could easily check that before doing other processing.
Currently that's not being checked, but it can easily be done without adding too much complexity so i think we should add that check. I'll be working on this. Edit: RickiNano's next commit supersedes this. |
@dsiganos
The validation rules are:
I have also added a test case with leading zeros |
@dsiganos Please check this when possible :) No rush on getting it shipped. I intend on paying bounties when you simply give the 👍🏽 |
@RickiNano Do you mind providing nano address for reward. The 100 NANO prize is split 50/50 with @marcusmmmz . Hope this PR makes in when adequate. |
@dsiganos Have you reviewed what's left to be reviewed yet? it's been quite some time and we'd like at least some instructions on what to do next. |
This change is controversial, Colin for example doesn't want it (because he regards it to be beyond the scope of nano node), but he will reluctantly accept it, if it is demonstrated that it is safe. To finish this PR we need:
In article the below, I say: I am currently trying to clean up existing PRs. Let's revisit this on Monday. |
Apparently this was closed by mistake so I am reopening. |
This adds support for decimal numbers when converting from Nano to raw. It is also backwards compatible with integer amounts both expressed like "35" or like "35.00000"
Decimals beyond 30 are cut to conform with the precision specifications
Invalid numbers will still show an error message
This pr fixes #3777