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)
This commit is contained in:
commit
643114f539
6 changed files with 44 additions and 42 deletions
|
@ -11,6 +11,7 @@
|
|||
#include "sync.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "utilmoneystr.h"
|
||||
#include "utilstrencodings.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet/wallet.h"
|
||||
|
@ -118,25 +119,21 @@ void RPCTypeCheckObj(const UniValue& o,
|
|||
}
|
||||
}
|
||||
|
||||
static inline int64_t roundint64(double d)
|
||||
{
|
||||
return (int64_t)(d > 0 ? d + 0.5 : d - 0.5);
|
||||
}
|
||||
|
||||
CAmount AmountFromValue(const UniValue& value)
|
||||
{
|
||||
double dAmount = value.get_real();
|
||||
if (dAmount <= 0.0 || dAmount > 21000000.0)
|
||||
if (!value.isReal() && !value.isNum())
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number");
|
||||
CAmount amount;
|
||||
if (!ParseMoney(value.getValStr(), amount))
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
|
||||
CAmount nAmount = roundint64(dAmount * COIN);
|
||||
if (!MoneyRange(nAmount))
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
|
||||
return nAmount;
|
||||
if (!MoneyRange(amount))
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range");
|
||||
return amount;
|
||||
}
|
||||
|
||||
UniValue ValueFromAmount(const CAmount& amount)
|
||||
{
|
||||
return (double)amount / (double)COIN;
|
||||
return UniValue(UniValue::VREAL, FormatMoney(amount));
|
||||
}
|
||||
|
||||
uint256 ParseHashV(const UniValue& v, string strName)
|
||||
|
|
|
@ -131,6 +131,9 @@ static UniValue ValueFromString(const std::string &str)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values)
|
||||
{
|
||||
BOOST_CHECK_THROW(AmountFromValue(ValueFromString("-0.00000001")), UniValue);
|
||||
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0")), 0LL);
|
||||
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000000")), 0LL);
|
||||
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000001")), 1LL);
|
||||
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.17622195")), 17622195LL);
|
||||
BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.5")), 50000000LL);
|
||||
|
|
|
@ -146,29 +146,27 @@ BOOST_AUTO_TEST_CASE(util_GetArg)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(util_FormatMoney)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(FormatMoney(0, false), "0.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789, false), "12345.6789");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN, true), "+1.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(-COIN, false), "-1.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(-COIN, true), "-1.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00");
|
||||
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000, false), "100000000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000, false), "10000000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000, false), "1000000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*100000, false), "100000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*10000, false), "10000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*1000, false), "1000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*100, false), "100.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*10, false), "10.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN, false), "1.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/10, false), "0.10");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/100, false), "0.01");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/1000, false), "0.001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/10000, false), "0.0001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/100000, false), "0.00001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000, false), "0.000001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000, false), "0.0000001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000, false), "0.00000001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/10), "0.10");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001");
|
||||
BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(util_ParseMoney)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
string FormatMoney(const CAmount& n, bool fPlus)
|
||||
std::string FormatMoney(const CAmount& n)
|
||||
{
|
||||
// Note: not using straight sprintf here because we do NOT want
|
||||
// localized number formatting.
|
||||
|
@ -29,8 +29,6 @@ string FormatMoney(const CAmount& n, bool fPlus)
|
|||
|
||||
if (n < 0)
|
||||
str.insert((unsigned int)0, 1, '-');
|
||||
else if (fPlus && n > 0)
|
||||
str.insert((unsigned int)0, 1, '+');
|
||||
return str;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "amount.h"
|
||||
|
||||
std::string FormatMoney(const CAmount& n, bool fPlus=false);
|
||||
std::string FormatMoney(const CAmount& n);
|
||||
bool ParseMoney(const std::string& str, CAmount& nRet);
|
||||
bool ParseMoney(const char* pszIn, CAmount& nRet);
|
||||
|
||||
|
|
|
@ -414,6 +414,8 @@ UniValue sendtoaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
// Amount
|
||||
CAmount nAmount = AmountFromValue(params[1]);
|
||||
if (nAmount <= 0)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
||||
|
||||
// Wallet comments
|
||||
CWalletTx wtx;
|
||||
|
@ -809,6 +811,8 @@ UniValue movecmd(const UniValue& params, bool fHelp)
|
|||
string strFrom = AccountFromValue(params[0]);
|
||||
string strTo = AccountFromValue(params[1]);
|
||||
CAmount nAmount = AmountFromValue(params[2]);
|
||||
if (nAmount <= 0)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
||||
if (params.size() > 3)
|
||||
// unused parameter, used to be nMinDepth, keep type-checking it though
|
||||
(void)params[3].get_int();
|
||||
|
@ -888,6 +892,8 @@ UniValue sendfrom(const UniValue& params, bool fHelp)
|
|||
if (!address.IsValid())
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||
CAmount nAmount = AmountFromValue(params[2]);
|
||||
if (nAmount <= 0)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
||||
int nMinDepth = 1;
|
||||
if (params.size() > 3)
|
||||
nMinDepth = params[3].get_int();
|
||||
|
@ -987,6 +993,8 @@ UniValue sendmany(const UniValue& params, bool fHelp)
|
|||
|
||||
CScript scriptPubKey = GetScriptForDestination(address.Get());
|
||||
CAmount nAmount = AmountFromValue(sendTo[name_]);
|
||||
if (nAmount <= 0)
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount for send");
|
||||
totalAmount += nAmount;
|
||||
|
||||
bool fSubtractFeeFromAmount = false;
|
||||
|
@ -2168,9 +2176,7 @@ UniValue settxfee(const UniValue& params, bool fHelp)
|
|||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
// Amount
|
||||
CAmount nAmount = 0;
|
||||
if (params[0].get_real() != 0.0)
|
||||
nAmount = AmountFromValue(params[0]); // rejects 0.0 amounts
|
||||
CAmount nAmount = AmountFromValue(params[0]);
|
||||
|
||||
payTxFee = CFeeRate(nAmount, 1000);
|
||||
return true;
|
||||
|
@ -2352,4 +2358,4 @@ UniValue listunspent(const UniValue& params, bool fHelp)
|
|||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue