-
Notifications
You must be signed in to change notification settings - Fork 37.1k
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
Conversation
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)) |
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 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
- There is one place in the source where this is worked around with an ugly hack: https://github.com/bitcoin/bitcoin/blob/master/src/wallet/rpcwallet.cpp#L2172
- The other places where AmountFromValue is used are
sendtoaddress
movecmd
sendfrom
sendmany
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
.
Just wanted to mention that |
@Diapolo True, but not relevant here, I'm not intending to change MoneyRange's semantics. |
Nice! |
@jonasschnelli What do you think about the range issue mentioned in my comment above? |
@laanwj: If we take a closer look at a Therefore ACK this solution (even if it's a slightly API change). |
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
Thanks. Pushed a commit that adds the checks to caller sites where needed, and adds tests. |
Add UniValue as subtree Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#6637 - bitcoin/bitcoin#6239 - bitcoin/bitcoin#6379 - bitcoin/bitcoin#6456 - bitcoin/bitcoin#6788
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
.