Merge #10999: Fix amounts formatting in decoderawtransaction

ce07638 doc: Add comment to use ValueFromAmount/AmountFromValue for JSON, not utilmoneystr (Wladimir J. van der Laan)
ec05c50 rpc: Use ValueFromAmount instead of FormatMoney in TxToUniv (Wladimir J. van der Laan)
46347ad rpc: Move ValueFromAmount to core_write (Wladimir J. van der Laan)
dac3782 doc: Correct AmountFromValue/ValueFromAmount names (Wladimir J. van der Laan)

Pull request description:

  With this, the amounts returned in `decoderawtransaction` will be padded to 8 digits like anywhere else in the API.

  This is accomplished by using `ValueFromAmount` in `TxToUniv`, instead of `FormatMoney` which it currently (mistakingly) uses. The `FormatMoney` function is only for debugging/logging use!

  To avoid dependency issues, `ValueFromAmount` is moved to `core_write.cpp`, where it also fits better. I don't move `AmountFromValue` to `core_read.cpp` at the same time, as this would have more impact due to the RPCError dependency there.

  (n.b.: large number of changed files is solely due to the util_tests JSONs needing update)

Tree-SHA512: 10fc2d27d33a77dbcb57aa7eccd4f53110c05d38eb7df6d40f10f14c08fad4274472e93af75aa59fe68ad0720fdf0930f0108124abef518e0dd162b3d2b2b292
This commit is contained in:
Wladimir J. van der Laan 2017-08-08 11:27:15 +02:00
commit 627c3c0e49
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
30 changed files with 46 additions and 39 deletions

View File

@ -561,10 +561,10 @@ A few guidelines for introducing and reviewing new RPC interfaces:
which is error prone, and it is easy to get things such as escaping wrong. which is error prone, and it is easy to get things such as escaping wrong.
JSON already supports nested data structures, no need to re-invent the wheel. JSON already supports nested data structures, no need to re-invent the wheel.
- *Exception*: AmountToValue can parse amounts as string. This was introduced because many JSON - *Exception*: AmountFromValue can parse amounts as string. This was introduced because many JSON
parsers and formatters hard-code handling decimal numbers as floating point parsers and formatters hard-code handling decimal numbers as floating point
values, resulting in potential loss of precision. This is unacceptable for values, resulting in potential loss of precision. This is unacceptable for
monetary values. **Always** use `AmountToValue` and `ValueToAmount` when monetary values. **Always** use `AmountFromValue` and `ValueFromAmount` when
inputting or outputting monetary values. The only exceptions to this are inputting or outputting monetary values. The only exceptions to this are
`prioritisetransaction` and `getblocktemplate` because their interface `prioritisetransaction` and `getblocktemplate` because their interface
is specified as-is in BIP22. is specified as-is in BIP22.

View File

@ -5,6 +5,8 @@
#ifndef BITCOIN_CORE_IO_H #ifndef BITCOIN_CORE_IO_H
#define BITCOIN_CORE_IO_H #define BITCOIN_CORE_IO_H
#include "amount.h"
#include <string> #include <string>
#include <vector> #include <vector>
@ -25,6 +27,7 @@ uint256 ParseHashStr(const std::string&, const std::string& strName);
std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName); std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName);
// core_write.cpp // core_write.cpp
UniValue ValueFromAmount(const CAmount& amount);
std::string FormatScript(const CScript& script); std::string FormatScript(const CScript& script);
std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0); std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0);
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);

View File

@ -16,6 +16,16 @@
#include "utilmoneystr.h" #include "utilmoneystr.h"
#include "utilstrencodings.h" #include "utilstrencodings.h"
UniValue ValueFromAmount(const CAmount& amount)
{
bool sign = amount < 0;
int64_t n_abs = (sign ? -amount : amount);
int64_t quotient = n_abs / COIN;
int64_t remainder = n_abs % COIN;
return UniValue(UniValue::VNUM,
strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder));
}
std::string FormatScript(const CScript& script) std::string FormatScript(const CScript& script)
{ {
std::string ret; std::string ret;
@ -184,8 +194,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
UniValue out(UniValue::VOBJ); UniValue out(UniValue::VOBJ);
UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue)); out.pushKV("value", ValueFromAmount(txout.nValue));
out.pushKV("value", outValue);
out.pushKV("n", (int64_t)i); out.pushKV("n", (int64_t)i);
UniValue o(UniValue::VOBJ); UniValue o(UniValue::VOBJ);

View File

@ -6,6 +6,7 @@
#include "base58.h" #include "base58.h"
#include "chain.h" #include "chain.h"
#include "clientversion.h" #include "clientversion.h"
#include "core_io.h"
#include "init.h" #include "init.h"
#include "validation.h" #include "validation.h"
#include "httpserver.h" #include "httpserver.h"

View File

@ -6,6 +6,7 @@
#include "chainparams.h" #include "chainparams.h"
#include "clientversion.h" #include "clientversion.h"
#include "core_io.h"
#include "validation.h" #include "validation.h"
#include "net.h" #include "net.h"
#include "net_processing.h" #include "net_processing.h"

View File

@ -123,16 +123,6 @@ CAmount AmountFromValue(const UniValue& value)
return amount; return amount;
} }
UniValue ValueFromAmount(const CAmount& amount)
{
bool sign = amount < 0;
int64_t n_abs = (sign ? -amount : amount);
int64_t quotient = n_abs / COIN;
int64_t remainder = n_abs % COIN;
return UniValue(UniValue::VNUM,
strprintf("%s%d.%08d", sign ? "-" : "", quotient, remainder));
}
uint256 ParseHashV(const UniValue& v, std::string strName) uint256 ParseHashV(const UniValue& v, std::string strName)
{ {
std::string strHex; std::string strHex;

View File

@ -185,7 +185,6 @@ extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strNa
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey); extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
extern CAmount AmountFromValue(const UniValue& value); extern CAmount AmountFromValue(const UniValue& value);
extern UniValue ValueFromAmount(const CAmount& amount);
extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); extern std::string HelpExampleCli(const std::string& methodname, const std::string& args);
extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args); extern std::string HelpExampleRpc(const std::string& methodname, const std::string& args);

View File

@ -6,6 +6,7 @@
#include "rpc/client.h" #include "rpc/client.h"
#include "base58.h" #include "base58.h"
#include "core_io.h"
#include "netbase.h" #include "netbase.h"
#include "test/test_bitcoin.h" #include "test/test_bitcoin.h"

View File

@ -14,6 +14,9 @@
#include "amount.h" #include "amount.h"
/* Do not use these functions to represent or parse monetary amounts to or from
* JSON but use AmountFromValue and ValueFromAmount for that.
*/
std::string FormatMoney(const CAmount& n); std::string FormatMoney(const CAmount& n);
bool ParseMoney(const std::string& str, CAmount& nRet); bool ParseMoney(const std::string& str, CAmount& nRet);
bool ParseMoney(const char* pszIn, CAmount& nRet); bool ParseMoney(const char* pszIn, CAmount& nRet);

View File

@ -189,7 +189,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 1.3782, "value": 1.37820000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",

View File

@ -198,7 +198,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 1.3782, "value": 1.37820000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",

View File

@ -198,7 +198,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 1.3782, "value": 1.37820000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",

View File

@ -36,7 +36,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.18, "value": 0.18000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
@ -49,7 +49,7 @@
} }
}, },
{ {
"value": 4.00, "value": 4.00000000,
"n": 1, "n": 1,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.00, "value": 0.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "", "asm": "",

View File

@ -18,7 +18,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.18, "value": 0.18000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
@ -31,7 +31,7 @@
} }
}, },
{ {
"value": 4.00, "value": 4.00000000,
"n": 1, "n": 1,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", "asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",

View File

@ -18,7 +18,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.18, "value": 0.18000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
@ -31,7 +31,7 @@
} }
}, },
{ {
"value": 0.00, "value": 0.00000000,
"n": 1, "n": 1,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e", "asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",

View File

@ -18,7 +18,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.18, "value": 0.18000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",

View File

@ -27,7 +27,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.18, "value": 0.18000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 1.00, "value": 1.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG", "asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 1.00, "value": 1.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL", "asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 1.00, "value": 1.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05", "asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 1.00, "value": 1.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL", "asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.00, "value": 0.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 OP_CHECKSIG", "asm": "02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 OP_CHECKSIG",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.00, "value": 0.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "0 a2516e770582864a6a56ed21a102044e388c62e3", "asm": "0 a2516e770582864a6a56ed21a102044e388c62e3",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.00, "value": 0.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL", "asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.00, "value": 0.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DROP", "asm": "OP_DROP",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.00, "value": 0.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL", "asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.00, "value": 0.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6", "asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6",

View File

@ -9,7 +9,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.00, "value": 0.00000000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL", "asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL",

View File

@ -18,7 +18,7 @@
], ],
"vout": [ "vout": [
{ {
"value": 0.001, "value": 0.00100000,
"n": 0, "n": 0,
"scriptPubKey": { "scriptPubKey": {
"asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG", "asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG",