Browse Source

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
0.15
Wladimir J. van der Laan 7 years ago
parent
commit
627c3c0e49
No known key found for this signature in database
GPG Key ID: 1E4AED62986CD25D
  1. 4
      doc/developer-notes.md
  2. 3
      src/core_io.h
  3. 13
      src/core_write.cpp
  4. 1
      src/rpc/misc.cpp
  5. 1
      src/rpc/net.cpp
  6. 10
      src/rpc/server.cpp
  7. 1
      src/rpc/server.h
  8. 1
      src/test/rpc_tests.cpp
  9. 3
      src/utilmoneystr.h
  10. 2
      test/util/data/tt-delin1-out.json
  11. 2
      test/util/data/tt-delout1-out.json
  12. 2
      test/util/data/tt-locktime317000-out.json
  13. 4
      test/util/data/txcreate1.json
  14. 2
      test/util/data/txcreate2.json
  15. 4
      test/util/data/txcreatedata1.json
  16. 4
      test/util/data/txcreatedata2.json
  17. 2
      test/util/data/txcreatedata_seq0.json
  18. 2
      test/util/data/txcreatedata_seq1.json
  19. 2
      test/util/data/txcreatemultisig1.json
  20. 2
      test/util/data/txcreatemultisig2.json
  21. 2
      test/util/data/txcreatemultisig3.json
  22. 2
      test/util/data/txcreatemultisig4.json
  23. 2
      test/util/data/txcreateoutpubkey1.json
  24. 2
      test/util/data/txcreateoutpubkey2.json
  25. 2
      test/util/data/txcreateoutpubkey3.json
  26. 2
      test/util/data/txcreatescript1.json
  27. 2
      test/util/data/txcreatescript2.json
  28. 2
      test/util/data/txcreatescript3.json
  29. 2
      test/util/data/txcreatescript4.json
  30. 2
      test/util/data/txcreatesignv1.json

4
doc/developer-notes.md

@ -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.

3
src/core_io.h

@ -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);

13
src/core_write.cpp

@ -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);

1
src/rpc/misc.cpp

@ -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"

1
src/rpc/net.cpp

@ -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"

10
src/rpc/server.cpp

@ -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;

1
src/rpc/server.h

@ -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);

1
src/test/rpc_tests.cpp

@ -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"

3
src/utilmoneystr.h

@ -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);

2
test/util/data/tt-delin1-out.json

@ -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",

2
test/util/data/tt-delout1-out.json

@ -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",

2
test/util/data/tt-locktime317000-out.json

@ -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",

4
test/util/data/txcreate1.json

@ -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",

2
test/util/data/txcreate2.json

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

4
test/util/data/txcreatedata1.json

@ -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",

4
test/util/data/txcreatedata2.json

@ -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",

2
test/util/data/txcreatedata_seq0.json

@ -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",

2
test/util/data/txcreatedata_seq1.json

@ -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",

2
test/util/data/txcreatemultisig1.json

@ -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",

2
test/util/data/txcreatemultisig2.json

@ -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",

2
test/util/data/txcreatemultisig3.json

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

2
test/util/data/txcreatemultisig4.json

@ -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",

2
test/util/data/txcreateoutpubkey1.json

@ -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",

2
test/util/data/txcreateoutpubkey2.json

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

2
test/util/data/txcreateoutpubkey3.json

@ -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",

2
test/util/data/txcreatescript1.json

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

2
test/util/data/txcreatescript2.json

@ -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",

2
test/util/data/txcreatescript3.json

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

2
test/util/data/txcreatescript4.json

@ -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",

2
test/util/data/txcreatesignv1.json

@ -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",

Loading…
Cancel
Save