Skip to content

Don't go through double in AmountFromValue and ValueFromAmount #6239

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

Merged
merged 3 commits into from
Jun 9, 2015

Conversation

laanwj
Copy link
Member

@laanwj laanwj commented Jun 5, 2015

My prime gripe with JSON spirit was that monetary values still had to be converted from and to floating point which can cause deviations (see #3759 and https://bitcoin.stackexchange.com/questions/22716/bitcoind-sendfrom-round-amount-error).

As UniValue stores internal values as strings, this is no longer necessary. By using fixed-point parsing and formatting already available, this avoids risky double-to-integer and integer-to-double conversions completely, and results in more elegant code to boot.

Also contains a related dead code cleanup commit for FormatMoney.

@jgarzik
Copy link
Contributor

jgarzik commented Jun 5, 2015

Indeed - that was the intention RE stored as strings - great work @laanwj

"it works" tested ACK

throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
return nAmount;
if (!MoneyRange(amount))
Copy link
Member Author

Choose a reason for hiding this comment

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

I just noticed that there is a slight change of semantics here. The old check dAmount <= 0.0 || dAmount > 21000000.0 did not allow zero amounts, whereas MoneyRange allows nValue >= 0 && nValue <= MAX_MONEY.

Unsure what to do here. The no-brainer solution would be to restore the old behavior, however

The alternative would be to handle zero-ness at the other call sites, which is feasible as they are few. It would be less surprising to handle specific constraints like this at the call side instead of the parser function. Whatever is decided there should be a test for this in rpc_parse_monetary_values.

@Diapolo
Copy link

Diapolo commented Jun 5, 2015

Just wanted to mention that PaymentServer::verifyAmount() also uses MoneyRange().

@laanwj
Copy link
Member Author

laanwj commented Jun 5, 2015

@Diapolo True, but not relevant here, I'm not intending to change MoneyRange's semantics.

@jonasschnelli
Copy link
Contributor

Nice!
Tested and reviewed ACK.

@laanwj
Copy link
Member Author

laanwj commented Jun 5, 2015

@jonasschnelli What do you think about the range issue mentioned in my comment above?

@jonasschnelli
Copy link
Contributor

@laanwj: If we take a closer look at a AmountFromValue, than i think, CAmount can be 0 so AmountFromValue() should also be able to handle 0ness. Even, a single function must not/should not represent the behavior of the whole system (if someone would define our system behavior to reject 0 values everywhere).
AmountFromValue is also used in createrawtransaction and there i could imaging usecases for 0 value in/outputs (to replace later by some hex/further manipulating, etc.).

Therefore ACK this solution (even if it's a slightly API change).
And yes, adding a test for a 0 value would probably be a good idea.

laanwj added 3 commits June 6, 2015 09:30
My prime gripe with JSON spirit was that monetary values still had to be
converted from and to floating point which can cause deviations (see bitcoin#3759
and https://bitcoin.stackexchange.com/questions/22716/bitcoind-sendfrom-round-amount-error).

As UniValue stores internal values as strings, this is no longer
necessary. This avoids risky double-to-integer and integer-to-double
conversions completely, and results in more elegant code to boot.
It's never used with any other value than false, the default.
- Add an accept test for zero amounts, and a reject test for negative
  amounts
- Remove ugly hack in `settxfee` that is no longer necessary
- Do explicit zero checks in wallet RPC functions
- Don't add a check for zero amounts in `createrawtransaction` - this
  could be seen as a feature
@laanwj laanwj force-pushed the 2015_06_jsonrpc branch from 94897e6 to 7d8ffac Compare June 6, 2015 07:46
@laanwj
Copy link
Member Author

laanwj commented Jun 6, 2015

Thanks. Pushed a commit that adds the checks to caller sites where needed, and adds tests.

@laanwj laanwj merged commit 7d8ffac into bitcoin:master Jun 9, 2015
laanwj added a commit that referenced this pull request Jun 9, 2015
7d8ffac Changes necessary now that zero values accepted in AmountFromValue (Wladimir J. van der Laan)
a04bdef Get rid of fPlus argument to FormatMoney (Wladimir J. van der Laan)
4b4b9a8 Don't go through double in AmountFromValue and ValueFromAmount (Wladimir J. van der Laan)
zkbot added a commit to zcash/zcash that referenced this pull request Feb 10, 2017
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Sep 8, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants