Skip to content

Commit 643114f

Browse files
committed
Merge pull request #6239
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)
2 parents 3a2ca9b + 7d8ffac commit 643114f

File tree

6 files changed

+45
-43
lines changed

6 files changed

+45
-43
lines changed

src/rpcserver.cpp

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "sync.h"
1212
#include "ui_interface.h"
1313
#include "util.h"
14+
#include "utilmoneystr.h"
1415
#include "utilstrencodings.h"
1516
#ifdef ENABLE_WALLET
1617
#include "wallet/wallet.h"
@@ -118,25 +119,21 @@ void RPCTypeCheckObj(const UniValue& o,
118119
}
119120
}
120121

121-
static inline int64_t roundint64(double d)
122-
{
123-
return (int64_t)(d > 0 ? d + 0.5 : d - 0.5);
124-
}
125-
126122
CAmount AmountFromValue(const UniValue& value)
127123
{
128-
double dAmount = value.get_real();
129-
if (dAmount <= 0.0 || dAmount > 21000000.0)
130-
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
131-
CAmount nAmount = roundint64(dAmount * COIN);
132-
if (!MoneyRange(nAmount))
124+
if (!value.isReal() && !value.isNum())
125+
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number");
126+
CAmount amount;
127+
if (!ParseMoney(value.getValStr(), amount))
133128
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
134-
return nAmount;
129+
if (!MoneyRange(amount))
130+
throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
131+
return amount;
135132
}
136133

137134
UniValue ValueFromAmount(const CAmount& amount)
138135
{
139-
return (double)amount / (double)COIN;
136+
return UniValue(UniValue::VREAL, FormatMoney(amount));
140137
}
141138

142139
uint256 ParseHashV(const UniValue& v, string strName)

src/test/rpc_tests.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,9 @@ static UniValue ValueFromString(const std::string &str)
131131

132132
BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values)
133133
{
134+
BOOST_CHECK_THROW(AmountFromValue(ValueFromString("-0.00000001")), UniValue);
135+
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0")), 0LL);
136+
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000000")), 0LL);
134137
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001")), 1LL);
135138
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.17622195")), 17622195LL);
136139
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.5")), 50000000LL);

src/test/util_tests.cpp

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -146,29 +146,27 @@ BOOST_AUTO_TEST_CASE(util_GetArg)
146146

147147
BOOST_AUTO_TEST_CASE(util_FormatMoney)
148148
{
149-
BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00");
150-
BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789");
151-
BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00");
152-
BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00");
153-
BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00");
154-
155-
BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00");
156-
BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00");
157-
BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00");
158-
BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00");
159-
BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00");
160-
BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00");
161-
BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00");
162-
BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00");
163-
BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00");
164-
BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10");
165-
BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01");
166-
BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001");
167-
BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001");
168-
BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001");
169-
BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001");
170-
BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001");
171-
BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001");
149+
BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
150+
BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789");
151+
BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00");
152+
153+
BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00");
154+
BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00");
155+
BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00");
156+
BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00");
157+
BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00");
158+
BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00");
159+
BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00");
160+
BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00");
161+
BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00");
162+
BOOST_CHECK_EQUAL(FormatMoney(COIN/10), "0.10");
163+
BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01");
164+
BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001");
165+
BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001");
166+
BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001");
167+
BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001");
168+
BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001");
169+
BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001");
172170
}
173171

174172
BOOST_AUTO_TEST_CASE(util_ParseMoney)

src/utilmoneystr.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
using namespace std;
1313

14-
string FormatMoney(const CAmount& n, bool fPlus)
14+
std::string FormatMoney(const CAmount& n)
1515
{
1616
// Note: not using straight sprintf here because we do NOT want
1717
// localized number formatting.
@@ -29,8 +29,6 @@ string FormatMoney(const CAmount& n, bool fPlus)
2929

3030
if (n < 0)
3131
str.insert((unsigned int)0, 1, '-');
32-
else if (fPlus && n > 0)
33-
str.insert((unsigned int)0, 1, '+');
3432
return str;
3533
}
3634

src/utilmoneystr.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
#include "amount.h"
1616

17-
std::string FormatMoney(const CAmount& n, bool fPlus=false);
17+
std::string FormatMoney(const CAmount& n);
1818
bool ParseMoney(const std::string& str, CAmount& nRet);
1919
bool ParseMoney(const char* pszIn, CAmount& nRet);
2020

src/wallet/rpcwallet.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,8 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
414414

415415
// Amount
416416
CAmount nAmount = AmountFromValue(params[1]);
417+
if (nAmount <= 0)
418+
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
417419

418420
// Wallet comments
419421
CWalletTx wtx;
@@ -809,6 +811,8 @@ UniValue movecmd(const UniValue& params, bool fHelp)
809811
string strFrom = AccountFromValue(params[0]);
810812
string strTo = AccountFromValue(params[1]);
811813
CAmount nAmount = AmountFromValue(params[2]);
814+
if (nAmount <= 0)
815+
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
812816
if (params.size() > 3)
813817
// unused parameter, used to be nMinDepth, keep type-checking it though
814818
(void)params[3].get_int();
@@ -888,6 +892,8 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
888892
if (!address.IsValid())
889893
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
890894
CAmount nAmount = AmountFromValue(params[2]);
895+
if (nAmount <= 0)
896+
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
891897
int nMinDepth = 1;
892898
if (params.size() > 3)
893899
nMinDepth = params[3].get_int();
@@ -987,6 +993,8 @@ UniValue sendmany(const UniValue& params, bool fHelp)
987993

988994
CScript scriptPubKey = GetScriptForDestination(address.Get());
989995
CAmount nAmount = AmountFromValue(sendTo[name_]);
996+
if (nAmount <= 0)
997+
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
990998
totalAmount += nAmount;
991999

9921000
bool fSubtractFeeFromAmount = false;
@@ -2168,9 +2176,7 @@ UniValue settxfee(const UniValue& params, bool fHelp)
21682176
LOCK2(cs_main, pwalletMain->cs_wallet);
21692177

21702178
// Amount
2171-
CAmount nAmount = 0;
2172-
if (params[0].get_real() != 0.0)
2173-
nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
2179+
CAmount nAmount = AmountFromValue(params[0]);
21742180

21752181
payTxFee = CFeeRate(nAmount, 1000);
21762182
return true;
@@ -2352,4 +2358,4 @@ UniValue listunspent(const UniValue& params, bool fHelp)
23522358
}
23532359

23542360
return results;
2355-
}
2361+
}

0 commit comments

Comments
 (0)