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:
commit
627c3c0e49
30 changed files with 46 additions and 39 deletions
|
@ -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.
|
||||
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
|
||||
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
|
||||
`prioritisetransaction` and `getblocktemplate` because their interface
|
||||
is specified as-is in BIP22.
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
#ifndef BITCOIN_CORE_IO_H
|
||||
#define BITCOIN_CORE_IO_H
|
||||
|
||||
#include "amount.h"
|
||||
|
||||
#include <string>
|
||||
#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);
|
||||
|
||||
// core_write.cpp
|
||||
UniValue ValueFromAmount(const CAmount& amount);
|
||||
std::string FormatScript(const CScript& script);
|
||||
std::string EncodeHexTx(const CTransaction& tx, const int serializeFlags = 0);
|
||||
void ScriptPubKeyToUniv(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
|
||||
|
|
|
@ -16,6 +16,16 @@
|
|||
#include "utilmoneystr.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 ret;
|
||||
|
@ -184,8 +194,7 @@ void TxToUniv(const CTransaction& tx, const uint256& hashBlock, UniValue& entry)
|
|||
|
||||
UniValue out(UniValue::VOBJ);
|
||||
|
||||
UniValue outValue(UniValue::VNUM, FormatMoney(txout.nValue));
|
||||
out.pushKV("value", outValue);
|
||||
out.pushKV("value", ValueFromAmount(txout.nValue));
|
||||
out.pushKV("n", (int64_t)i);
|
||||
|
||||
UniValue o(UniValue::VOBJ);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "base58.h"
|
||||
#include "chain.h"
|
||||
#include "clientversion.h"
|
||||
#include "core_io.h"
|
||||
#include "init.h"
|
||||
#include "validation.h"
|
||||
#include "httpserver.h"
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "chainparams.h"
|
||||
#include "clientversion.h"
|
||||
#include "core_io.h"
|
||||
#include "validation.h"
|
||||
#include "net.h"
|
||||
#include "net_processing.h"
|
||||
|
|
|
@ -123,16 +123,6 @@ CAmount AmountFromValue(const UniValue& value)
|
|||
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)
|
||||
{
|
||||
std::string strHex;
|
||||
|
|
|
@ -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 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 HelpExampleRpc(const std::string& methodname, const std::string& args);
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "rpc/client.h"
|
||||
|
||||
#include "base58.h"
|
||||
#include "core_io.h"
|
||||
#include "netbase.h"
|
||||
|
||||
#include "test/test_bitcoin.h"
|
||||
|
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
#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);
|
||||
bool ParseMoney(const std::string& str, CAmount& nRet);
|
||||
bool ParseMoney(const char* pszIn, CAmount& nRet);
|
||||
|
|
|
@ -189,7 +189,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1.3782,
|
||||
"value": 1.37820000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1.3782,
|
||||
"value": 1.37820000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
|
|
@ -198,7 +198,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1.3782,
|
||||
"value": 1.37820000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.18,
|
||||
"value": 0.18000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
@ -49,7 +49,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"value": 4.00,
|
||||
"value": 4.00000000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 f2d4db28cad6502226ee484ae24505c2885cb12d OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.18,
|
||||
"value": 0.18000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
@ -31,7 +31,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"value": 4.00,
|
||||
"value": 4.00000000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.18,
|
||||
"value": 0.18000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
@ -31,7 +31,7 @@
|
|||
}
|
||||
},
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 1,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_RETURN 54686973204f505f52455455524e207472616e73616374696f6e206f7574707574207761732063726561746564206279206d6f646966696564206372656174657261777472616e73616374696f6e2e",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.18,
|
||||
"value": 0.18000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.18,
|
||||
"value": 0.18000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 1fc11f39be1729bf973a7ab6a615ca4729d64574 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1.00,
|
||||
"value": 1.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "2 02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 021ac43c7ff740014c3b33737ede99c967e4764553d1b2b83db77c83b8715fa72d 02df2089105c77f266fa11a9d33f05c735234075f2e8780824c6b709415f9fb485 3 OP_CHECKMULTISIG",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1.00,
|
||||
"value": 1.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_HASH160 1c6fbaf46d64221e80cbae182c33ddf81b9294ac OP_EQUAL",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1.00,
|
||||
"value": 1.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "0 e15a86a23178f433d514dbbce042e87d72662b8b5edcacfd2e37ab7a2d135f05",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 1.00,
|
||||
"value": 1.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_HASH160 6edf12858999f0dae74f9c692e6694ee3621b2ac OP_EQUAL",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "02a5613bd857b7048924264d1e70e08fb2a7e6527d32b7ab1bb993ac59964ff397 OP_CHECKSIG",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "0 a2516e770582864a6a56ed21a102044e388c62e3",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_HASH160 a5ab14c9804d0d8bf02f1aea4e82780733ad0a83 OP_EQUAL",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DROP",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_HASH160 71ed53322d470bb96657deb786b94f97dd46fb15 OP_EQUAL",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "0 0bfe935e70c321c7ca3afc75ce0d0ca2f98b5422e008bb31c00c6d7f1f1c0ad6",
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.00,
|
||||
"value": 0.00000000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_HASH160 6a2c482f4985f57e702f325816c90e3723ca81ae OP_EQUAL",
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
],
|
||||
"vout": [
|
||||
{
|
||||
"value": 0.001,
|
||||
"value": 0.00100000,
|
||||
"n": 0,
|
||||
"scriptPubKey": {
|
||||
"asm": "OP_DUP OP_HASH160 5834479edbbe0539b31ffd3a8f8ebadc2165ed01 OP_EQUALVERIFY OP_CHECKSIG",
|
||||
|
|
Loading…
Reference in a new issue