From f71994ccc98059fb79e51affe33c3a15beaa48d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Tue, 21 Mar 2017 23:13:31 +0100 Subject: [PATCH 1/3] Upstream? assert(decimals == 8 || decimals == 0) in ParseFixedPoint --- src/utilstrencodings.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 5ffdb3be15cf4..0d4d5dd5a62e7 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -612,6 +612,7 @@ static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantiss bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out) { + assert(decimals == 8 || decimals == 0); int64_t mantissa = 0; int64_t exponent = 0; int mantissa_tzeros = 0; From 362eb080c36abd8cdf94e396657e67067edcb7cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 22 Mar 2017 02:49:46 +0100 Subject: [PATCH 2/3] Upstream?: Tests(unit) for AmountFromValue/ValueFromAmount with 0 decimals --- src/rpc/server.cpp | 12 +++++++++--- src/rpc/server.h | 4 ++-- src/test/rpc_tests.cpp | 25 +++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) diff --git a/src/rpc/server.cpp b/src/rpc/server.cpp index 23149baa6d945..147a3c527ae59 100644 --- a/src/rpc/server.cpp +++ b/src/rpc/server.cpp @@ -117,21 +117,27 @@ void RPCTypeCheckObj(const UniValue& o, } } -CAmount AmountFromValue(const UniValue& value) +CAmount AmountFromValue(const UniValue& value, const bool f8Decimals) { if (!value.isNum() && !value.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number or string"); CAmount amount; - if (!ParseFixedPoint(value.getValStr(), 8, &amount)) + // TODO Decimals: Just don't call ParseFixedPoint if !f8Decimals + int decimals = f8Decimals ? 8 : 0; + if (!ParseFixedPoint(value.getValStr(), decimals, &amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); if (!MoneyRange(amount)) throw JSONRPCError(RPC_TYPE_ERROR, "Amount out of range"); return amount; } -UniValue ValueFromAmount(const CAmount& amount) +UniValue ValueFromAmount(const CAmount& amount, const bool f8Decimals) { bool sign = amount < 0; + if (!f8Decimals) { + assert(!sign); // FIX throw exception ? + return UniValue(UniValue::VNUM, strprintf("%d", amount)); + } int64_t n_abs = (sign ? -amount : amount); int64_t quotient = n_abs / COIN; int64_t remainder = n_abs % COIN; diff --git a/src/rpc/server.h b/src/rpc/server.h index b5ccc153d07ef..b77c51d3f425e 100644 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -181,8 +181,8 @@ extern std::vector ParseHexV(const UniValue& v, std::string strNa extern std::vector ParseHexO(const UniValue& o, std::string strKey); extern int64_t nWalletUnlockTime; -extern CAmount AmountFromValue(const UniValue& value); -extern UniValue ValueFromAmount(const CAmount& amount); +CAmount AmountFromValue(const UniValue& value, const bool f8Decimals=true); +UniValue ValueFromAmount(const CAmount& amount, const bool f8Decimals=true); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpRequiringPassphrase(); extern std::string HelpExampleCli(const std::string& methodname, const std::string& args); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index bbda6a48f4d5a..f894c96319a42 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -132,6 +132,18 @@ BOOST_AUTO_TEST_CASE(rpc_createraw_op_return) BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) { + BOOST_CHECK(ValueFromAmount(0LL, false).write() == "0"); + BOOST_CHECK(ValueFromAmount(1LL, false).write() == "1"); + BOOST_CHECK(ValueFromAmount(17622195LL, false).write() == "17622195"); + BOOST_CHECK(ValueFromAmount(50000000LL, false).write() == "50000000"); + BOOST_CHECK(ValueFromAmount(89898989LL, false).write() == "89898989"); + BOOST_CHECK(ValueFromAmount(100000000LL, false).write() == "100000000"); // 1 CURRENCY_UNIT + BOOST_CHECK(ValueFromAmount(100000000000000LL, false).write() == "100000000000000"); // 1 M CURRENCY_UNIT + BOOST_CHECK(ValueFromAmount(2100000000000000LL, false).write() == "2100000000000000"); // 21 M CURRENCY_UNIT + BOOST_CHECK(ValueFromAmount(10000000000000000LL, false).write() == "10000000000000000"); // 100 M CURRENCY_UNIT (100 000 000 0000 0000 MINIMAL_UNIT) + BOOST_CHECK(ValueFromAmount(2099999999999990LL, false).write() == "2099999999999990"); + BOOST_CHECK(ValueFromAmount(2099999999999999LL, false).write() == "2099999999999999"); + BOOST_CHECK(ValueFromAmount(0LL).write() == "0.00000000"); BOOST_CHECK(ValueFromAmount(1LL).write() == "0.00000001"); BOOST_CHECK(ValueFromAmount(17622195LL).write() == "0.17622195"); @@ -174,6 +186,19 @@ static UniValue ValueFromString(const std::string &str) BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) { + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("-1"), false), UniValue); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0"), false), 0LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("1"), false), 1LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("17622195"), false), 17622195LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("50000000"), false), 50000000LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("89898989"), false), 89898989LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("100000000"), false), 100000000LL); // 1 CURRENCY_UNIT + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("100000000000000"), false), 100000000000000LL); // 1 M CURRENCY_UNIT + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("2100000000000000"), false), 2100000000000000LL); // 21 M CURRENCY_UNIT + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("2099999999999999"), false), 2099999999999999LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("2099999999999990"), false), 2099999999999990LL); + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("209999999999999"), false), 209999999999999LL); + BOOST_CHECK_THROW(AmountFromValue(ValueFromString("-0.00000001")), UniValue); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0")), 0LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0.00000000")), 0LL); From 82aff771d4505595372fdca40ffaa1b9ba5c29dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Tim=C3=B3n?= Date: Wed, 22 Mar 2017 02:50:51 +0100 Subject: [PATCH 3/3] Altchain: ERROR-unit: FIX why 21? --- src/test/rpc_tests.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index f894c96319a42..e763121d5b153 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -198,6 +198,8 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("2099999999999999"), false), 2099999999999999LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("2099999999999990"), false), 2099999999999990LL); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("209999999999999"), false), 209999999999999LL); + // FIX Decimals: This shouldn't fail? or make sure it always fails + BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("10000000000000000"), false), 10000000000000000LL); // 100 M CURRENCY_UNIT (100 000 000 0000 0000 MINIMAL_UNIT) BOOST_CHECK_THROW(AmountFromValue(ValueFromString("-0.00000001")), UniValue); BOOST_CHECK_EQUAL(AmountFromValue(ValueFromString("0")), 0LL);