aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2015-07-18 07:44:19 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2015-07-18 09:04:18 +0200
commit7650449a6777710cf818d41862626164da0cd412 (patch)
treeddb32fd03bd9df82961ea176810b50faba133a23
parente061e2778d592826970483e0844308c4e9a12626 (diff)
downloadbitcoin-7650449a6777710cf818d41862626164da0cd412.tar.xz
univalue: Avoid unnecessary roundtrip through double for numbers
JSON makes no distinction between numbers and reals, and our code doesn't need to do so either. This removes VREAL, as well as its specific post-processing in `UniValue::write`. Non-monetary amounts do not need to be forcibly formatted with 8 decimals, so the extra roundtrip was unnecessary (and potentially loses precision).
-rwxr-xr-xqa/rpc-tests/rest.py3
-rw-r--r--src/rpcserver.cpp2
-rw-r--r--src/test/univalue_tests.cpp6
-rw-r--r--src/univalue/univalue.cpp5
-rw-r--r--src/univalue/univalue.h3
-rw-r--r--src/univalue/univalue_write.cpp7
6 files changed, 9 insertions, 17 deletions
diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py
index 1a2d326cc3..b0cde7268e 100755
--- a/qa/rpc-tests/rest.py
+++ b/qa/rpc-tests/rest.py
@@ -14,6 +14,7 @@ from struct import *
import binascii
import json
import StringIO
+import decimal
try:
import http.client as httplib
@@ -243,7 +244,7 @@ class RESTTest (BitcoinTestFramework):
response_header_json = http_get_call(url.hostname, url.port, '/rest/headers/1/'+bb_hash+self.FORMAT_SEPARATOR+"json", "", True)
assert_equal(response_header_json.status, 200)
response_header_json_str = response_header_json.read()
- json_obj = json.loads(response_header_json_str)
+ json_obj = json.loads(response_header_json_str, parse_float=decimal.Decimal)
assert_equal(len(json_obj), 1) #ensure that there is one header in the json response
assert_equal(json_obj[0]['hash'], bb_hash) #request/response hash should be the same
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index c5402e0dfa..201fc5eba8 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -120,7 +120,7 @@ void RPCTypeCheckObj(const UniValue& o,
CAmount AmountFromValue(const UniValue& value)
{
- if (!value.isReal() && !value.isNum())
+ if (!value.isNum())
throw JSONRPCError(RPC_TYPE_ERROR, "Amount is not a number");
CAmount amount;
if (!ParseFixedPoint(value.getValStr(), 8, &amount))
diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp
index 16bc8d30f6..67cb9b9623 100644
--- a/src/test/univalue_tests.cpp
+++ b/src/test/univalue_tests.cpp
@@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(univalue_constructor)
double vd = -7.21;
UniValue v7(vd);
- BOOST_CHECK(v7.isReal());
+ BOOST_CHECK(v7.isNum());
BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
string vs("yawn");
@@ -127,7 +127,7 @@ BOOST_AUTO_TEST_CASE(univalue_set)
BOOST_CHECK_EQUAL(v.getValStr(), "zum");
BOOST_CHECK(v.setFloat(-1.01));
- BOOST_CHECK(v.isReal());
+ BOOST_CHECK(v.isNum());
BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
BOOST_CHECK(v.setInt((int)1023));
@@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(univalue_object)
objTypes["distance"] = UniValue::VNUM;
objTypes["time"] = UniValue::VNUM;
objTypes["calories"] = UniValue::VNUM;
- objTypes["temperature"] = UniValue::VREAL;
+ objTypes["temperature"] = UniValue::VNUM;
objTypes["cat1"] = UniValue::VNUM;
objTypes["cat2"] = UniValue::VNUM;
BOOST_CHECK(obj.checkObject(objTypes));
diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp
index 6920c44c96..1d49a2cfc9 100644
--- a/src/univalue/univalue.cpp
+++ b/src/univalue/univalue.cpp
@@ -86,7 +86,7 @@ bool UniValue::setFloat(double val)
oss << std::setprecision(16) << val;
bool ret = setNumStr(oss.str());
- typ = VREAL;
+ typ = VNUM;
return ret;
}
@@ -210,7 +210,6 @@ const char *uvTypeName(UniValue::VType t)
case UniValue::VARR: return "array";
case UniValue::VSTR: return "string";
case UniValue::VNUM: return "number";
- case UniValue::VREAL: return "number";
}
// not reached
@@ -280,7 +279,7 @@ int64_t UniValue::get_int64() const
double UniValue::get_real() const
{
- if (typ != VREAL && typ != VNUM)
+ if (typ != VNUM)
throw std::runtime_error("JSON value is not a number as expected");
double retval;
if (!ParseDouble(getValStr(), &retval))
diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h
index 54239741e2..4742b56f3d 100644
--- a/src/univalue/univalue.h
+++ b/src/univalue/univalue.h
@@ -16,7 +16,7 @@
class UniValue {
public:
- enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VREAL, VBOOL, };
+ enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
UniValue() { typ = VNULL; }
UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
@@ -78,7 +78,6 @@ public:
bool isBool() const { return (typ == VBOOL); }
bool isStr() const { return (typ == VSTR); }
bool isNum() const { return (typ == VNUM); }
- bool isReal() const { return (typ == VREAL); }
bool isArray() const { return (typ == VARR); }
bool isObject() const { return (typ == VOBJ); }
diff --git a/src/univalue/univalue_write.cpp b/src/univalue/univalue_write.cpp
index d360c253b0..bce3997af7 100644
--- a/src/univalue/univalue_write.cpp
+++ b/src/univalue/univalue_write.cpp
@@ -61,13 +61,6 @@ string UniValue::write(unsigned int prettyIndent,
case VSTR:
s += "\"" + json_escape(val) + "\"";
break;
- case VREAL:
- {
- std::stringstream ss;
- ss << std::showpoint << std::fixed << std::setprecision(8) << get_real();
- s += ss.str();
- }
- break;
case VNUM:
s += val;
break;