From ec57cc0ffe4e6bdc8633a47b01188e80bc025da5 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 20 Aug 2014 09:59:31 -0400 Subject: [PATCH 01/26] UniValue: prefer .size() to .count(), to harmonize w/ existing tree --- src/bitcoin-tx.cpp | 4 ++-- src/test/univalue_tests.cpp | 16 ++++++++-------- src/univalue/univalue.h | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index ed4e9ff82..4fed20865 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -347,7 +347,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) UniValue keysObj = registers["privatekeys"]; fGivenKeys = true; - for (unsigned int kidx = 0; kidx < keysObj.count(); kidx++) { + for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) { if (!keysObj[kidx].isStr()) throw runtime_error("privatekey not a string"); CBitcoinSecret vchSecret; @@ -364,7 +364,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) throw runtime_error("prevtxs register variable must be set."); UniValue prevtxsObj = registers["prevtxs"]; { - for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) { + for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) { UniValue prevOut = prevtxsObj[previdx]; if (!prevOut.isObject()) throw runtime_error("expected prevtxs internal object"); diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 8cecfbf65..6df980ad0 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -72,13 +72,13 @@ BOOST_AUTO_TEST_CASE(univalue_set) BOOST_CHECK(v.setObject()); BOOST_CHECK(v.isObject()); - BOOST_CHECK_EQUAL(v.count(), 0); + BOOST_CHECK_EQUAL(v.size(), 0); BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ); BOOST_CHECK(v.empty()); BOOST_CHECK(v.setArray()); BOOST_CHECK(v.isArray()); - BOOST_CHECK_EQUAL(v.count(), 0); + BOOST_CHECK_EQUAL(v.size(), 0); BOOST_CHECK(v.setStr("zum")); BOOST_CHECK(v.isStr()); @@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(univalue_array) BOOST_CHECK(arr.push_backV(vec)); BOOST_CHECK_EQUAL(arr.empty(), false); - BOOST_CHECK_EQUAL(arr.count(), 5); + BOOST_CHECK_EQUAL(arr.size(), 5); BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023"); BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy"); @@ -157,7 +157,7 @@ BOOST_AUTO_TEST_CASE(univalue_array) arr.clear(); BOOST_CHECK(arr.empty()); - BOOST_CHECK_EQUAL(arr.count(), 0); + BOOST_CHECK_EQUAL(arr.size(), 0); } BOOST_AUTO_TEST_CASE(univalue_object) @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) BOOST_CHECK(obj.pushKVs(obj2)); BOOST_CHECK_EQUAL(obj.empty(), false); - BOOST_CHECK_EQUAL(obj.count(), 9); + BOOST_CHECK_EQUAL(obj.size(), 9); BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100"); BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John"); @@ -240,7 +240,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) obj.clear(); BOOST_CHECK(obj.empty()); - BOOST_CHECK_EQUAL(obj.count(), 0); + BOOST_CHECK_EQUAL(obj.size(), 0); } static const char *json1 = @@ -255,13 +255,13 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite) BOOST_CHECK(v.read(strJson1)); BOOST_CHECK(v.isArray()); - BOOST_CHECK_EQUAL(v.count(), 2); + BOOST_CHECK_EQUAL(v.size(), 2); BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1"); UniValue obj = v[1]; BOOST_CHECK(obj.isObject()); - BOOST_CHECK_EQUAL(obj.count(), 3); + BOOST_CHECK_EQUAL(obj.size(), 3); BOOST_CHECK(obj["key1"].isStr()); BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str"); diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 88d73b8c6..d31c596a6 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -58,7 +58,7 @@ public: std::string getValStr() const { return val; } bool empty() const { return (values.size() == 0); } - size_t count() const { return values.size(); } + size_t size() const { return values.size(); } bool getBool() const { return isTrue(); } bool checkObject(const std::map& memberTypes); From 03912600e80217400e0d4b80c71bc2c3accca686 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 20 Aug 2014 11:13:52 -0400 Subject: [PATCH 02/26] UniValue: export NullUniValue global constant --- src/univalue/univalue.cpp | 10 +++++----- src/univalue/univalue.h | 2 ++ 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index 4e445a542..6870ce59e 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -9,7 +9,7 @@ using namespace std; -static const UniValue nullValue; +const UniValue NullUniValue; void UniValue::clear() { @@ -175,11 +175,11 @@ bool UniValue::checkObject(const std::map& t) const UniValue& UniValue::operator[](const std::string& key) const { if (typ != VOBJ) - return nullValue; + return NullUniValue; int index = findKey(key); if (index < 0) - return nullValue; + return NullUniValue; return values[index]; } @@ -187,9 +187,9 @@ const UniValue& UniValue::operator[](const std::string& key) const const UniValue& UniValue::operator[](unsigned int index) const { if (typ != VOBJ && typ != VARR) - return nullValue; + return NullUniValue; if (index >= values.size()) - return nullValue; + return NullUniValue; return values[index]; } diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index d31c596a6..afe751ed9 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -152,4 +152,6 @@ extern enum jtokentype getJsonToken(std::string& tokenVal, unsigned int& consumed, const char *raw); extern const char *uvTypeName(UniValue::VType t); +extern const UniValue NullUniValue; #endif // BITCOIN_UNIVALUE_UNIVALUE_H + From ed21d5bd4bf6ccfd44f8ca9dc126ad14f0b691a5 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Wed, 20 Aug 2014 15:15:16 -0400 Subject: [PATCH 03/26] Convert tree to using univalue. Eliminate all json_spirit uses. --- src/Makefile.am | 1 + src/bitcoin-cli.cpp | 20 ++++---- src/json_spirit_wrapper.h | 17 +++++++ src/qt/rpcconsole.cpp | 18 +++++--- src/rpcblockchain.cpp | 16 +++++-- src/rpcclient.cpp | 2 +- src/rpcclient.h | 4 +- src/rpcmining.cpp | 19 ++++---- src/rpcmisc.cpp | 5 +- src/rpcnet.cpp | 8 ++-- src/rpcprotocol.cpp | 10 ++-- src/rpcprotocol.h | 4 +- src/rpcrawtransaction.cpp | 47 ++++++++++--------- src/rpcserver.cpp | 51 +++++++++++---------- src/rpcserver.h | 18 ++++---- src/test/base58_tests.cpp | 40 +++++++--------- src/test/rpc_tests.cpp | 18 ++++---- src/test/script_tests.cpp | 22 ++++----- src/test/sighash_tests.cpp | 11 ++--- src/test/transaction_tests.cpp | 33 +++++++++---- src/univalue/univalue.h | 84 ++++++++++++++++++++++++++++++++++ src/wallet/rpcdump.cpp | 12 ++--- src/wallet/rpcwallet.cpp | 64 ++++++++++++++------------ 23 files changed, 320 insertions(+), 204 deletions(-) create mode 100644 src/json_spirit_wrapper.h diff --git a/src/Makefile.am b/src/Makefile.am index ce25d1765..34434b8ab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -423,6 +423,7 @@ endif zcash_cli_LDADD = \ $(LIBBITCOIN_CLI) \ + $(LIBBITCOIN_UNIVALUE) \ $(LIBBITCOIN_UTIL) \ $(BOOST_LIBS) \ $(SSL_LIBS) \ diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 4e15bd197..03a727719 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -153,7 +153,7 @@ Object CallRPC(const string& strMethod, const Array& params) // Parse reply Value valReply; - if (!read_string(strReply, valReply)) + if (!valReply.read(strReply)) throw runtime_error("couldn't parse reply from server"); const Object& reply = valReply.get_obj(); if (reply.empty()) @@ -186,29 +186,27 @@ int CommandLineRPC(int argc, char *argv[]) const bool fWait = GetBoolArg("-rpcwait", false); do { try { - const Object reply = CallRPC(strMethod, params); + // Execute + Object reply = CallRPC(strMethod, params); // Parse reply const Value& result = find_value(reply, "result"); const Value& error = find_value(reply, "error"); - if (error.type() != null_type) { + if (!error.isNull()) { // Error - const int code = find_value(error.get_obj(), "code").get_int(); - if (fWait && code == RPC_IN_WARMUP) - throw CConnectionFailed("server in warmup"); - strPrint = "error: " + write_string(error, false); + strPrint = "error: " + error.write(); + int code = error["code"].get_int(); nRet = abs(code); } else { // Result - if (result.type() == null_type) + if (result.isNull()) strPrint = ""; - else if (result.type() == str_type) + else if (result.isStr()) strPrint = result.get_str(); else - strPrint = write_string(result, true); + strPrint = result.write(2); } - // Connection succeeded, no need to retry. break; } diff --git a/src/json_spirit_wrapper.h b/src/json_spirit_wrapper.h new file mode 100644 index 000000000..1962cf643 --- /dev/null +++ b/src/json_spirit_wrapper.h @@ -0,0 +1,17 @@ +#ifndef __JSON_SPIRIT_WRAPPER_H__ +#define __JSON_SPIRIT_WRAPPER_H__ + +#include "univalue/univalue.h" + +namespace json_spirit { + +typedef UniValue Value; +typedef UniValue Array; +typedef UniValue Object; +typedef UniValue::VType Value_type; + +} + +#define find_value(val,key) (val[key]) + +#endif // __JSON_SPIRIT_WRAPPER_H__ diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index bdf2925fe..25ccf42d2 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -16,10 +16,10 @@ #include "rpcclient.h" #include "util.h" -#include "json/json_spirit_value.h" - #include +#include "univalue/univalue.h" + #ifdef ENABLE_WALLET #include #endif @@ -167,21 +167,25 @@ void RPCExecutor::request(const QString &command) std::string strPrint; // Convert argument list to JSON objects in method-dependent way, // and pass it along with the method name to the dispatcher. - json_spirit::Value result = tableRPC.execute( + UniValue result = tableRPC.execute( args[0], RPCConvertValues(args[0], std::vector(args.begin() + 1, args.end()))); // Format result reply - if (result.type() == json_spirit::null_type) + if (result.isNull()) strPrint = ""; - else if (result.type() == json_spirit::str_type) + else if (result.isStr()) strPrint = result.get_str(); else - strPrint = write_string(result, true); + strPrint = result.write(2); Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); } +<<<<<<< HEAD catch (const json_spirit::Object& objError) +======= + catch (UniValue& objError) +>>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { try // Nice formatting for standard-format error { @@ -191,7 +195,7 @@ void RPCExecutor::request(const QString &command) } catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message { // Show raw JSON object - Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false))); + Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(objError.write())); } } catch (const std::exception& e) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 4e6d42a6b..d97b05049 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -13,7 +13,7 @@ #include -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -228,7 +228,13 @@ Value getrawmempool(const Array& params, bool fHelp) if (mempool.exists(txin.prevout.hash)) setDepends.insert(txin.prevout.hash.ToString()); } - Array depends(setDepends.begin(), setDepends.end()); + + UniValue depends; + BOOST_FOREACH(const string& dep, setDepends) + { + depends.push_back(dep); + } + info.push_back(Pair("depends", depends)); o.push_back(Pair(hash.ToString(), info)); } @@ -434,14 +440,14 @@ Value gettxout(const Array& params, bool fHelp) LOCK(mempool.cs); CCoinsViewMemPool view(pcoinsTip, mempool); if (!view.GetCoins(hash, coins)) - return Value::null; + return NullUniValue; mempool.pruneSpent(hash, coins); // TODO: this should be done by the CCoinsViewMemPool } else { if (!pcoinsTip->GetCoins(hash, coins)) - return Value::null; + return NullUniValue; } if (n<0 || (unsigned int)n>=coins.vout.size() || coins.vout[n].IsNull()) - return Value::null; + return NullUniValue; BlockMap::iterator it = mapBlockIndex.find(pcoinsTip->GetBestBlock()); CBlockIndex *pindex = it->second; diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index b482a8eb9..60ff66a1e 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -151,7 +151,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector& strParams); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index c500db398..f8357f773 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -28,8 +28,7 @@ #include -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -322,7 +321,7 @@ Value setgenerate(const Array& params, bool fHelp) GenerateBitcoins(fGenerate, nGenProcLimit); #endif - return Value::null; + return NullUniValue; } #endif @@ -503,16 +502,16 @@ Value getblocktemplate(const Array& params, bool fHelp) } std::string strMode = "template"; - Value lpval = Value::null; + Value lpval = NullUniValue; // TODO: Re-enable coinbasevalue once a specification has been written bool coinbasetxn = true; if (params.size() > 0) { const Object& oparam = params[0].get_obj(); const Value& modeval = find_value(oparam, "mode"); - if (modeval.type() == str_type) + if (modeval.isStr()) strMode = modeval.get_str(); - else if (modeval.type() == null_type) + else if (modeval.isNull()) { /* Do nothing */ } @@ -562,14 +561,14 @@ Value getblocktemplate(const Array& params, bool fHelp) static unsigned int nTransactionsUpdatedLast; - if (lpval.type() != null_type) + if (!lpval.isNull()) { // Wait to respond until either the best block changes, OR a minute has passed and there are more transactions uint256 hashWatchedChain; boost::system_time checktxtime; unsigned int nTransactionsUpdatedLastLP; - if (lpval.type() == str_type) + if (lpval.isStr()) { // Format: std::string lpstr = lpval.get_str(); @@ -829,7 +828,7 @@ Value estimatefee(const Array& params, bool fHelp) + HelpExampleCli("estimatefee", "6") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); int nBlocks = params[0].get_int(); if (nBlocks < 1) @@ -861,7 +860,7 @@ Value estimatepriority(const Array& params, bool fHelp) + HelpExampleCli("estimatepriority", "6") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); int nBlocks = params[0].get_int(); if (nBlocks < 1) diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index d5770fc47..647643350 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -20,8 +20,7 @@ #include #include -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" #include "zcash/Address.hpp" @@ -206,7 +205,7 @@ Value validateaddress(const Array& params, bool fHelp) if (mine != ISMINE_NO) { ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); - ret.insert(ret.end(), detail.begin(), detail.end()); + ret.pushKVs(detail); } if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name)); diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index e3d264a57..d8b2f6101 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -16,7 +16,7 @@ #include -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -59,7 +59,7 @@ Value ping(const Array& params, bool fHelp) pNode->fPingQueued = true; } - return Value::null; + return NullUniValue; } static void CopyNodeStats(std::vector& vstats) @@ -190,7 +190,7 @@ Value addnode(const Array& params, bool fHelp) { CAddress addr; OpenNetworkConnection(addr, NULL, strNode.c_str()); - return Value::null; + return NullUniValue; } LOCK(cs_vAddedNodes); @@ -212,7 +212,7 @@ Value addnode(const Array& params, bool fHelp) vAddedNodes.erase(it); } - return Value::null; + return NullUniValue; } Value getaddednodeinfo(const Array& params, bool fHelp) diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index 19badb473..bdea60410 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -25,7 +25,7 @@ #include #include #include -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" using namespace std; using namespace json_spirit; @@ -262,14 +262,14 @@ string JSONRPCRequest(const string& strMethod, const Array& params, const Value& request.push_back(Pair("method", strMethod)); request.push_back(Pair("params", params)); request.push_back(Pair("id", id)); - return write_string(Value(request), false) + "\n"; + return request.write() + "\n"; } Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) { Object reply; - if (error.type() != null_type) - reply.push_back(Pair("result", Value::null)); + if (!error.isNull()) + reply.push_back(Pair("result", NullUniValue)); else reply.push_back(Pair("result", result)); reply.push_back(Pair("error", error)); @@ -280,7 +280,7 @@ Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id) string JSONRPCReply(const Value& result, const Value& error, const Value& id) { Object reply = JSONRPCReplyObj(result, error, id); - return write_string(Value(reply), false) + "\n"; + return reply.write() + "\n"; } Object JSONRPCError(int code, const string& message) diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index a58a77fe0..8554a2ed9 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -16,9 +16,7 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" //! HTTP status codes enum HTTPStatusCode diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 4b4beb796..4c309e994 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -25,8 +25,7 @@ #include #include -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -429,20 +428,21 @@ Value createrawtransaction(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(array_type)(obj_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)); Array inputs = params[0].get_array(); Object sendTo = params[1].get_obj(); CMutableTransaction rawTx; - BOOST_FOREACH(const Value& input, inputs) { + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const Value& input = inputs[idx]; const Object& o = input.get_obj(); uint256 txid = ParseHashO(o, "txid"); const Value& vout_v = find_value(o, "vout"); - if (vout_v.type() != int_type) + if (!vout_v.isNum()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); int nOutput = vout_v.get_int(); if (nOutput < 0) @@ -453,17 +453,18 @@ Value createrawtransaction(const Array& params, bool fHelp) } set setAddress; - BOOST_FOREACH(const Pair& s, sendTo) { - CBitcoinAddress address(s.name_); + vector addrList = sendTo.getKeys(); + BOOST_FOREACH(const string& name_, addrList) { + CBitcoinAddress address(name_); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+name_); if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(sendTo[name_]); CTxOut out(nAmount, scriptPubKey); rawTx.vout.push_back(out); @@ -551,7 +552,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); CTransaction tx; @@ -683,7 +684,7 @@ Value signrawtransaction(const Array& params, bool fHelp) #else LOCK(cs_main); #endif - RPCTypeCheck(params, boost::assign::list_of(str_type)(array_type)(array_type)(str_type), true); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VARR)(UniValue::VARR)(UniValue::VSTR), true); vector txData(ParseHexV(params[0], "argument 1")); CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION); @@ -726,10 +727,11 @@ Value signrawtransaction(const Array& params, bool fHelp) bool fGivenKeys = false; CBasicKeyStore tempKeystore; - if (params.size() > 2 && params[2].type() != null_type) { + if (params.size() > 2 && !params[2].isNull()) { fGivenKeys = true; Array keys = params[2].get_array(); - BOOST_FOREACH(Value k, keys) { + for (unsigned int idx = 0; idx < keys.size(); idx++) { + Value k = keys[idx]; CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(k.get_str()); if (!fGood) @@ -746,15 +748,16 @@ Value signrawtransaction(const Array& params, bool fHelp) #endif // Add previous txouts given in the RPC call: - if (params.size() > 1 && params[1].type() != null_type) { + if (params.size() > 1 && !params[1].isNull()) { Array prevTxs = params[1].get_array(); - BOOST_FOREACH(Value& p, prevTxs) { - if (p.type() != obj_type) + for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { + const Value& p = prevTxs[idx]; + if (!p.isObject()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); Object prevOut = p.get_obj(); - RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)); + RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)); uint256 txid = ParseHashO(prevOut, "txid"); @@ -782,9 +785,9 @@ Value signrawtransaction(const Array& params, bool fHelp) // if redeemScript given and not using the local wallet (private keys // given), add redeemScript to the tempKeystore so it can be signed: if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { - RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type)("redeemScript",str_type)); + RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR)); Value v = find_value(prevOut, "redeemScript"); - if (!(v == Value::null)) { + if (!v.isNull()) { vector rsData(ParseHexV(v, "redeemScript")); CScript redeemScript(rsData.begin(), rsData.end()); tempKeystore.AddCScript(redeemScript); @@ -800,7 +803,7 @@ Value signrawtransaction(const Array& params, bool fHelp) #endif int nHashType = SIGHASH_ALL; - if (params.size() > 3 && params[3].type() != null_type) { + if (params.size() > 3 && !params[3].isNull()) { static map mapSigHashValues = boost::assign::map_list_of (string("ALL"), int(SIGHASH_ALL)) @@ -882,7 +885,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)(bool_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VBOOL)); // parse hex string from parameter CTransaction tx; diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 4100a7f7c..8284e9932 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -30,7 +30,8 @@ #include #include #include -#include "json/json_spirit_writer_template.h" + +#include "json_spirit_wrapper.h" using namespace boost::asio; using namespace json_spirit; @@ -92,30 +93,30 @@ void RPCTypeCheck(const Array& params, break; const Value& v = params[i]; - if (!((v.type() == t) || (fAllowNull && (v.type() == null_type)))) + if (!((v.type() == t) || (fAllowNull && (v.isNull())))) { string err = strprintf("Expected type %s, got %s", - Value_type_name[t], Value_type_name[v.type()]); + uvTypeName(t), uvTypeName(v.type())); throw JSONRPCError(RPC_TYPE_ERROR, err); } i++; } } -void RPCTypeCheck(const Object& o, - const map& typesExpected, +void RPCTypeCheckObj(const UniValue& o, + const map& typesExpected, bool fAllowNull) { BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) { const Value& v = find_value(o, t.first); - if (!fAllowNull && v.type() == null_type) + if (!fAllowNull && v.isNull()) throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first)); - if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type)))) + if (!((v.type() == t.second) || (fAllowNull && (v.isNull())))) { string err = strprintf("Expected type %s for %s, got %s", - Value_type_name[t.second], t.first, Value_type_name[v.type()]); + uvTypeName(t.second), t.first, uvTypeName(v.type())); throw JSONRPCError(RPC_TYPE_ERROR, err); } } @@ -145,7 +146,7 @@ Value ValueFromAmount(const CAmount& amount) uint256 ParseHashV(const Value& v, string strName) { string strHex; - if (v.type() == str_type) + if (v.isStr()) strHex = v.get_str(); if (!IsHex(strHex)) // Note: IsHex("") is false throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); @@ -160,7 +161,7 @@ uint256 ParseHashO(const Object& o, string strKey) vector ParseHexV(const Value& v, string strName) { string strHex; - if (v.type() == str_type) + if (v.isStr()) strHex = v.get_str(); if (!IsHex(strHex)) throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); @@ -444,7 +445,7 @@ void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) int code = find_value(objError, "code").get_int(); if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST; else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND; - string strReply = JSONRPCReply(Value::null, objError, id); + string strReply = JSONRPCReply(NullUniValue, objError, id); stream << HTTPReply(nStatus, strReply, false) << std::flush; } @@ -866,14 +867,14 @@ public: string strMethod; Array params; - JSONRequest() { id = Value::null; } + JSONRequest() { id = NullUniValue; } void parse(const Value& valRequest); }; void JSONRequest::parse(const Value& valRequest) { // Parse request - if (valRequest.type() != obj_type) + if (!valRequest.isObject()) throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object"); const Object& request = valRequest.get_obj(); @@ -882,9 +883,9 @@ void JSONRequest::parse(const Value& valRequest) // Parse method Value valMethod = find_value(request, "method"); - if (valMethod.type() == null_type) + if (valMethod.isNull()) throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); - if (valMethod.type() != str_type) + if (!valMethod.isStr()) throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string"); strMethod = valMethod.get_str(); if (strMethod != "getblocktemplate") @@ -892,9 +893,9 @@ void JSONRequest::parse(const Value& valRequest) // Parse params Value valParams = find_value(request, "params"); - if (valParams.type() == array_type) + if (valParams.isArray()) params = valParams.get_array(); - else if (valParams.type() == null_type) + else if (valParams.isNull()) params = Array(); else throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); @@ -910,15 +911,15 @@ static Object JSONRPCExecOne(const Value& req) jreq.parse(req); Value result = tableRPC.execute(jreq.strMethod, jreq.params); - rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id); + rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); } catch (const Object& objError) { - rpc_result = JSONRPCReplyObj(Value::null, objError, jreq.id); + rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); } catch (const std::exception& e) { - rpc_result = JSONRPCReplyObj(Value::null, + rpc_result = JSONRPCReplyObj(NullUniValue, JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); } @@ -931,7 +932,7 @@ static string JSONRPCExecBatch(const Array& vReq) for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) ret.push_back(JSONRPCExecOne(vReq[reqIdx])); - return write_string(Value(ret), false) + "\n"; + return ret.write() + "\n"; } static bool HTTPReq_JSONRPC(AcceptedConnection *conn, @@ -963,7 +964,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, { // Parse request Value valRequest; - if (!read_string(strRequest, valRequest)) + if (!valRequest.read(strRequest)) throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); // Return immediately if in warmup @@ -976,16 +977,16 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, string strReply; // singleton request - if (valRequest.type() == obj_type) { + if (valRequest.isObject()) { jreq.parse(valRequest); Value result = tableRPC.execute(jreq.strMethod, jreq.params); // Send reply - strReply = JSONRPCReply(result, Value::null, jreq.id); + strReply = JSONRPCReply(result, NullUniValue, jreq.id); // array of requests - } else if (valRequest.type() == array_type) + } else if (valRequest.isArray()) strReply = JSONRPCExecBatch(valRequest.get_array()); else throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error"); diff --git a/src/rpcserver.h b/src/rpcserver.h index fd53bf116..01c27685d 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -16,9 +16,8 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include +#include "json_spirit_wrapper.h" class AsyncRPCQueue; class CRPCCommand; @@ -79,12 +78,13 @@ bool RPCIsInWarmup(std::string *statusOut); */ void RPCTypeCheck(const json_spirit::Array& params, const std::list& typesExpected, bool fAllowNull=false); -/** - * Check for expected keys/value types in an Object. - * Use like: RPCTypeCheck(object, boost::assign::map_list_of("name", str_type)("value", int_type)); - */ -void RPCTypeCheck(const json_spirit::Object& o, - const std::map& typesExpected, bool fAllowNull=false); + +/* + Check for expected keys/value types in an Object. + Use like: RPCTypeCheckObj(object, boost::assign::map_list_of("name", str_type)("value", int_type)); +*/ +void RPCTypeCheckObj(const UniValue& o, + const std::map& typesExpected, bool fAllowNull=false); /** * Run func nSeconds from now. Uses boost deadline timers. diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index f07dd7a7d..a806fe7b0 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -17,9 +17,7 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; extern Array read_json(const std::string& jsondata); @@ -30,10 +28,9 @@ BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(base58_EncodeBase58) { Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -53,10 +50,9 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58) Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); std::vector result; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -130,10 +126,9 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) CBitcoinAddress addr; SelectParams(CBaseChainParams::MAIN); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -185,10 +180,10 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) { Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector result; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); @@ -256,10 +251,9 @@ BOOST_AUTO_TEST_CASE(base58_keys_invalid) CBitcoinSecret secret; CBitcoinAddress addr; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 16709dc80..cb882816b 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -117,20 +117,20 @@ BOOST_AUTO_TEST_CASE(rpc_rawsign) BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) { - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(0LL), false), "0.00000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(1LL), false), "0.00000001"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(17622195LL), false), "0.17622195"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(50000000LL), false), "0.50000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(89898989LL), false), "0.89898989"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(100000000LL), false), "1.00000000"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999990LL), false), "20999999.99999990"); - BOOST_CHECK_EQUAL(write_string(ValueFromAmount(2099999999999999LL), false), "20999999.99999999"); + BOOST_CHECK(ValueFromAmount(0LL).write() == "0.00000000"); + BOOST_CHECK(ValueFromAmount(1LL).write() == "0.00000001"); + BOOST_CHECK(ValueFromAmount(17622195LL).write() == "0.17622195"); + BOOST_CHECK(ValueFromAmount(50000000LL).write() == "0.50000000"); + BOOST_CHECK(ValueFromAmount(89898989LL).write() == "0.89898989"); + BOOST_CHECK(ValueFromAmount(100000000LL).write() == "1.00000000"); + BOOST_CHECK(ValueFromAmount(2099999999999990LL).write() == "20999999.99999990"); + BOOST_CHECK(ValueFromAmount(2099999999999999LL).write() == "20999999.99999999"); } static Value ValueFromString(const std::string &str) { Value value; - BOOST_CHECK(read_string(str, value)); + BOOST_CHECK(value.read(str)); return value; } diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index cb028dfbb..5bd37111e 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -26,9 +26,7 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" using namespace std; using namespace json_spirit; @@ -46,7 +44,7 @@ read_json(const std::string& jsondata) { Value v; - if (!read_string(jsondata, v) || v.type() != array_type) + if (!v.read(jsondata) || !v.isArray()) { BOOST_ERROR("Parse error."); return Array(); @@ -636,10 +634,9 @@ BOOST_AUTO_TEST_CASE(script_valid) // scripts. Array tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + string strTest = test.write(); if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) { if (test.size() != 1) { @@ -662,11 +659,10 @@ BOOST_AUTO_TEST_CASE(script_invalid) // Scripts that should evaluate as invalid Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + string strTest = test.write(); + if (test.size() < 3) // Allow size > 2; extra stuff ignored (useful for comments) { if (test.size() != 1) { BOOST_ERROR("Bad test: " << strTest); diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index c825a8bad..9e7556cc9 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -17,9 +17,7 @@ #include #include -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; extern Array read_json(const std::string& jsondata); @@ -207,10 +205,9 @@ BOOST_AUTO_TEST_CASE(sighash_from_data) { Array tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - std::string strTest = write_string(tv, false); + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { BOOST_ERROR("Bad test: " << strTest); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 64fa4b298..1cadd5745 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -25,7 +25,8 @@ #include #include #include -#include "json/json_spirit_writer_template.h" + +#include "json_spirit_wrapper.h" #include "zcash/Note.hpp" #include "zcash/Address.hpp" @@ -99,14 +100,21 @@ BOOST_AUTO_TEST_CASE(tx_valid) Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); auto verifier = libzcash::ProofVerifier::Strict(); +<<<<<<< HEAD ScriptError err; BOOST_FOREACH(Value& tv, tests) { Array test = tv.get_array(); string strTest = write_string(tv, false); if (test[0].type() == array_type) +======= + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + string strTest = test.write(); + if (test[0].isArray()) +>>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { - if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type) + if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { BOOST_ERROR("Bad test: " << strTest); continue; @@ -115,9 +123,9 @@ BOOST_AUTO_TEST_CASE(tx_valid) map mapprevOutScriptPubKeys; Array inputs = test[0].get_array(); bool fValid = true; - BOOST_FOREACH(Value& input, inputs) - { - if (input.type() != array_type) + for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { + const Value& input = inputs[inpIdx]; + if (!input.isArray()) { fValid = false; break; @@ -176,14 +184,21 @@ BOOST_AUTO_TEST_CASE(tx_invalid) Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); auto verifier = libzcash::ProofVerifier::Strict(); +<<<<<<< HEAD ScriptError err; BOOST_FOREACH(Value& tv, tests) { Array test = tv.get_array(); string strTest = write_string(tv, false); if (test[0].type() == array_type) +======= + for (unsigned int idx = 0; idx < tests.size(); idx++) { + Array test = tests[idx]; + string strTest = test.write(); + if (test[0].isArray()) +>>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { - if (test.size() != 3 || test[1].type() != str_type || test[2].type() != str_type) + if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { BOOST_ERROR("Bad test: " << strTest); continue; @@ -192,9 +207,9 @@ BOOST_AUTO_TEST_CASE(tx_invalid) map mapprevOutScriptPubKeys; Array inputs = test[0].get_array(); bool fValid = true; - BOOST_FOREACH(Value& input, inputs) - { - if (input.type() != array_type) + for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { + const Value& input = inputs[inpIdx]; + if (!input.isArray()) { fValid = false; break; diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index afe751ed9..28d6e3d3c 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -11,6 +11,10 @@ #include #include +#include // .get_int64() +#include // std::pair +#include // atoi(), atof() TODO: remove + class UniValue { public: enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; @@ -130,8 +134,88 @@ private: int findKey(const std::string& key) const; void writeArray(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; + +public: + // + // The following were added for compatibility with json_spirit. + // Most duplicate other methods, and should be removed. + // + std::vector getKeys() const { return keys; } + std::vector getValues() const { return values; } + bool get_bool() const { return getBool(); } + std::string get_str() const { return getValStr(); } + int get_int() const { return atoi(getValStr().c_str()); } + double get_real() const { return atof(getValStr().c_str()); } + const UniValue& get_obj() const { return *this; } + const UniValue& get_array() const { return *this; } + enum VType type() const { return getType(); } + bool push_back(std::pair pear) { + return pushKV(pear.first, pear.second); + } + int64_t get_int64() const { + int64_t ret; + std::istringstream(getValStr()) >> ret; + return ret; + } }; +// +// The following were added for compatibility with json_spirit. +// Most duplicate other methods, and should be removed. +// +static inline std::pair Pair(const char *cKey, const char *cVal) +{ + std::string key(cKey); + UniValue uVal(cVal); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, std::string strVal) +{ + std::string key(cKey); + UniValue uVal(strVal); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, uint64_t u64Val) +{ + std::string key(cKey); + UniValue uVal(u64Val); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, int64_t i64Val) +{ + std::string key(cKey); + UniValue uVal(i64Val); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, int iVal) +{ + std::string key(cKey); + UniValue uVal(iVal); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, double dVal) +{ + std::string key(cKey); + UniValue uVal(dVal); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(const char *cKey, const UniValue& uVal) +{ + std::string key(cKey); + return std::make_pair(key, uVal); +} + +static inline std::pair Pair(std::string key, const UniValue& uVal) +{ + return std::make_pair(key, uVal); +} + enum jtokentype { JTOK_ERR = -1, JTOK_NONE = 0, // eof diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 41f3f670f..2f1564dca 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -19,7 +19,7 @@ #include #include -#include "json/json_spirit_value.h" +#include "json_spirit_wrapper.h" using namespace json_spirit; using namespace std; @@ -130,7 +130,7 @@ Value importprivkey(const Array& params, bool fHelp) // Don't throw error in case a key is already there if (pwalletMain->HaveKey(vchAddress)) - return Value::null; + return NullUniValue; pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; @@ -145,7 +145,7 @@ Value importprivkey(const Array& params, bool fHelp) } } - return Value::null; + return NullUniValue; } Value importaddress(const Array& params, bool fHelp) @@ -204,7 +204,7 @@ Value importaddress(const Array& params, bool fHelp) // Don't throw error in case an address is already there if (pwalletMain->HaveWatchOnly(script)) - return Value::null; + return NullUniValue; pwalletMain->MarkDirty(); @@ -218,7 +218,7 @@ Value importaddress(const Array& params, bool fHelp) } } - return Value::null; + return NullUniValue; } Value z_importwallet(const Array& params, bool fHelp) @@ -378,7 +378,7 @@ Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys) if (!fGood) throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet"); - return Value::null; + return NullUniValue; } Value dumpprivkey(const Array& params, bool fHelp) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index b3ec08463..07fccad36 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -22,6 +22,7 @@ #include "utiltime.h" #include "asyncrpcoperation.h" +#include "asyncrpcqueue.h" #include "wallet/asyncrpcoperation_sendmany.h" #include "sodium.h" @@ -30,9 +31,7 @@ #include -#include "json/json_spirit_utils.h" -#include "json/json_spirit_value.h" -#include "asyncrpcqueue.h" +#include "json_spirit_wrapper.h" #include @@ -294,7 +293,7 @@ Value setaccount(const Array& params, bool fHelp) else throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address"); - return Value::null; + return NullUniValue; } @@ -438,9 +437,9 @@ Value sendtoaddress(const Array& params, bool fHelp) // Wallet comments CWalletTx wtx; - if (params.size() > 2 && params[2].type() != null_type && !params[2].get_str().empty()) + if (params.size() > 2 && !params[2].isNull() && !params[2].get_str().empty()) wtx.mapValue["comment"] = params[2].get_str(); - if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["to"] = params[3].get_str(); bool fSubtractFeeFromAmount = false; @@ -911,9 +910,9 @@ Value sendfrom(const Array& params, bool fHelp) CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 4 && params[4].type() != null_type && !params[4].get_str().empty()) + if (params.size() > 4 && !params[4].isNull() && !params[4].get_str().empty()) wtx.mapValue["comment"] = params[4].get_str(); - if (params.size() > 5 && params[5].type() != null_type && !params[5].get_str().empty()) + if (params.size() > 5 && !params[5].isNull() && !params[5].get_str().empty()) wtx.mapValue["to"] = params[5].get_str(); EnsureWalletIsUnlocked(); @@ -980,7 +979,7 @@ Value sendmany(const Array& params, bool fHelp) CWalletTx wtx; wtx.strFromAccount = strAccount; - if (params.size() > 3 && params[3].type() != null_type && !params[3].get_str().empty()) + if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); Array subtractFeeFromAmount; @@ -991,18 +990,19 @@ Value sendmany(const Array& params, bool fHelp) vector vecSend; CAmount totalAmount = 0; - BOOST_FOREACH(const Pair& s, sendTo) + vector keys = sendTo.getKeys(); + BOOST_FOREACH(const string& name_, keys) { - CBitcoinAddress address(s.name_); + CBitcoinAddress address(name_); if (!address.IsValid()) - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+name_); if (setAddress.count(address)) - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_); + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+name_); setAddress.insert(address); CScript scriptPubKey = GetScriptForDestination(address.Get()); - CAmount nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(sendTo[name_]); totalAmount += nAmount; bool fSubtractFeeFromAmount = false; @@ -1490,15 +1490,21 @@ Value listtransactions(const Array& params, bool fHelp) nFrom = ret.size(); if ((nFrom + nCount) > (int)ret.size()) nCount = ret.size() - nFrom; - Array::iterator first = ret.begin(); + + vector arrTmp = ret.getValues(); + + vector::iterator first = arrTmp.begin(); std::advance(first, nFrom); - Array::iterator last = ret.begin(); + vector::iterator last = arrTmp.begin(); std::advance(last, nFrom+nCount); - if (last != ret.end()) ret.erase(last, ret.end()); - if (first != ret.begin()) ret.erase(ret.begin(), first); + if (last != arrTmp.end()) arrTmp.erase(last, arrTmp.end()); + if (first != arrTmp.begin()) arrTmp.erase(arrTmp.begin(), first); - std::reverse(ret.begin(), ret.end()); // Return oldest to newest + std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest + + ret.clear(); + ret.push_backV(arrTmp); return ret; } @@ -1839,7 +1845,7 @@ Value keypoolrefill(const Array& params, bool fHelp) if (pwalletMain->GetKeyPoolSize() < kpSize) throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); - return Value::null; + return NullUniValue; } @@ -1908,7 +1914,7 @@ Value walletpassphrase(const Array& params, bool fHelp) nWalletUnlockTime = GetTime() + nSleepTime; RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime); - return Value::null; + return NullUniValue; } @@ -1954,7 +1960,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass)) throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect."); - return Value::null; + return NullUniValue; } @@ -1993,7 +1999,7 @@ Value walletlock(const Array& params, bool fHelp) nWalletUnlockTime = 0; } - return Value::null; + return NullUniValue; } @@ -2109,9 +2115,9 @@ Value lockunspent(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); if (params.size() == 1) - RPCTypeCheck(params, boost::assign::list_of(bool_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)); else - RPCTypeCheck(params, boost::assign::list_of(bool_type)(array_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VBOOL)(UniValue::VARR)); bool fUnlock = params[0].get_bool(); @@ -2122,13 +2128,13 @@ Value lockunspent(const Array& params, bool fHelp) } Array outputs = params[1].get_array(); - BOOST_FOREACH(Value& output, outputs) - { - if (output.type() != obj_type) + for (unsigned int idx = 0; idx < outputs.size(); idx++) { + const UniValue& output = outputs[idx]; + if (!output.isObject()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); const Object& o = output.get_obj(); - RPCTypeCheck(o, boost::assign::map_list_of("txid", str_type)("vout", int_type)); + RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)); string txid = find_value(o, "txid").get_str(); if (!IsHex(txid)) From 9756b7bd2997a633c8dad1fafe9aaa53e982a9e4 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 13:35:44 +0200 Subject: [PATCH 04/26] extend conversion to UniValue --- src/Makefile.am | 1 + src/bitcoin-cli.cpp | 2 +- src/rest.cpp | 9 ++-- src/rpcblockchain.cpp | 4 +- src/rpcclient.cpp | 2 +- src/rpcmining.cpp | 4 +- src/rpcmisc.cpp | 4 +- src/rpcprotocol.cpp | 6 +-- src/rpcrawtransaction.cpp | 7 +-- src/test/script_tests.cpp | 14 +++--- src/test/transaction_tests.cpp | 1 + src/wallet/rpcdump.cpp | 10 ++--- src/wallet/rpcwallet.cpp | 81 ++++++++++++++++++---------------- 13 files changed, 76 insertions(+), 69 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 34434b8ab..c639e860b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -117,6 +117,7 @@ BITCOIN_CORE_H = \ ecwrapper.h \ hash.h \ init.h \ + json_spirit_wrapper.h \ key.h \ keystore.h \ leveldbwrapper.h \ diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 03a727719..4b4781fbf 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -152,7 +152,7 @@ Object CallRPC(const string& strMethod, const Array& params) throw runtime_error("no response from server"); // Parse reply - Value valReply; + Value valReply(UniValue::VSTR); if (!valReply.read(strReply)) throw runtime_error("couldn't parse reply from server"); const Object& reply = valReply.get_obj(); diff --git a/src/rest.cpp b/src/rest.cpp index 7c238d506..5f64a0091 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -222,7 +222,7 @@ static bool rest_block(AcceptedConnection* conn, case RF_JSON: { Object objBlock = blockToJSON(block, pblockindex, showTxDetails); - string strJSON = write_string(Value(objBlock), false) + "\n"; + string strJSON = objBlock.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -267,8 +267,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, case RF_JSON: { Array rpcParams; Value chainInfoObject = getblockchaininfo(rpcParams, false); - - string strJSON = write_string(chainInfoObject, false) + "\n"; + string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -319,7 +318,7 @@ static bool rest_tx(AcceptedConnection* conn, case RF_JSON: { Object objTx; TxToJSON(tx, hashBlock, objTx); - string strJSON = write_string(Value(objTx), false) + "\n"; + string strJSON = objTx.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } @@ -516,7 +515,7 @@ static bool rest_getutxos(AcceptedConnection* conn, objGetUTXOResponse.push_back(Pair("utxos", utxos)); // return json string - string strJSON = write_string(Value(objGetUTXOResponse), false) + "\n"; + string strJSON = objGetUTXOResponse.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index d97b05049..9aa60d44d 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -757,7 +757,7 @@ Value invalidateblock(const Array& params, bool fHelp) throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); } - return Value::null; + return NullUniValue; } Value reconsiderblock(const Array& params, bool fHelp) @@ -796,5 +796,5 @@ Value reconsiderblock(const Array& params, bool fHelp) throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason()); } - return Value::null; + return NullUniValue; } diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 60ff66a1e..19b338f66 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -138,7 +138,7 @@ static CRPCConvertTable rpcCvtTable; /** Convert strings to command-specific RPC representation */ Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { - Array params; + UniValue params(UniValue::VARR); for (unsigned int idx = 0; idx < strParams.size(); idx++) { const std::string& strVal = strParams[idx]; diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index f8357f773..b112b3cae 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -522,7 +522,7 @@ Value getblocktemplate(const Array& params, bool fHelp) if (strMode == "proposal") { const Value& dataval = find_value(oparam, "data"); - if (dataval.type() != str_type) + if (dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; @@ -646,7 +646,7 @@ Value getblocktemplate(const Array& params, bool fHelp) UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nNonce = uint256(); - static const Array aCaps = boost::assign::list_of("proposal"); + Array aCaps; aCaps.push_back("proposal"); Value txCoinbase = Value::null; Array transactions; diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 647643350..5d67b1219 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -454,8 +454,8 @@ Value setmocktime(const Array& params, bool fHelp) LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(int_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)); SetMockTime(params[0].get_int64()); - return Value::null; + return NullUniValue; } diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index bdea60410..a095a45b6 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -258,7 +258,7 @@ int ReadHTTPMessage(std::basic_istream& stream, map setTxids; uint256 oneTxid; Array txids = params[0].get_array(); - BOOST_FOREACH(Value& txid, txids) { + for (unsigned int idx = 0; idx < txids.size(); idx++) { + const Value& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str()); uint256 hash(uint256S(txid.get_str())); @@ -559,7 +560,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) if (!DecodeHexTx(tx, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); - Object result; + UniValue result(UniValue::VOBJ); TxToJSON(tx, uint256(), result); return result; @@ -591,7 +592,7 @@ Value decodescript(const Array& params, bool fHelp) ); LOCK(cs_main); - RPCTypeCheck(params, boost::assign::list_of(str_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); Object r; CScript script; diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 5bd37111e..fc6b44951 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -583,11 +583,13 @@ BOOST_AUTO_TEST_CASE(script_build) Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - BOOST_FOREACH(Value& tv, json_good) { - tests_good.insert(write_string(Value(tv.get_array()), true)); + for (unsigned int idx = 0; idx < json_good.size(); idx++) { + const Value& tv = json_good[idx]; + tests_good.insert(tv.get_array().write()); } - BOOST_FOREACH(Value& tv, json_bad) { - tests_bad.insert(write_string(Value(tv.get_array()), true)); + for (unsigned int idx = 0; idx < json_bad.size(); idx++) { + const Value& tv = json_bad[idx]; + tests_bad.insert(tv.get_array().write()); } } @@ -596,7 +598,7 @@ BOOST_AUTO_TEST_CASE(script_build) BOOST_FOREACH(TestBuilder& test, good) { test.Test(true); - std::string str = write_string(Value(test.GetJSON()), true); + std::string str = test.GetJSON().write(); #ifndef UPDATE_JSON_TESTS if (tests_good.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment()); @@ -606,7 +608,7 @@ BOOST_AUTO_TEST_CASE(script_build) } BOOST_FOREACH(TestBuilder& test, bad) { test.Test(false); - std::string str = write_string(Value(test.GetJSON()), true); + std::string str = test.GetJSON().write(); #ifndef UPDATE_JSON_TESTS if (tests_bad.count(str) == 0) { BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment()); diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 1cadd5745..8e21a98ff 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -23,6 +23,7 @@ #include #include +#include #include #include diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 2f1564dca..f80c18637 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -77,7 +77,7 @@ std::string DecodeDumpString(const std::string &str) { Value importprivkey(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( @@ -151,7 +151,7 @@ Value importprivkey(const Array& params, bool fHelp) Value importaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( @@ -247,7 +247,7 @@ Value z_importwallet(const Array& params, bool fHelp) Value importwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -384,7 +384,7 @@ Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys) Value dumpprivkey(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -444,7 +444,7 @@ Value z_exportwallet(const Array& params, bool fHelp) Value dumpwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 07fccad36..2defd4b59 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -110,7 +110,7 @@ string AccountFromValue(const Value& value) Value getnewaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -187,7 +187,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) Value getaccountaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -219,7 +219,7 @@ Value getaccountaddress(const Array& params, bool fHelp) Value getrawchangeaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -254,7 +254,7 @@ Value getrawchangeaddress(const Array& params, bool fHelp) Value setaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -300,7 +300,7 @@ Value setaccount(const Array& params, bool fHelp) Value getaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -332,7 +332,7 @@ Value getaccount(const Array& params, bool fHelp) Value getaddressesbyaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -400,7 +400,7 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr Value sendtoaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( @@ -456,7 +456,7 @@ Value sendtoaddress(const Array& params, bool fHelp) Value listaddressgroupings(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp) throw runtime_error( @@ -507,7 +507,7 @@ Value listaddressgroupings(const Array& params, bool fHelp) Value signmessage(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 2) throw runtime_error( @@ -563,7 +563,7 @@ Value signmessage(const Array& params, bool fHelp) Value getreceivedbyaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -621,7 +621,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) Value getreceivedbyaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -710,7 +710,7 @@ CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminef Value getbalance(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -782,7 +782,7 @@ Value getbalance(const Array& params, bool fHelp) Value getunconfirmedbalance(const Array ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 0) throw runtime_error( @@ -798,7 +798,7 @@ Value getunconfirmedbalance(const Array ¶ms, bool fHelp) Value movecmd(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 3 || params.size() > 5) throw runtime_error( @@ -868,7 +868,7 @@ Value movecmd(const Array& params, bool fHelp) Value sendfrom(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 3 || params.size() > 6) throw runtime_error( @@ -931,7 +931,7 @@ Value sendfrom(const Array& params, bool fHelp) Value sendmany(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 5) throw runtime_error( @@ -1006,9 +1006,11 @@ Value sendmany(const Array& params, bool fHelp) totalAmount += nAmount; bool fSubtractFeeFromAmount = false; - BOOST_FOREACH(const Value& addr, subtractFeeFromAmount) - if (addr.get_str() == s.name_) + for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) { + const Value& addr = subtractFeeFromAmount[idx]; + if (addr.get_str() == name_) fSubtractFeeFromAmount = true; + } CRecipient recipient = {scriptPubKey, nAmount, fSubtractFeeFromAmount}; vecSend.push_back(recipient); @@ -1041,7 +1043,7 @@ extern CScript _createmultisig_redeemScript(const Array& params); Value addmultisigaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 3) { @@ -1222,7 +1224,7 @@ Value ListReceived(const Array& params, bool fByAccounts) Value listreceivedbyaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -1259,7 +1261,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) Value listreceivedbyaccount(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -1391,7 +1393,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar Value listtransactions(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 4) throw runtime_error( @@ -1512,7 +1514,7 @@ Value listtransactions(const Array& params, bool fHelp) Value listaccounts(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 2) throw runtime_error( @@ -1592,7 +1594,7 @@ Value listaccounts(const Array& params, bool fHelp) Value listsinceblock(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp) throw runtime_error( @@ -1683,7 +1685,7 @@ Value listsinceblock(const Array& params, bool fHelp) Value gettransaction(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -1772,7 +1774,7 @@ Value gettransaction(const Array& params, bool fHelp) Value backupwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -1815,7 +1817,7 @@ Value backupwallet(const Array& params, bool fHelp) Value keypoolrefill(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -1859,7 +1861,7 @@ static void LockWallet(CWallet* pWallet) Value walletpassphrase(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( @@ -1921,7 +1923,7 @@ Value walletpassphrase(const Array& params, bool fHelp) Value walletpassphrasechange(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 2)) throw runtime_error( @@ -1967,7 +1969,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) Value walletlock(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (pwalletMain->IsCrypted() && (fHelp || params.size() != 0)) throw runtime_error( @@ -2006,7 +2008,7 @@ Value walletlock(const Array& params, bool fHelp) Value encryptwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; auto fEnableWalletEncryption = fExperimentalMode && GetBoolArg("-developerencryptwallet", false); @@ -2074,7 +2076,7 @@ Value encryptwallet(const Array& params, bool fHelp) Value lockunspent(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -2158,7 +2160,7 @@ Value lockunspent(const Array& params, bool fHelp) Value listlockunspent(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 0) throw runtime_error( @@ -2207,7 +2209,7 @@ Value listlockunspent(const Array& params, bool fHelp) Value settxfee(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( @@ -2236,7 +2238,7 @@ Value settxfee(const Array& params, bool fHelp) Value getwalletinfo(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 0) throw runtime_error( @@ -2276,7 +2278,7 @@ Value getwalletinfo(const Array& params, bool fHelp) Value resendwallettransactions(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 0) throw runtime_error( @@ -2301,7 +2303,7 @@ Value resendwallettransactions(const Array& params, bool fHelp) Value listunspent(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 3) throw runtime_error( @@ -2339,7 +2341,7 @@ Value listunspent(const Array& params, bool fHelp) + HelpExampleRpc("listunspent", "6, 9999999 \"[\\\"1PGFqEzfmQch1gKD3ra4k18PNj3tTUUSqg\\\",\\\"1LtvqCaApEdUGFkpKMM4MstjcaL4dKg8SP\\\"]\"") ); - RPCTypeCheck(params, boost::assign::list_of(int_type)(int_type)(array_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM)(UniValue::VNUM)(UniValue::VARR)); int nMinDepth = 1; if (params.size() > 0) @@ -2352,7 +2354,8 @@ Value listunspent(const Array& params, bool fHelp) set setAddress; if (params.size() > 2) { Array inputs = params[2].get_array(); - BOOST_FOREACH(Value& input, inputs) { + for (unsigned int idx = 0; idx < inputs.size(); idx++) { + const Value& input = inputs[idx]; CBitcoinAddress address(input.get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+input.get_str()); From 38fc4b7090f28ec282c0fe127f4339c489d72775 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 14:48:35 +0200 Subject: [PATCH 05/26] expicit set UniValue type to avoid empty values --- src/rest.cpp | 12 ++++----- src/rpcblockchain.cpp | 26 ++++++++++---------- src/rpcmining.cpp | 20 +++++++-------- src/rpcmisc.cpp | 12 ++++----- src/rpcnet.cpp | 32 ++++++++++++------------ src/rpcrawtransaction.cpp | 26 ++++++++++---------- src/rpcserver.cpp | 2 +- src/test/rpc_tests.cpp | 4 +-- src/test/script_tests.cpp | 2 +- src/wallet/rpcwallet.cpp | 51 ++++++++++++++++++++------------------- 10 files changed, 94 insertions(+), 93 deletions(-) diff --git a/src/rest.cpp b/src/rest.cpp index 5f64a0091..f3195746b 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -265,7 +265,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, switch (rf) { case RF_JSON: { - Array rpcParams; + UniValue rpcParams(UniValue::VARR); Value chainInfoObject = getblockchaininfo(rpcParams, false); string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; @@ -316,7 +316,7 @@ static bool rest_tx(AcceptedConnection* conn, } case RF_JSON: { - Object objTx; + UniValue objTx(UniValue::VOBJ); TxToJSON(tx, hashBlock, objTx); string strJSON = objTx.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; @@ -491,7 +491,7 @@ static bool rest_getutxos(AcceptedConnection* conn, } case RF_JSON: { - Object objGetUTXOResponse; + UniValue objGetUTXOResponse(UniValue::VOBJ); // pack in some essentials // use more or less the same output as mentioned in Bip64 @@ -499,15 +499,15 @@ static bool rest_getutxos(AcceptedConnection* conn, objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex())); objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation)); - Array utxos; + UniValue utxos(UniValue::VARR); BOOST_FOREACH (const CCoin& coin, outs) { - Object utxo; + UniValue utxo(UniValue::VOBJ); utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer)); utxo.push_back(Pair("height", (int32_t)coin.nHeight)); utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue))); // include the script in a json output - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true); utxo.push_back(Pair("scriptPubKey", o)); utxos.push_back(utxo); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 9aa60d44d..485d022b5 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -76,7 +76,7 @@ double GetNetworkDifficulty(const CBlockIndex* blockindex) Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hash", block.GetHash().GetHex())); int confirmations = -1; // Only report confirmations if the block is on the main chain @@ -87,12 +87,12 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe result.push_back(Pair("height", blockindex->nHeight)); result.push_back(Pair("version", block.nVersion)); result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex())); - Array txs; + UniValue txs(UniValue::VARR); BOOST_FOREACH(const CTransaction&tx, block.vtx) { if(txDetails) { - Object objTx; + UniValue objTx(UniValue::VOBJ); TxToJSON(tx, uint256(), objTx); txs.push_back(objTx); } @@ -209,12 +209,12 @@ Value getrawmempool(const Array& params, bool fHelp) if (fVerbose) { LOCK(mempool.cs); - Object o; + UniValue o(UniValue::VOBJ); BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx) { const uint256& hash = entry.first; const CTxMemPoolEntry& e = entry.second; - Object info; + UniValue info(UniValue::VOBJ); info.push_back(Pair("size", (int)e.GetTxSize())); info.push_back(Pair("fee", ValueFromAmount(e.GetFee()))); info.push_back(Pair("time", e.GetTime())); @@ -245,7 +245,7 @@ Value getrawmempool(const Array& params, bool fHelp) vector vtxid; mempool.queryHashes(vtxid); - Array a; + UniValue a(UniValue::VARR); BOOST_FOREACH(const uint256& hash, vtxid) a.push_back(hash.ToString()); @@ -370,7 +370,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) LOCK(cs_main); - Object ret; + UniValue ret(UniValue::VOBJ); CCoinsStats stats; FlushStateToDisk(); @@ -426,7 +426,7 @@ Value gettxout(const Array& params, bool fHelp) LOCK(cs_main); - Object ret; + UniValue ret(UniValue::VOBJ); std::string strHash = params[0].get_str(); uint256 hash(uint256S(strHash)); @@ -457,7 +457,7 @@ Value gettxout(const Array& params, bool fHelp) else ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1)); ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue))); - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true); ret.push_back(Pair("scriptPubKey", o)); ret.push_back(Pair("version", coins.nVersion)); @@ -561,7 +561,7 @@ Value getblockchaininfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("chain", Params().NetworkIDString())); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1)); @@ -661,10 +661,10 @@ Value getchaintips(const Array& params, bool fHelp) setTips.insert(chainActive.Tip()); /* Construct the output array. */ - Array res; + UniValue res(UniValue::VARR); BOOST_FOREACH(const CBlockIndex* block, setTips) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("height", block->nHeight)); obj.push_back(Pair("hash", block->phashBlock->GetHex())); @@ -715,7 +715,7 @@ Value getmempoolinfo(const Array& params, bool fHelp) + HelpExampleRpc("getmempoolinfo", "") ); - Object ret; + UniValue ret; ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index b112b3cae..4240a167f 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -201,7 +201,7 @@ Value generate(const Array& params, bool fHelp) nHeightEnd = nHeightStart+nGenerate; } unsigned int nExtraNonce = 0; - Array blockHashes; + UniValue blockHashes(UniValue::VARR); unsigned int n = Params().EquihashN(); unsigned int k = Params().EquihashK(); while (nHeight < nHeightEnd) @@ -355,7 +355,7 @@ Value getmininginfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("blocks", (int)chainActive.Height())); obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize)); obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx)); @@ -646,10 +646,10 @@ Value getblocktemplate(const Array& params, bool fHelp) UpdateTime(pblock, Params().GetConsensus(), pindexPrev); pblock->nNonce = uint256(); - Array aCaps; aCaps.push_back("proposal"); + UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); - Value txCoinbase = Value::null; - Array transactions; + Value txCoinbase = NullUniValue; + UniValue transactions(UniValue::VARR); map setTxIndex; int i = 0; BOOST_FOREACH (CTransaction& tx, pblock->vtx) @@ -660,13 +660,13 @@ Value getblocktemplate(const Array& params, bool fHelp) if (tx.IsCoinBase() && !coinbasetxn) continue; - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("data", EncodeHexTx(tx))); entry.push_back(Pair("hash", txHash.GetHex())); - Array deps; + UniValue deps(UniValue::VARR); BOOST_FOREACH (const CTxIn &in, tx.vin) { if (setTxIndex.count(in.prevout.hash)) @@ -691,12 +691,12 @@ Value getblocktemplate(const Array& params, bool fHelp) } } - Object aux; + UniValue aux(UniValue::VOBJ); aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end()))); arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits); - static Array aMutable; + static UniValue aMutable(UniValue::VARR); if (aMutable.empty()) { aMutable.push_back("time"); @@ -704,7 +704,7 @@ Value getblocktemplate(const Array& params, bool fHelp) aMutable.push_back("prevblock"); } - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("capabilities", aCaps)); result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 5d67b1219..898083379 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -79,7 +79,7 @@ Value getinfo(const Array& params, bool fHelp) proxyType proxy; GetProxy(NET_IPV4, proxy); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("protocolversion", PROTOCOL_VERSION)); #ifdef ENABLE_WALLET @@ -120,7 +120,7 @@ public: Object operator()(const CNoDestination &dest) const { return Object(); } Object operator()(const CKeyID &keyID) const { - Object obj; + UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; obj.push_back(Pair("isscript", false)); if (mine == ISMINE_SPENDABLE) { @@ -132,7 +132,7 @@ public: } Object operator()(const CScriptID &scriptID) const { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("isscript", true)); if (mine != ISMINE_NO) { CScript subscript; @@ -143,7 +143,7 @@ public: ExtractDestinations(subscript, whichType, addresses, nRequired); obj.push_back(Pair("script", GetTxnOutputType(whichType))); obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end()))); - Array a; + UniValue a(UniValue::VARR); BOOST_FOREACH(const CTxDestination& addr, addresses) a.push_back(CBitcoinAddress(addr).ToString()); obj.push_back(Pair("addresses", a)); @@ -188,7 +188,7 @@ Value validateaddress(const Array& params, bool fHelp) CBitcoinAddress address(params[0].get_str()); bool isValid = address.IsValid(); - Object ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("isvalid", isValid)); if (isValid) { @@ -377,7 +377,7 @@ Value createmultisig(const Array& params, bool fHelp) CScriptID innerID(inner); CBitcoinAddress address(innerID); - Object result; + UniValue result; result.push_back(Pair("address", address.ToString())); result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index d8b2f6101..1cf17484e 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -120,10 +120,10 @@ Value getpeerinfo(const Array& params, bool fHelp) vector vstats; CopyNodeStats(vstats); - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(const CNodeStats& stats, vstats) { - Object obj; + UniValue obj(UniValue::VOBJ); CNodeStateStats statestats; bool fStateStats = GetNodeStateStats(stats.nodeid, statestats); obj.push_back(Pair("id", stats.nodeid)); @@ -151,7 +151,7 @@ Value getpeerinfo(const Array& params, bool fHelp) obj.push_back(Pair("banscore", statestats.nMisbehavior)); obj.push_back(Pair("synced_headers", statestats.nSyncHeight)); obj.push_back(Pair("synced_blocks", statestats.nCommonHeight)); - Array heights; + UniValue heights(UniValue::VARR); BOOST_FOREACH(int height, statestats.vHeightInFlight) { heights.push_back(height); } @@ -271,12 +271,12 @@ Value getaddednodeinfo(const Array& params, bool fHelp) throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added."); } - Array ret; + UniValue ret(UniValue::VARR); if (!fDns) { BOOST_FOREACH(string& strAddNode, laddedNodes) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", strAddNode)); ret.push_back(obj); } @@ -291,10 +291,10 @@ Value getaddednodeinfo(const Array& params, bool fHelp) laddedAddreses.push_back(make_pair(strAddNode, vservNode)); else { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", strAddNode)); obj.push_back(Pair("connected", false)); - Array addresses; + UniValue addresses(UniValue::VARR); obj.push_back(Pair("addresses", addresses)); } } @@ -302,15 +302,15 @@ Value getaddednodeinfo(const Array& params, bool fHelp) LOCK(cs_vNodes); for (list > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("addednode", it->first)); - Array addresses; + UniValue addresses(UniValue::VARR); bool fConnected = false; BOOST_FOREACH(CService& addrNode, it->second) { bool fFound = false; - Object node; + UniValue node(UniValue::VOBJ); node.push_back(Pair("address", addrNode.ToString())); BOOST_FOREACH(CNode* pnode, vNodes) if (pnode->addr == addrNode) @@ -350,7 +350,7 @@ Value getnettotals(const Array& params, bool fHelp) + HelpExampleRpc("getnettotals", "") ); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv())); obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent())); obj.push_back(Pair("timemillis", GetTimeMillis())); @@ -359,14 +359,14 @@ Value getnettotals(const Array& params, bool fHelp) static Array GetNetworksInfo() { - Array networks; + UniValue networks(UniValue::VARR); for(int n=0; n(n); if(network == NET_UNROUTABLE) continue; proxyType proxy; - Object obj; + UniValue obj(UniValue::VOBJ); GetProxy(network, proxy); obj.push_back(Pair("name", GetNetworkName(network))); obj.push_back(Pair("limited", IsLimited(network))); @@ -418,7 +418,7 @@ Value getnetworkinfo(const Array& params, bool fHelp) LOCK(cs_main); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("version", CLIENT_VERSION)); obj.push_back(Pair("subversion", FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector()))); @@ -428,12 +428,12 @@ Value getnetworkinfo(const Array& params, bool fHelp) obj.push_back(Pair("connections", (int)vNodes.size())); obj.push_back(Pair("networks", GetNetworksInfo())); obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK()))); - Array localAddresses; + UniValue localAddresses(UniValue::VARR); { LOCK(cs_mapLocalHost); BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost) { - Object rec; + UniValue rec(UniValue::VOBJ); rec.push_back(Pair("address", item.first.ToString())); rec.push_back(Pair("port", item.second.nPort)); rec.push_back(Pair("score", item.second.nScore)); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 5367f3d87..b873b904f 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -48,7 +48,7 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeH out.push_back(Pair("reqSigs", nRequired)); out.push_back(Pair("type", GetTxnOutputType(type))); - Array a; + UniValue a(UniValue::VARR); BOOST_FOREACH(const CTxDestination& addr, addresses) a.push_back(CBitcoinAddress(addr).ToString()); out.push_back(Pair("addresses", a)); @@ -115,15 +115,15 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); entry.push_back(Pair("locktime", (int64_t)tx.nLockTime)); - Array vin; + UniValue vin(UniValue::VARR); BOOST_FOREACH(const CTxIn& txin, tx.vin) { - Object in; + UniValue in(UniValue::VOBJ); if (tx.IsCoinBase()) in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); else { in.push_back(Pair("txid", txin.prevout.hash.GetHex())); in.push_back(Pair("vout", (int64_t)txin.prevout.n)); - Object o; + UniValue o(UniValue::VOBJ); o.push_back(Pair("asm", txin.scriptSig.ToString())); o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); in.push_back(Pair("scriptSig", o)); @@ -132,13 +132,13 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) vin.push_back(in); } entry.push_back(Pair("vin", vin)); - Array vout; + UniValue vout(UniValue::VARR); for (unsigned int i = 0; i < tx.vout.size(); i++) { const CTxOut& txout = tx.vout[i]; - Object out; + UniValue out(UniValue::VOBJ); out.push_back(Pair("value", ValueFromAmount(txout.nValue))); out.push_back(Pair("n", (int64_t)i)); - Object o; + UniValue o(UniValue::VOBJ); ScriptPubKeyToJSON(txout.scriptPubKey, o, true); out.push_back(Pair("scriptPubKey", o)); vout.push_back(out); @@ -275,7 +275,7 @@ Value getrawtransaction(const Array& params, bool fHelp) if (!fVerbose) return strHex; - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", strHex)); TxToJSON(tx, hashBlock, result); return result; @@ -379,7 +379,7 @@ Value verifytxoutproof(const Array& params, bool fHelp) CMerkleBlock merkleBlock; ssMB >> merkleBlock; - Array res; + UniValue res(UniValue::VARR); vector vMatch; if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot) @@ -594,7 +594,7 @@ Value decodescript(const Array& params, bool fHelp) LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)); - Object r; + UniValue r(UniValue::VOBJ); CScript script; if (params[0].get_str().size() > 0){ vector scriptData(ParseHexV(params[0], "argument")); @@ -611,7 +611,7 @@ Value decodescript(const Array& params, bool fHelp) /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */ static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage) { - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", txin.prevout.hash.ToString())); entry.push_back(Pair("vout", (uint64_t)txin.prevout.n)); entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end()))); @@ -824,7 +824,7 @@ Value signrawtransaction(const Array& params, bool fHelp) bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); // Script verification errors - Array vErrors; + UniValue vErrors(UniValue::VARR); // Sign what we can: for (unsigned int i = 0; i < mergedTx.vin.size(); i++) { @@ -852,7 +852,7 @@ Value signrawtransaction(const Array& params, bool fHelp) } bool fComplete = vErrors.empty(); - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("hex", EncodeHexTx(mergedTx))); result.push_back(Pair("complete", fComplete)); if (!vErrors.empty()) { diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 8284e9932..336f7edf9 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -904,7 +904,7 @@ void JSONRequest::parse(const Value& valRequest) static Object JSONRPCExecOne(const Value& req) { - Object rpc_result; + UniValue rpc_result(UniValue::VOBJ); JSONRequest jreq; try { diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index cb882816b..4bb5334d0 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -19,9 +19,9 @@ using namespace json_spirit; Array createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) { - Array result; + UniValue result(UniValue::VARR); result.push_back(nRequired); - Array addresses; + UniValue addresses(UniValue::VARR); if (address1) addresses.push_back(address1); if (address2) addresses.push_back(address2); result.push_back(addresses); diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index fc6b44951..f3f3ffa2d 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -296,7 +296,7 @@ public: Array GetJSON() { DoPush(); - Array array; + UniValue array(UniValue::VARR); array.push_back(FormatScript(spendTx.vin[0].scriptSig)); array.push_back(FormatScript(creditTx.vout[0].scriptPubKey)); array.push_back(FormatScriptFlags(flags)); diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 2defd4b59..14e8cb2c1 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -87,7 +87,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) } uint256 hash = wtx.GetHash(); entry.push_back(Pair("txid", hash.GetHex())); - Array conflicts; + UniValue conflicts(UniValue::VARR); BOOST_FOREACH(const uint256& conflict, wtx.GetConflicts()) conflicts.push_back(conflict.GetHex()); entry.push_back(Pair("walletconflicts", conflicts)); @@ -355,7 +355,7 @@ Value getaddressesbyaccount(const Array& params, bool fHelp) string strAccount = AccountFromValue(params[0]); // Find all addresses that have the given account - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) { const CBitcoinAddress& address = item.first; @@ -483,14 +483,14 @@ Value listaddressgroupings(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - Array jsonGroupings; + UniValue jsonGroupings(UniValue::VARR); map balances = pwalletMain->GetAddressBalances(); BOOST_FOREACH(set grouping, pwalletMain->GetAddressGroupings()) { - Array jsonGrouping; + UniValue jsonGrouping(UniValue::VARR); BOOST_FOREACH(CTxDestination address, grouping) { - Array addressInfo; + UniValue addressInfo(UniValue::VARR); addressInfo.push_back(CBitcoinAddress(address).ToString()); addressInfo.push_back(ValueFromAmount(balances[address])); { @@ -982,7 +982,7 @@ Value sendmany(const Array& params, bool fHelp) if (params.size() > 3 && !params[3].isNull() && !params[3].get_str().empty()) wtx.mapValue["comment"] = params[3].get_str(); - Array subtractFeeFromAmount; + UniValue subtractFeeFromAmount(UniValue::VARR); if (params.size() > 4) subtractFeeFromAmount = params[4].get_array(); @@ -1153,7 +1153,7 @@ Value ListReceived(const Array& params, bool fByAccounts) } // Reply - Array ret; + UniValue ret(UniValue::VARR); map mapAccountTally; BOOST_FOREACH(const PAIRTYPE(CBitcoinAddress, CAddressBookData)& item, pwalletMain->mapAddressBook) { @@ -1182,14 +1182,14 @@ Value ListReceived(const Array& params, bool fByAccounts) } else { - Object obj; + UniValue obj(UniValue::VOBJ); if(fIsWatchonly) obj.push_back(Pair("involvesWatchonly", true)); obj.push_back(Pair("address", address.ToString())); obj.push_back(Pair("account", strAccount)); obj.push_back(Pair("amount", ValueFromAmount(nAmount))); obj.push_back(Pair("confirmations", (nConf == std::numeric_limits::max() ? 0 : nConf))); - Array transactions; + UniValue transactions(UniValue::VARR); if (it != mapTally.end()) { BOOST_FOREACH(const uint256& item, (*it).second.txids) @@ -1208,7 +1208,7 @@ Value ListReceived(const Array& params, bool fByAccounts) { CAmount nAmount = (*it).second.nAmount; int nConf = (*it).second.nConf; - Object obj; + UniValue obj(UniValue::VOBJ); if((*it).second.fIsWatchonly) obj.push_back(Pair("involvesWatchonly", true)); obj.push_back(Pair("account", (*it).first)); @@ -1318,7 +1318,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe { BOOST_FOREACH(const COutputEntry& s, listSent) { - Object entry; + UniValue entry(UniValue::VOBJ); if(involvesWatchonly || (::IsMine(*pwalletMain, s.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", strSentAccount)); @@ -1344,7 +1344,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe account = pwalletMain->mapAddressBook[r.destination].name; if (fAllAccounts || (account == strAccount)) { - Object entry; + UniValue entry(UniValue::VOBJ); if(involvesWatchonly || (::IsMine(*pwalletMain, r.destination) & ISMINE_WATCH_ONLY)) entry.push_back(Pair("involvesWatchonly", true)); entry.push_back(Pair("account", account)); @@ -1379,7 +1379,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar if (fAllAccounts || acentry.strAccount == strAccount) { - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("account", acentry.strAccount)); entry.push_back(Pair("category", "move")); entry.push_back(Pair("time", acentry.nTime)); @@ -1469,7 +1469,7 @@ Value listtransactions(const Array& params, bool fHelp) if (nFrom < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); - Array ret; + UniValue ret(UniValue::VARR); std::list acentries; CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount); @@ -1506,6 +1506,7 @@ Value listtransactions(const Array& params, bool fHelp) std::reverse(arrTmp.begin(), arrTmp.end()); // Return oldest to newest ret.clear(); + ret.setArray(); ret.push_backV(arrTmp); return ret; @@ -1584,7 +1585,7 @@ Value listaccounts(const Array& params, bool fHelp) BOOST_FOREACH(const CAccountingEntry& entry, acentries) mapAccountBalances[entry.strAccount] += entry.nCreditDebit; - Object ret; + UniValue ret(UniValue::VOBJ); BOOST_FOREACH(const PAIRTYPE(string, CAmount)& accountBalance, mapAccountBalances) { ret.push_back(Pair(accountBalance.first, ValueFromAmount(accountBalance.second))); } @@ -1662,7 +1663,7 @@ Value listsinceblock(const Array& params, bool fHelp) int depth = pindex ? (1 + chainActive.Height() - pindex->nHeight) : -1; - Array transactions; + UniValue transactions(UniValue::VARR); for (map::iterator it = pwalletMain->mapWallet.begin(); it != pwalletMain->mapWallet.end(); it++) { @@ -1675,7 +1676,7 @@ Value listsinceblock(const Array& params, bool fHelp) CBlockIndex *pblockLast = chainActive[chainActive.Height() + 1 - target_confirms]; uint256 lastblock = pblockLast ? pblockLast->GetBlockHash() : uint256(); - Object ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("transactions", transactions)); ret.push_back(Pair("lastblock", lastblock.GetHex())); @@ -1744,7 +1745,7 @@ Value gettransaction(const Array& params, bool fHelp) if(params[1].get_bool()) filter = filter | ISMINE_WATCH_ONLY; - Object entry; + UniValue entry(UniValue::VOBJ); if (!pwalletMain->mapWallet.count(hash)) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id"); const CWalletTx& wtx = pwalletMain->mapWallet[hash]; @@ -1760,7 +1761,7 @@ Value gettransaction(const Array& params, bool fHelp) WalletTxToJSON(wtx, entry); - Array details; + UniValue details(UniValue::VARR); ListTransactions(wtx, "*", 0, false, details, filter); entry.push_back(Pair("details", details)); @@ -2193,10 +2194,10 @@ Value listlockunspent(const Array& params, bool fHelp) vector vOutpts; pwalletMain->ListLockedCoins(vOutpts); - Array ret; + UniValue ret(UniValue::VARR); BOOST_FOREACH(COutPoint &outpt, vOutpts) { - Object o; + UniValue o(UniValue::VOBJ); o.push_back(Pair("txid", outpt.hash.GetHex())); o.push_back(Pair("vout", (int)outpt.n)); @@ -2262,7 +2263,7 @@ Value getwalletinfo(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("walletversion", pwalletMain->GetVersion())); obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); obj.push_back(Pair("unconfirmed_balance", ValueFromAmount(pwalletMain->GetUnconfirmedBalance()))); @@ -2292,7 +2293,7 @@ Value resendwallettransactions(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); std::vector txids = pwalletMain->ResendWalletTransactionsBefore(GetTime()); - Array result; + UniValue result(UniValue::VARR); BOOST_FOREACH(const uint256& txid, txids) { result.push_back(txid.ToString()); @@ -2365,7 +2366,7 @@ Value listunspent(const Array& params, bool fHelp) } } - Array results; + UniValue results(UniValue::VARR); vector vecOutputs; assert(pwalletMain != NULL); LOCK2(cs_main, pwalletMain->cs_wallet); @@ -2385,7 +2386,7 @@ Value listunspent(const Array& params, bool fHelp) CAmount nValue = out.tx->vout[out.i].nValue; const CScript& pk = out.tx->vout[out.i].scriptPubKey; - Object entry; + UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", out.tx->GetHash().GetHex())); entry.push_back(Pair("vout", out.i)); CTxDestination address; From 23f71dc740fd2ab68d4cc36cf93fe32f03bb3d45 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 14:49:18 +0200 Subject: [PATCH 06/26] special threatment for null,true,false because they are non valid json --- src/rpcclient.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 19b338f66..fd82953eb 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -11,6 +11,8 @@ #include #include +#include // for to_lower() + using namespace std; using namespace json_spirit; @@ -150,9 +152,19 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector Date: Sun, 10 May 2015 15:53:54 +0200 Subject: [PATCH 07/26] univalue: add support for real, fix percision and make it json_spirit compatible - avoid breaking the API because of different number/percision handling --- src/rpcclient.cpp | 5 +++-- src/test/univalue_tests.cpp | 10 +++++----- src/univalue/univalue.cpp | 8 ++++++-- src/univalue/univalue.h | 3 ++- src/univalue/univalue_write.cpp | 9 +++++++++ 5 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index fd82953eb..795469481 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -162,8 +162,9 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector 0)) + if(!jVal.setNumStr(strVal) || jVal.isNull()) + throw runtime_error(string("Error parsing JSON:")+strVal); } params.push_back(jVal); } diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 6df980ad0..87186cac4 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.isNum()); + BOOST_CHECK(v7.isReal()); BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21"); string vs("yawn"); @@ -85,7 +85,7 @@ BOOST_AUTO_TEST_CASE(univalue_set) BOOST_CHECK_EQUAL(v.getValStr(), "zum"); BOOST_CHECK(v.setFloat(-1.01)); - BOOST_CHECK(v.isNum()); + BOOST_CHECK(v.isReal()); BOOST_CHECK_EQUAL(v.getValStr(), "-1.01"); BOOST_CHECK(v.setInt((int)1023)); @@ -230,7 +230,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) objTypes["distance"] = UniValue::VNUM; objTypes["time"] = UniValue::VNUM; objTypes["calories"] = UniValue::VNUM; - objTypes["temperature"] = UniValue::VNUM; + objTypes["temperature"] = UniValue::VREAL; objTypes["cat1"] = UniValue::VNUM; objTypes["cat2"] = UniValue::VNUM; BOOST_CHECK(obj.checkObject(objTypes)); @@ -244,7 +244,7 @@ BOOST_AUTO_TEST_CASE(univalue_object) } static const char *json1 = -"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; +"[1.10000000,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]"; BOOST_AUTO_TEST_CASE(univalue_readwrite) { @@ -257,7 +257,7 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite) BOOST_CHECK(v.isArray()); BOOST_CHECK_EQUAL(v.size(), 2); - BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1"); + BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000"); UniValue obj = v[1]; BOOST_CHECK(obj.isObject()); diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index 6870ce59e..994d93113 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "univalue.h" @@ -78,9 +79,11 @@ bool UniValue::setFloat(double val) string s; ostringstream oss; - oss << val; + oss << std::setprecision(16) << val; - return setNumStr(oss.str()); + bool ret = setNumStr(oss.str()); + typ = VREAL; + return ret; } bool UniValue::setStr(const string& val_) @@ -203,6 +206,7 @@ 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 diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 28d6e3d3c..efcf202bd 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -17,7 +17,7 @@ class UniValue { public: - enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, }; + enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VREAL, VBOOL, }; UniValue() { typ = VNULL; } UniValue(UniValue::VType initialType, const std::string& initialStr = "") { @@ -76,6 +76,7 @@ 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 9a1d364c9..d360c253b 100644 --- a/src/univalue/univalue_write.cpp +++ b/src/univalue/univalue_write.cpp @@ -3,6 +3,8 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include +#include #include #include "univalue.h" #include "univalue_escapes.h" @@ -59,6 +61,13 @@ 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; From 9ccfdd9a011c4adc7be3476700d1a564e8cb29d1 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 15:54:11 +0200 Subject: [PATCH 08/26] univalue: correct bool support --- src/univalue/univalue.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index efcf202bd..c37a3829f 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -30,6 +30,9 @@ public: UniValue(int64_t val_) { setInt(val_); } + UniValue(bool val_) { + setBool(val_); + } UniValue(int val_) { setInt(val_); } @@ -192,6 +195,13 @@ static inline std::pair Pair(const char *cKey, int64_t i64 return std::make_pair(key, uVal); } +static inline std::pair Pair(const char *cKey, bool iVal) +{ + std::string key(cKey); + UniValue uVal(iVal); + return std::make_pair(key, uVal); +} + static inline std::pair Pair(const char *cKey, int iVal) { std::string key(cKey); From 565d26737ab1b2cfe9fb9d61f1227a18b15b487f Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Sun, 10 May 2015 15:55:32 +0200 Subject: [PATCH 09/26] fix rpc unit test, plain numbers are not JSON compatible object UniValues read() does only read valid json. --- src/test/rpc_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 4bb5334d0..8a6b98da4 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -129,8 +129,8 @@ BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) static Value ValueFromString(const std::string &str) { - Value value; - BOOST_CHECK(value.read(str)); + UniValue value; + BOOST_CHECK(value.setNumStr(str)); return value; } From 851f58f94e0da3fb50253f71a756461694ab7d54 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 13 May 2015 21:29:19 +0200 Subject: [PATCH 10/26] remove JSON Spirit UniValue wrapper --- src/Makefile.am | 1 - src/bitcoin-cli.cpp | 9 +- src/json_spirit_wrapper.h | 17 --- src/rest.cpp | 6 +- src/rpcblockchain.cpp | 30 ++--- src/rpcclient.cpp | 2 +- src/rpcclient.h | 4 +- src/rpcmining.cpp | 24 ++-- src/rpcmisc.cpp | 18 +-- src/rpcnet.cpp | 16 +-- src/rpcprotocol.cpp | 8 +- src/rpcprotocol.h | 8 +- src/rpcrawtransaction.cpp | 32 ++--- src/rpcserver.cpp | 28 ++-- src/rpcserver.h | 236 ++++++++++++++++----------------- src/test/base58_tests.cpp | 26 ++-- src/test/rpc_tests.cpp | 2 +- src/test/rpc_wallet_tests.cpp | 4 +- src/test/script_tests.cpp | 14 +- src/test/sighash_tests.cpp | 6 +- src/test/transaction_tests.cpp | 18 +-- src/wallet/rpcdump.cpp | 10 +- src/wallet/rpcwallet.cpp | 10 +- 23 files changed, 255 insertions(+), 274 deletions(-) delete mode 100644 src/json_spirit_wrapper.h diff --git a/src/Makefile.am b/src/Makefile.am index c639e860b..34434b8ab 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -117,7 +117,6 @@ BITCOIN_CORE_H = \ ecwrapper.h \ hash.h \ init.h \ - json_spirit_wrapper.h \ key.h \ keystore.h \ leveldbwrapper.h \ diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 4b4781fbf..97fc730cf 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -96,7 +96,7 @@ static bool AppInitRPC(int argc, char* argv[]) return true; } -Object CallRPC(const string& strMethod, const Array& params) +UniValue CallRPC(const string& strMethod, const Array& params) { // Connect to localhost bool fUseSSL = GetBoolArg("-rpcssl", false); @@ -152,7 +152,7 @@ Object CallRPC(const string& strMethod, const Array& params) throw runtime_error("no response from server"); // Parse reply - Value valReply(UniValue::VSTR); + UniValue valReply(UniValue::VSTR); if (!valReply.read(strReply)) throw runtime_error("couldn't parse reply from server"); const Object& reply = valReply.get_obj(); @@ -180,14 +180,13 @@ int CommandLineRPC(int argc, char *argv[]) // Parameters default to strings std::vector strParams(&argv[2], &argv[argc]); - Array params = RPCConvertValues(strMethod, strParams); + UniValue params = RPCConvertValues(strMethod, strParams); // Execute and handle connection failures with -rpcwait const bool fWait = GetBoolArg("-rpcwait", false); do { try { - // Execute - Object reply = CallRPC(strMethod, params); + const UniValue reply = CallRPC(strMethod, params); // Parse reply const Value& result = find_value(reply, "result"); diff --git a/src/json_spirit_wrapper.h b/src/json_spirit_wrapper.h deleted file mode 100644 index 1962cf643..000000000 --- a/src/json_spirit_wrapper.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __JSON_SPIRIT_WRAPPER_H__ -#define __JSON_SPIRIT_WRAPPER_H__ - -#include "univalue/univalue.h" - -namespace json_spirit { - -typedef UniValue Value; -typedef UniValue Array; -typedef UniValue Object; -typedef UniValue::VType Value_type; - -} - -#define find_value(val,key) (val[key]) - -#endif // __JSON_SPIRIT_WRAPPER_H__ diff --git a/src/rest.cpp b/src/rest.cpp index f3195746b..3142b2503 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -62,7 +62,7 @@ public: }; extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); -extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); static RestErr RESTERR(enum HTTPStatusCode status, string message) @@ -221,7 +221,7 @@ static bool rest_block(AcceptedConnection* conn, } case RF_JSON: { - Object objBlock = blockToJSON(block, pblockindex, showTxDetails); + UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails); string strJSON = objBlock.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; @@ -266,7 +266,7 @@ static bool rest_chaininfo(AcceptedConnection* conn, switch (rf) { case RF_JSON: { UniValue rpcParams(UniValue::VARR); - Value chainInfoObject = getblockchaininfo(rpcParams, false); + UniValue chainInfoObject = getblockchaininfo(rpcParams, false); string strJSON = chainInfoObject.write() + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 485d022b5..0bec434f5 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -74,7 +74,7 @@ double GetNetworkDifficulty(const CBlockIndex* blockindex) } -Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) +UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false) { UniValue result(UniValue::VOBJ); result.push_back(Pair("hash", block.GetHash().GetHex())); @@ -116,7 +116,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe } -Value getblockcount(const Array& params, bool fHelp) +UniValue getblockcount(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -133,7 +133,7 @@ Value getblockcount(const Array& params, bool fHelp) return chainActive.Height(); } -Value getbestblockhash(const Array& params, bool fHelp) +UniValue getbestblockhash(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -150,7 +150,7 @@ Value getbestblockhash(const Array& params, bool fHelp) return chainActive.Tip()->GetBlockHash().GetHex(); } -Value getdifficulty(const Array& params, bool fHelp) +UniValue getdifficulty(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -168,7 +168,7 @@ Value getdifficulty(const Array& params, bool fHelp) } -Value getrawmempool(const Array& params, bool fHelp) +UniValue getrawmempool(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -253,7 +253,7 @@ Value getrawmempool(const Array& params, bool fHelp) } } -Value getblockhash(const Array& params, bool fHelp) +UniValue getblockhash(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -278,7 +278,7 @@ Value getblockhash(const Array& params, bool fHelp) return pblockindex->GetBlockHash().GetHex(); } -Value getblock(const Array& params, bool fHelp) +UniValue getblock(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -346,7 +346,7 @@ Value getblock(const Array& params, bool fHelp) return blockToJSON(block, pblockindex); } -Value gettxoutsetinfo(const Array& params, bool fHelp) +UniValue gettxoutsetinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -386,7 +386,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp) return ret; } -Value gettxout(const Array& params, bool fHelp) +UniValue gettxout(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) throw runtime_error( @@ -466,7 +466,7 @@ Value gettxout(const Array& params, bool fHelp) return ret; } -Value verifychain(const Array& params, bool fHelp) +UniValue verifychain(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -524,7 +524,7 @@ Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, c return rv; } -Value getblockchaininfo(const Array& params, bool fHelp) +UniValue getblockchaininfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -609,7 +609,7 @@ struct CompareBlocksByHeight } }; -Value getchaintips(const Array& params, bool fHelp) +UniValue getchaintips(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -699,7 +699,7 @@ Value getchaintips(const Array& params, bool fHelp) return res; } -Value getmempoolinfo(const Array& params, bool fHelp) +UniValue getmempoolinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -722,7 +722,7 @@ Value getmempoolinfo(const Array& params, bool fHelp) return ret; } -Value invalidateblock(const Array& params, bool fHelp) +UniValue invalidateblock(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -760,7 +760,7 @@ Value invalidateblock(const Array& params, bool fHelp) return NullUniValue; } -Value reconsiderblock(const Array& params, bool fHelp) +UniValue reconsiderblock(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 795469481..aec69d9bd 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -138,7 +138,7 @@ CRPCConvertTable::CRPCConvertTable() static CRPCConvertTable rpcCvtTable; /** Convert strings to command-specific RPC representation */ -Array RPCConvertValues(const std::string &strMethod, const std::vector &strParams) +UniValue RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { UniValue params(UniValue::VARR); diff --git a/src/rpcclient.h b/src/rpcclient.h index 29c126027..52270aec7 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -6,8 +6,8 @@ #ifndef BITCOIN_RPCCLIENT_H #define BITCOIN_RPCCLIENT_H -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -json_spirit::Array RPCConvertValues(const std::string& strMethod, const std::vector& strParams); +UniValue RPCConvertValues(const std::string& strMethod, const std::vector& strParams); #endif // BITCOIN_RPCCLIENT_H diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 4240a167f..eddc3ea89 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -115,7 +115,7 @@ Value getnetworksolps(const Array& params, bool fHelp) return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } -Value getnetworkhashps(const Array& params, bool fHelp) +UniValue getnetworkhashps(const Array& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -139,7 +139,7 @@ Value getnetworkhashps(const Array& params, bool fHelp) } #ifdef ENABLE_MINING -Value getgenerate(const Array& params, bool fHelp) +UniValue getgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -158,7 +158,7 @@ Value getgenerate(const Array& params, bool fHelp) return GetBoolArg("-gen", false); } -Value generate(const Array& params, bool fHelp) +UniValue generate(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( @@ -267,7 +267,7 @@ endloop: } -Value setgenerate(const Array& params, bool fHelp) +UniValue setgenerate(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -326,7 +326,7 @@ Value setgenerate(const Array& params, bool fHelp) #endif -Value getmininginfo(const Array& params, bool fHelp) +UniValue getmininginfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -376,7 +376,7 @@ Value getmininginfo(const Array& params, bool fHelp) // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts -Value prioritisetransaction(const Array& params, bool fHelp) +UniValue prioritisetransaction(const Array& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -408,7 +408,7 @@ Value prioritisetransaction(const Array& params, bool fHelp) // NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller -static Value BIP22ValidationResult(const CValidationState& state) +static UniValue BIP22ValidationResult(const CValidationState& state) { if (state.IsValid()) return Value::null; @@ -426,7 +426,7 @@ static Value BIP22ValidationResult(const CValidationState& state) return "valid?"; } -Value getblocktemplate(const Array& params, bool fHelp) +UniValue getblocktemplate(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -502,7 +502,7 @@ Value getblocktemplate(const Array& params, bool fHelp) } std::string strMode = "template"; - Value lpval = NullUniValue; + UniValue lpval = NullUniValue; // TODO: Re-enable coinbasevalue once a specification has been written bool coinbasetxn = true; if (params.size() > 0) @@ -748,7 +748,7 @@ protected: }; }; -Value submitblock(const Array& params, bool fHelp) +UniValue submitblock(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -809,7 +809,7 @@ Value submitblock(const Array& params, bool fHelp) return BIP22ValidationResult(state); } -Value estimatefee(const Array& params, bool fHelp) +UniValue estimatefee(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -841,7 +841,7 @@ Value estimatefee(const Array& params, bool fHelp) return ValueFromAmount(feeRate.GetFeePerK()); } -Value estimatepriority(const Array& params, bool fHelp) +UniValue estimatepriority(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 898083379..8e68dd271 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -40,7 +40,7 @@ using namespace std; * * Or alternatively, create a specific query method for the information. **/ -Value getinfo(const Array& params, bool fHelp) +UniValue getinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -117,9 +117,9 @@ private: public: DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {} - Object operator()(const CNoDestination &dest) const { return Object(); } + UniValue operator()(const CNoDestination &dest) const { return Object(); } - Object operator()(const CKeyID &keyID) const { + UniValue operator()(const CKeyID &keyID) const { UniValue obj(UniValue::VOBJ); CPubKey vchPubKey; obj.push_back(Pair("isscript", false)); @@ -131,7 +131,7 @@ public: return obj; } - Object operator()(const CScriptID &scriptID) const { + UniValue operator()(const CScriptID &scriptID) const { UniValue obj(UniValue::VOBJ); obj.push_back(Pair("isscript", true)); if (mine != ISMINE_NO) { @@ -155,7 +155,7 @@ public: }; #endif -Value validateaddress(const Array& params, bool fHelp) +UniValue validateaddress(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -204,7 +204,7 @@ Value validateaddress(const Array& params, bool fHelp) ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false)); if (mine != ISMINE_NO) { ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false)); - Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); + UniValue detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest); ret.pushKVs(detail); } if (pwalletMain && pwalletMain->mapAddressBook.count(dest)) @@ -341,7 +341,7 @@ CScript _createmultisig_redeemScript(const Array& params) return result; } -Value createmultisig(const Array& params, bool fHelp) +UniValue createmultisig(const Array& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 2) { @@ -384,7 +384,7 @@ Value createmultisig(const Array& params, bool fHelp) return result; } -Value verifymessage(const Array& params, bool fHelp) +UniValue verifymessage(const Array& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -438,7 +438,7 @@ Value verifymessage(const Array& params, bool fHelp) return (pubkey.GetID() == keyID); } -Value setmocktime(const Array& params, bool fHelp) +UniValue setmocktime(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 1cf17484e..34ba59f3d 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -21,7 +21,7 @@ using namespace json_spirit; using namespace std; -Value getconnectioncount(const Array& params, bool fHelp) +UniValue getconnectioncount(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -39,7 +39,7 @@ Value getconnectioncount(const Array& params, bool fHelp) return (int)vNodes.size(); } -Value ping(const Array& params, bool fHelp) +UniValue ping(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -75,7 +75,7 @@ static void CopyNodeStats(std::vector& vstats) } } -Value getpeerinfo(const Array& params, bool fHelp) +UniValue getpeerinfo(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -165,7 +165,7 @@ Value getpeerinfo(const Array& params, bool fHelp) return ret; } -Value addnode(const Array& params, bool fHelp) +UniValue addnode(const Array& params, bool fHelp) { string strCommand; if (params.size() == 2) @@ -215,7 +215,7 @@ Value addnode(const Array& params, bool fHelp) return NullUniValue; } -Value getaddednodeinfo(const Array& params, bool fHelp) +UniValue getaddednodeinfo(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -332,7 +332,7 @@ Value getaddednodeinfo(const Array& params, bool fHelp) return ret; } -Value getnettotals(const Array& params, bool fHelp) +UniValue getnettotals(const Array& params, bool fHelp) { if (fHelp || params.size() > 0) throw runtime_error( @@ -357,7 +357,7 @@ Value getnettotals(const Array& params, bool fHelp) return obj; } -static Array GetNetworksInfo() +static UniValue GetNetworksInfo() { UniValue networks(UniValue::VARR); for(int n=0; n& stream, map& stream, int &proto); int ReadHTTPHeaders(std::basic_istream& stream, std::map& mapHeadersRet); int ReadHTTPMessage(std::basic_istream& stream, std::map& mapHeadersRet, std::string& strMessageRet, int nProto, size_t max_size); -std::string JSONRPCRequest(const std::string& strMethod, const json_spirit::Array& params, const json_spirit::Value& id); -json_spirit::Object JSONRPCReplyObj(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id); -std::string JSONRPCReply(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id); -json_spirit::Object JSONRPCError(int code, const std::string& message); +std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id); +UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id); +std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id); +UniValue JSONRPCError(int code, const std::string& message); /** Get name of RPC authentication cookie file */ boost::filesystem::path GetAuthCookieFile(); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index b873b904f..224396268 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -164,7 +164,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) } } -Value getrawtransaction(const Array& params, bool fHelp) +UniValue getrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -281,7 +281,7 @@ Value getrawtransaction(const Array& params, bool fHelp) return result; } -Value gettxoutproof(const Array& params, bool fHelp) +UniValue gettxoutproof(const Array& params, bool fHelp) { if (fHelp || (params.size() != 1 && params.size() != 2)) throw runtime_error( @@ -305,7 +305,7 @@ Value gettxoutproof(const Array& params, bool fHelp) set setTxids; uint256 oneTxid; - Array txids = params[0].get_array(); + UniValue txids = params[0].get_array(); for (unsigned int idx = 0; idx < txids.size(); idx++) { const Value& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) @@ -362,7 +362,7 @@ Value gettxoutproof(const Array& params, bool fHelp) return strHex; } -Value verifytxoutproof(const Array& params, bool fHelp) +UniValue verifytxoutproof(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -395,7 +395,7 @@ Value verifytxoutproof(const Array& params, bool fHelp) return res; } -Value createrawtransaction(const Array& params, bool fHelp) +UniValue createrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error( @@ -431,8 +431,8 @@ Value createrawtransaction(const Array& params, bool fHelp) LOCK(cs_main); RPCTypeCheck(params, boost::assign::list_of(UniValue::VARR)(UniValue::VOBJ)); - Array inputs = params[0].get_array(); - Object sendTo = params[1].get_obj(); + UniValue inputs = params[0].get_array(); + UniValue sendTo = params[1].get_obj(); CMutableTransaction rawTx; @@ -474,7 +474,7 @@ Value createrawtransaction(const Array& params, bool fHelp) return EncodeHexTx(rawTx); } -Value decoderawtransaction(const Array& params, bool fHelp) +UniValue decoderawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -566,7 +566,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) return result; } -Value decodescript(const Array& params, bool fHelp) +UniValue decodescript(const Array& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -620,7 +620,7 @@ static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::str vErrorsRet.push_back(entry); } -Value signrawtransaction(const Array& params, bool fHelp) +UniValue signrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 4) throw runtime_error( @@ -730,9 +730,9 @@ Value signrawtransaction(const Array& params, bool fHelp) CBasicKeyStore tempKeystore; if (params.size() > 2 && !params[2].isNull()) { fGivenKeys = true; - Array keys = params[2].get_array(); + UniValue keys = params[2].get_array(); for (unsigned int idx = 0; idx < keys.size(); idx++) { - Value k = keys[idx]; + UniValue k = keys[idx]; CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(k.get_str()); if (!fGood) @@ -750,13 +750,13 @@ Value signrawtransaction(const Array& params, bool fHelp) // Add previous txouts given in the RPC call: if (params.size() > 1 && !params[1].isNull()) { - Array prevTxs = params[1].get_array(); + UniValue prevTxs = params[1].get_array(); for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { const Value& p = prevTxs[idx]; if (!p.isObject()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); - Object prevOut = p.get_obj(); + UniValue prevOut = p.get_obj(); RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)); @@ -787,7 +787,7 @@ Value signrawtransaction(const Array& params, bool fHelp) // given), add redeemScript to the tempKeystore so it can be signed: if (fGivenKeys && scriptPubKey.IsPayToScriptHash()) { RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR)); - Value v = find_value(prevOut, "redeemScript"); + UniValue v = find_value(prevOut, "redeemScript"); if (!v.isNull()) { vector rsData(ParseHexV(v, "redeemScript")); CScript redeemScript(rsData.begin(), rsData.end()); @@ -862,7 +862,7 @@ Value signrawtransaction(const Array& params, bool fHelp) return result; } -Value sendrawtransaction(const Array& params, bool fHelp) +UniValue sendrawtransaction(const Array& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 336f7edf9..25e9e67d1 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -138,7 +138,7 @@ CAmount AmountFromValue(const Value& value) return nAmount; } -Value ValueFromAmount(const CAmount& amount) +UniValue ValueFromAmount(const CAmount& amount) { return (double)amount / (double)COIN; } @@ -199,7 +199,7 @@ string CRPCTable::help(string strCommand) const continue; try { - Array params; + UniValue params; rpcfn_type pfn = pcmd->actor; if (setDone.insert(pfn).second) (*pfn)(params, true); @@ -232,7 +232,7 @@ string CRPCTable::help(string strCommand) const return strRet; } -Value help(const Array& params, bool fHelp) +UniValue help(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -252,7 +252,7 @@ Value help(const Array& params, bool fHelp) } -Value stop(const Array& params, bool fHelp) +UniValue stop(const Array& params, bool fHelp) { // Accept the deprecated and ignored 'detach' boolean argument if (fHelp || params.size() > 1) @@ -863,9 +863,9 @@ void RPCRunLater(const std::string& name, boost::function func, int6 class JSONRequest { public: - Value id; + UniValue id; string strMethod; - Array params; + UniValue params; JSONRequest() { id = NullUniValue; } void parse(const Value& valRequest); @@ -882,7 +882,7 @@ void JSONRequest::parse(const Value& valRequest) id = find_value(request, "id"); // Parse method - Value valMethod = find_value(request, "method"); + UniValue valMethod = find_value(request, "method"); if (valMethod.isNull()) throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); if (!valMethod.isStr()) @@ -892,7 +892,7 @@ void JSONRequest::parse(const Value& valRequest) LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod)); // Parse params - Value valParams = find_value(request, "params"); + UniValue valParams = find_value(request, "params"); if (valParams.isArray()) params = valParams.get_array(); else if (valParams.isNull()) @@ -902,7 +902,7 @@ void JSONRequest::parse(const Value& valRequest) } -static Object JSONRPCExecOne(const Value& req) +static UniValue JSONRPCExecOne(const Value& req) { UniValue rpc_result(UniValue::VOBJ); @@ -910,7 +910,7 @@ static Object JSONRPCExecOne(const Value& req) try { jreq.parse(req); - Value result = tableRPC.execute(jreq.strMethod, jreq.params); + UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); } catch (const Object& objError) @@ -928,7 +928,7 @@ static Object JSONRPCExecOne(const Value& req) static string JSONRPCExecBatch(const Array& vReq) { - Array ret; + UniValue ret; for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) ret.push_back(JSONRPCExecOne(vReq[reqIdx])); @@ -963,7 +963,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, try { // Parse request - Value valRequest; + UniValue valRequest; if (!valRequest.read(strRequest)) throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); @@ -980,7 +980,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, if (valRequest.isObject()) { jreq.parse(valRequest); - Value result = tableRPC.execute(jreq.strMethod, jreq.params); + UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); // Send reply strReply = JSONRPCReply(result, NullUniValue, jreq.id); @@ -1049,7 +1049,7 @@ void ServiceConnection(AcceptedConnection *conn) } } -json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const +UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const { // Find method const CRPCCommand *pcmd = tableRPC[strMethod]; diff --git a/src/rpcserver.h b/src/rpcserver.h index 01c27685d..37c65f8b1 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -76,8 +76,8 @@ bool RPCIsInWarmup(std::string *statusOut); * the right number of arguments are passed, just that any passed are the correct type. * Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type)); */ -void RPCTypeCheck(const json_spirit::Array& params, - const std::list& typesExpected, bool fAllowNull=false); +void RPCTypeCheck(const UniValue& params, + const std::list& typesExpected, bool fAllowNull=false); /* Check for expected keys/value types in an Object. @@ -95,7 +95,7 @@ void RPCRunLater(const std::string& name, boost::function func, int6 //! Convert boost::asio address to CNetAddr extern CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address); -typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp); +typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp); class CRPCCommand { @@ -121,11 +121,11 @@ public: /** * Execute a method. * @param method Method to execute - * @param params Array of arguments (JSON objects) + * @param params UniValue Array of arguments (JSON objects) * @returns Result of the call. - * @throws an exception (json_spirit::Value) when an error happens. + * @throws an exception (UniValue) when an error happens. */ - json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const; + UniValue execute(const std::string &method, const UniValue ¶ms) const; }; extern const CRPCTable tableRPC; @@ -134,17 +134,17 @@ extern const CRPCTable tableRPC; * Utilities: convert hex-encoded Values * (throws error if not hex). */ -extern uint256 ParseHashV(const json_spirit::Value& v, std::string strName); -extern uint256 ParseHashO(const json_spirit::Object& o, std::string strKey); -extern std::vector ParseHexV(const json_spirit::Value& v, std::string strName); -extern std::vector ParseHexO(const json_spirit::Object& o, std::string strKey); +extern uint256 ParseHashV(const UniValue& v, std::string strName); +extern uint256 ParseHashO(const UniValue& o, std::string strKey); +extern std::vector ParseHexV(const UniValue& v, std::string strName); +extern std::vector ParseHexO(const UniValue& o, std::string strKey); extern void InitRPCMining(); extern void ShutdownRPCMining(); extern int64_t nWalletUnlockTime; -extern CAmount AmountFromValue(const json_spirit::Value& value); -extern json_spirit::Value ValueFromAmount(const CAmount& amount); +extern CAmount AmountFromValue(const UniValue& value); +extern UniValue ValueFromAmount(const CAmount& amount); extern double GetDifficulty(const CBlockIndex* blockindex = NULL); extern double GetNetworkDifficulty(const CBlockIndex* blockindex = NULL); extern std::string HelpRequiringPassphrase(); @@ -153,119 +153,119 @@ extern std::string HelpExampleRpc(std::string methodname, std::string args); extern void EnsureWalletIsUnlocked(); -extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp -extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value ping(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnettotals(const json_spirit::Array& params, bool fHelp); +extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp +extern UniValue getpeerinfo(const UniValue& params, bool fHelp); +extern UniValue ping(const UniValue& params, bool fHelp); +extern UniValue addnode(const UniValue& params, bool fHelp); +extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp); +extern UniValue getnettotals(const UniValue& params, bool fHelp); -extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp -extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value importaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value dumpwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fHelp); +extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue importprivkey(const UniValue& params, bool fHelp); +extern UniValue importaddress(const UniValue& params, bool fHelp); +extern UniValue dumpwallet(const UniValue& params, bool fHelp); +extern UniValue importwallet(const UniValue& params, bool fHelp); -extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp -extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getlocalsolps(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnetworksolps(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value estimatepriority(const json_spirit::Array& params, bool fHelp); +extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpcmining.cpp +extern UniValue setgenerate(const UniValue& params, bool fHelp); +extern UniValue generate(const UniValue& params, bool fHelp); +extern UniValue getlocalsolps(const UniValue& params, bool fHelp); +extern UniValue getnetworksolps(const UniValue& params, bool fHelp); +extern UniValue getnetworkhashps(const UniValue& params, bool fHelp); +extern UniValue getmininginfo(const UniValue& params, bool fHelp); +extern UniValue prioritisetransaction(const UniValue& params, bool fHelp); +extern UniValue getblocktemplate(const UniValue& params, bool fHelp); +extern UniValue submitblock(const UniValue& params, bool fHelp); +extern UniValue estimatefee(const UniValue& params, bool fHelp); +extern UniValue estimatepriority(const UniValue& params, bool fHelp); -extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getrawchangeaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getunconfirmedbalance(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value createmultisig(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getwalletinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value zc_benchmark(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value zc_raw_receive(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value zc_sample_joinsplit(const json_spirit::Array& params, bool fHelp); +extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue getaccountaddress(const UniValue& params, bool fHelp); +extern UniValue getrawchangeaddress(const UniValue& params, bool fHelp); +extern UniValue setaccount(const UniValue& params, bool fHelp); +extern UniValue getaccount(const UniValue& params, bool fHelp); +extern UniValue getaddressesbyaccount(const UniValue& params, bool fHelp); +extern UniValue sendtoaddress(const UniValue& params, bool fHelp); +extern UniValue signmessage(const UniValue& params, bool fHelp); +extern UniValue verifymessage(const UniValue& params, bool fHelp); +extern UniValue getreceivedbyaddress(const UniValue& params, bool fHelp); +extern UniValue getreceivedbyaccount(const UniValue& params, bool fHelp); +extern UniValue getbalance(const UniValue& params, bool fHelp); +extern UniValue getunconfirmedbalance(const UniValue& params, bool fHelp); +extern UniValue movecmd(const UniValue& params, bool fHelp); +extern UniValue sendfrom(const UniValue& params, bool fHelp); +extern UniValue sendmany(const UniValue& params, bool fHelp); +extern UniValue addmultisigaddress(const UniValue& params, bool fHelp); +extern UniValue createmultisig(const UniValue& params, bool fHelp); +extern UniValue listreceivedbyaddress(const UniValue& params, bool fHelp); +extern UniValue listreceivedbyaccount(const UniValue& params, bool fHelp); +extern UniValue listtransactions(const UniValue& params, bool fHelp); +extern UniValue listaddressgroupings(const UniValue& params, bool fHelp); +extern UniValue listaccounts(const UniValue& params, bool fHelp); +extern UniValue listsinceblock(const UniValue& params, bool fHelp); +extern UniValue gettransaction(const UniValue& params, bool fHelp); +extern UniValue backupwallet(const UniValue& params, bool fHelp); +extern UniValue keypoolrefill(const UniValue& params, bool fHelp); +extern UniValue walletpassphrase(const UniValue& params, bool fHelp); +extern UniValue walletpassphrasechange(const UniValue& params, bool fHelp); +extern UniValue walletlock(const UniValue& params, bool fHelp); +extern UniValue encryptwallet(const UniValue& params, bool fHelp); +extern UniValue validateaddress(const UniValue& params, bool fHelp); +extern UniValue getinfo(const UniValue& params, bool fHelp); +extern UniValue getwalletinfo(const UniValue& params, bool fHelp); +extern UniValue getblockchaininfo(const UniValue& params, bool fHelp); +extern UniValue getnetworkinfo(const UniValue& params, bool fHelp); +extern UniValue setmocktime(const UniValue& params, bool fHelp); +extern UniValue resendwallettransactions(const UniValue& params, bool fHelp); +extern UniValue zc_benchmark(const UniValue& params, bool fHelp); +extern UniValue zc_raw_keygen(const UniValue& params, bool fHelp); +extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp); +extern UniValue zc_raw_receive(const UniValue& params, bool fHelp); +extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp); -extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp -extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value decodescript(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxoutproof(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifytxoutproof(const json_spirit::Array& params, bool fHelp); +extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp +extern UniValue listunspent(const UniValue& params, bool fHelp); +extern UniValue lockunspent(const UniValue& params, bool fHelp); +extern UniValue listlockunspent(const UniValue& params, bool fHelp); +extern UniValue createrawtransaction(const UniValue& params, bool fHelp); +extern UniValue decoderawtransaction(const UniValue& params, bool fHelp); +extern UniValue decodescript(const UniValue& params, bool fHelp); +extern UniValue signrawtransaction(const UniValue& params, bool fHelp); +extern UniValue sendrawtransaction(const UniValue& params, bool fHelp); +extern UniValue gettxoutproof(const UniValue& params, bool fHelp); +extern UniValue verifytxoutproof(const UniValue& params, bool fHelp); -extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp -extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getmempoolinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp); -extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp); +extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp +extern UniValue getbestblockhash(const UniValue& params, bool fHelp); +extern UniValue getdifficulty(const UniValue& params, bool fHelp); +extern UniValue settxfee(const UniValue& params, bool fHelp); +extern UniValue getmempoolinfo(const UniValue& params, bool fHelp); +extern UniValue getrawmempool(const UniValue& params, bool fHelp); +extern UniValue getblockhash(const UniValue& params, bool fHelp); +extern UniValue getblock(const UniValue& params, bool fHelp); +extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp); +extern UniValue gettxout(const UniValue& params, bool fHelp); +extern UniValue verifychain(const UniValue& params, bool fHelp); +extern UniValue getchaintips(const UniValue& params, bool fHelp); +extern UniValue invalidateblock(const UniValue& params, bool fHelp); +extern UniValue reconsiderblock(const UniValue& params, bool fHelp); -extern json_spirit::Value getblocksubsidy(const json_spirit::Array& params, bool fHelp); +extern UniValue getblocksubsidy(const UniValue& params, bool fHelp); -extern json_spirit::Value z_exportkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp -extern json_spirit::Value z_importkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp -extern json_spirit::Value z_getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_listaddresses(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_exportwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp -extern json_spirit::Value z_importwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp -extern json_spirit::Value z_listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_getbalance(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_gettotalbalance(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_sendmany(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_getoperationstatus(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_getoperationresult(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_listoperationids(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp -extern json_spirit::Value z_validateaddress(const json_spirit::Array& params, bool fHelp); // in rpcmisc.cpp +extern UniValue z_exportkey(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue z_importkey(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue z_getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_listaddresses(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_exportwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue z_importwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp +extern UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_getbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_gettotalbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_sendmany(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_getoperationresult(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_listoperationids(const UniValue& params, bool fHelp); // in rpcwallet.cpp +extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpcmisc.cpp // in rest.cpp diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index a806fe7b0..114bd79ea 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -20,16 +20,16 @@ #include "json_spirit_wrapper.h" using namespace json_spirit; -extern Array read_json(const std::string& jsondata); +extern UniValue read_json(const std::string& jsondata); BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) // Goal: test low-level base58 encoding functionality BOOST_AUTO_TEST_CASE(base58_EncodeBase58) { - Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); + UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { @@ -47,11 +47,11 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58) // Goal: test low-level base58 decoding functionality BOOST_AUTO_TEST_CASE(base58_DecodeBase58) { - Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); + UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); std::vector result; for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) { @@ -120,14 +120,14 @@ public: // Goal: check that parsed keys match test payload BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) { - Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); + UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector result; CBitcoinSecret secret; CBitcoinAddress addr; SelectParams(CBaseChainParams::MAIN); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { @@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) } std::string exp_base58string = test[0].get_str(); std::vector exp_payload = ParseHex(test[1].get_str()); - const Object &metadata = test[2].get_obj(); + const UniValue &metadata = test[2].get_obj(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool(); if (isTestnet) @@ -178,11 +178,11 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) // Goal: check that generated keys match test vectors BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) { - Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); + UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector result; for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) { @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) } std::string exp_base58string = test[0].get_str(); std::vector exp_payload = ParseHex(test[1].get_str()); - const Object &metadata = test[2].get_obj(); + const UniValue &metadata = test[2].get_obj(); bool isPrivkey = find_value(metadata, "isPrivkey").get_bool(); bool isTestnet = find_value(metadata, "isTestnet").get_bool(); if (isTestnet) @@ -246,13 +246,13 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) // Goal: check that base58 parsing code is robust against a variety of corrupted data BOOST_AUTO_TEST_CASE(base58_keys_invalid) { - Array tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases + UniValue tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases std::vector result; CBitcoinSecret secret; CBitcoinAddress addr; for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 8a6b98da4..8ea4af6ef 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -40,7 +40,7 @@ Value CallRPC(string args) vArgs[i] = ""; } } - Array params = RPCConvertValues(strMethod, vArgs); + UniValue params = RPCConvertValues(strMethod, vArgs); rpcfn_type method = tableRPC[strMethod]->actor; try { diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index d0ee27aea..9b5bd7acb 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -34,7 +34,7 @@ using namespace std; using namespace json_spirit; -extern Array createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); +extern UniValue createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); extern Value CallRPC(string args); extern CWallet* pwalletMain; @@ -239,7 +239,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) *********************************/ BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error); BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount)); - Array arr = retValue.get_array(); + UniValue arr = retValue.get_array(); BOOST_CHECK_EQUAL(4, arr.size()); bool notFound = true; for (auto a : arr) { diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index f3f3ffa2d..a1d44d6dd 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -293,7 +293,7 @@ public: return *this; } - Array GetJSON() + UniValue GetJSON() { DoPush(); UniValue array(UniValue::VARR); @@ -580,8 +580,8 @@ BOOST_AUTO_TEST_CASE(script_build) std::set tests_bad; { - Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); - Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); + UniValue json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); + UniValue json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); for (unsigned int idx = 0; idx < json_good.size(); idx++) { const Value& tv = json_good[idx]; @@ -634,10 +634,10 @@ BOOST_AUTO_TEST_CASE(script_valid) // Inner arrays are [ "scriptSig", "scriptPubKey", "flags" ] // ... where scriptSig and scriptPubKey are stringified // scripts. - Array tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); + UniValue tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; string strTest = test.write(); if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) { @@ -659,10 +659,10 @@ BOOST_AUTO_TEST_CASE(script_valid) BOOST_AUTO_TEST_CASE(script_invalid) { // Scripts that should evaluate as invalid - Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); + UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; string strTest = test.write(); if (test.size() < 3) // Allow size > 2; extra stuff ignored (useful for comments) { diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 9e7556cc9..6e169e0e7 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -20,7 +20,7 @@ #include "json_spirit_wrapper.h" using namespace json_spirit; -extern Array read_json(const std::string& jsondata); +extern UniValue read_json(const std::string& jsondata); // Old script.cpp SignatureHash function uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType) @@ -203,10 +203,10 @@ BOOST_AUTO_TEST_CASE(sighash_test) // Goal: check that SignatureHash generates correct hash BOOST_AUTO_TEST_CASE(sighash_from_data) { - Array tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); + UniValue tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) { diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 8e21a98ff..21893b76e 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -37,7 +37,7 @@ using namespace std; using namespace json_spirit; // In script_tests.cpp -extern Array read_json(const std::string& jsondata); +extern UniValue read_json(const std::string& jsondata); static std::map mapFlagNames = boost::assign::map_list_of (string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE) @@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) // ... where all scripts are stringified scripts. // // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" - Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); + UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); auto verifier = libzcash::ProofVerifier::Strict(); <<<<<<< HEAD @@ -110,7 +110,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) if (test[0].type() == array_type) ======= for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) >>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. @@ -122,7 +122,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) } map mapprevOutScriptPubKeys; - Array inputs = test[0].get_array(); + UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { const Value& input = inputs[inpIdx]; @@ -131,7 +131,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) fValid = false; break; } - Array vinput = input.get_array(); + UniValue vinput = input.get_array(); if (vinput.size() != 3) { fValid = false; @@ -182,7 +182,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) // ... where all scripts are stringified scripts. // // verifyFlags is a comma separated list of script verification flags to apply, or "NONE" - Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); + UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); auto verifier = libzcash::ProofVerifier::Strict(); <<<<<<< HEAD @@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) if (test[0].type() == array_type) ======= for (unsigned int idx = 0; idx < tests.size(); idx++) { - Array test = tests[idx]; + UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) >>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. @@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) } map mapprevOutScriptPubKeys; - Array inputs = test[0].get_array(); + UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { const Value& input = inputs[inpIdx]; @@ -215,7 +215,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) fValid = false; break; } - Array vinput = input.get_array(); + UniValue vinput = input.get_array(); if (vinput.size() != 3) { fValid = false; diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index f80c18637..13cb0d4df 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -74,7 +74,7 @@ std::string DecodeDumpString(const std::string &str) { return ret.str(); } -Value importprivkey(const Array& params, bool fHelp) +UniValue importprivkey(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -148,7 +148,7 @@ Value importprivkey(const Array& params, bool fHelp) return NullUniValue; } -Value importaddress(const Array& params, bool fHelp) +UniValue importaddress(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -244,7 +244,7 @@ Value z_importwallet(const Array& params, bool fHelp) return importwallet_impl(params, fHelp, true); } -Value importwallet(const Array& params, bool fHelp) +UniValue importwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -381,7 +381,7 @@ Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys) return NullUniValue; } -Value dumpprivkey(const Array& params, bool fHelp) +UniValue dumpprivkey(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -441,7 +441,7 @@ Value z_exportwallet(const Array& params, bool fHelp) return dumpwallet_impl(params, fHelp, true); } -Value dumpwallet(const Array& params, bool fHelp) +UniValue dumpwallet(const Array& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 14e8cb2c1..0fbeebf07 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -779,7 +779,7 @@ Value getbalance(const Array& params, bool fHelp) return ValueFromAmount(nBalance); } -Value getunconfirmedbalance(const Array ¶ms, bool fHelp) +Value getunconfirmedbalance(const UniValue ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -972,7 +972,7 @@ Value sendmany(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); string strAccount = AccountFromValue(params[0]); - Object sendTo = params[1].get_obj(); + UniValue sendTo = params[1].get_obj(); int nMinDepth = 1; if (params.size() > 2) nMinDepth = params[2].get_int(); @@ -1294,7 +1294,7 @@ Value listreceivedbyaccount(const Array& params, bool fHelp) return ListReceived(params, true); } -static void MaybePushAddress(Object & entry, const CTxDestination &dest) +static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) { CBitcoinAddress addr; if (addr.Set(dest)) @@ -2130,7 +2130,7 @@ Value lockunspent(const Array& params, bool fHelp) return true; } - Array outputs = params[1].get_array(); + UniValue outputs = params[1].get_array(); for (unsigned int idx = 0; idx < outputs.size(); idx++) { const UniValue& output = outputs[idx]; if (!output.isObject()) @@ -2354,7 +2354,7 @@ Value listunspent(const Array& params, bool fHelp) set setAddress; if (params.size() > 2) { - Array inputs = params[2].get_array(); + UniValue inputs = params[2].get_array(); for (unsigned int idx = 0; idx < inputs.size(); idx++) { const Value& input = inputs[idx]; CBitcoinAddress address(input.get_str()); From d014114d67190672f9419aa865afc6f7875f5d71 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Mon, 18 May 2015 14:02:18 +0200 Subject: [PATCH 11/26] Remove JSON Spirit wrapper, remove JSON Spirit leftovers - implement find_value() function for UniValue - replace all Array/Value/Object types with UniValues, remove JSON Spirit to UniValue wrapper - remove JSON Spirit sources --- src/Makefile.am | 12 - src/bitcoin-cli.cpp | 15 +- src/json/LICENSE.txt | 24 - src/json/json_spirit.h | 18 - src/json/json_spirit_error_position.h | 54 --- src/json/json_spirit_reader.cpp | 137 ------ src/json/json_spirit_reader.h | 62 --- src/json/json_spirit_reader_template.h | 618 ------------------------- src/json/json_spirit_stream_reader.h | 70 --- src/json/json_spirit_utils.h | 61 --- src/json/json_spirit_value.cpp | 8 - src/json/json_spirit_value.h | 534 --------------------- src/json/json_spirit_writer.cpp | 95 ---- src/json/json_spirit_writer.h | 50 -- src/json/json_spirit_writer_template.h | 249 ---------- src/qt/rpcconsole.cpp | 4 - src/rest.cpp | 7 +- src/rpcblockchain.cpp | 35 +- src/rpcclient.cpp | 4 +- src/rpcmining.cpp | 31 +- src/rpcmisc.cpp | 21 +- src/rpcnet.cpp | 17 +- src/rpcprotocol.cpp | 10 +- src/rpcprotocol.h | 2 +- src/rpcrawtransaction.cpp | 36 +- src/rpcserver.cpp | 47 +- src/rpcserver.h | 3 +- src/test/base58_tests.cpp | 4 +- src/test/rpc_tests.cpp | 19 +- src/test/rpc_wallet_tests.cpp | 11 +- src/test/script_tests.cpp | 14 +- src/test/sighash_tests.cpp | 4 +- src/test/transaction_tests.cpp | 23 +- src/univalue/univalue.cpp | 12 + src/univalue/univalue.h | 4 + src/wallet/rpcdump.cpp | 13 +- src/wallet/rpcwallet.cpp | 93 ++-- 37 files changed, 212 insertions(+), 2209 deletions(-) delete mode 100644 src/json/LICENSE.txt delete mode 100644 src/json/json_spirit.h delete mode 100644 src/json/json_spirit_error_position.h delete mode 100644 src/json/json_spirit_reader.cpp delete mode 100644 src/json/json_spirit_reader.h delete mode 100644 src/json/json_spirit_reader_template.h delete mode 100644 src/json/json_spirit_stream_reader.h delete mode 100644 src/json/json_spirit_utils.h delete mode 100644 src/json/json_spirit_value.cpp delete mode 100644 src/json/json_spirit_value.h delete mode 100644 src/json/json_spirit_writer.cpp delete mode 100644 src/json/json_spirit_writer.h delete mode 100644 src/json/json_spirit_writer_template.h diff --git a/src/Makefile.am b/src/Makefile.am index 34434b8ab..2c3274673 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -182,17 +182,6 @@ BITCOIN_CORE_H = \ zmq/zmqpublishnotifier.h -JSON_H = \ - json/json_spirit.h \ - json/json_spirit_error_position.h \ - json/json_spirit_reader.h \ - json/json_spirit_reader_template.h \ - json/json_spirit_stream_reader.h \ - json/json_spirit_utils.h \ - json/json_spirit_value.h \ - json/json_spirit_writer.h \ - json/json_spirit_writer_template.h - obj/build.h: FORCE @$(MKDIR_P) $(builddir)/obj @$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \ @@ -233,7 +222,6 @@ libbitcoin_server_a_SOURCES = \ txdb.cpp \ txmempool.cpp \ validationinterface.cpp \ - $(JSON_H) \ $(BITCOIN_CORE_H) \ $(LIBZCASH_H) diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp index 97fc730cf..d589a5a7c 100644 --- a/src/bitcoin-cli.cpp +++ b/src/bitcoin-cli.cpp @@ -12,8 +12,9 @@ #include +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; std::string HelpMessageCli() { @@ -96,7 +97,7 @@ static bool AppInitRPC(int argc, char* argv[]) return true; } -UniValue CallRPC(const string& strMethod, const Array& params) +UniValue CallRPC(const string& strMethod, const UniValue& params) { // Connect to localhost bool fUseSSL = GetBoolArg("-rpcssl", false); @@ -155,7 +156,7 @@ UniValue CallRPC(const string& strMethod, const Array& params) UniValue valReply(UniValue::VSTR); if (!valReply.read(strReply)) throw runtime_error("couldn't parse reply from server"); - const Object& reply = valReply.get_obj(); + const UniValue& reply = valReply.get_obj(); if (reply.empty()) throw runtime_error("expected reply to have result, error and id properties"); @@ -189,13 +190,15 @@ int CommandLineRPC(int argc, char *argv[]) const UniValue reply = CallRPC(strMethod, params); // Parse reply - const Value& result = find_value(reply, "result"); - const Value& error = find_value(reply, "error"); + const UniValue& result = find_value(reply, "result"); + const UniValue& error = find_value(reply, "error"); if (!error.isNull()) { // Error - strPrint = "error: " + error.write(); int code = error["code"].get_int(); + if (fWait && code == RPC_IN_WARMUP) + throw CConnectionFailed("server in warmup"); + strPrint = "error: " + error.write(); nRet = abs(code); } else { // Result diff --git a/src/json/LICENSE.txt b/src/json/LICENSE.txt deleted file mode 100644 index 797d5363b..000000000 --- a/src/json/LICENSE.txt +++ /dev/null @@ -1,24 +0,0 @@ -The MIT License - -Copyright (c) 2007 - 2009 John W. Wilkinson - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/json/json_spirit.h b/src/json/json_spirit.h deleted file mode 100644 index ac1879d5b..000000000 --- a/src/json/json_spirit.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef JSON_SPIRIT -#define JSON_SPIRIT - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include "json_spirit_reader.h" -#include "json_spirit_writer.h" -#include "json_spirit_utils.h" - -#endif diff --git a/src/json/json_spirit_error_position.h b/src/json/json_spirit_error_position.h deleted file mode 100644 index 17208507d..000000000 --- a/src/json/json_spirit_error_position.h +++ /dev/null @@ -1,54 +0,0 @@ -#ifndef JSON_SPIRIT_ERROR_POSITION -#define JSON_SPIRIT_ERROR_POSITION - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include - -namespace json_spirit -{ - // An Error_position exception is thrown by the "read_or_throw" functions below on finding an error. - // Note the "read_or_throw" functions are around 3 times slower than the standard functions "read" - // functions that return a bool. - // - struct Error_position - { - Error_position(); - Error_position( unsigned int line, unsigned int column, const std::string& reason ); - bool operator==( const Error_position& lhs ) const; - unsigned int line_; - unsigned int column_; - std::string reason_; - }; - - inline Error_position::Error_position() - : line_( 0 ) - , column_( 0 ) - { - } - - inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason ) - : line_( line ) - , column_( column ) - , reason_( reason ) - { - } - - inline bool Error_position::operator==( const Error_position& lhs ) const - { - if( this == &lhs ) return true; - - return ( reason_ == lhs.reason_ ) && - ( line_ == lhs.line_ ) && - ( column_ == lhs.column_ ); -} -} - -#endif diff --git a/src/json/json_spirit_reader.cpp b/src/json/json_spirit_reader.cpp deleted file mode 100644 index aa4f63722..000000000 --- a/src/json/json_spirit_reader.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_reader.h" -#include "json_spirit_reader_template.h" - -using namespace json_spirit; - -bool json_spirit::read( const std::string& s, Value& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::string& s, Value& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::istream& is, Value& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::istream& is, Value& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#ifndef BOOST_NO_STD_WSTRING - -bool json_spirit::read( const std::wstring& s, wValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::wstring& s, wValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::wistream& is, wValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::wistream& is, wValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#endif - -bool json_spirit::read( const std::string& s, mValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::string& s, mValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::istream& is, mValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::istream& is, mValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#ifndef BOOST_NO_STD_WSTRING - -bool json_spirit::read( const std::wstring& s, wmValue& value ) -{ - return read_string( s, value ); -} - -void json_spirit::read_or_throw( const std::wstring& s, wmValue& value ) -{ - read_string_or_throw( s, value ); -} - -bool json_spirit::read( std::wistream& is, wmValue& value ) -{ - return read_stream( is, value ); -} - -void json_spirit::read_or_throw( std::wistream& is, wmValue& value ) -{ - read_stream_or_throw( is, value ); -} - -bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) -{ - return read_range( begin, end, value ); -} - -void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ) -{ - begin = read_range_or_throw( begin, end, value ); -} - -#endif diff --git a/src/json/json_spirit_reader.h b/src/json/json_spirit_reader.h deleted file mode 100644 index 96494a978..000000000 --- a/src/json/json_spirit_reader.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef JSON_SPIRIT_READER -#define JSON_SPIRIT_READER - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include "json_spirit_error_position.h" -#include - -namespace json_spirit -{ - // functions to reads a JSON values - - bool read( const std::string& s, Value& value ); - bool read( std::istream& is, Value& value ); - bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); - - void read_or_throw( const std::string& s, Value& value ); - void read_or_throw( std::istream& is, Value& value ); - void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value ); - -#ifndef BOOST_NO_STD_WSTRING - - bool read( const std::wstring& s, wValue& value ); - bool read( std::wistream& is, wValue& value ); - bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); - - void read_or_throw( const std::wstring& s, wValue& value ); - void read_or_throw( std::wistream& is, wValue& value ); - void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value ); - -#endif - - bool read( const std::string& s, mValue& value ); - bool read( std::istream& is, mValue& value ); - bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); - - void read_or_throw( const std::string& s, mValue& value ); - void read_or_throw( std::istream& is, mValue& value ); - void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value ); - -#ifndef BOOST_NO_STD_WSTRING - - bool read( const std::wstring& s, wmValue& value ); - bool read( std::wistream& is, wmValue& value ); - bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); - - void read_or_throw( const std::wstring& s, wmValue& value ); - void read_or_throw( std::wistream& is, wmValue& value ); - void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value ); - -#endif -} - -#endif diff --git a/src/json/json_spirit_reader_template.h b/src/json/json_spirit_reader_template.h deleted file mode 100644 index 33aa0958e..000000000 --- a/src/json/json_spirit_reader_template.h +++ /dev/null @@ -1,618 +0,0 @@ -#ifndef JSON_SPIRIT_READER_TEMPLATE -#define JSON_SPIRIT_READER_TEMPLATE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_value.h" -#include "json_spirit_error_position.h" - -//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread - -#include -#include -#include - -#if BOOST_VERSION >= 103800 - #include - #include - #include - #include - #include - #define spirit_namespace boost::spirit::classic -#else - #include - #include - #include - #include - #include - #define spirit_namespace boost::spirit -#endif - -namespace json_spirit -{ - const spirit_namespace::int_parser < int64_t > int64_p = spirit_namespace::int_parser < int64_t >(); - const spirit_namespace::uint_parser< uint64_t > uint64_p = spirit_namespace::uint_parser< uint64_t >(); - - template< class Iter_type > - bool is_eq( Iter_type first, Iter_type last, const char* c_str ) - { - for( Iter_type i = first; i != last; ++i, ++c_str ) - { - if( *c_str == 0 ) return false; - - if( *i != *c_str ) return false; - } - - return true; - } - - template< class Char_type > - Char_type hex_to_num( const Char_type c ) - { - if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0'; - if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10; - if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10; - return 0; - } - - template< class Char_type, class Iter_type > - Char_type hex_str_to_char( Iter_type& begin ) - { - const Char_type c1( *( ++begin ) ); - const Char_type c2( *( ++begin ) ); - - return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 ); - } - - template< class Char_type, class Iter_type > - Char_type unicode_str_to_char( Iter_type& begin ) - { - const Char_type c1( *( ++begin ) ); - const Char_type c2( *( ++begin ) ); - const Char_type c3( *( ++begin ) ); - const Char_type c4( *( ++begin ) ); - - return ( hex_to_num( c1 ) << 12 ) + - ( hex_to_num( c2 ) << 8 ) + - ( hex_to_num( c3 ) << 4 ) + - hex_to_num( c4 ); - } - - template< class String_type > - void append_esc_char_and_incr_iter( String_type& s, - typename String_type::const_iterator& begin, - typename String_type::const_iterator end ) - { - typedef typename String_type::value_type Char_type; - - const Char_type c2( *begin ); - - switch( c2 ) - { - case 't': s += '\t'; break; - case 'b': s += '\b'; break; - case 'f': s += '\f'; break; - case 'n': s += '\n'; break; - case 'r': s += '\r'; break; - case '\\': s += '\\'; break; - case '/': s += '/'; break; - case '"': s += '"'; break; - case 'x': - { - if( end - begin >= 3 ) // expecting "xHH..." - { - s += hex_str_to_char< Char_type >( begin ); - } - break; - } - case 'u': - { - if( end - begin >= 5 ) // expecting "uHHHH..." - { - s += unicode_str_to_char< Char_type >( begin ); - } - break; - } - } - } - - template< class String_type > - String_type substitute_esc_chars( typename String_type::const_iterator begin, - typename String_type::const_iterator end ) - { - typedef typename String_type::const_iterator Iter_type; - - if( end - begin < 2 ) return String_type( begin, end ); - - String_type result; - - result.reserve( end - begin ); - - const Iter_type end_minus_1( end - 1 ); - - Iter_type substr_start = begin; - Iter_type i = begin; - - for( ; i < end_minus_1; ++i ) - { - if( *i == '\\' ) - { - result.append( substr_start, i ); - - ++i; // skip the '\' - - append_esc_char_and_incr_iter( result, i, end ); - - substr_start = i + 1; - } - } - - result.append( substr_start, end ); - - return result; - } - - template< class String_type > - String_type get_str_( typename String_type::const_iterator begin, - typename String_type::const_iterator end ) - { - assert( end - begin >= 2 ); - - typedef typename String_type::const_iterator Iter_type; - - Iter_type str_without_quotes( ++begin ); - Iter_type end_without_quotes( --end ); - - return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes ); - } - - inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end ) - { - return get_str_< std::string >( begin, end ); - } - - inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end ) - { - return get_str_< std::wstring >( begin, end ); - } - - template< class String_type, class Iter_type > - String_type get_str( Iter_type begin, Iter_type end ) - { - const String_type tmp( begin, end ); // convert multipass iterators to string iterators - - return get_str( tmp.begin(), tmp.end() ); - } - - // this class's methods get called by the spirit parse resulting - // in the creation of a JSON object or array - // - // NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator - // - template< class Value_type, class Iter_type > - class Semantic_actions - { - public: - - typedef typename Value_type::Config_type Config_type; - typedef typename Config_type::String_type String_type; - typedef typename Config_type::Object_type Object_type; - typedef typename Config_type::Array_type Array_type; - typedef typename String_type::value_type Char_type; - - Semantic_actions( Value_type& value ) - : value_( value ) - , current_p_( 0 ) - { - } - - void begin_obj( Char_type c ) - { - assert( c == '{' ); - - begin_compound< Object_type >(); - } - - void end_obj( Char_type c ) - { - assert( c == '}' ); - - end_compound(); - } - - void begin_array( Char_type c ) - { - assert( c == '[' ); - - begin_compound< Array_type >(); - } - - void end_array( Char_type c ) - { - assert( c == ']' ); - - end_compound(); - } - - void new_name( Iter_type begin, Iter_type end ) - { - assert( current_p_->type() == obj_type ); - - name_ = get_str< String_type >( begin, end ); - } - - void new_str( Iter_type begin, Iter_type end ) - { - add_to_current( get_str< String_type >( begin, end ) ); - } - - void new_true( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "true" ) ); - - add_to_current( true ); - } - - void new_false( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "false" ) ); - - add_to_current( false ); - } - - void new_null( Iter_type begin, Iter_type end ) - { - assert( is_eq( begin, end, "null" ) ); - - add_to_current( Value_type() ); - } - - void new_int( int64_t i ) - { - add_to_current( i ); - } - - void new_uint64( uint64_t ui ) - { - add_to_current( ui ); - } - - void new_real( double d ) - { - add_to_current( d ); - } - - private: - - Semantic_actions& operator=( const Semantic_actions& ); - // to prevent "assignment operator could not be generated" warning - - Value_type* add_first( const Value_type& value ) - { - assert( current_p_ == 0 ); - - value_ = value; - current_p_ = &value_; - return current_p_; - } - - template< class Array_or_obj > - void begin_compound() - { - if( current_p_ == 0 ) - { - add_first( Array_or_obj() ); - } - else - { - // ZCASH: Prevent potential stack overflow by setting a limit on the number of nested compound elements - if (stack_.size() > 128) { - throw std::domain_error("too many nested elements"); - } - // ENDZCASH - - stack_.push_back( current_p_ ); - - Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place - - current_p_ = add_to_current( new_array_or_obj ); - } - } - - void end_compound() - { - if( current_p_ != &value_ ) - { - current_p_ = stack_.back(); - - stack_.pop_back(); - } - } - - Value_type* add_to_current( const Value_type& value ) - { - if( current_p_ == 0 ) - { - return add_first( value ); - } - else if( current_p_->type() == array_type ) - { - current_p_->get_array().push_back( value ); - - return ¤t_p_->get_array().back(); - } - - assert( current_p_->type() == obj_type ); - - return &Config_type::add( current_p_->get_obj(), name_, value ); - } - - Value_type& value_; // this is the object or array that is being created - Value_type* current_p_; // the child object or array that is currently being constructed - - std::vector< Value_type* > stack_; // previous child objects and arrays - - String_type name_; // of current name/value pair - }; - - template< typename Iter_type > - void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason ) - { - throw Error_position( i.get_position().line, i.get_position().column, reason ); - } - - template< typename Iter_type > - void throw_error( Iter_type i, const std::string& reason ) - { - throw reason; - } - - // the spirit grammer - // - template< class Value_type, class Iter_type > - class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > > - { - public: - - typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t; - - Json_grammer( Semantic_actions_t& semantic_actions ) - : actions_( semantic_actions ) - { - } - - static void throw_not_value( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a value" ); - } - - static void throw_not_array( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not an array" ); - } - - static void throw_not_object( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not an object" ); - } - - static void throw_not_pair( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a pair" ); - } - - static void throw_not_colon( Iter_type begin, Iter_type end ) - { - throw_error( begin, "no colon in pair" ); - } - - static void throw_not_string( Iter_type begin, Iter_type end ) - { - throw_error( begin, "not a string" ); - } - - template< typename ScannerT > - class definition - { - public: - - definition( const Json_grammer& self ) - { - using namespace spirit_namespace; - - typedef typename Value_type::String_type::value_type Char_type; - - // first we convert the semantic action class methods to functors with the - // parameter signature expected by spirit - - typedef boost::function< void( Char_type ) > Char_action; - typedef boost::function< void( Iter_type, Iter_type ) > Str_action; - typedef boost::function< void( double ) > Real_action; - typedef boost::function< void( int64_t ) > Int_action; - typedef boost::function< void( uint64_t ) > Uint64_action; - - Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) ); - Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) ); - Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) ); - Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) ); - Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) ); - Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) ); - Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) ); - Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) ); - Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) ); - Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) ); - Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) ); - Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) ); - - // actual grammer - - json_ - = value_ | eps_p[ &throw_not_value ] - ; - - value_ - = string_[ new_str ] - | number_ - | object_ - | array_ - | str_p( "true" ) [ new_true ] - | str_p( "false" )[ new_false ] - | str_p( "null" ) [ new_null ] - ; - - object_ - = ch_p('{')[ begin_obj ] - >> !members_ - >> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] ) - ; - - members_ - = pair_ >> *( ',' >> pair_ ) - ; - - pair_ - = string_[ new_name ] - >> ( ':' | eps_p[ &throw_not_colon ] ) - >> ( value_ | eps_p[ &throw_not_value ] ) - ; - - array_ - = ch_p('[')[ begin_array ] - >> !elements_ - >> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] ) - ; - - elements_ - = value_ >> *( ',' >> value_ ) - ; - - string_ - = lexeme_d // this causes white space inside a string to be retained - [ - confix_p - ( - '"', - *lex_escape_ch_p, - '"' - ) - ] - ; - - number_ - = strict_real_p[ new_real ] - | int64_p [ new_int ] - | uint64_p [ new_uint64 ] - ; - } - - spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_; - - const spirit_namespace::rule< ScannerT >& start() const { return json_; } - }; - - private: - - Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning - - Semantic_actions_t& actions_; - }; - - template< class Iter_type, class Value_type > - Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) - { - Semantic_actions< Value_type, Iter_type > semantic_actions( value ); - - const spirit_namespace::parse_info< Iter_type > info = - spirit_namespace::parse( begin, end, - Json_grammer< Value_type, Iter_type >( semantic_actions ) >> spirit_namespace::end_p, - spirit_namespace::space_p ); - - if( !info.hit ) - { - throw_error( info.stop, "error" ); - } - - return info.stop; - } - - template< class Iter_type, class Value_type > - void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value ) - { - typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t; - - const Posn_iter_t posn_begin( begin, end ); - const Posn_iter_t posn_end( end, end ); - - read_range_or_throw( posn_begin, posn_end, value ); - } - - template< class Iter_type, class Value_type > - bool read_range( Iter_type& begin, Iter_type end, Value_type& value ) - { - try - { - begin = read_range_or_throw( begin, end, value ); - - return true; - } - catch( ... ) - { - return false; - } - } - - template< class String_type, class Value_type > - void read_string_or_throw( const String_type& s, Value_type& value ) - { - add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value ); - } - - template< class String_type, class Value_type > - bool read_string( const String_type& s, Value_type& value ) - { - typename String_type::const_iterator begin = s.begin(); - - bool success = read_range( begin, s.end(), value ); - return success && begin == s.end(); - } - - template< class Istream_type > - struct Multi_pass_iters - { - typedef typename Istream_type::char_type Char_type; - typedef std::istream_iterator< Char_type, Char_type > istream_iter; - typedef spirit_namespace::multi_pass< istream_iter > Mp_iter; - - Multi_pass_iters( Istream_type& is ) - { - is.unsetf( std::ios::skipws ); - - begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) ); - end_ = spirit_namespace::make_multi_pass( istream_iter() ); - } - - Mp_iter begin_; - Mp_iter end_; - }; - - template< class Istream_type, class Value_type > - bool read_stream( Istream_type& is, Value_type& value ) - { - Multi_pass_iters< Istream_type > mp_iters( is ); - - return read_range( mp_iters.begin_, mp_iters.end_, value ); - } - - template< class Istream_type, class Value_type > - void read_stream_or_throw( Istream_type& is, Value_type& value ) - { - const Multi_pass_iters< Istream_type > mp_iters( is ); - - add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value ); - } -} - -#endif diff --git a/src/json/json_spirit_stream_reader.h b/src/json/json_spirit_stream_reader.h deleted file mode 100644 index 7e59c9adc..000000000 --- a/src/json/json_spirit_stream_reader.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef JSON_SPIRIT_READ_STREAM -#define JSON_SPIRIT_READ_STREAM - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_reader_template.h" - -namespace json_spirit -{ - // these classes allows you to read multiple top level contiguous values from a stream, - // the normal stream read functions have a bug that prevent multiple top level values - // from being read unless they are separated by spaces - - template< class Istream_type, class Value_type > - class Stream_reader - { - public: - - Stream_reader( Istream_type& is ) - : iters_( is ) - { - } - - bool read_next( Value_type& value ) - { - return read_range( iters_.begin_, iters_.end_, value ); - } - - private: - - typedef Multi_pass_iters< Istream_type > Mp_iters; - - Mp_iters iters_; - }; - - template< class Istream_type, class Value_type > - class Stream_reader_thrower - { - public: - - Stream_reader_thrower( Istream_type& is ) - : iters_( is ) - , posn_begin_( iters_.begin_, iters_.end_ ) - , posn_end_( iters_.end_, iters_.end_ ) - { - } - - void read_next( Value_type& value ) - { - posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value ); - } - - private: - - typedef Multi_pass_iters< Istream_type > Mp_iters; - typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t; - - Mp_iters iters_; - Posn_iter_t posn_begin_, posn_end_; - }; -} - -#endif diff --git a/src/json/json_spirit_utils.h b/src/json/json_spirit_utils.h deleted file mode 100644 index 553e3b96a..000000000 --- a/src/json/json_spirit_utils.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef JSON_SPIRIT_UTILS -#define JSON_SPIRIT_UTILS - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include - -namespace json_spirit -{ - template< class Obj_t, class Map_t > - void obj_to_map( const Obj_t& obj, Map_t& mp_obj ) - { - mp_obj.clear(); - - for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i ) - { - mp_obj[ i->name_ ] = i->value_; - } - } - - template< class Obj_t, class Map_t > - void map_to_obj( const Map_t& mp_obj, Obj_t& obj ) - { - obj.clear(); - - for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i ) - { - obj.push_back( typename Obj_t::value_type( i->first, i->second ) ); - } - } - - typedef std::map< std::string, Value > Mapped_obj; - -#ifndef BOOST_NO_STD_WSTRING - typedef std::map< std::wstring, wValue > wMapped_obj; -#endif - - template< class Object_type, class String_type > - const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name ) - { - for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i ) - { - if( i->name_ == name ) - { - return i->value_; - } - } - - return Object_type::value_type::Value_type::null; - } -} - -#endif diff --git a/src/json/json_spirit_value.cpp b/src/json/json_spirit_value.cpp deleted file mode 100644 index 44d2f06a0..000000000 --- a/src/json/json_spirit_value.cpp +++ /dev/null @@ -1,8 +0,0 @@ -/* Copyright (c) 2007 John W Wilkinson - - This source code can be used for any purpose as long as - this comment is retained. */ - -// json spirit version 2.00 - -#include "json_spirit_value.h" diff --git a/src/json/json_spirit_value.h b/src/json/json_spirit_value.h deleted file mode 100644 index 13cc89210..000000000 --- a/src/json/json_spirit_value.h +++ /dev/null @@ -1,534 +0,0 @@ -#ifndef JSON_SPIRIT_VALUE -#define JSON_SPIRIT_VALUE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace json_spirit -{ - enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type }; - static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"}; - - template< class Config > // Config determines whether the value uses std::string or std::wstring and - // whether JSON Objects are represented as vectors or maps - class Value_impl - { - public: - - typedef Config Config_type; - typedef typename Config::String_type String_type; - typedef typename Config::Object_type Object; - typedef typename Config::Array_type Array; - typedef typename String_type::const_pointer Const_str_ptr; // eg const char* - - Value_impl(); // creates null value - Value_impl( Const_str_ptr value ); - Value_impl( const String_type& value ); - Value_impl( const Object& value ); - Value_impl( const Array& value ); - Value_impl( bool value ); - Value_impl( int value ); - Value_impl( int64_t value ); - Value_impl( uint64_t value ); - Value_impl( double value ); - - Value_impl( const Value_impl& other ); - - bool operator==( const Value_impl& lhs ) const; - - Value_impl& operator=( const Value_impl& lhs ); - - Value_type type() const; - - bool is_uint64() const; - bool is_null() const; - - const String_type& get_str() const; - const Object& get_obj() const; - const Array& get_array() const; - bool get_bool() const; - int get_int() const; - int64_t get_int64() const; - uint64_t get_uint64() const; - double get_real() const; - - Object& get_obj(); - Array& get_array(); - - template< typename T > T get_value() const; // example usage: int i = value.get_value< int >(); - // or double d = value.get_value< double >(); - - static const Value_impl null; - - private: - - void check_type( const Value_type vtype ) const; - - typedef boost::variant< String_type, - boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, - bool, int64_t, double > Variant; - - Value_type type_; - Variant v_; - bool is_uint64_; - }; - - // vector objects - - template< class Config > - struct Pair_impl - { - typedef typename Config::String_type String_type; - typedef typename Config::Value_type Value_type; - - Pair_impl( const String_type& name, const Value_type& value ); - - bool operator==( const Pair_impl& lhs ) const; - - String_type name_; - Value_type value_; - }; - - template< class String > - struct Config_vector - { - typedef String String_type; - typedef Value_impl< Config_vector > Value_type; - typedef Pair_impl < Config_vector > Pair_type; - typedef std::vector< Value_type > Array_type; - typedef std::vector< Pair_type > Object_type; - - static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) - { - obj.push_back( Pair_type( name , value ) ); - - return obj.back().value_; - } - - static String_type get_name( const Pair_type& pair ) - { - return pair.name_; - } - - static Value_type get_value( const Pair_type& pair ) - { - return pair.value_; - } - }; - - // typedefs for ASCII - - typedef Config_vector< std::string > Config; - - typedef Config::Value_type Value; - typedef Config::Pair_type Pair; - typedef Config::Object_type Object; - typedef Config::Array_type Array; - - // typedefs for Unicode - -#ifndef BOOST_NO_STD_WSTRING - - typedef Config_vector< std::wstring > wConfig; - - typedef wConfig::Value_type wValue; - typedef wConfig::Pair_type wPair; - typedef wConfig::Object_type wObject; - typedef wConfig::Array_type wArray; -#endif - - // map objects - - template< class String > - struct Config_map - { - typedef String String_type; - typedef Value_impl< Config_map > Value_type; - typedef std::vector< Value_type > Array_type; - typedef std::map< String_type, Value_type > Object_type; - typedef typename Object_type::value_type Pair_type; - - static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value ) - { - return obj[ name ] = value; - } - - static String_type get_name( const Pair_type& pair ) - { - return pair.first; - } - - static Value_type get_value( const Pair_type& pair ) - { - return pair.second; - } - }; - - // typedefs for ASCII - - typedef Config_map< std::string > mConfig; - - typedef mConfig::Value_type mValue; - typedef mConfig::Object_type mObject; - typedef mConfig::Array_type mArray; - - // typedefs for Unicode - -#ifndef BOOST_NO_STD_WSTRING - - typedef Config_map< std::wstring > wmConfig; - - typedef wmConfig::Value_type wmValue; - typedef wmConfig::Object_type wmObject; - typedef wmConfig::Array_type wmArray; - -#endif - - /////////////////////////////////////////////////////////////////////////////////////////////// - // - // implementation - - template< class Config > - const Value_impl< Config > Value_impl< Config >::null; - - template< class Config > - Value_impl< Config >::Value_impl() - : type_( null_type ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Const_str_ptr value ) - : type_( str_type ) - , v_( String_type( value ) ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const String_type& value ) - : type_( str_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Object& value ) - : type_( obj_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Array& value ) - : type_( array_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( bool value ) - : type_( bool_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( int value ) - : type_( int_type ) - , v_( static_cast< int64_t >( value ) ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( int64_t value ) - : type_( int_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( uint64_t value ) - : type_( int_type ) - , v_( static_cast< int64_t >( value ) ) - , is_uint64_( true ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( double value ) - : type_( real_type ) - , v_( value ) - , is_uint64_( false ) - { - } - - template< class Config > - Value_impl< Config >::Value_impl( const Value_impl< Config >& other ) - : type_( other.type() ) - , v_( other.v_ ) - , is_uint64_( other.is_uint64_ ) - { - } - - template< class Config > - Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs ) - { - Value_impl tmp( lhs ); - - std::swap( type_, tmp.type_ ); - std::swap( v_, tmp.v_ ); - std::swap( is_uint64_, tmp.is_uint64_ ); - - return *this; - } - - template< class Config > - bool Value_impl< Config >::operator==( const Value_impl& lhs ) const - { - if( this == &lhs ) return true; - - if( type() != lhs.type() ) return false; - - return v_ == lhs.v_; - } - - template< class Config > - Value_type Value_impl< Config >::type() const - { - return type_; - } - - template< class Config > - bool Value_impl< Config >::is_uint64() const - { - return is_uint64_; - } - - template< class Config > - bool Value_impl< Config >::is_null() const - { - return type() == null_type; - } - - template< class Config > - void Value_impl< Config >::check_type( const Value_type vtype ) const - { - if( type() != vtype ) - { - std::ostringstream os; - - ///// Bitcoin: Tell the types by name instead of by number - os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype]; - - throw std::runtime_error( os.str() ); - } - } - - template< class Config > - const typename Config::String_type& Value_impl< Config >::get_str() const - { - check_type( str_type ); - - return *boost::get< String_type >( &v_ ); - } - - template< class Config > - const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const - { - check_type( obj_type ); - - return *boost::get< Object >( &v_ ); - } - - template< class Config > - const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const - { - check_type( array_type ); - - return *boost::get< Array >( &v_ ); - } - - template< class Config > - bool Value_impl< Config >::get_bool() const - { - check_type( bool_type ); - - return boost::get< bool >( v_ ); - } - - template< class Config > - int Value_impl< Config >::get_int() const - { - check_type( int_type ); - - return static_cast< int >( get_int64() ); - } - - template< class Config > - int64_t Value_impl< Config >::get_int64() const - { - check_type( int_type ); - - return boost::get< int64_t >( v_ ); - } - - template< class Config > - uint64_t Value_impl< Config >::get_uint64() const - { - check_type( int_type ); - - return static_cast< uint64_t >( get_int64() ); - } - - template< class Config > - double Value_impl< Config >::get_real() const - { - if( type() == int_type ) - { - return is_uint64() ? static_cast< double >( get_uint64() ) - : static_cast< double >( get_int64() ); - } - - check_type( real_type ); - - return boost::get< double >( v_ ); - } - - template< class Config > - typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() - { - check_type( obj_type ); - - return *boost::get< Object >( &v_ ); - } - - template< class Config > - typename Value_impl< Config >::Array& Value_impl< Config >::get_array() - { - check_type( array_type ); - - return *boost::get< Array >( &v_ ); - } - - template< class Config > - Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value ) - : name_( name ) - , value_( value ) - { - } - - template< class Config > - bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const - { - if( this == &lhs ) return true; - - return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ ); - } - - // converts a C string, ie. 8 bit char array, to a string object - // - template < class String_type > - String_type to_str( const char* c_str ) - { - String_type result; - - for( const char* p = c_str; *p != 0; ++p ) - { - result += *p; - } - - return result; - } - - // - - namespace internal_ - { - template< typename T > - struct Type_to_type - { - }; - - template< class Value > - int get_value( const Value& value, Type_to_type< int > ) - { - return value.get_int(); - } - - template< class Value > - int64_t get_value( const Value& value, Type_to_type< int64_t > ) - { - return value.get_int64(); - } - - template< class Value > - uint64_t get_value( const Value& value, Type_to_type< uint64_t > ) - { - return value.get_uint64(); - } - - template< class Value > - double get_value( const Value& value, Type_to_type< double > ) - { - return value.get_real(); - } - - template< class Value > - typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > ) - { - return value.get_str(); - } - - template< class Value > - typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > ) - { - return value.get_array(); - } - - template< class Value > - typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > ) - { - return value.get_obj(); - } - - template< class Value > - bool get_value( const Value& value, Type_to_type< bool > ) - { - return value.get_bool(); - } - } - - template< class Config > - template< typename T > - T Value_impl< Config >::get_value() const - { - return internal_::get_value( *this, internal_::Type_to_type< T >() ); - } -} - -#endif diff --git a/src/json/json_spirit_writer.cpp b/src/json/json_spirit_writer.cpp deleted file mode 100644 index d24a632cf..000000000 --- a/src/json/json_spirit_writer.cpp +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_writer.h" -#include "json_spirit_writer_template.h" - -void json_spirit::write( const Value& value, std::ostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const Value& value, std::ostream& os ) -{ - write_stream( value, os, true ); -} - -std::string json_spirit::write( const Value& value ) -{ - return write_string( value, false ); -} - -std::string json_spirit::write_formatted( const Value& value ) -{ - return write_string( value, true ); -} - -#ifndef BOOST_NO_STD_WSTRING - -void json_spirit::write( const wValue& value, std::wostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const wValue& value, std::wostream& os ) -{ - write_stream( value, os, true ); -} - -std::wstring json_spirit::write( const wValue& value ) -{ - return write_string( value, false ); -} - -std::wstring json_spirit::write_formatted( const wValue& value ) -{ - return write_string( value, true ); -} - -#endif - -void json_spirit::write( const mValue& value, std::ostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const mValue& value, std::ostream& os ) -{ - write_stream( value, os, true ); -} - -std::string json_spirit::write( const mValue& value ) -{ - return write_string( value, false ); -} - -std::string json_spirit::write_formatted( const mValue& value ) -{ - return write_string( value, true ); -} - -#ifndef BOOST_NO_STD_WSTRING - -void json_spirit::write( const wmValue& value, std::wostream& os ) -{ - write_stream( value, os, false ); -} - -void json_spirit::write_formatted( const wmValue& value, std::wostream& os ) -{ - write_stream( value, os, true ); -} - -std::wstring json_spirit::write( const wmValue& value ) -{ - return write_string( value, false ); -} - -std::wstring json_spirit::write_formatted( const wmValue& value ) -{ - return write_string( value, true ); -} - -#endif diff --git a/src/json/json_spirit_writer.h b/src/json/json_spirit_writer.h deleted file mode 100644 index 52e14068e..000000000 --- a/src/json/json_spirit_writer.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef JSON_SPIRIT_WRITER -#define JSON_SPIRIT_WRITER - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - -#include "json_spirit_value.h" -#include - -namespace json_spirit -{ - // functions to convert JSON Values to text, - // the "formatted" versions add whitespace to format the output nicely - - void write ( const Value& value, std::ostream& os ); - void write_formatted( const Value& value, std::ostream& os ); - std::string write ( const Value& value ); - std::string write_formatted( const Value& value ); - -#ifndef BOOST_NO_STD_WSTRING - - void write ( const wValue& value, std::wostream& os ); - void write_formatted( const wValue& value, std::wostream& os ); - std::wstring write ( const wValue& value ); - std::wstring write_formatted( const wValue& value ); - -#endif - - void write ( const mValue& value, std::ostream& os ); - void write_formatted( const mValue& value, std::ostream& os ); - std::string write ( const mValue& value ); - std::string write_formatted( const mValue& value ); - -#ifndef BOOST_NO_STD_WSTRING - - void write ( const wmValue& value, std::wostream& os ); - void write_formatted( const wmValue& value, std::wostream& os ); - std::wstring write ( const wmValue& value ); - std::wstring write_formatted( const wmValue& value ); - -#endif -} - -#endif diff --git a/src/json/json_spirit_writer_template.h b/src/json/json_spirit_writer_template.h deleted file mode 100644 index 6b4978a1f..000000000 --- a/src/json/json_spirit_writer_template.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef JSON_SPIRIT_WRITER_TEMPLATE -#define JSON_SPIRIT_WRITER_TEMPLATE - -// Copyright John W. Wilkinson 2007 - 2009. -// Distributed under the MIT License, see accompanying file LICENSE.txt - -// json spirit version 4.03 - -#include "json_spirit_value.h" - -#include -#include -#include - -namespace json_spirit -{ - inline char to_hex_char( unsigned int c ) - { - assert( c <= 0xF ); - - const char ch = static_cast< char >( c ); - - if( ch < 10 ) return '0' + ch; - - return 'A' - 10 + ch; - } - - template< class String_type > - String_type non_printable_to_string( unsigned int c ) - { - // Silence the warning: typedef ‘Char_type’ locally defined but not used [-Wunused-local-typedefs] - // typedef typename String_type::value_type Char_type; - - String_type result( 6, '\\' ); - - result[1] = 'u'; - - result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4; - result[ 2 ] = to_hex_char( c & 0x000F ); - - return result; - } - - template< typename Char_type, class String_type > - bool add_esc_char( Char_type c, String_type& s ) - { - switch( c ) - { - case '"': s += to_str< String_type >( "\\\"" ); return true; - case '\\': s += to_str< String_type >( "\\\\" ); return true; - case '\b': s += to_str< String_type >( "\\b" ); return true; - case '\f': s += to_str< String_type >( "\\f" ); return true; - case '\n': s += to_str< String_type >( "\\n" ); return true; - case '\r': s += to_str< String_type >( "\\r" ); return true; - case '\t': s += to_str< String_type >( "\\t" ); return true; - } - - return false; - } - - template< class String_type > - String_type add_esc_chars( const String_type& s ) - { - typedef typename String_type::const_iterator Iter_type; - typedef typename String_type::value_type Char_type; - - String_type result; - - const Iter_type end( s.end() ); - - for( Iter_type i = s.begin(); i != end; ++i ) - { - const Char_type c( *i ); - - if( add_esc_char( c, result ) ) continue; - - const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c ); - - if( iswprint( unsigned_c ) ) - { - result += c; - } - else - { - result += non_printable_to_string< String_type >( unsigned_c ); - } - } - - return result; - } - - // this class generates the JSON text, - // it keeps track of the indentation level etc. - // - template< class Value_type, class Ostream_type > - class Generator - { - typedef typename Value_type::Config_type Config_type; - typedef typename Config_type::String_type String_type; - typedef typename Config_type::Object_type Object_type; - typedef typename Config_type::Array_type Array_type; - typedef typename String_type::value_type Char_type; - typedef typename Object_type::value_type Obj_member_type; - - public: - - Generator( const Value_type& value, Ostream_type& os, bool pretty ) - : os_( os ) - , indentation_level_( 0 ) - , pretty_( pretty ) - { - output( value ); - } - - private: - - void output( const Value_type& value ) - { - switch( value.type() ) - { - case obj_type: output( value.get_obj() ); break; - case array_type: output( value.get_array() ); break; - case str_type: output( value.get_str() ); break; - case bool_type: output( value.get_bool() ); break; - case int_type: output_int( value ); break; - - /// Bitcoin: Added std::fixed and changed precision from 16 to 8 - case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8) - << value.get_real(); break; - - case null_type: os_ << "null"; break; - default: assert( false ); - } - } - - void output( const Object_type& obj ) - { - output_array_or_obj( obj, '{', '}' ); - } - - void output( const Array_type& arr ) - { - output_array_or_obj( arr, '[', ']' ); - } - - void output( const Obj_member_type& member ) - { - output( Config_type::get_name( member ) ); space(); - os_ << ':'; space(); - output( Config_type::get_value( member ) ); - } - - void output_int( const Value_type& value ) - { - if( value.is_uint64() ) - { - os_ << value.get_uint64(); - } - else - { - os_ << value.get_int64(); - } - } - - void output( const String_type& s ) - { - os_ << '"' << add_esc_chars( s ) << '"'; - } - - void output( bool b ) - { - os_ << to_str< String_type >( b ? "true" : "false" ); - } - - template< class T > - void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char ) - { - os_ << start_char; new_line(); - - ++indentation_level_; - - for( typename T::const_iterator i = t.begin(); i != t.end(); ++i ) - { - indent(); output( *i ); - - typename T::const_iterator next = i; - - if( ++next != t.end()) - { - os_ << ','; - } - - new_line(); - } - - --indentation_level_; - - indent(); os_ << end_char; - } - - void indent() - { - if( !pretty_ ) return; - - for( int i = 0; i < indentation_level_; ++i ) - { - os_ << " "; - } - } - - void space() - { - if( pretty_ ) os_ << ' '; - } - - void new_line() - { - if( pretty_ ) os_ << '\n'; - } - - Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning - - Ostream_type& os_; - int indentation_level_; - bool pretty_; - }; - - template< class Value_type, class Ostream_type > - void write_stream( const Value_type& value, Ostream_type& os, bool pretty ) - { - Generator< Value_type, Ostream_type >( value, os, pretty ); - } - - template< class Value_type > - typename Value_type::String_type write_string( const Value_type& value, bool pretty ) - { - typedef typename Value_type::String_type::value_type Char_type; - - std::basic_ostringstream< Char_type > os; - - write_stream( value, os, pretty ); - - return os.str(); - } -} - -#endif diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 25ccf42d2..feb282644 100644 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -181,11 +181,7 @@ void RPCExecutor::request(const QString &command) Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint)); } -<<<<<<< HEAD - catch (const json_spirit::Object& objError) -======= catch (UniValue& objError) ->>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { try // Nice formatting for standard-format error { diff --git a/src/rest.cpp b/src/rest.cpp index 3142b2503..1fce7dfc9 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -16,8 +16,9 @@ #include #include +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; static const int MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once @@ -61,9 +62,9 @@ public: string message; }; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); -extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); +extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); static RestErr RESTERR(enum HTTPStatusCode status, string message) { diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 0bec434f5..205d7df2c 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -13,13 +13,12 @@ #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; -extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry); -void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex); +extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry); +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex); double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty) { @@ -116,7 +115,7 @@ UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool tx } -UniValue getblockcount(const Array& params, bool fHelp) +UniValue getblockcount(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -133,7 +132,7 @@ UniValue getblockcount(const Array& params, bool fHelp) return chainActive.Height(); } -UniValue getbestblockhash(const Array& params, bool fHelp) +UniValue getbestblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -150,7 +149,7 @@ UniValue getbestblockhash(const Array& params, bool fHelp) return chainActive.Tip()->GetBlockHash().GetHex(); } -UniValue getdifficulty(const Array& params, bool fHelp) +UniValue getdifficulty(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -168,7 +167,7 @@ UniValue getdifficulty(const Array& params, bool fHelp) } -UniValue getrawmempool(const Array& params, bool fHelp) +UniValue getrawmempool(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -253,7 +252,7 @@ UniValue getrawmempool(const Array& params, bool fHelp) } } -UniValue getblockhash(const Array& params, bool fHelp) +UniValue getblockhash(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -278,7 +277,7 @@ UniValue getblockhash(const Array& params, bool fHelp) return pblockindex->GetBlockHash().GetHex(); } -UniValue getblock(const Array& params, bool fHelp) +UniValue getblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -346,7 +345,7 @@ UniValue getblock(const Array& params, bool fHelp) return blockToJSON(block, pblockindex); } -UniValue gettxoutsetinfo(const Array& params, bool fHelp) +UniValue gettxoutsetinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -386,7 +385,7 @@ UniValue gettxoutsetinfo(const Array& params, bool fHelp) return ret; } -UniValue gettxout(const Array& params, bool fHelp) +UniValue gettxout(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 3) throw runtime_error( @@ -466,7 +465,7 @@ UniValue gettxout(const Array& params, bool fHelp) return ret; } -UniValue verifychain(const Array& params, bool fHelp) +UniValue verifychain(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -524,7 +523,7 @@ Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, c return rv; } -UniValue getblockchaininfo(const Array& params, bool fHelp) +UniValue getblockchaininfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -609,7 +608,7 @@ struct CompareBlocksByHeight } }; -UniValue getchaintips(const Array& params, bool fHelp) +UniValue getchaintips(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -699,7 +698,7 @@ UniValue getchaintips(const Array& params, bool fHelp) return res; } -UniValue getmempoolinfo(const Array& params, bool fHelp) +UniValue getmempoolinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -722,7 +721,7 @@ UniValue getmempoolinfo(const Array& params, bool fHelp) return ret; } -UniValue invalidateblock(const Array& params, bool fHelp) +UniValue invalidateblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -760,7 +759,7 @@ UniValue invalidateblock(const Array& params, bool fHelp) return NullUniValue; } -UniValue reconsiderblock(const Array& params, bool fHelp) +UniValue reconsiderblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index aec69d9bd..e4813d042 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -12,9 +12,9 @@ #include #include // for to_lower() +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; class CRPCConvertParam { @@ -153,7 +153,7 @@ UniValue RPCConvertValues(const std::string &strMethod, const std::vector -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; /** @@ -115,7 +114,7 @@ Value getnetworksolps(const Array& params, bool fHelp) return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1); } -UniValue getnetworkhashps(const Array& params, bool fHelp) +UniValue getnetworkhashps(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -139,7 +138,7 @@ UniValue getnetworkhashps(const Array& params, bool fHelp) } #ifdef ENABLE_MINING -UniValue getgenerate(const Array& params, bool fHelp) +UniValue getgenerate(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -158,7 +157,7 @@ UniValue getgenerate(const Array& params, bool fHelp) return GetBoolArg("-gen", false); } -UniValue generate(const Array& params, bool fHelp) +UniValue generate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 1) throw runtime_error( @@ -267,7 +266,7 @@ endloop: } -UniValue setgenerate(const Array& params, bool fHelp) +UniValue setgenerate(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -326,7 +325,7 @@ UniValue setgenerate(const Array& params, bool fHelp) #endif -UniValue getmininginfo(const Array& params, bool fHelp) +UniValue getmininginfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -376,7 +375,7 @@ UniValue getmininginfo(const Array& params, bool fHelp) // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts -UniValue prioritisetransaction(const Array& params, bool fHelp) +UniValue prioritisetransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -411,7 +410,7 @@ UniValue prioritisetransaction(const Array& params, bool fHelp) static UniValue BIP22ValidationResult(const CValidationState& state) { if (state.IsValid()) - return Value::null; + return NullUniValue; std::string strRejectReason = state.GetRejectReason(); if (state.IsError()) @@ -426,7 +425,7 @@ static UniValue BIP22ValidationResult(const CValidationState& state) return "valid?"; } -UniValue getblocktemplate(const Array& params, bool fHelp) +UniValue getblocktemplate(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -507,8 +506,8 @@ UniValue getblocktemplate(const Array& params, bool fHelp) bool coinbasetxn = true; if (params.size() > 0) { - const Object& oparam = params[0].get_obj(); - const Value& modeval = find_value(oparam, "mode"); + const UniValue& oparam = params[0].get_obj(); + const UniValue& modeval = find_value(oparam, "mode"); if (modeval.isStr()) strMode = modeval.get_str(); else if (modeval.isNull()) @@ -521,7 +520,7 @@ UniValue getblocktemplate(const Array& params, bool fHelp) if (strMode == "proposal") { - const Value& dataval = find_value(oparam, "data"); + const UniValue& dataval = find_value(oparam, "data"); if (dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); @@ -748,7 +747,7 @@ protected: }; }; -UniValue submitblock(const Array& params, bool fHelp) +UniValue submitblock(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -809,7 +808,7 @@ UniValue submitblock(const Array& params, bool fHelp) return BIP22ValidationResult(state); } -UniValue estimatefee(const Array& params, bool fHelp) +UniValue estimatefee(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -841,7 +840,7 @@ UniValue estimatefee(const Array& params, bool fHelp) return ValueFromAmount(feeRate.GetFeePerK()); } -UniValue estimatepriority(const Array& params, bool fHelp) +UniValue estimatepriority(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 8e68dd271..e4c5fa284 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -20,11 +20,10 @@ #include #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" #include "zcash/Address.hpp" -using namespace json_spirit; using namespace std; /** @@ -40,7 +39,7 @@ using namespace std; * * Or alternatively, create a specific query method for the information. **/ -UniValue getinfo(const Array& params, bool fHelp) +UniValue getinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -109,7 +108,7 @@ UniValue getinfo(const Array& params, bool fHelp) } #ifdef ENABLE_WALLET -class DescribeAddressVisitor : public boost::static_visitor +class DescribeAddressVisitor : public boost::static_visitor { private: isminetype mine; @@ -117,7 +116,7 @@ private: public: DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {} - UniValue operator()(const CNoDestination &dest) const { return Object(); } + UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); } UniValue operator()(const CKeyID &keyID) const { UniValue obj(UniValue::VOBJ); @@ -155,7 +154,7 @@ public: }; #endif -UniValue validateaddress(const Array& params, bool fHelp) +UniValue validateaddress(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -280,10 +279,10 @@ Value z_validateaddress(const Array& params, bool fHelp) /** * Used by addmultisigaddress / createmultisig: */ -CScript _createmultisig_redeemScript(const Array& params) +CScript _createmultisig_redeemScript(const UniValue& params) { int nRequired = params[0].get_int(); - const Array& keys = params[1].get_array(); + const UniValue& keys = params[1].get_array(); // Gather public keys if (nRequired < 1) @@ -341,7 +340,7 @@ CScript _createmultisig_redeemScript(const Array& params) return result; } -UniValue createmultisig(const Array& params, bool fHelp) +UniValue createmultisig(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 2 || params.size() > 2) { @@ -384,7 +383,7 @@ UniValue createmultisig(const Array& params, bool fHelp) return result; } -UniValue verifymessage(const Array& params, bool fHelp) +UniValue verifymessage(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 3) throw runtime_error( @@ -438,7 +437,7 @@ UniValue verifymessage(const Array& params, bool fHelp) return (pubkey.GetID() == keyID); } -UniValue setmocktime(const Array& params, bool fHelp) +UniValue setmocktime(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 34ba59f3d..e8eca24f8 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -16,12 +16,11 @@ #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; -UniValue getconnectioncount(const Array& params, bool fHelp) +UniValue getconnectioncount(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -39,7 +38,7 @@ UniValue getconnectioncount(const Array& params, bool fHelp) return (int)vNodes.size(); } -UniValue ping(const Array& params, bool fHelp) +UniValue ping(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -75,7 +74,7 @@ static void CopyNodeStats(std::vector& vstats) } } -UniValue getpeerinfo(const Array& params, bool fHelp) +UniValue getpeerinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( @@ -165,7 +164,7 @@ UniValue getpeerinfo(const Array& params, bool fHelp) return ret; } -UniValue addnode(const Array& params, bool fHelp) +UniValue addnode(const UniValue& params, bool fHelp) { string strCommand; if (params.size() == 2) @@ -215,7 +214,7 @@ UniValue addnode(const Array& params, bool fHelp) return NullUniValue; } -UniValue getaddednodeinfo(const Array& params, bool fHelp) +UniValue getaddednodeinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -332,7 +331,7 @@ UniValue getaddednodeinfo(const Array& params, bool fHelp) return ret; } -UniValue getnettotals(const Array& params, bool fHelp) +UniValue getnettotals(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 0) throw runtime_error( @@ -378,7 +377,7 @@ static UniValue GetNetworksInfo() return networks; } -UniValue getnetworkinfo(const Array& params, bool fHelp) +UniValue getnetworkinfo(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 0) throw runtime_error( diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index d80f93253..c0aaf2c29 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -25,10 +25,10 @@ #include #include #include -#include "json_spirit_wrapper.h" + +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; //! Number of bytes to allocate and read at most at once in post data const size_t POST_READ_SIZE = 256 * 1024; @@ -256,7 +256,7 @@ int ReadHTTPMessage(std::basic_istream& stream, map #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" //! HTTP status codes enum HTTPStatusCode diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 224396268..f0a95fb9e 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -25,12 +25,12 @@ #include #include -#include "json_spirit_wrapper.h" -using namespace json_spirit; +#include "univalue/univalue.h" + using namespace std; -void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex) +void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex) { txnouttype type; vector addresses; @@ -110,7 +110,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) { return vjoinsplit; } -void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) +void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) { entry.push_back(Pair("txid", tx.GetHash().GetHex())); entry.push_back(Pair("version", tx.nVersion)); @@ -164,7 +164,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry) } } -UniValue getrawtransaction(const Array& params, bool fHelp) +UniValue getrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -281,7 +281,7 @@ UniValue getrawtransaction(const Array& params, bool fHelp) return result; } -UniValue gettxoutproof(const Array& params, bool fHelp) +UniValue gettxoutproof(const UniValue& params, bool fHelp) { if (fHelp || (params.size() != 1 && params.size() != 2)) throw runtime_error( @@ -307,7 +307,7 @@ UniValue gettxoutproof(const Array& params, bool fHelp) uint256 oneTxid; UniValue txids = params[0].get_array(); for (unsigned int idx = 0; idx < txids.size(); idx++) { - const Value& txid = txids[idx]; + const UniValue& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str()); uint256 hash(uint256S(txid.get_str())); @@ -362,7 +362,7 @@ UniValue gettxoutproof(const Array& params, bool fHelp) return strHex; } -UniValue verifytxoutproof(const Array& params, bool fHelp) +UniValue verifytxoutproof(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -395,7 +395,7 @@ UniValue verifytxoutproof(const Array& params, bool fHelp) return res; } -UniValue createrawtransaction(const Array& params, bool fHelp) +UniValue createrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 2) throw runtime_error( @@ -437,12 +437,12 @@ UniValue createrawtransaction(const Array& params, bool fHelp) CMutableTransaction rawTx; for (unsigned int idx = 0; idx < inputs.size(); idx++) { - const Value& input = inputs[idx]; - const Object& o = input.get_obj(); + const UniValue& input = inputs[idx]; + const UniValue& o = input.get_obj(); uint256 txid = ParseHashO(o, "txid"); - const Value& vout_v = find_value(o, "vout"); + const UniValue& vout_v = find_value(o, "vout"); if (!vout_v.isNum()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key"); int nOutput = vout_v.get_int(); @@ -474,7 +474,7 @@ UniValue createrawtransaction(const Array& params, bool fHelp) return EncodeHexTx(rawTx); } -UniValue decoderawtransaction(const Array& params, bool fHelp) +UniValue decoderawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -566,7 +566,7 @@ UniValue decoderawtransaction(const Array& params, bool fHelp) return result; } -UniValue decodescript(const Array& params, bool fHelp) +UniValue decodescript(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -609,7 +609,7 @@ UniValue decodescript(const Array& params, bool fHelp) } /** Pushes a JSON object for script verification or signing errors to vErrorsRet. */ -static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage) +static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage) { UniValue entry(UniValue::VOBJ); entry.push_back(Pair("txid", txin.prevout.hash.ToString())); @@ -620,7 +620,7 @@ static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::str vErrorsRet.push_back(entry); } -UniValue signrawtransaction(const Array& params, bool fHelp) +UniValue signrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 4) throw runtime_error( @@ -752,7 +752,7 @@ UniValue signrawtransaction(const Array& params, bool fHelp) if (params.size() > 1 && !params[1].isNull()) { UniValue prevTxs = params[1].get_array(); for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { - const Value& p = prevTxs[idx]; + const UniValue& p = prevTxs[idx]; if (!p.isObject()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); @@ -862,7 +862,7 @@ UniValue signrawtransaction(const Array& params, bool fHelp) return result; } -UniValue sendrawtransaction(const Array& params, bool fHelp) +UniValue sendrawtransaction(const UniValue& params, bool fHelp) { if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 25e9e67d1..7b4323d75 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -31,10 +31,9 @@ #include #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" using namespace boost::asio; -using namespace json_spirit; using namespace RPCServer; using namespace std; @@ -82,17 +81,17 @@ void RPCServer::OnPostCommand(boost::function slot) g_rpcSignals.PostCommand.connect(boost::bind(slot, _1)); } -void RPCTypeCheck(const Array& params, - const list& typesExpected, +void RPCTypeCheck(const UniValue& params, + const list& typesExpected, bool fAllowNull) { unsigned int i = 0; - BOOST_FOREACH(Value_type t, typesExpected) + BOOST_FOREACH(UniValue::VType t, typesExpected) { if (params.size() <= i) break; - const Value& v = params[i]; + const UniValue& v = params[i]; if (!((v.type() == t) || (fAllowNull && (v.isNull())))) { string err = strprintf("Expected type %s, got %s", @@ -107,9 +106,9 @@ void RPCTypeCheckObj(const UniValue& o, const map& typesExpected, bool fAllowNull) { - BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected) + BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected) { - const Value& v = find_value(o, t.first); + const UniValue& v = find_value(o, t.first); if (!fAllowNull && v.isNull()) throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first)); @@ -127,7 +126,7 @@ static inline int64_t roundint64(double d) return (int64_t)(d > 0 ? d + 0.5 : d - 0.5); } -CAmount AmountFromValue(const Value& value) +CAmount AmountFromValue(const UniValue& value) { double dAmount = value.get_real(); if (dAmount <= 0.0 || dAmount > 21000000.0) @@ -143,7 +142,7 @@ UniValue ValueFromAmount(const CAmount& amount) return (double)amount / (double)COIN; } -uint256 ParseHashV(const Value& v, string strName) +uint256 ParseHashV(const UniValue& v, string strName) { string strHex; if (v.isStr()) @@ -154,11 +153,11 @@ uint256 ParseHashV(const Value& v, string strName) result.SetHex(strHex); return result; } -uint256 ParseHashO(const Object& o, string strKey) +uint256 ParseHashO(const UniValue& o, string strKey) { return ParseHashV(find_value(o, strKey), strKey); } -vector ParseHexV(const Value& v, string strName) +vector ParseHexV(const UniValue& v, string strName) { string strHex; if (v.isStr()) @@ -167,7 +166,7 @@ vector ParseHexV(const Value& v, string strName) throw JSONRPCError(RPC_INVALID_PARAMETER, strName+" must be hexadecimal string (not '"+strHex+"')"); return ParseHex(strHex); } -vector ParseHexO(const Object& o, string strKey) +vector ParseHexO(const UniValue& o, string strKey) { return ParseHexV(find_value(o, strKey), strKey); } @@ -232,7 +231,7 @@ string CRPCTable::help(string strCommand) const return strRet; } -UniValue help(const Array& params, bool fHelp) +UniValue help(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -252,7 +251,7 @@ UniValue help(const Array& params, bool fHelp) } -UniValue stop(const Array& params, bool fHelp) +UniValue stop(const UniValue& params, bool fHelp) { // Accept the deprecated and ignored 'detach' boolean argument if (fHelp || params.size() > 1) @@ -438,7 +437,7 @@ bool HTTPAuthorized(map& mapHeaders) return TimingResistantEqual(strUserPass, strRPCUserColonPass); } -void ErrorReply(std::ostream& stream, const Object& objError, const Value& id) +void ErrorReply(std::ostream& stream, const UniValue& objError, const UniValue& id) { // Send error reply from json-rpc error object int nStatus = HTTP_INTERNAL_SERVER_ERROR; @@ -868,15 +867,15 @@ public: UniValue params; JSONRequest() { id = NullUniValue; } - void parse(const Value& valRequest); + void parse(const UniValue& valRequest); }; -void JSONRequest::parse(const Value& valRequest) +void JSONRequest::parse(const UniValue& valRequest) { // Parse request if (!valRequest.isObject()) throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object"); - const Object& request = valRequest.get_obj(); + const UniValue& request = valRequest.get_obj(); // Parse id now so errors from here on will have the id id = find_value(request, "id"); @@ -896,13 +895,13 @@ void JSONRequest::parse(const Value& valRequest) if (valParams.isArray()) params = valParams.get_array(); else if (valParams.isNull()) - params = Array(); + params = UniValue(UniValue::VARR); else throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array"); } -static UniValue JSONRPCExecOne(const Value& req) +static UniValue JSONRPCExecOne(const UniValue& req) { UniValue rpc_result(UniValue::VOBJ); @@ -913,7 +912,7 @@ static UniValue JSONRPCExecOne(const Value& req) UniValue result = tableRPC.execute(jreq.strMethod, jreq.params); rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id); } - catch (const Object& objError) + catch (const UniValue& objError) { rpc_result = JSONRPCReplyObj(NullUniValue, objError, jreq.id); } @@ -926,7 +925,7 @@ static UniValue JSONRPCExecOne(const Value& req) return rpc_result; } -static string JSONRPCExecBatch(const Array& vReq) +static string JSONRPCExecBatch(const UniValue& vReq) { UniValue ret; for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) @@ -993,7 +992,7 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn, conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush; } - catch (const Object& objError) + catch (const UniValue& objError) { ErrorReply(conn->stream(), objError, jreq.id); return false; diff --git a/src/rpcserver.h b/src/rpcserver.h index 37c65f8b1..607cff1c2 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -17,7 +17,8 @@ #include #include -#include "json_spirit_wrapper.h" + +#include "univalue/univalue.h" class AsyncRPCQueue; class CRPCCommand; diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 114bd79ea..9e74f5f42 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -17,9 +17,9 @@ #include #include -#include "json_spirit_wrapper.h" -using namespace json_spirit; +#include "univalue/univalue.h" + extern UniValue read_json(const std::string& jsondata); BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 8ea4af6ef..0c3a58466 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -13,10 +13,11 @@ #include #include -using namespace std; -using namespace json_spirit; +#include "univalue/univalue.h" -Array +using namespace std; + +UniValue createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) { UniValue result(UniValue::VARR); @@ -28,7 +29,7 @@ createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL) return result; } -Value CallRPC(string args) +UniValue CallRPC(string args) { vector vArgs; boost::split(vArgs, args, boost::is_any_of(" \t")); @@ -44,10 +45,10 @@ Value CallRPC(string args) rpcfn_type method = tableRPC[strMethod]->actor; try { - Value result = (*method)(params, false); + UniValue result = (*method)(params, false); return result; } - catch (const Object& objError) { + catch (const UniValue& objError) { throw runtime_error(find_value(objError, "message").get_str()); } } @@ -58,7 +59,7 @@ BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup) BOOST_AUTO_TEST_CASE(rpc_rawparams) { // Test raw transaction API argument handling - Value r; + UniValue r; BOOST_CHECK_THROW(CallRPC("getrawtransaction"), runtime_error); BOOST_CHECK_THROW(CallRPC("getrawtransaction not_hex"), runtime_error); @@ -98,7 +99,7 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams) BOOST_AUTO_TEST_CASE(rpc_rawsign) { - Value r; + UniValue r; // input is a 1-of-2 multisig (so is output): string prevout = "[{\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\"," @@ -127,7 +128,7 @@ BOOST_AUTO_TEST_CASE(rpc_format_monetary_values) BOOST_CHECK(ValueFromAmount(2099999999999999LL).write() == "20999999.99999999"); } -static Value ValueFromString(const std::string &str) +static UniValue ValueFromString(const std::string &str) { UniValue value; BOOST_CHECK(value.setNumStr(str)); diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index 9b5bd7acb..a1323a5c8 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -31,11 +31,12 @@ #include #include +#include "univalue/univalue.h" + using namespace std; -using namespace json_spirit; extern UniValue createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL); -extern Value CallRPC(string args); +extern UniValue CallRPC(string args); extern CWallet* pwalletMain; @@ -56,7 +57,7 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) // new, compressed: const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4"; - Value v; + UniValue v; CBitcoinAddress address; BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false)); address.SetString(v.get_str()); @@ -87,13 +88,13 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig) BOOST_AUTO_TEST_CASE(rpc_wallet) { // Test RPC calls for various wallet statistics - Value r; + UniValue r; LOCK2(cs_main, pwalletMain->cs_wallet); CPubKey demoPubkey = pwalletMain->GenerateNewKey(); CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID())); - Value retValue; + UniValue retValue; string strAccount = ""; string strPurpose = "receive"; BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */ diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index a1d44d6dd..02cd878d8 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -26,10 +26,10 @@ #include #include -#include "json_spirit_wrapper.h" + +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; // Uncomment if you want to output updated JSON tests. // #define UPDATE_JSON_TESTS @@ -39,15 +39,15 @@ static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(string strFlags); string FormatScriptFlags(unsigned int flags); -Array +UniValue read_json(const std::string& jsondata) { - Value v; + UniValue v; if (!v.read(jsondata) || !v.isArray()) { BOOST_ERROR("Parse error."); - return Array(); + return UniValue(UniValue::VARR); } return v.get_array(); } @@ -584,11 +584,11 @@ BOOST_AUTO_TEST_CASE(script_build) UniValue json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); for (unsigned int idx = 0; idx < json_good.size(); idx++) { - const Value& tv = json_good[idx]; + const UniValue& tv = json_good[idx]; tests_good.insert(tv.get_array().write()); } for (unsigned int idx = 0; idx < json_bad.size(); idx++) { - const Value& tv = json_bad[idx]; + const UniValue& tv = json_bad[idx]; tests_bad.insert(tv.get_array().write()); } } diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 6e169e0e7..9b3a82557 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -17,9 +17,9 @@ #include #include -#include "json_spirit_wrapper.h" -using namespace json_spirit; +#include "univalue/univalue.h" + extern UniValue read_json(const std::string& jsondata); // Old script.cpp SignatureHash function diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 21893b76e..514982980 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -27,14 +27,13 @@ #include #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" #include "zcash/Note.hpp" #include "zcash/Address.hpp" #include "zcash/Proof.hpp" using namespace std; -using namespace json_spirit; // In script_tests.cpp extern UniValue read_json(const std::string& jsondata); @@ -101,19 +100,11 @@ BOOST_AUTO_TEST_CASE(tx_valid) UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid))); auto verifier = libzcash::ProofVerifier::Strict(); -<<<<<<< HEAD ScriptError err; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test[0].type() == array_type) -======= for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) ->>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { @@ -125,7 +116,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { - const Value& input = inputs[inpIdx]; + const UniValue& input = inputs[inpIdx]; if (!input.isArray()) { fValid = false; @@ -185,19 +176,11 @@ BOOST_AUTO_TEST_CASE(tx_invalid) UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid))); auto verifier = libzcash::ProofVerifier::Strict(); -<<<<<<< HEAD ScriptError err; - BOOST_FOREACH(Value& tv, tests) - { - Array test = tv.get_array(); - string strTest = write_string(tv, false); - if (test[0].type() == array_type) -======= for (unsigned int idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) ->>>>>>> Convert tree to using univalue. Eliminate all json_spirit uses. { if (test.size() != 3 || !test[1].isStr() || !test[2].isStr()) { @@ -209,7 +192,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) UniValue inputs = test[0].get_array(); bool fValid = true; for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { - const Value& input = inputs[inpIdx]; + const UniValue& input = inputs[inpIdx]; if (!input.isArray()) { fValid = false; diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index 994d93113..e8fc51343 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -213,3 +213,15 @@ const char *uvTypeName(UniValue::VType t) return NULL; } +const UniValue& find_value( const UniValue& obj, const std::string& name) +{ + for (unsigned int i = 0; i < obj.keys.size(); i++) + { + if( obj.keys[i] == name ) + { + return obj.values[i]; + } + } + + return NullUniValue; +} \ No newline at end of file diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index c37a3829f..57a96abe2 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -161,6 +161,7 @@ public: std::istringstream(getValStr()) >> ret; return ret; } + friend const UniValue& find_value( const UniValue& obj, const std::string& name); }; // @@ -248,5 +249,8 @@ extern enum jtokentype getJsonToken(std::string& tokenVal, extern const char *uvTypeName(UniValue::VType t); extern const UniValue NullUniValue; + +const UniValue& find_value( const UniValue& obj, const std::string& name); + #endif // BITCOIN_UNIVALUE_UNIVALUE_H diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 13cb0d4df..975d38bc1 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -19,9 +19,8 @@ #include #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" -using namespace json_spirit; using namespace std; void EnsureWalletIsUnlocked(); @@ -74,7 +73,7 @@ std::string DecodeDumpString(const std::string &str) { return ret.str(); } -UniValue importprivkey(const Array& params, bool fHelp) +UniValue importprivkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -148,7 +147,7 @@ UniValue importprivkey(const Array& params, bool fHelp) return NullUniValue; } -UniValue importaddress(const Array& params, bool fHelp) +UniValue importaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -244,7 +243,7 @@ Value z_importwallet(const Array& params, bool fHelp) return importwallet_impl(params, fHelp, true); } -UniValue importwallet(const Array& params, bool fHelp) +UniValue importwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -381,7 +380,7 @@ Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys) return NullUniValue; } -UniValue dumpprivkey(const Array& params, bool fHelp) +UniValue dumpprivkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -441,7 +440,7 @@ Value z_exportwallet(const Array& params, bool fHelp) return dumpwallet_impl(params, fHelp, true); } -UniValue dumpwallet(const Array& params, bool fHelp) +UniValue dumpwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0fbeebf07..d4086371a 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -31,12 +31,11 @@ #include -#include "json_spirit_wrapper.h" +#include "univalue/univalue.h" #include using namespace std; -using namespace json_spirit; using namespace libzcash; @@ -73,7 +72,7 @@ void EnsureWalletIsUnlocked() throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first."); } -void WalletTxToJSON(const CWalletTx& wtx, Object& entry) +void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) { int confirms = wtx.GetDepthInMainChain(); entry.push_back(Pair("confirmations", confirms)); @@ -99,7 +98,7 @@ void WalletTxToJSON(const CWalletTx& wtx, Object& entry) entry.push_back(Pair("vjoinsplit", TxJoinSplitToJSON(wtx))); } -string AccountFromValue(const Value& value) +string AccountFromValue(const UniValue& value) { string strAccount = value.get_str(); if (strAccount != "") @@ -107,7 +106,7 @@ string AccountFromValue(const Value& value) return strAccount; } -Value getnewaddress(const Array& params, bool fHelp) +UniValue getnewaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -184,7 +183,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) return CBitcoinAddress(account.vchPubKey.GetID()); } -Value getaccountaddress(const Array& params, bool fHelp) +UniValue getaccountaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -209,14 +208,14 @@ Value getaccountaddress(const Array& params, bool fHelp) // Parse the account first so we don't generate a key if there's an error string strAccount = AccountFromValue(params[0]); - Value ret; + UniValue ret(UniValue::VSTR); ret = GetAccountAddress(strAccount).ToString(); return ret; } -Value getrawchangeaddress(const Array& params, bool fHelp) +UniValue getrawchangeaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -251,7 +250,7 @@ Value getrawchangeaddress(const Array& params, bool fHelp) } -Value setaccount(const Array& params, bool fHelp) +UniValue setaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -297,7 +296,7 @@ Value setaccount(const Array& params, bool fHelp) } -Value getaccount(const Array& params, bool fHelp) +UniValue getaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -329,7 +328,7 @@ Value getaccount(const Array& params, bool fHelp) } -Value getaddressesbyaccount(const Array& params, bool fHelp) +UniValue getaddressesbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -397,7 +396,7 @@ static void SendMoney(const CTxDestination &address, CAmount nValue, bool fSubtr throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here."); } -Value sendtoaddress(const Array& params, bool fHelp) +UniValue sendtoaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -453,7 +452,7 @@ Value sendtoaddress(const Array& params, bool fHelp) return wtx.GetHash().GetHex(); } -Value listaddressgroupings(const Array& params, bool fHelp) +UniValue listaddressgroupings(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -504,7 +503,7 @@ Value listaddressgroupings(const Array& params, bool fHelp) return jsonGroupings; } -Value signmessage(const Array& params, bool fHelp) +UniValue signmessage(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -560,7 +559,7 @@ Value signmessage(const Array& params, bool fHelp) return EncodeBase64(&vchSig[0], vchSig.size()); } -Value getreceivedbyaddress(const Array& params, bool fHelp) +UniValue getreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -618,7 +617,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) } -Value getreceivedbyaccount(const Array& params, bool fHelp) +UniValue getreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -707,7 +706,7 @@ CAmount GetAccountBalance(const string& strAccount, int nMinDepth, const isminef } -Value getbalance(const Array& params, bool fHelp) +UniValue getbalance(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -779,7 +778,7 @@ Value getbalance(const Array& params, bool fHelp) return ValueFromAmount(nBalance); } -Value getunconfirmedbalance(const UniValue ¶ms, bool fHelp) +UniValue getunconfirmedbalance(const UniValue ¶ms, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -795,7 +794,7 @@ Value getunconfirmedbalance(const UniValue ¶ms, bool fHelp) } -Value movecmd(const Array& params, bool fHelp) +UniValue movecmd(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -865,7 +864,7 @@ Value movecmd(const Array& params, bool fHelp) } -Value sendfrom(const Array& params, bool fHelp) +UniValue sendfrom(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -928,7 +927,7 @@ Value sendfrom(const Array& params, bool fHelp) } -Value sendmany(const Array& params, bool fHelp) +UniValue sendmany(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1007,7 +1006,7 @@ Value sendmany(const Array& params, bool fHelp) bool fSubtractFeeFromAmount = false; for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) { - const Value& addr = subtractFeeFromAmount[idx]; + const UniValue& addr = subtractFeeFromAmount[idx]; if (addr.get_str() == name_) fSubtractFeeFromAmount = true; } @@ -1038,9 +1037,9 @@ Value sendmany(const Array& params, bool fHelp) } // Defined in rpcmisc.cpp -extern CScript _createmultisig_redeemScript(const Array& params); +extern CScript _createmultisig_redeemScript(const UniValue& params); -Value addmultisigaddress(const Array& params, bool fHelp) +UniValue addmultisigaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1103,7 +1102,7 @@ struct tallyitem } }; -Value ListReceived(const Array& params, bool fByAccounts) +UniValue ListReceived(const UniValue& params, bool fByAccounts) { // Minimum confirmations int nMinDepth = 1; @@ -1221,7 +1220,7 @@ Value ListReceived(const Array& params, bool fByAccounts) return ret; } -Value listreceivedbyaddress(const Array& params, bool fHelp) +UniValue listreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1258,7 +1257,7 @@ Value listreceivedbyaddress(const Array& params, bool fHelp) return ListReceived(params, false); } -Value listreceivedbyaccount(const Array& params, bool fHelp) +UniValue listreceivedbyaccount(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1301,7 +1300,7 @@ static void MaybePushAddress(UniValue & entry, const CTxDestination &dest) entry.push_back(Pair("address", addr.ToString())); } -void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, Array& ret, const isminefilter& filter) +void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDepth, bool fLong, UniValue& ret, const isminefilter& filter) { CAmount nFee; string strSentAccount; @@ -1373,7 +1372,7 @@ void ListTransactions(const CWalletTx& wtx, const string& strAccount, int nMinDe } } -void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Array& ret) +void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, UniValue& ret) { bool fAllAccounts = (strAccount == string("*")); @@ -1390,7 +1389,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const string& strAccount, Ar } } -Value listtransactions(const Array& params, bool fHelp) +UniValue listtransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1512,7 +1511,7 @@ Value listtransactions(const Array& params, bool fHelp) return ret; } -Value listaccounts(const Array& params, bool fHelp) +UniValue listaccounts(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1592,7 +1591,7 @@ Value listaccounts(const Array& params, bool fHelp) return ret; } -Value listsinceblock(const Array& params, bool fHelp) +UniValue listsinceblock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1683,7 +1682,7 @@ Value listsinceblock(const Array& params, bool fHelp) return ret; } -Value gettransaction(const Array& params, bool fHelp) +UniValue gettransaction(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1772,7 +1771,7 @@ Value gettransaction(const Array& params, bool fHelp) } -Value backupwallet(const Array& params, bool fHelp) +UniValue backupwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1815,7 +1814,7 @@ Value backupwallet(const Array& params, bool fHelp) } -Value keypoolrefill(const Array& params, bool fHelp) +UniValue keypoolrefill(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1859,7 +1858,7 @@ static void LockWallet(CWallet* pWallet) pWallet->Lock(); } -Value walletpassphrase(const Array& params, bool fHelp) +UniValue walletpassphrase(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1921,7 +1920,7 @@ Value walletpassphrase(const Array& params, bool fHelp) } -Value walletpassphrasechange(const Array& params, bool fHelp) +UniValue walletpassphrasechange(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -1967,7 +1966,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) } -Value walletlock(const Array& params, bool fHelp) +UniValue walletlock(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2006,7 +2005,7 @@ Value walletlock(const Array& params, bool fHelp) } -Value encryptwallet(const Array& params, bool fHelp) +UniValue encryptwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2074,7 +2073,7 @@ Value encryptwallet(const Array& params, bool fHelp) return "wallet encrypted; Zcash server stopping, restart to run with encrypted wallet. The keypool has been flushed, you need to make a new backup."; } -Value lockunspent(const Array& params, bool fHelp) +UniValue lockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2135,7 +2134,7 @@ Value lockunspent(const Array& params, bool fHelp) const UniValue& output = outputs[idx]; if (!output.isObject()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); - const Object& o = output.get_obj(); + const UniValue& o = output.get_obj(); RPCTypeCheckObj(o, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)); @@ -2158,7 +2157,7 @@ Value lockunspent(const Array& params, bool fHelp) return true; } -Value listlockunspent(const Array& params, bool fHelp) +UniValue listlockunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2207,7 +2206,7 @@ Value listlockunspent(const Array& params, bool fHelp) return ret; } -Value settxfee(const Array& params, bool fHelp) +UniValue settxfee(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2236,7 +2235,7 @@ Value settxfee(const Array& params, bool fHelp) return true; } -Value getwalletinfo(const Array& params, bool fHelp) +UniValue getwalletinfo(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2276,7 +2275,7 @@ Value getwalletinfo(const Array& params, bool fHelp) return obj; } -Value resendwallettransactions(const Array& params, bool fHelp) +UniValue resendwallettransactions(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2301,7 +2300,7 @@ Value resendwallettransactions(const Array& params, bool fHelp) return result; } -Value listunspent(const Array& params, bool fHelp) +UniValue listunspent(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) return NullUniValue; @@ -2356,7 +2355,7 @@ Value listunspent(const Array& params, bool fHelp) if (params.size() > 2) { UniValue inputs = params[2].get_array(); for (unsigned int idx = 0; idx < inputs.size(); idx++) { - const Value& input = inputs[idx]; + const UniValue& input = inputs[idx]; CBitcoinAddress address(input.get_str()); if (!address.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Zcash address: ")+input.get_str()); From bf3f56025d9c942eec0d6b2abd265eb600baaf14 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 2 Jun 2015 11:41:00 +0200 Subject: [PATCH 12/26] fix rpc batching univalue issue --- src/rpcserver.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 7b4323d75..d5b66471d 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -927,7 +927,7 @@ static UniValue JSONRPCExecOne(const UniValue& req) static string JSONRPCExecBatch(const UniValue& vReq) { - UniValue ret; + UniValue ret(UniValue::VARR); for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) ret.push_back(JSONRPCExecOne(vReq[reqIdx])); From b47f3aea36b437528cde6d0c35a4142c841a0c20 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Tue, 2 Jun 2015 12:28:54 +0200 Subject: [PATCH 13/26] fix missing univalue types during constructing --- src/rpcblockchain.cpp | 4 ++-- src/rpcmisc.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 205d7df2c..7e70a5ec2 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -228,7 +228,7 @@ UniValue getrawmempool(const UniValue& params, bool fHelp) setDepends.insert(txin.prevout.hash.ToString()); } - UniValue depends; + UniValue depends(UniValue::VARR); BOOST_FOREACH(const string& dep, setDepends) { depends.push_back(dep); @@ -714,7 +714,7 @@ UniValue getmempoolinfo(const UniValue& params, bool fHelp) + HelpExampleRpc("getmempoolinfo", "") ); - UniValue ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("size", (int64_t) mempool.size())); ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index e4c5fa284..ee0274a4b 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -376,7 +376,7 @@ UniValue createmultisig(const UniValue& params, bool fHelp) CScriptID innerID(inner); CBitcoinAddress address(innerID); - UniValue result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("address", address.ToString())); result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end()))); From c288192b19e189a50dee73bb698c12489ecfd4b6 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 4 Jun 2015 10:35:36 +0200 Subject: [PATCH 14/26] fix univalue json parse tests --- src/test/rpc_tests.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 0c3a58466..17af5568c 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -149,20 +149,23 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) BOOST_AUTO_TEST_CASE(json_parse_errors) { - Value value; + UniValue value; // Valid - BOOST_CHECK_EQUAL(read_string(std::string("1.0"), value), true); + BOOST_CHECK_EQUAL(value.read(std::string("1.0")), false); + BOOST_CHECK_EQUAL(value.read(std::string("[1.0]")), true); // Valid, with trailing whitespace - BOOST_CHECK_EQUAL(read_string(std::string("1.0 "), value), true); + BOOST_CHECK_EQUAL(value.read(std::string("1.0 ")), false); + BOOST_CHECK_EQUAL(value.read(std::string("[1.0 ] ")), true); // Invalid, initial garbage - BOOST_CHECK_EQUAL(read_string(std::string("[1.0"), value), false); - BOOST_CHECK_EQUAL(read_string(std::string("a1.0"), value), false); + BOOST_CHECK_EQUAL(value.read(std::string("[1.0")), false); + BOOST_CHECK_EQUAL(value.read(std::string("[a1.0]")), false); + BOOST_CHECK_EQUAL(value.read(std::string("[\"a1.0\"]")), true); // Invalid, trailing garbage - BOOST_CHECK_EQUAL(read_string(std::string("1.0sds"), value), false); - BOOST_CHECK_EQUAL(read_string(std::string("1.0]"), value), false); + BOOST_CHECK_EQUAL(value.read(std::string("1.0sds")), false); + BOOST_CHECK_EQUAL(value.read(std::string("1.0]")), false); // BTC addresses should fail parsing - BOOST_CHECK_EQUAL(read_string(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), value), false); - BOOST_CHECK_EQUAL(read_string(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), value), false); + BOOST_CHECK_EQUAL(value.read(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")), false); + BOOST_CHECK_EQUAL(value.read(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL")), false); } BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) From ff67da37cd718f047ad747cc5237a09e383be6c9 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 4 Jun 2015 10:31:22 +0200 Subject: [PATCH 15/26] Simplify RPCclient, adapt json_parse_error test # Conflicts: # src/test/rpc_tests.cpp --- src/rpcclient.cpp | 36 ++++++++++++++++-------------------- src/rpcclient.h | 4 ++++ src/test/rpc_tests.cpp | 23 ++++++++++------------- 3 files changed, 30 insertions(+), 33 deletions(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index e4813d042..1f780bcb0 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -137,6 +137,18 @@ CRPCConvertTable::CRPCConvertTable() static CRPCConvertTable rpcCvtTable; +/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) + * as well as objects and arrays. + */ +UniValue ParseNonRFCJSONValue(const std::string& strVal) +{ + UniValue jVal; + if (!jVal.read(std::string("[")+strVal+std::string("]")) || + !jVal.isArray() || jVal.size()!=1) + throw runtime_error(string("Error parsing JSON:")+strVal); + return jVal[0]; +} + /** Convert strings to command-specific RPC representation */ UniValue RPCConvertValues(const std::string &strMethod, const std::vector &strParams) { @@ -145,28 +157,12 @@ UniValue RPCConvertValues(const std::string &strMethod, const std::vector 0)) - if(!jVal.setNumStr(strVal) || jVal.isNull()) - throw runtime_error(string("Error parsing JSON:")+strVal); - } - params.push_back(jVal); + } else { + // parse string as JSON, insert bool/number/object/etc. value + params.push_back(ParseNonRFCJSONValue(strVal)); } } diff --git a/src/rpcclient.h b/src/rpcclient.h index 52270aec7..d68b4ed6a 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -9,5 +9,9 @@ #include "univalue/univalue.h" UniValue RPCConvertValues(const std::string& strMethod, const std::vector& strParams); +/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null) + * as well as objects and arrays. + */ +UniValue ParseNonRFCJSONValue(const std::string& strVal); #endif // BITCOIN_RPCCLIENT_H diff --git a/src/test/rpc_tests.cpp b/src/test/rpc_tests.cpp index 17af5568c..9037d3f16 100644 --- a/src/test/rpc_tests.cpp +++ b/src/test/rpc_tests.cpp @@ -149,23 +149,20 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values) BOOST_AUTO_TEST_CASE(json_parse_errors) { - UniValue value; // Valid - BOOST_CHECK_EQUAL(value.read(std::string("1.0")), false); - BOOST_CHECK_EQUAL(value.read(std::string("[1.0]")), true); - // Valid, with trailing whitespace - BOOST_CHECK_EQUAL(value.read(std::string("1.0 ")), false); - BOOST_CHECK_EQUAL(value.read(std::string("[1.0 ] ")), true); + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0").get_real(), 1.0); + // Valid, with leading or trailing whitespace + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue(" 1.0").get_real(), 1.0); + BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0 ").get_real(), 1.0); // Invalid, initial garbage - BOOST_CHECK_EQUAL(value.read(std::string("[1.0")), false); - BOOST_CHECK_EQUAL(value.read(std::string("[a1.0]")), false); - BOOST_CHECK_EQUAL(value.read(std::string("[\"a1.0\"]")), true); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("[1.0"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("a1.0"), std::runtime_error); // Invalid, trailing garbage - BOOST_CHECK_EQUAL(value.read(std::string("1.0sds")), false); - BOOST_CHECK_EQUAL(value.read(std::string("1.0]")), false); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0sds"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0]"), std::runtime_error); // BTC addresses should fail parsing - BOOST_CHECK_EQUAL(value.read(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W")), false); - BOOST_CHECK_EQUAL(value.read(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL")), false); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), std::runtime_error); + BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error); } BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr) From 5960d70002df572f5b922f11d503aa30338e196e Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 4 Jun 2015 12:03:09 +0200 Subject: [PATCH 16/26] util: Add ParseInt64 and ParseDouble functions Strict parsing functions for other numeric types. - ParseInt64 analogous to ParseInt32, but for 64-bit values. - ParseDouble for doubles. - Make all three Parse* functions more strict (e.g. reject whitespace on the inside) Also add tests. --- src/test/util_tests.cpp | 65 ++++++++++++++++++++++++++++++++++++++++ src/utilstrencodings.cpp | 43 +++++++++++++++++++++++++- src/utilstrencodings.h | 14 +++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 46114c066..606c803a0 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -322,9 +322,16 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) BOOST_CHECK(ParseInt32("-2147483648", &n) && n == -2147483648); BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234); // Invalid values + BOOST_CHECK(!ParseInt32("", &n)); + BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseInt32("1 ", &n)); BOOST_CHECK(!ParseInt32("1a", &n)); BOOST_CHECK(!ParseInt32("aap", &n)); BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex + BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseInt32(teststr, &n)); // no embedded NULs // Overflow and underflow BOOST_CHECK(!ParseInt32("-2147483649", NULL)); BOOST_CHECK(!ParseInt32("2147483648", NULL)); @@ -332,6 +339,64 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32) BOOST_CHECK(!ParseInt32("32482348723847471234", NULL)); } +BOOST_AUTO_TEST_CASE(test_ParseInt64) +{ + int64_t n; + // Valid values + BOOST_CHECK(ParseInt64("1234", NULL)); + BOOST_CHECK(ParseInt64("0", &n) && n == 0LL); + BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL); + BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal + BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL); + BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL); + BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == 9223372036854775807LL); + BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == 9223372036854775808LL); + BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL); + // Invalid values + BOOST_CHECK(!ParseInt64("", &n)); + BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseInt64("1 ", &n)); + BOOST_CHECK(!ParseInt64("1a", &n)); + BOOST_CHECK(!ParseInt64("aap", &n)); + BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseInt64(teststr, &n)); // no embedded NULs + // Overflow and underflow + BOOST_CHECK(!ParseInt64("-9223372036854775809", NULL)); + BOOST_CHECK(!ParseInt64("9223372036854775808", NULL)); + BOOST_CHECK(!ParseInt64("-32482348723847471234", NULL)); + BOOST_CHECK(!ParseInt64("32482348723847471234", NULL)); +} + +BOOST_AUTO_TEST_CASE(test_ParseDouble) +{ + double n; + // Valid values + BOOST_CHECK(ParseDouble("1234", NULL)); + BOOST_CHECK(ParseDouble("0", &n) && n == 0.0); + BOOST_CHECK(ParseDouble("1234", &n) && n == 1234.0); + BOOST_CHECK(ParseDouble("01234", &n) && n == 1234.0); // no octal + BOOST_CHECK(ParseDouble("2147483647", &n) && n == 2147483647.0); + BOOST_CHECK(ParseDouble("-2147483648", &n) && n == -2147483648.0); + BOOST_CHECK(ParseDouble("-1234", &n) && n == -1234.0); + BOOST_CHECK(ParseDouble("1e6", &n) && n == 1e6); + BOOST_CHECK(ParseDouble("-1e6", &n) && n == -1e6); + // Invalid values + BOOST_CHECK(!ParseDouble("", &n)); + BOOST_CHECK(!ParseDouble(" 1", &n)); // no padding inside + BOOST_CHECK(!ParseDouble("1 ", &n)); + BOOST_CHECK(!ParseDouble("1a", &n)); + BOOST_CHECK(!ParseDouble("aap", &n)); + BOOST_CHECK(!ParseDouble("0x1", &n)); // no hex + const char test_bytes[] = {'1', 0, '1'}; + std::string teststr(test_bytes, sizeof(test_bytes)); + BOOST_CHECK(!ParseDouble(teststr, &n)); // no embedded NULs + // Overflow and underflow + BOOST_CHECK(!ParseDouble("-1e10000", NULL)); + BOOST_CHECK(!ParseDouble("1e10000", NULL)); +} + BOOST_AUTO_TEST_CASE(test_FormatParagraph) { BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), ""); diff --git a/src/utilstrencodings.cpp b/src/utilstrencodings.cpp index 646536f1e..81f9e2f9d 100644 --- a/src/utilstrencodings.cpp +++ b/src/utilstrencodings.cpp @@ -432,12 +432,25 @@ string DecodeBase32(const string& str) return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size()); } +static bool ParsePrechecks(const std::string& str) +{ + if (str.empty()) // No empty string allowed + return false; + if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed + return false; + if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed + return false; + return true; +} + bool ParseInt32(const std::string& str, int32_t *out) { + if (!ParsePrechecks(str)) + return false; char *endp = NULL; errno = 0; // strtol will not set errno if valid long int n = strtol(str.c_str(), &endp, 10); - if(out) *out = (int)n; + if(out) *out = (int32_t)n; // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit // platforms the size of these types may be different. @@ -446,6 +459,34 @@ bool ParseInt32(const std::string& str, int32_t *out) n <= std::numeric_limits::max(); } +bool ParseInt64(const std::string& str, int64_t *out) +{ + if (!ParsePrechecks(str)) + return false; + char *endp = NULL; + errno = 0; // strtoll will not set errno if valid + long long int n = strtoll(str.c_str(), &endp, 10); + if(out) *out = (int64_t)n; + // Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow + // we still have to check that the returned value is within the range of an *int64_t*. + return endp && *endp == 0 && !errno && + n >= std::numeric_limits::min() && + n <= std::numeric_limits::max(); +} + +bool ParseDouble(const std::string& str, double *out) +{ + if (!ParsePrechecks(str)) + return false; + if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed + return false; + char *endp = NULL; + errno = 0; // strtod will not set errno if valid + double n = strtod(str.c_str(), &endp); + if(out) *out = n; + return endp && *endp == 0 && !errno; +} + std::string FormatParagraph(const std::string in, size_t width, size_t indent) { std::stringstream out; diff --git a/src/utilstrencodings.h b/src/utilstrencodings.h index e08de362b..a6184d8f1 100644 --- a/src/utilstrencodings.h +++ b/src/utilstrencodings.h @@ -50,6 +50,20 @@ int atoi(const std::string& str); */ bool ParseInt32(const std::string& str, int32_t *out); +/** + * Convert string to signed 64-bit integer with strict parse error feedback. + * @returns true if the entire string could be parsed as valid integer, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseInt64(const std::string& str, int64_t *out); + +/** + * Convert string to double with strict parse error feedback. + * @returns true if the entire string could be parsed as valid double, + * false if not the entire string could be parsed or when overflow or underflow occurred. + */ +bool ParseDouble(const std::string& str, double *out); + template std::string HexStr(const T itbegin, const T itend, bool fSpaces=false) { From 4bcb9c9099df8f9208bbaf69edc38e6c8f6de121 Mon Sep 17 00:00:00 2001 From: "Wladimir J. van der Laan" Date: Thu, 4 Jun 2015 11:40:03 +0200 Subject: [PATCH 17/26] univalue: add strict type checking --- src/univalue/univalue.cpp | 79 ++++++++++++++++++++++++++++++++++++++- src/univalue/univalue.h | 32 +++++++--------- 2 files changed, 91 insertions(+), 20 deletions(-) diff --git a/src/univalue/univalue.cpp b/src/univalue/univalue.cpp index e8fc51343..6920c44c9 100644 --- a/src/univalue/univalue.cpp +++ b/src/univalue/univalue.cpp @@ -6,8 +6,12 @@ #include #include #include +#include // std::runtime_error + #include "univalue.h" +#include "utilstrencodings.h" // ParseXX + using namespace std; const UniValue NullUniValue; @@ -224,4 +228,77 @@ const UniValue& find_value( const UniValue& obj, const std::string& name) } return NullUniValue; -} \ No newline at end of file +} + +std::vector UniValue::getKeys() const +{ + if (typ != VOBJ) + throw std::runtime_error("JSON value is not an object as expected"); + return keys; +} + +std::vector UniValue::getValues() const +{ + if (typ != VOBJ && typ != VARR) + throw std::runtime_error("JSON value is not an object or array as expected"); + return values; +} + +bool UniValue::get_bool() const +{ + if (typ != VBOOL) + throw std::runtime_error("JSON value is not a boolean as expected"); + return getBool(); +} + +std::string UniValue::get_str() const +{ + if (typ != VSTR) + throw std::runtime_error("JSON value is not a string as expected"); + return getValStr(); +} + +int UniValue::get_int() const +{ + if (typ != VNUM) + throw std::runtime_error("JSON value is not an integer as expected"); + int32_t retval; + if (!ParseInt32(getValStr(), &retval)) + throw std::runtime_error("JSON integer out of range"); + return retval; +} + +int64_t UniValue::get_int64() const +{ + if (typ != VNUM) + throw std::runtime_error("JSON value is not an integer as expected"); + int64_t retval; + if (!ParseInt64(getValStr(), &retval)) + throw std::runtime_error("JSON integer out of range"); + return retval; +} + +double UniValue::get_real() const +{ + if (typ != VREAL && typ != VNUM) + throw std::runtime_error("JSON value is not a number as expected"); + double retval; + if (!ParseDouble(getValStr(), &retval)) + throw std::runtime_error("JSON double out of range"); + return retval; +} + +const UniValue& UniValue::get_obj() const +{ + if (typ != VOBJ) + throw std::runtime_error("JSON value is not an object as expected"); + return *this; +} + +const UniValue& UniValue::get_array() const +{ + if (typ != VARR) + throw std::runtime_error("JSON value is not an array as expected"); + return *this; +} + diff --git a/src/univalue/univalue.h b/src/univalue/univalue.h index 57a96abe2..79018bb78 100644 --- a/src/univalue/univalue.h +++ b/src/univalue/univalue.h @@ -13,7 +13,6 @@ #include // .get_int64() #include // std::pair -#include // atoi(), atof() TODO: remove class UniValue { public: @@ -75,7 +74,7 @@ public: bool isNull() const { return (typ == VNULL); } bool isTrue() const { return (typ == VBOOL) && (val == "1"); } - bool isFalse() const { return (!isTrue()); } + bool isFalse() const { return (typ == VBOOL) && (val != "1"); } bool isBool() const { return (typ == VBOOL); } bool isStr() const { return (typ == VSTR); } bool isNum() const { return (typ == VNUM); } @@ -140,27 +139,22 @@ private: void writeObject(unsigned int prettyIndent, unsigned int indentLevel, std::string& s) const; public: - // - // The following were added for compatibility with json_spirit. - // Most duplicate other methods, and should be removed. - // - std::vector getKeys() const { return keys; } - std::vector getValues() const { return values; } - bool get_bool() const { return getBool(); } - std::string get_str() const { return getValStr(); } - int get_int() const { return atoi(getValStr().c_str()); } - double get_real() const { return atof(getValStr().c_str()); } - const UniValue& get_obj() const { return *this; } - const UniValue& get_array() const { return *this; } + // Strict type-specific getters, these throw std::runtime_error if the + // value is of unexpected type + std::vector getKeys() const; + std::vector getValues() const; + bool get_bool() const; + std::string get_str() const; + int get_int() const; + int64_t get_int64() const; + double get_real() const; + const UniValue& get_obj() const; + const UniValue& get_array() const; + enum VType type() const { return getType(); } bool push_back(std::pair pear) { return pushKV(pear.first, pear.second); } - int64_t get_int64() const { - int64_t ret; - std::istringstream(getValStr()) >> ret; - return ret; - } friend const UniValue& find_value( const UniValue& obj, const std::string& name); }; From 6b1e42bbfa75712bc50d5bde719686be18bf4d6f Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 4 Jun 2015 13:58:14 +0200 Subject: [PATCH 18/26] univalue: add type check unit tests --- src/test/univalue_tests.cpp | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/src/test/univalue_tests.cpp b/src/test/univalue_tests.cpp index 87186cac4..de84faca2 100644 --- a/src/test/univalue_tests.cpp +++ b/src/test/univalue_tests.cpp @@ -63,6 +63,48 @@ BOOST_AUTO_TEST_CASE(univalue_constructor) BOOST_CHECK_EQUAL(v9.getValStr(), "zappa"); } +BOOST_AUTO_TEST_CASE(univalue_typecheck) +{ + UniValue v1; + BOOST_CHECK(v1.setNumStr("1")); + BOOST_CHECK(v1.isNum()); + BOOST_CHECK_THROW(v1.get_bool(), runtime_error); + + UniValue v2; + BOOST_CHECK(v2.setBool(true)); + BOOST_CHECK_EQUAL(v2.get_bool(), true); + BOOST_CHECK_THROW(v2.get_int(), runtime_error); + + UniValue v3; + BOOST_CHECK(v3.setNumStr("32482348723847471234")); + BOOST_CHECK_THROW(v3.get_int64(), runtime_error); + BOOST_CHECK(v3.setNumStr("1000")); + BOOST_CHECK_EQUAL(v3.get_int64(), 1000); + + UniValue v4; + BOOST_CHECK(v4.setNumStr("2147483648")); + BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648); + BOOST_CHECK_THROW(v4.get_int(), runtime_error); + BOOST_CHECK(v4.setNumStr("1000")); + BOOST_CHECK_EQUAL(v4.get_int(), 1000); + BOOST_CHECK_THROW(v4.get_str(), runtime_error); + BOOST_CHECK_EQUAL(v4.get_real(), 1000); + BOOST_CHECK_THROW(v4.get_array(), runtime_error); + BOOST_CHECK_THROW(v4.getKeys(), runtime_error); + BOOST_CHECK_THROW(v4.getValues(), runtime_error); + BOOST_CHECK_THROW(v4.get_obj(), runtime_error); + + UniValue v5; + BOOST_CHECK(v5.read("[true, 10]")); + BOOST_CHECK_NO_THROW(v5.get_array()); + std::vector vals = v5.getValues(); + BOOST_CHECK_THROW(vals[0].get_int(), runtime_error); + BOOST_CHECK_EQUAL(vals[0].get_bool(), true); + + BOOST_CHECK_EQUAL(vals[1].get_int(), 10); + BOOST_CHECK_THROW(vals[1].get_bool(), runtime_error); +} + BOOST_AUTO_TEST_CASE(univalue_set) { UniValue v(UniValue::VSTR, "foo"); From b60e9f230ff04ae2c23957be8a0c99b8ed8ee423 Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Fri, 5 Jun 2015 17:04:56 +0200 Subject: [PATCH 19/26] fix util_tests.cpp clang warnings was introduced with #6121 --- src/test/util_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/util_tests.cpp b/src/test/util_tests.cpp index 606c803a0..2224a119d 100644 --- a/src/test/util_tests.cpp +++ b/src/test/util_tests.cpp @@ -349,8 +349,8 @@ BOOST_AUTO_TEST_CASE(test_ParseInt64) BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL); BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL); - BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == 9223372036854775807LL); - BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == 9223372036854775808LL); + BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == (int64_t)9223372036854775807); + BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == (int64_t)-9223372036854775807-1); BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL); // Invalid values BOOST_CHECK(!ParseInt64("", &n)); From f70084cf06d4c7d7d98881751cc1c5f347073d2c Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Thu, 4 Jun 2015 21:39:44 +0200 Subject: [PATCH 20/26] fix rpcmining/getblocktemplate univalue transition logic error --- src/rpcmining.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 3bc5d646a..2d78f0651 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -521,7 +521,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) if (strMode == "proposal") { const UniValue& dataval = find_value(oparam, "data"); - if (dataval.isStr()) + if (!dataval.isStr()) throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); CBlock block; From 0d37ae3a594bf690fa68dbeba58b24907f2752bc Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Fri, 6 Jan 2017 19:15:56 +0100 Subject: [PATCH 21/26] Migrate Zcash-specific code to UniValue --- src/Makefile.gtest.include | 1 - src/asyncrpcoperation.cpp | 39 +++--- src/asyncrpcoperation.h | 16 +-- src/gtest/json_test_vectors.cpp | 8 +- src/gtest/json_test_vectors.h | 7 +- src/gtest/test_jsonspirit.cpp | 17 --- src/gtest/test_merkletree.cpp | 34 +++--- src/gtest/test_proofs.cpp | 8 +- src/gtest/test_rpc.cpp | 9 +- src/rpcblockchain.cpp | 10 +- src/rpcmining.cpp | 12 +- src/rpcmisc.cpp | 4 +- src/rpcrawtransaction.cpp | 16 +-- src/test/alert_tests.cpp | 1 - src/test/rpc_wallet_tests.cpp | 86 +++++++------- src/wallet/asyncrpcoperation_sendmany.cpp | 77 ++++++------ src/wallet/asyncrpcoperation_sendmany.h | 26 ++-- src/wallet/rpcdump.cpp | 28 ++--- src/wallet/rpcwallet.cpp | 138 +++++++++++----------- 19 files changed, 258 insertions(+), 279 deletions(-) delete mode 100644 src/gtest/test_jsonspirit.cpp diff --git a/src/Makefile.gtest.include b/src/Makefile.gtest.include index a9e5e04dc..d608bfcc1 100644 --- a/src/Makefile.gtest.include +++ b/src/Makefile.gtest.include @@ -18,7 +18,6 @@ zcash_gtest_SOURCES += \ wallet/gtest/test_wallet_zkeys.cpp endif zcash_gtest_SOURCES += \ - gtest/test_jsonspirit.cpp \ gtest/test_tautology.cpp \ gtest/test_equihash.cpp \ gtest/test_joinsplit.cpp \ diff --git a/src/asyncrpcoperation.cpp b/src/asyncrpcoperation.cpp index 508cd0a51..f32e8d716 100644 --- a/src/asyncrpcoperation.cpp +++ b/src/asyncrpcoperation.cpp @@ -13,7 +13,6 @@ #include using namespace std; -using namespace json_spirit; static boost::uuids::random_generator uuidgen; @@ -109,34 +108,34 @@ void AsyncRPCOperation::main() { */ // Otherwise, if the operation was a success: - Value v("We have a result!"); + UniValue v(UniValue::VSTR, "We have a result!"); set_result(v); set_state(OperationStatus::SUCCESS); } /** - * Return the error of the completed operation as a Value object. - * If there is no error, return null Value. + * Return the error of the completed operation as a UniValue object. + * If there is no error, return null UniValue. */ -Value AsyncRPCOperation::getError() const { +UniValue AsyncRPCOperation::getError() const { if (!isFailed()) { - return Value::null; + return NullUniValue; } std::lock_guard guard(lock_); - Object error; + UniValue error(UniValue::VOBJ); error.push_back(Pair("code", this->error_code_)); error.push_back(Pair("message", this->error_message_)); - return Value(error); + return error; } /** - * Return the result of the completed operation as a Value object. - * If the operation did not succeed, return null Value. + * Return the result of the completed operation as a UniValue object. + * If the operation did not succeed, return null UniValue. */ -Value AsyncRPCOperation::getResult() const { +UniValue AsyncRPCOperation::getResult() const { if (!isSuccess()) { - return Value::null; + return NullUniValue; } std::lock_guard guard(lock_); @@ -145,24 +144,24 @@ Value AsyncRPCOperation::getResult() const { /** - * Returns a status Value object. + * Returns a status UniValue object. * If the operation has failed, it will include an error object. * If the operation has succeeded, it will include the result value. * If the operation was cancelled, there will be no error object or result value. */ -Value AsyncRPCOperation::getStatus() const { +UniValue AsyncRPCOperation::getStatus() const { OperationStatus status = this->getState(); - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("id", this->id_)); obj.push_back(Pair("status", OperationStatusMap[status])); obj.push_back(Pair("creation_time", this->creation_time_)); // TODO: Issue #1354: There may be other useful metadata to return to the user. - Value err = this->getError(); - if (!err.is_null()) { + UniValue err = this->getError(); + if (!err.isNull()) { obj.push_back(Pair("error", err.get_obj())); } - Value result = this->getResult(); - if (!result.is_null()) { + UniValue result = this->getResult(); + if (!result.isNull()) { obj.push_back(Pair("result", result)); // Include execution time for successful operation @@ -170,7 +169,7 @@ Value AsyncRPCOperation::getStatus() const { obj.push_back(Pair("execution_secs", elapsed_seconds.count())); } - return Value(obj); + return obj; } /** diff --git a/src/asyncrpcoperation.h b/src/asyncrpcoperation.h index 526a62ad0..e095e57b1 100644 --- a/src/asyncrpcoperation.h +++ b/src/asyncrpcoperation.h @@ -15,13 +15,9 @@ #include #include -#include "json/json_spirit_value.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_writer_template.h" +#include "univalue/univalue.h" using namespace std; -using namespace json_spirit; /** * AsyncRPCOperation objects are submitted to the AsyncRPCQueue for processing. @@ -67,11 +63,11 @@ public: } // Override this method to add data to the default status object. - virtual Value getStatus() const; + virtual UniValue getStatus() const; - Value getError() const; + UniValue getError() const; - Value getResult() const; + UniValue getResult() const; std::string getStateAsString() const; @@ -114,7 +110,7 @@ protected: // internal state. Currently, all operations are executed in a single-thread // by a single worker. mutable std::mutex lock_; // lock on this when read/writing non-atomics - Value result_; + UniValue result_; int error_code_; std::string error_message_; std::atomic state_; @@ -137,7 +133,7 @@ protected: this->error_message_ = errorMessage; } - void set_result(Value v) { + void set_result(UniValue v) { std::lock_guard guard(lock_); this->result_ = v; } diff --git a/src/gtest/json_test_vectors.cpp b/src/gtest/json_test_vectors.cpp index 737668d9b..94ba5b4c5 100644 --- a/src/gtest/json_test_vectors.cpp +++ b/src/gtest/json_test_vectors.cpp @@ -1,14 +1,14 @@ #include "json_test_vectors.h" -Array +UniValue read_json(const std::string& jsondata) { - Value v; + UniValue v; - if (!read_string(jsondata, v) || v.type() != array_type) + if (!(v.read(jsondata) && v.isArray())) { ADD_FAILURE(); - return Array(); + return UniValue(UniValue::VARR); } return v.get_array(); } diff --git a/src/gtest/json_test_vectors.h b/src/gtest/json_test_vectors.h index 136865bfb..623dab5e1 100644 --- a/src/gtest/json_test_vectors.h +++ b/src/gtest/json_test_vectors.h @@ -5,12 +5,9 @@ #include "serialize.h" #include "streams.h" -#include "json/json_spirit_reader_template.h" -#include "json/json_spirit_utils.h" -#include "json/json_spirit_writer_template.h" +#include "univalue/univalue.h" -using namespace json_spirit; -Array +UniValue read_json(const std::string& jsondata); // #define PRINT_JSON 1 diff --git a/src/gtest/test_jsonspirit.cpp b/src/gtest/test_jsonspirit.cpp deleted file mode 100644 index f93e8d459..000000000 --- a/src/gtest/test_jsonspirit.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include - -#include "json/json_spirit_reader_template.h" - -using namespace json_spirit; - -// This test checks if we have fixed a stack overflow problem with json_spirit. -// It was possible to try and create an unlimited number of nested compound elements. -// Without the fix in json_spirit_reader_template.h, this test will segfault. -TEST(json_spirit_tests, nested_input_segfault) { - std::vector v (100000); - std::fill (v.begin(),v.end(), '['); - std::string s(v.begin(), v.end()); - Value value; - bool b = json_spirit::read_string(s, value); - ASSERT_FALSE(b); -} diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index cf1d8617a..bd60d37c4 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -57,18 +57,18 @@ void expect_ser_test_vector(B& b, const C& c, const A& tree) { template void test_tree( - Array commitment_tests, - Array root_tests, - Array ser_tests, - Array witness_ser_tests, - Array path_tests + UniValue commitment_tests, + UniValue root_tests, + UniValue ser_tests, + UniValue witness_ser_tests, + UniValue path_tests ) { - Array::iterator commitment_iterator = commitment_tests.begin(); - Array::iterator root_iterator = root_tests.begin(); - Array::iterator ser_iterator = ser_tests.begin(); - Array::iterator witness_ser_iterator = witness_ser_tests.begin(); - Array::iterator path_iterator = path_tests.begin(); + vector::iterator commitment_iterator = commitment_tests.getValues().begin(); + vector::iterator root_iterator = root_tests.getValues().begin(); + vector::iterator ser_iterator = ser_tests.getValues().begin(); + vector::iterator witness_ser_iterator = witness_ser_tests.getValues().begin(); + vector::iterator path_iterator = path_tests.getValues().begin(); Tree tree; @@ -193,18 +193,18 @@ void test_tree( } TEST(merkletree, vectors) { - Array root_tests = read_json(std::string(json_tests::merkle_roots, json_tests::merkle_roots + sizeof(json_tests::merkle_roots))); - Array ser_tests = read_json(std::string(json_tests::merkle_serialization, json_tests::merkle_serialization + sizeof(json_tests::merkle_serialization))); - Array witness_ser_tests = read_json(std::string(json_tests::merkle_witness_serialization, json_tests::merkle_witness_serialization + sizeof(json_tests::merkle_witness_serialization))); - Array path_tests = read_json(std::string(json_tests::merkle_path, json_tests::merkle_path + sizeof(json_tests::merkle_path))); - Array commitment_tests = read_json(std::string(json_tests::merkle_commitments, json_tests::merkle_commitments + sizeof(json_tests::merkle_commitments))); + UniValue root_tests = read_json(std::string(json_tests::merkle_roots, json_tests::merkle_roots + sizeof(json_tests::merkle_roots))); + UniValue ser_tests = read_json(std::string(json_tests::merkle_serialization, json_tests::merkle_serialization + sizeof(json_tests::merkle_serialization))); + UniValue witness_ser_tests = read_json(std::string(json_tests::merkle_witness_serialization, json_tests::merkle_witness_serialization + sizeof(json_tests::merkle_witness_serialization))); + UniValue path_tests = read_json(std::string(json_tests::merkle_path, json_tests::merkle_path + sizeof(json_tests::merkle_path))); + UniValue commitment_tests = read_json(std::string(json_tests::merkle_commitments, json_tests::merkle_commitments + sizeof(json_tests::merkle_commitments))); test_tree(commitment_tests, root_tests, ser_tests, witness_ser_tests, path_tests); } TEST(merkletree, emptyroots) { - Array empty_roots = read_json(std::string(json_tests::merkle_roots_empty, json_tests::merkle_roots_empty + sizeof(json_tests::merkle_roots_empty))); - Array::iterator root_iterator = empty_roots.begin(); + UniValue empty_roots = read_json(std::string(json_tests::merkle_roots_empty, json_tests::merkle_roots_empty + sizeof(json_tests::merkle_roots_empty))); + vector::iterator root_iterator = empty_roots.getValues().begin(); libzcash::EmptyMerkleRoots<64, libzcash::SHA256Compress> emptyroots; diff --git a/src/gtest/test_proofs.cpp b/src/gtest/test_proofs.cpp index 1e8d30bd7..69ffdbe54 100644 --- a/src/gtest/test_proofs.cpp +++ b/src/gtest/test_proofs.cpp @@ -629,8 +629,8 @@ TEST(proofs, g2_deserialization) TEST(proofs, g1_test_vectors) { - Array v = read_json(std::string(json_tests::g1_compressed, json_tests::g1_compressed + sizeof(json_tests::g1_compressed))); - Array::iterator v_iterator = v.begin(); + UniValue v = read_json(std::string(json_tests::g1_compressed, json_tests::g1_compressed + sizeof(json_tests::g1_compressed))); + std::vector::iterator v_iterator = v.getValues().begin(); curve_G1 e = curve_Fr("34958239045823") * curve_G1::one(); for (size_t i = 0; i < 10000; i++) { @@ -646,8 +646,8 @@ TEST(proofs, g1_test_vectors) TEST(proofs, g2_test_vectors) { - Array v = read_json(std::string(json_tests::g2_compressed, json_tests::g2_compressed + sizeof(json_tests::g2_compressed))); - Array::iterator v_iterator = v.begin(); + UniValue v = read_json(std::string(json_tests::g2_compressed, json_tests::g2_compressed + sizeof(json_tests::g2_compressed))); + std::vector::iterator v_iterator = v.getValues().begin(); curve_G2 e = curve_Fr("34958239045823") * curve_G2::one(); for (size_t i = 0; i < 10000; i++) { diff --git a/src/gtest/test_rpc.cpp b/src/gtest/test_rpc.cpp index dc7a07e0d..baebc7c65 100644 --- a/src/gtest/test_rpc.cpp +++ b/src/gtest/test_rpc.cpp @@ -1,6 +1,5 @@ #include -#include "json/json_spirit_value.h" -#include "json/json_spirit_utils.h" +#include "univalue/univalue.h" #include "chain.h" #include "chainparams.h" @@ -10,7 +9,7 @@ #include "streams.h" #include "utilstrencodings.h" -extern json_spirit::Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); +extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false); TEST(rpc, check_blockToJSON_returns_minified_solution) { SelectParams(CBaseChainParams::TESTNET); @@ -24,6 +23,6 @@ TEST(rpc, check_blockToJSON_returns_minified_solution) { CBlockIndex index {block}; index.nHeight = 1391; - json_spirit::Object obj = blockToJSON(block, &index); - EXPECT_EQ("009f44ff7505d789b964d6817734b8ce1377d456255994370d06e59ac99bd5791b6ad174a66fd71c70e60cfc7fd88243ffe06f80b1ad181625f210779c745524629448e25348a5fce4f346a1735e60fdf53e144c0157dbc47c700a21a236f1efb7ee75f65b8d9d9e29026cfd09048233175202b211b9a49de4ab46f1cac71b6ea57a686377bd612378746e70c61a659c9cd683269e9c2a5cbc1d19f1149345302bbd0a1e62bf4bab01e9caeea789a1519441a61b146de35a4cc75dbdf01029127e311ad5073e7e96397f47226a7df9df66b2086b70756db013bbaeb068260157014b2602fc7dc71336e1439c887d2742d9730b4e79b08ec7839c3e2a037ae1565d04e05e351bb3531e5ef42cf7b71ca1482a9205245dd41f4db0f71644f8bdb88e845558537c03834c06ac83f336651e54e2edfc12e15ea9b7ea2c074e6155654d44c4d3bd90d9511050e9ad87d170db01448e5be6f45419cd86008978db5e3ceab79890234f992648d69bf1053855387db646ccdee5575c65f81dd0f670b016d9f9a84707d91f77b862f697b8bb08365ba71fbe6bfa47af39155a75ebdcb1e5d69f59c40c9e3a64988c1ec26f7f5159eef5c244d504a9e46125948ecc389c2ec3028ac4ff39ffd66e7743970819272b21e0c2df75b308bc62896873952147e57ed79446db4cdb5a563e76ec4c25899d41128afb9a5f8fc8063621efb7a58b9dd666d30c73e318cdcf3393bfec200e160f500e645f7baac263db99fa4a7c1cb4fea219fc512193102034d379f244c21a81821301b8d47c90247713a3e902c762d7bafa6cdb744eeb6d3b50dd175599d02b6e9f5bbda59366e04862aa765135968426e7ac0116de7351940dc57c0ae451d63f667e39891bc81e09e6c76f6f8a7582f7447c6f5945f717b0e52a7e3dd0c6db4061362123cc53fd8ede4abed4865201dc4d8eb4e5d48baa565183b69a5304a44c0600bb24dcaeee9d95ceebd27c1b0a33e0b46f23797d7d7907300b2bb7d62ef2fc5aa139250c73930c621bb5f41fc235534ee8014dfaddd5245aeb01198420ba7b5c076545329c94d54fa725a8e807579f5f0cc9d98170598023268f5930893620190275e6b3c6f5181e36310a9a475208316911d78f917d724c5946c553b7ec042c563c540114b6b78bd4c6e808ee391a4a9d93e127032983c5b3708037b14aa604cfb034e7c8b0ffdd6936446fe80216178506a87402653a373926eeff66e704daf992a0a9a5c3ad80566c0339be9e5b8e35b3b3226b2f7767e20d992ea6c3d6e322eca37b0c7f7e60060802f5abcc1975841365cadbdc3867063addfc803766ae525375ecddee61f9df9ffcd20343c83ab82b0e91de039c59cb435c8d3159cc338b4901f40c9b5c27043bcf2bd5fa9b685b65c9ba5a1e11a51dd3f773051560341f9ec81d05bf259e2d4b7161f896fbb6812cfc924a32120b7367d5e40439e267adda6a1315bb0d6200ce6a503174c8d2a638ea6fd6b1f486d68db11bdca63c4f4a725d1ab6231ea875484e70b27d293c05803386924f283d4c12bb953474d92b7dd43d2d97193bd96281ebb63fa075d2f9ecd310c70ee1d97b5330bd8fb5791c5943ecf084e5f2c83915acac57519c46b166136068d6f9ec0dd598616e32c591128ce13705a283ca39d5b211409600e07b3713113374d9700207a45394eac5b3b7afc9b1b2bad7d89fd3f35f6b2413ce615ee7869b3569009403b96fdacdb32ef0a7e5229e2b666d51e95bdfb009b892e88bde70621a9b6509f068781392df4bdbc5723bb15071993f0d9a11575af5ff6ef85eaea39bc86805b35d8beee91b779354147f2d85304b8b49d053e7444fdd3deb9d16de331f2552af5b3be7766bb8f3f6a78c62148efb231f2268", json_spirit::find_value(obj, "solution").get_str()); + UniValue obj = blockToJSON(block, &index); + EXPECT_EQ("009f44ff7505d789b964d6817734b8ce1377d456255994370d06e59ac99bd5791b6ad174a66fd71c70e60cfc7fd88243ffe06f80b1ad181625f210779c745524629448e25348a5fce4f346a1735e60fdf53e144c0157dbc47c700a21a236f1efb7ee75f65b8d9d9e29026cfd09048233175202b211b9a49de4ab46f1cac71b6ea57a686377bd612378746e70c61a659c9cd683269e9c2a5cbc1d19f1149345302bbd0a1e62bf4bab01e9caeea789a1519441a61b146de35a4cc75dbdf01029127e311ad5073e7e96397f47226a7df9df66b2086b70756db013bbaeb068260157014b2602fc7dc71336e1439c887d2742d9730b4e79b08ec7839c3e2a037ae1565d04e05e351bb3531e5ef42cf7b71ca1482a9205245dd41f4db0f71644f8bdb88e845558537c03834c06ac83f336651e54e2edfc12e15ea9b7ea2c074e6155654d44c4d3bd90d9511050e9ad87d170db01448e5be6f45419cd86008978db5e3ceab79890234f992648d69bf1053855387db646ccdee5575c65f81dd0f670b016d9f9a84707d91f77b862f697b8bb08365ba71fbe6bfa47af39155a75ebdcb1e5d69f59c40c9e3a64988c1ec26f7f5159eef5c244d504a9e46125948ecc389c2ec3028ac4ff39ffd66e7743970819272b21e0c2df75b308bc62896873952147e57ed79446db4cdb5a563e76ec4c25899d41128afb9a5f8fc8063621efb7a58b9dd666d30c73e318cdcf3393bfec200e160f500e645f7baac263db99fa4a7c1cb4fea219fc512193102034d379f244c21a81821301b8d47c90247713a3e902c762d7bafa6cdb744eeb6d3b50dd175599d02b6e9f5bbda59366e04862aa765135968426e7ac0116de7351940dc57c0ae451d63f667e39891bc81e09e6c76f6f8a7582f7447c6f5945f717b0e52a7e3dd0c6db4061362123cc53fd8ede4abed4865201dc4d8eb4e5d48baa565183b69a5304a44c0600bb24dcaeee9d95ceebd27c1b0a33e0b46f23797d7d7907300b2bb7d62ef2fc5aa139250c73930c621bb5f41fc235534ee8014dfaddd5245aeb01198420ba7b5c076545329c94d54fa725a8e807579f5f0cc9d98170598023268f5930893620190275e6b3c6f5181e36310a9a475208316911d78f917d724c5946c553b7ec042c563c540114b6b78bd4c6e808ee391a4a9d93e127032983c5b3708037b14aa604cfb034e7c8b0ffdd6936446fe80216178506a87402653a373926eeff66e704daf992a0a9a5c3ad80566c0339be9e5b8e35b3b3226b2f7767e20d992ea6c3d6e322eca37b0c7f7e60060802f5abcc1975841365cadbdc3867063addfc803766ae525375ecddee61f9df9ffcd20343c83ab82b0e91de039c59cb435c8d3159cc338b4901f40c9b5c27043bcf2bd5fa9b685b65c9ba5a1e11a51dd3f773051560341f9ec81d05bf259e2d4b7161f896fbb6812cfc924a32120b7367d5e40439e267adda6a1315bb0d6200ce6a503174c8d2a638ea6fd6b1f486d68db11bdca63c4f4a725d1ab6231ea875484e70b27d293c05803386924f283d4c12bb953474d92b7dd43d2d97193bd96281ebb63fa075d2f9ecd310c70ee1d97b5330bd8fb5791c5943ecf084e5f2c83915acac57519c46b166136068d6f9ec0dd598616e32c591128ce13705a283ca39d5b211409600e07b3713113374d9700207a45394eac5b3b7afc9b1b2bad7d89fd3f35f6b2413ce615ee7869b3569009403b96fdacdb32ef0a7e5229e2b666d51e95bdfb009b892e88bde70621a9b6509f068781392df4bdbc5723bb15071993f0d9a11575af5ff6ef85eaea39bc86805b35d8beee91b779354147f2d85304b8b49d053e7444fdd3deb9d16de331f2552af5b3be7766bb8f3f6a78c62148efb231f2268", find_value(obj, "solution").get_str()); } diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 7e70a5ec2..fef578cc5 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -494,7 +494,7 @@ UniValue verifychain(const UniValue& params, bool fHelp) } /** Implementation of IsSuperMajority with better feedback */ -Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams) +static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams) { int nFound = 0; CBlockIndex* pstart = pindex; @@ -505,7 +505,7 @@ Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, pstart = pstart->pprev; } - Object rv; + UniValue rv(UniValue::VOBJ); rv.push_back(Pair("status", nFound >= nRequired)); rv.push_back(Pair("found", nFound)); rv.push_back(Pair("required", nRequired)); @@ -513,9 +513,9 @@ Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, return rv; } -Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) +static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams) { - Object rv; + UniValue rv(UniValue::VOBJ); rv.push_back(Pair("id", name)); rv.push_back(Pair("version", version)); rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams))); @@ -576,7 +576,7 @@ UniValue getblockchaininfo(const UniValue& params, bool fHelp) const Consensus::Params& consensusParams = Params().GetConsensus(); CBlockIndex* tip = chainActive.Tip(); - Array softforks; + UniValue softforks(UniValue::VARR); softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams)); softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams)); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 2d78f0651..8f63b752c 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -74,7 +74,7 @@ int64_t GetNetworkHashPS(int lookup, int height) { return (int64_t)(workDiff.getdouble() / timeDiff); } -Value getlocalsolps(const Array& params, bool fHelp) +UniValue getlocalsolps(const UniValue& params, bool fHelp) { if (fHelp) throw runtime_error( @@ -92,7 +92,7 @@ Value getlocalsolps(const Array& params, bool fHelp) return GetLocalSolPS(); } -Value getnetworksolps(const Array& params, bool fHelp) +UniValue getnetworksolps(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 2) throw runtime_error( @@ -647,7 +647,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal"); - Value txCoinbase = NullUniValue; + UniValue txCoinbase = NullUniValue; UniValue transactions(UniValue::VARR); map setTxIndex; int i = 0; @@ -709,7 +709,7 @@ UniValue getblocktemplate(const UniValue& params, bool fHelp) result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); if (coinbasetxn) { - assert(txCoinbase.type() == obj_type); + assert(txCoinbase.isObject()); result.push_back(Pair("coinbasetxn", txCoinbase)); } else { result.push_back(Pair("coinbaseaux", aux)); @@ -868,7 +868,7 @@ UniValue estimatepriority(const UniValue& params, bool fHelp) return mempool.estimatePriority(nBlocks); } -Value getblocksubsidy(const Array& params, bool fHelp) +UniValue getblocksubsidy(const UniValue& params, bool fHelp) { if (fHelp || params.size() > 1) throw runtime_error( @@ -897,7 +897,7 @@ Value getblocksubsidy(const Array& params, bool fHelp) nFoundersReward = nReward/5; nReward -= nFoundersReward; } - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("miner", ValueFromAmount(nReward))); result.push_back(Pair("founders", ValueFromAmount(nFoundersReward))); return result; diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index ee0274a4b..ef480034c 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -214,7 +214,7 @@ UniValue validateaddress(const UniValue& params, bool fHelp) } -Value z_validateaddress(const Array& params, bool fHelp) +UniValue z_validateaddress(const UniValue& params, bool fHelp) { if (fHelp || params.size() != 1) throw runtime_error( @@ -261,7 +261,7 @@ Value z_validateaddress(const Array& params, bool fHelp) // address is invalid, nop here as isValid is false. } - Object ret; + UniValue ret(UniValue::VOBJ); ret.push_back(Pair("isvalid", isValid)); if (isValid) { diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index f0a95fb9e..597da3763 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -55,11 +55,11 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fInclud } -Array TxJoinSplitToJSON(const CTransaction& tx) { - Array vjoinsplit; +UniValue TxJoinSplitToJSON(const CTransaction& tx) { + UniValue vjoinsplit(UniValue::VARR); for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) { const JSDescription& jsdescription = tx.vjoinsplit[i]; - Object joinsplit; + UniValue joinsplit(UniValue::VOBJ); joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old))); joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new))); @@ -67,7 +67,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) { joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex())); { - Array nullifiers; + UniValue nullifiers(UniValue::VARR); BOOST_FOREACH(const uint256 nf, jsdescription.nullifiers) { nullifiers.push_back(nf.GetHex()); } @@ -75,7 +75,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) { } { - Array commitments; + UniValue commitments(UniValue::VARR); BOOST_FOREACH(const uint256 commitment, jsdescription.commitments) { commitments.push_back(commitment.GetHex()); } @@ -86,7 +86,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) { joinsplit.push_back(Pair("randomSeed", jsdescription.randomSeed.GetHex())); { - Array macs; + UniValue macs(UniValue::VARR); BOOST_FOREACH(const uint256 mac, jsdescription.macs) { macs.push_back(mac.GetHex()); } @@ -98,7 +98,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) { joinsplit.push_back(Pair("proof", HexStr(ssProof.begin(), ssProof.end()))); { - Array ciphertexts; + UniValue ciphertexts(UniValue::VARR); for (const ZCNoteEncryption::Ciphertext ct : jsdescription.ciphertexts) { ciphertexts.push_back(HexStr(ct.begin(), ct.end())); } @@ -145,7 +145,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry) } entry.push_back(Pair("vout", vout)); - Array vjoinsplit = TxJoinSplitToJSON(tx); + UniValue vjoinsplit = TxJoinSplitToJSON(tx); entry.push_back(Pair("vjoinsplit", vjoinsplit)); if (!hashBlock.IsNull()) { diff --git a/src/test/alert_tests.cpp b/src/test/alert_tests.cpp index 9a861f182..ab3841c48 100644 --- a/src/test/alert_tests.cpp +++ b/src/test/alert_tests.cpp @@ -27,7 +27,6 @@ #include #include #include -#include "json/json_spirit_reader_template.h" #include "key.h" #include "alertkeys.h" diff --git a/src/test/rpc_wallet_tests.cpp b/src/test/rpc_wallet_tests.cpp index a1323a5c8..f3d1ce0ed 100644 --- a/src/test/rpc_wallet_tests.cpp +++ b/src/test/rpc_wallet_tests.cpp @@ -40,7 +40,7 @@ extern UniValue CallRPC(string args); extern CWallet* pwalletMain; -bool find_error(const Object& objError, const std::string& expected) { +bool find_error(const UniValue& objError, const std::string& expected) { return find_value(objError, "message").get_str().find(expected) != string::npos; } @@ -243,7 +243,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) UniValue arr = retValue.get_array(); BOOST_CHECK_EQUAL(4, arr.size()); bool notFound = true; - for (auto a : arr) { + for (auto a : arr.getValues()) { notFound &= CBitcoinAddress(a.get_str()).Get() != demoAddress.Get(); } BOOST_CHECK(!notFound); @@ -254,17 +254,17 @@ BOOST_AUTO_TEST_CASE(rpc_wallet) BOOST_CHECK_THROW(CallRPC("getblocksubsidy too many args"), runtime_error); BOOST_CHECK_THROW(CallRPC("getblocksubsidy -1"), runtime_error); BOOST_CHECK_NO_THROW(retValue = CallRPC("getblocksubsidy 50000")); - Object obj = retValue.get_obj(); - BOOST_CHECK(find_value(obj, "miner") == 10.0); - BOOST_CHECK(find_value(obj, "founders") == 2.5); + UniValue obj = retValue.get_obj(); + BOOST_CHECK_EQUAL(find_value(obj, "miner").get_real(), 10.0); + BOOST_CHECK_EQUAL(find_value(obj, "founders").get_real(), 2.5); BOOST_CHECK_NO_THROW(retValue = CallRPC("getblocksubsidy 1000000")); obj = retValue.get_obj(); - BOOST_CHECK(find_value(obj, "miner") == 6.25); - BOOST_CHECK(find_value(obj, "founders") == 0.0); + BOOST_CHECK_EQUAL(find_value(obj, "miner").get_real(), 6.25); + BOOST_CHECK_EQUAL(find_value(obj, "founders").get_real(), 0.0); BOOST_CHECK_NO_THROW(retValue = CallRPC("getblocksubsidy 2000000")); obj = retValue.get_obj(); - BOOST_CHECK(find_value(obj, "miner") == 3.125); - BOOST_CHECK(find_value(obj, "founders") == 0.0); + BOOST_CHECK_EQUAL(find_value(obj, "miner").get_real(), 3.125); + BOOST_CHECK_EQUAL(find_value(obj, "founders").get_real(), 0.0); } BOOST_AUTO_TEST_CASE(rpc_wallet_getbalance) @@ -305,7 +305,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_validateaddress) LOCK2(cs_main, pwalletMain->cs_wallet); - Value retValue; + UniValue retValue; // Check number of args BOOST_CHECK_THROW(CallRPC("z_validateaddress"), runtime_error); @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_validateaddress) // This address is not valid, it belongs to another network BOOST_CHECK_NO_THROW(retValue = CallRPC("z_validateaddress ztaaga95QAPyp1kSQ1hD2kguCpzyMHjxWZqaYDEkzbvo7uYQYAw2S8X4Kx98AvhhofMtQL8PAXKHuZsmhRcanavKRKmdCzk")); - Object resultObj = retValue.get_obj(); + UniValue resultObj = retValue.get_obj(); bool b = find_value(resultObj, "isvalid").get_bool(); BOOST_CHECK_EQUAL(b, false); @@ -485,7 +485,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet) BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) { LOCK2(cs_main, pwalletMain->cs_wallet); - Value retValue; + UniValue retValue; int n1 = 1000; // number of times to import/export int n2 = 1000; // number of addresses to create and list @@ -516,12 +516,12 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) // Verify we can list the keys imported BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses")); - Array arr = retValue.get_array(); + UniValue arr = retValue.get_array(); BOOST_CHECK(arr.size() == n1); // Put addresses into a set std::unordered_set myaddrs; - for (Value element : arr) { + for (UniValue element : arr.getValues()) { myaddrs.insert(element.get_str()); } @@ -543,7 +543,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport) // Create a set from them std::unordered_set listaddrs; - for (Value element : arr) { + for (UniValue element : arr.getValues()) { listaddrs.insert(element.get_str()); } @@ -582,7 +582,7 @@ public: start_execution_clock(); std::this_thread::sleep_for(std::chrono::milliseconds(naptime)); stop_execution_clock(); - set_result(Value("done")); + set_result(UniValue(UniValue::VSTR, "done")); set_state(OperationStatus::SUCCESS); } }; @@ -621,8 +621,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations) BOOST_CHECK_EQUAL(op1->isReady(), false); BOOST_CHECK_EQUAL(op1->isFailed(), false); BOOST_CHECK_EQUAL(op1->isSuccess(), true); - BOOST_CHECK(op1->getError() == Value::null ); - BOOST_CHECK(op1->getResult().is_null() == false ); + BOOST_CHECK_EQUAL(op1->getError().isNull(), true); + BOOST_CHECK_EQUAL(op1->getResult().isNull(), false); BOOST_CHECK_EQUAL(op1->getStateAsString(), "success"); BOOST_CHECK_NE(op1->getStateAsString(), "executing"); @@ -782,12 +782,12 @@ BOOST_AUTO_TEST_CASE(rpc_z_getoperations) // Check if too many args BOOST_CHECK_THROW(CallRPC("z_listoperationids toomany args"), runtime_error); - Value retValue; + UniValue retValue; BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listoperationids")); BOOST_CHECK(retValue.get_array().size() == 2); BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getoperationstatus")); - Array array = retValue.get_array(); + UniValue array = retValue.get_array(); BOOST_CHECK(array.size() == 2); // idempotent @@ -795,18 +795,18 @@ BOOST_AUTO_TEST_CASE(rpc_z_getoperations) array = retValue.get_array(); BOOST_CHECK(array.size() == 2); - for (Value v : array) { - Object obj = v.get_obj(); - Value id = find_value(obj, "id"); + for (UniValue v : array.getValues()) { + UniValue obj = v.get_obj(); + UniValue id = find_value(obj, "id"); - Value result; + UniValue result; // removes result from internal storage BOOST_CHECK_NO_THROW(result = CallRPC("z_getoperationresult [\"" + id.get_str() + "\"]")); - Array resultArray = result.get_array(); + UniValue resultArray = result.get_array(); BOOST_CHECK(resultArray.size() == 1); - Object resultObj = resultArray.front().get_obj(); - Value resultId = find_value(resultObj, "id"); + UniValue resultObj = resultArray[0].get_obj(); + UniValue resultId = find_value(resultObj, "id"); BOOST_CHECK_EQUAL(id.get_str(), resultId.get_str()); // verify the operation has been removed @@ -885,26 +885,26 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters) // Test constructor of AsyncRPCOperation_sendmany try { std::shared_ptr operation(new AsyncRPCOperation_sendmany("",{}, {}, -1)); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "Minconf cannot be negative")); } try { std::shared_ptr operation(new AsyncRPCOperation_sendmany("",{}, {}, 1)); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "From address parameter missing")); } try { std::shared_ptr operation( new AsyncRPCOperation_sendmany("tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ", {}, {}, 1) ); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "No recipients")); } try { std::vector recipients = { SendManyRecipient("dummy",1.0, "") }; std::shared_ptr operation( new AsyncRPCOperation_sendmany("INVALID", recipients, {}, 1) ); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "payment address is invalid")); } @@ -912,7 +912,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters) try { std::vector recipients = { SendManyRecipient("dummy",1.0, "") }; std::shared_ptr operation( new AsyncRPCOperation_sendmany("zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U", recipients, {}, 1) ); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "payment address is for wrong network type")); } @@ -921,7 +921,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters) try { std::vector recipients = { SendManyRecipient("dummy",1.0, "") }; std::shared_ptr operation( new AsyncRPCOperation_sendmany("ztjiDe569DPNbyTE6TSdJTaSDhoXEHLGvYoUnBU1wfVNU52TEyT6berYtySkd21njAeEoh8fFJUT42kua9r8EnhBaEKqCpP", recipients, {}, 1) ); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "no spending key found for zaddr")); } } @@ -934,7 +934,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) LOCK(pwalletMain->cs_wallet); - Value retValue; + UniValue retValue; // add keys manually BOOST_CHECK_NO_THROW(retValue = CallRPC("getnewaddress")); @@ -986,7 +986,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) try { proxy.get_memo_from_hex_string(bigmemo); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "too big")); } @@ -996,7 +996,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) try { proxy.get_memo_from_hex_string(badmemo); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "hexadecimal format")); } @@ -1007,7 +1007,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) std::string oddmemo(v.begin(), v.end()); try { proxy.get_memo_from_hex_string(oddmemo); - } catch (const Object& objError) { + } catch (const UniValue& objError) { BOOST_CHECK( find_error(objError, "hexadecimal format")); } } @@ -1062,7 +1062,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) // Raw joinsplit is a zaddr->zaddr { std::string raw = "020000000000000000000100000000000000001027000000000000183a0d4c46c369078705e39bcfebee59a978dbd210ce8de3efc9555a03fbabfd3cea16693d730c63850d7e48ccde79854c19adcb7e9dcd7b7d18805ee09083f6b16e1860729d2d4a90e2f2acd009cf78b5eb0f4a6ee4bdb64b1262d7ce9eb910c460b02022991e968d0c50ee44908e4ccccbc591d0053bcca154dd6d6fc400a29fa686af4682339832ccea362a62aeb9df0d5aa74f86a1e75ac0f48a8ccc41e0a940643c6c33e1d09223b0a46eaf47a1bb4407cfc12b1dcf83a29c0cef51e45c7876ca5b9e5bae86d92976eb3ef68f29cd29386a8be8451b50f82bf9da10c04651868655194da8f6ed3d241bb5b5ff93a3e2bbe44644544d88bcde5cc35978032ee92699c7a61fcbb395e7583f47e698c4d53ede54f956629400bf510fb5e22d03158cc10bdcaaf29e418ef18eb6480dd9c8b9e2a377809f9f32a556ef872febd0021d4ad013aa9f0b7255e98e408d302abefd33a71180b720271835b487ab309e160b06dfe51932120fb84a7ede16b20c53599a11071592109e10260f265ee60d48c62bfe24074020e9b586ce9e9356e68f2ad1a9538258234afe4b83a209f178f45202270eaeaeecaf2ce3100b2c5a714f75f35777a9ebff5ebf47059d2bbf6f3726190216468f2b152673b766225b093f3a2f827c86d6b48b42117fec1d0ac38dd7af700308dcfb02eba821612b16a2c164c47715b9b0c93900893b1aba2ea03765c94d87022db5be06ab338d1912e0936dfe87586d0a8ee49144a6cd2e306abdcb652faa3e0222739deb23154d778b50de75069a4a2cce1208cd1ced3cb4744c9888ce1c2fcd2e66dc31e62d3aa9e423d7275882525e9981f92e84ac85975b8660739407efbe1e34c2249420fde7e17db3096d5b22e83d051d01f0e6e7690dca7d168db338aadf0897fedac10de310db2b1bff762d322935dddbb60c2efb8b15d231fa17b84630371cb275c209f0c4c7d0c68b150ea5cd514122215e3f7fcfb351d69514788d67c2f3c8922581946e3a04bdf1f07f15696ca76eb95b10698bf1188fd882945c57657515889d042a6fc45d38cbc943540c4f0f6d1c45a1574c81f3e42d1eb8702328b729909adee8a5cfed7c79d54627d1fd389af941d878376f7927b9830ca659bf9ab18c5ca5192d52d02723008728d03701b8ab3e1c4a3109409ec0b13df334c7deec3523eeef4c97b5603e643de3a647b873f4c1b47fbfc6586ba66724f112e51fc93839648005043620aa3ce458e246d77977b19c53d98e3e812de006afc1a79744df236582943631d04cc02941ac4be500e4ed9fb9e3e7cc187b1c4050fad1d9d09d5fd70d5d01d615b439d8c0015d2eb10398bcdbf8c4b2bd559dbe4c288a186aed3f86f608da4d582e120c4a896e015e2241900d1daeccd05db968852677c71d752bec46de9962174b46f980e8cc603654daf8b98a3ee92dac066033954164a89568b70b1780c2ce2410b2f816dbeddb2cd463e0c8f21a52cf6427d9647a6fd4bafa8fb4cd4d47ac057b0160bee86c6b2fb8adce214c2bcdda277512200adf0eaa5d2114a2c077b009836a68ec254bfe56f51d147b9afe2ddd9cb917c0c2de19d81b7b8fd9f4574f51fa1207630dc13976f4d7587c962f761af267de71f3909a576e6bedaf6311633910d291ac292c467cc8331ef577aef7646a5d949322fa0367a49f20597a13def53136ee31610395e3e48d291fd8f58504374031fe9dcfba5e06086ebcf01a9106f6a4d6e16e19e4c5bb893f7da79419c94eca31a384be6fa1747284dee0fc3bbc8b1b860172c10b29c1594bb8c747d7fe05827358ff2160f49050001625ffe2e880bd7fc26cd0ffd89750745379a8e862816e08a5a2008043921ab6a4976064ac18f7ee37b6628bc0127d8d5ebd3548e41d8881a082d86f20b32e33094f15a0e6ea6074b08c6cd28142de94713451640a55985051f5577eb54572699d838cb34a79c8939e981c0c277d06a6e2ce69ccb74f8a691ff08f81d8b99e6a86223d29a2b7c8e7b041aba44ea678ae654277f7e91cbfa79158b989164a3d549d9f4feb0cc43169699c13e321fe3f4b94258c75d198ff9184269cd6986c55409e07528c93f64942c6c283ce3917b4bf4c3be2fe3173c8c38cccb35f1fbda0ca88b35a599c0678cb22aa8eabea8249dbd2e4f849fffe69803d299e435ebcd7df95854003d8eda17a74d98b4be0e62d45d7fe48c06a6f464a14f8e0570077cc631279092802a89823f031eef5e1028a6d6fdbd502869a731ee7d28b4d6c71b419462a30d31442d3ee444ffbcbd16d558c9000c97e949c2b1f9d6f6d8db7b9131ebd963620d3fc8595278d6f8fdf49084325373196d53e64142fa5a23eccd6ef908c4d80b8b3e6cc334b7f7012103a3682e4678e9b518163d262a39a2c1a69bf88514c52b7ccd7cc8dc80e71f7c2ec0701cff982573eb0c2c4daeb47fa0b586f4451c10d1da2e5d182b03dd067a5e971b3a6138ca6667aaf853d2ac03b80a1d5870905f2cfb6c78ec3c3719c02f973d638a0f973424a2b0f2b0023f136d60092fe15fba4bc180b9176bd0ff576e053f1af6939fe9ca256203ffaeb3e569f09774d2a6cbf91873e56651f4d6ff77e0b5374b0a1a201d7e523604e0247644544cc571d48c458a4f96f45580b"; - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("rawtxn", raw)); // we have the spending key for the dummy recipient zaddr1 @@ -1080,9 +1080,9 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) // Verify test mode is returning output (since no input taddrs, signed and unsigned are the same). BOOST_CHECK_NO_THROW( proxy.sign_send_raw_transaction(obj) ); - Value result = operation->getResult(); - BOOST_CHECK(!result.is_null()); - Object resultObj = result.get_obj(); + UniValue result = operation->getResult(); + BOOST_CHECK(!result.isNull()); + UniValue resultObj = result.get_obj(); std::string hex = find_value(resultObj, "hex").get_str(); BOOST_CHECK_EQUAL(hex, raw); } @@ -1150,7 +1150,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals) BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys) { LOCK2(cs_main, pwalletMain->cs_wallet); - Value retValue; + UniValue retValue; int n = 100; // wallet should currently be empty @@ -1165,7 +1165,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys) // Verify we can list the keys imported BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses")); - Array arr = retValue.get_array(); + UniValue arr = retValue.get_array(); BOOST_CHECK(arr.size() == n); // Verify that the wallet encryption RPC is disabled diff --git a/src/wallet/asyncrpcoperation_sendmany.cpp b/src/wallet/asyncrpcoperation_sendmany.cpp index 122ed53cb..e18dd4408 100644 --- a/src/wallet/asyncrpcoperation_sendmany.cpp +++ b/src/wallet/asyncrpcoperation_sendmany.cpp @@ -29,16 +29,16 @@ using namespace libzcash; -int find_output(Object obj, int n) { - Value outputMapValue = find_value(obj, "outputmap"); - if (outputMapValue.type() != array_type) { +int find_output(UniValue obj, int n) { + UniValue outputMapValue = find_value(obj, "outputmap"); + if (!outputMapValue.isArray()) { throw JSONRPCError(RPC_WALLET_ERROR, "Missing outputmap for JoinSplit operation"); } - Array outputMap = outputMapValue.get_array(); + UniValue outputMap = outputMapValue.get_array(); assert(outputMap.size() == ZC_NUM_JS_OUTPUTS); for (size_t i = 0; i < outputMap.size(); i++) { - if (outputMap[i] == n) { + if (outputMap[i].get_int() == n) { return i; } } @@ -52,7 +52,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( std::vector zOutputs, int minDepth, CAmount fee, - Value contextInfo) : + UniValue contextInfo) : fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo) { assert(fee_ >= 0); @@ -94,7 +94,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany( // Log the context info i.e. the call parameters to z_sendmany if (LogAcceptCategory("zrpcunsafe")) { - LogPrint("zrpcunsafe", "%s: z_sendmany initialized (params=%s)\n", getId(), json_spirit::write_string( contextInfo, false)); + LogPrint("zrpcunsafe", "%s: z_sendmany initialized (params=%s)\n", getId(), contextInfo.write()); } else { LogPrint("zrpc", "%s: z_sendmany initialized\n", getId()); } @@ -114,7 +114,7 @@ void AsyncRPCOperation_sendmany::main() { try { success = main_impl(); - } catch (const Object& objError) { + } catch (const UniValue& objError) { int code = find_value(objError, "code").get_int(); std::string message = find_value(objError, "message").get_str(); set_error_code(code); @@ -307,7 +307,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { ); } - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("rawtxn", EncodeHexTx(tx_))); sign_send_raw_transaction(obj); return true; @@ -385,7 +385,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { } // Create joinsplits, where each output represents a zaddr recipient. - Object obj; + UniValue obj(UniValue::VOBJ); while (zOutputsDeque.size() > 0) { AsyncJoinSplitInfo info; info.vpub_old = 0; @@ -434,7 +434,7 @@ bool AsyncRPCOperation_sendmany::main_impl() { * SCENARIO #3 * Part 1: Add to the transparent value pool. */ - Object obj; + UniValue obj(UniValue::VOBJ); CAmount jsChange = 0; // this is updated after each joinsplit int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0 bool minersFeeProcessed = false; @@ -757,42 +757,47 @@ bool AsyncRPCOperation_sendmany::main_impl() { * Sign and send a raw transaction. * Raw transaction as hex string should be in object field "rawtxn" */ -void AsyncRPCOperation_sendmany::sign_send_raw_transaction(Object obj) +void AsyncRPCOperation_sendmany::sign_send_raw_transaction(UniValue obj) { // Sign the raw transaction - Value rawtxnValue = find_value(obj, "rawtxn"); - if (rawtxnValue.is_null()) { + UniValue rawtxnValue = find_value(obj, "rawtxn"); + if (rawtxnValue.isNull()) { throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction"); } std::string rawtxn = rawtxnValue.get_str(); - Value signResultValue = signrawtransaction({Value(rawtxn)}, false); - Object signResultObject = signResultValue.get_obj(); - Value completeValue = find_value(signResultObject, "complete"); + UniValue params = UniValue(UniValue::VARR); + params.push_back(rawtxn); + UniValue signResultValue = signrawtransaction(params, false); + UniValue signResultObject = signResultValue.get_obj(); + UniValue completeValue = find_value(signResultObject, "complete"); bool complete = completeValue.get_bool(); if (!complete) { // TODO: #1366 Maybe get "errors" and print array vErrors into a string throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction"); } - Value hexValue = find_value(signResultObject, "hex"); - if (hexValue.is_null()) { + UniValue hexValue = find_value(signResultObject, "hex"); + if (hexValue.isNull()) { throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction"); } std::string signedtxn = hexValue.get_str(); // Send the signed transaction if (!testmode) { - Value sendResultValue = sendrawtransaction({Value(signedtxn)}, false); - if (sendResultValue.is_null()) { + params.clear(); + params.setArray(); + params.push_back(signedtxn); + UniValue sendResultValue = sendrawtransaction(params, false); + if (sendResultValue.isNull()) { throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid."); } std::string txid = sendResultValue.get_str(); - Object o; + UniValue o(UniValue::VOBJ); o.push_back(Pair("txid", txid)); - set_result(Value(o)); + set_result(o); } else { // Test mode does not send the transaction to the network. @@ -800,11 +805,11 @@ void AsyncRPCOperation_sendmany::sign_send_raw_transaction(Object obj) CTransaction tx; stream >> tx; - Object o; + UniValue o(UniValue::VOBJ); o.push_back(Pair("test", 1)); o.push_back(Pair("txid", tx.GetHash().ToString())); o.push_back(Pair("hex", signedtxn)); - set_result(Value(o)); + set_result(o); } // Keep the signed transaction so we can hash to the same txid @@ -891,7 +896,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() { return true; } -Object AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info) { +UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info) { std::vector> witnesses; uint256 anchor; { @@ -902,7 +907,7 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info) } -Object AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info, std::vector & outPoints) { +UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info, std::vector & outPoints) { std::vector> witnesses; uint256 anchor; { @@ -912,7 +917,7 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info, return perform_joinsplit(info, witnesses, anchor); } -Object AsyncRPCOperation_sendmany::perform_joinsplit( +UniValue AsyncRPCOperation_sendmany::perform_joinsplit( AsyncJoinSplitInfo & info, std::vector> witnesses, uint256 anchor) @@ -1033,8 +1038,8 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit( encryptedNote2 = HexStr(ss2.begin(), ss2.end()); } - Array arrInputMap; - Array arrOutputMap; + UniValue arrInputMap(UniValue::VARR); + UniValue arrOutputMap(UniValue::VARR); for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) { arrInputMap.push_back(inputMap[i]); } @@ -1042,7 +1047,7 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit( arrOutputMap.push_back(outputMap[i]); } - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("encryptednote1", encryptedNote1)); obj.push_back(Pair("encryptednote2", encryptedNote2)); obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); @@ -1118,15 +1123,15 @@ boost::array AsyncRPCOperation_sendmany::get_memo_f /** * Override getStatus() to append the operation's input parameters to the default status object. */ -Value AsyncRPCOperation_sendmany::getStatus() const { - Value v = AsyncRPCOperation::getStatus(); - if (contextinfo_.is_null()) { +UniValue AsyncRPCOperation_sendmany::getStatus() const { + UniValue v = AsyncRPCOperation::getStatus(); + if (contextinfo_.isNull()) { return v; } - Object obj = v.get_obj(); + UniValue obj = v.get_obj(); obj.push_back(Pair("method", "z_sendmany")); obj.push_back(Pair("params", contextinfo_ )); - return Value(obj); + return obj; } diff --git a/src/wallet/asyncrpcoperation_sendmany.h b/src/wallet/asyncrpcoperation_sendmany.h index 5108de8c5..e870e6039 100644 --- a/src/wallet/asyncrpcoperation_sendmany.h +++ b/src/wallet/asyncrpcoperation_sendmany.h @@ -11,17 +11,17 @@ #include "primitives/transaction.h" #include "zcash/JoinSplit.hpp" #include "zcash/Address.hpp" -#include "json/json_spirit_value.h" #include "wallet.h" #include #include +#include "univalue/univalue.h" + // Default transaction fee if caller does not specify one. #define ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE 10000 using namespace libzcash; -using namespace json_spirit; // A recipient is a tuple of address, amount, memo (optional if zaddr) typedef std::tuple SendManyRecipient; @@ -50,7 +50,7 @@ struct WitnessAnchorData { class AsyncRPCOperation_sendmany : public AsyncRPCOperation { public: - AsyncRPCOperation_sendmany(std::string fromAddress, std::vector tOutputs, std::vector zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, Value contextInfo = Value::null); + AsyncRPCOperation_sendmany(std::string fromAddress, std::vector tOutputs, std::vector zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue); virtual ~AsyncRPCOperation_sendmany(); // We don't want to be copied or moved around @@ -61,14 +61,14 @@ public: virtual void main(); - virtual Value getStatus() const; + virtual UniValue getStatus() const; bool testmode = false; // Set to true to disable sending txs and generating proofs private: friend class TEST_FRIEND_AsyncRPCOperation_sendmany; // class for unit testing - Value contextinfo_; // optional data to include in return value from getStatus() + UniValue contextinfo_; // optional data to include in return value from getStatus() CAmount fee_; int mindepth_; @@ -100,18 +100,18 @@ private: bool main_impl(); // JoinSplit without any input notes to spend - Object perform_joinsplit(AsyncJoinSplitInfo &); + UniValue perform_joinsplit(AsyncJoinSplitInfo &); // JoinSplit with input notes to spend (JSOutPoints)) - Object perform_joinsplit(AsyncJoinSplitInfo &, std::vector & ); + UniValue perform_joinsplit(AsyncJoinSplitInfo &, std::vector & ); // JoinSplit where you have the witnesses and anchor - Object perform_joinsplit( + UniValue perform_joinsplit( AsyncJoinSplitInfo & info, std::vector> witnesses, uint256 anchor); - void sign_send_raw_transaction(Object obj); // throws exception if there was an error + void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error }; @@ -157,15 +157,15 @@ public: return delegate->main_impl(); } - Object perform_joinsplit(AsyncJoinSplitInfo &info) { + UniValue perform_joinsplit(AsyncJoinSplitInfo &info) { return delegate->perform_joinsplit(info); } - Object perform_joinsplit(AsyncJoinSplitInfo &info, std::vector &v ) { + UniValue perform_joinsplit(AsyncJoinSplitInfo &info, std::vector &v ) { return delegate->perform_joinsplit(info, v); } - Object perform_joinsplit( + UniValue perform_joinsplit( AsyncJoinSplitInfo & info, std::vector> witnesses, uint256 anchor) @@ -173,7 +173,7 @@ public: return delegate->perform_joinsplit(info, witnesses, anchor); } - void sign_send_raw_transaction(Object obj) { + void sign_send_raw_transaction(UniValue obj) { delegate->sign_send_raw_transaction(obj); } diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 975d38bc1..7f9c89da2 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -26,8 +26,8 @@ using namespace std; void EnsureWalletIsUnlocked(); bool EnsureWalletIsAvailable(bool avoidException); -Value dumpwallet_impl(const Array& params, bool fHelp, bool fDumpZKeys); -Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys); +UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys); +UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys); std::string static EncodeDumpTime(int64_t nTime) { @@ -220,10 +220,10 @@ UniValue importaddress(const UniValue& params, bool fHelp) return NullUniValue; } -Value z_importwallet(const Array& params, bool fHelp) +UniValue z_importwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -266,7 +266,7 @@ UniValue importwallet(const UniValue& params, bool fHelp) return importwallet_impl(params, fHelp, false); } -Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys) +UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys) { LOCK2(cs_main, pwalletMain->cs_wallet); @@ -419,10 +419,10 @@ UniValue dumpprivkey(const UniValue& params, bool fHelp) -Value z_exportwallet(const Array& params, bool fHelp) +UniValue z_exportwallet(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( @@ -461,7 +461,7 @@ UniValue dumpwallet(const UniValue& params, bool fHelp) return dumpwallet_impl(params, fHelp, false); } -Value dumpwallet_impl(const Array& params, bool fHelp, bool fDumpZKeys) +UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys) { LOCK2(cs_main, pwalletMain->cs_wallet); @@ -547,10 +547,10 @@ Value dumpwallet_impl(const Array& params, bool fHelp, bool fDumpZKeys) } -Value z_importkey(const Array& params, bool fHelp) +UniValue z_importkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 2) throw runtime_error( @@ -586,7 +586,7 @@ Value z_importkey(const Array& params, bool fHelp) { // Don't throw error in case a key is already there if (pwalletMain->HaveSpendingKey(addr)) - return Value::null; + return NullUniValue; pwalletMain->MarkDirty(); @@ -604,14 +604,14 @@ Value z_importkey(const Array& params, bool fHelp) } } - return Value::null; + return NullUniValue; } -Value z_exportkey(const Array& params, bool fHelp) +UniValue z_exportkey(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() != 1) throw runtime_error( diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d4086371a..90b6d04fa 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -39,13 +39,13 @@ using namespace std; using namespace libzcash; -extern Array TxJoinSplitToJSON(const CTransaction& tx); +extern UniValue TxJoinSplitToJSON(const CTransaction& tx); int64_t nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; // Private method: -Value z_getoperationstatus_IMPL(const Array&, bool); +UniValue z_getoperationstatus_IMPL(const UniValue&, bool); std::string HelpRequiringPassphrase() { @@ -2413,7 +2413,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) return results; } -Value zc_sample_joinsplit(const json_spirit::Array& params, bool fHelp) +UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp) { if (fHelp) { throw runtime_error( @@ -2441,10 +2441,10 @@ Value zc_sample_joinsplit(const json_spirit::Array& params, bool fHelp) return HexStr(ss.begin(), ss.end()); } -Value zc_benchmark(const json_spirit::Array& params, bool fHelp) +UniValue zc_benchmark(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) { - return Value::null; + return NullUniValue; } if (fHelp || params.size() < 2) { @@ -2532,9 +2532,9 @@ Value zc_benchmark(const json_spirit::Array& params, bool fHelp) } } - Array results; + UniValue results(UniValue::VARR); for (auto time : sample_times) { - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("runningtime", time)); results.push_back(result); } @@ -2542,10 +2542,10 @@ Value zc_benchmark(const json_spirit::Array& params, bool fHelp) return results; } -Value zc_raw_receive(const json_spirit::Array& params, bool fHelp) +UniValue zc_raw_receive(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) { - return Value::null; + return NullUniValue; } if (fHelp || params.size() != 2) { @@ -2563,7 +2563,7 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp) ); } - RPCTypeCheck(params, boost::assign::list_of(str_type)(str_type)); + RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR)(UniValue::VSTR)); LOCK(cs_main); @@ -2614,7 +2614,7 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp) CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); ss << npt; - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("amount", ValueFromAmount(decrypted_note.value))); result.push_back(Pair("note", HexStr(ss.begin(), ss.end()))); result.push_back(Pair("exists", (bool) witnesses[0])); @@ -2623,10 +2623,10 @@ Value zc_raw_receive(const json_spirit::Array& params, bool fHelp) -Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp) +UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) { - return Value::null; + return NullUniValue; } if (fHelp || params.size() != 5) { @@ -2659,8 +2659,8 @@ Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp) if (!DecodeHexTx(tx, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); - Object inputs = params[1].get_obj(); - Object outputs = params[2].get_obj(); + UniValue inputs = params[1].get_obj(); + UniValue outputs = params[2].get_obj(); CAmount vpub_old(0); CAmount vpub_new(0); @@ -2677,9 +2677,8 @@ Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp) std::vector keys; std::vector commitments; - BOOST_FOREACH(const Pair& s, inputs) - { - CZCSpendingKey spendingkey(s.value_.get_str()); + for (const string& name_ : inputs.getKeys()) { + CZCSpendingKey spendingkey(inputs[name_].get_str()); SpendingKey k = spendingkey.Get(); keys.push_back(k); @@ -2687,7 +2686,7 @@ Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp) NotePlaintext npt; { - CDataStream ssData(ParseHexV(s.name_, "note"), SER_NETWORK, PROTOCOL_VERSION); + CDataStream ssData(ParseHexV(name_, "note"), SER_NETWORK, PROTOCOL_VERSION); ssData >> npt; } @@ -2720,11 +2719,10 @@ Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp) vjsin.push_back(JSInput()); } - BOOST_FOREACH(const Pair& s, outputs) - { - CZCPaymentAddress pubaddr(s.name_); + for (const string& name_ : outputs.getKeys()) { + CZCPaymentAddress pubaddr(name_); PaymentAddress addrTo = pubaddr.Get(); - CAmount nAmount = AmountFromValue(s.value_); + CAmount nAmount = AmountFromValue(outputs[name_]); vjsout.push_back(JSOutput(addrTo, nAmount)); } @@ -2804,17 +2802,17 @@ Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp) encryptedNote2 = HexStr(ss2.begin(), ss2.end()); } - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("encryptednote1", encryptedNote1)); result.push_back(Pair("encryptednote2", encryptedNote2)); result.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end()))); return result; } -Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp) +UniValue zc_raw_keygen(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) { - return Value::null; + return NullUniValue; } if (fHelp || params.size() != 0) { @@ -2842,7 +2840,7 @@ Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp) CZCSpendingKey spendingkey(k); std::string viewing_hex = HexStr(viewing.begin(), viewing.end()); - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("zcaddress", pubaddr.ToString())); result.push_back(Pair("zcsecretkey", spendingkey.ToString())); result.push_back(Pair("zcviewingkey", viewing_hex)); @@ -2850,10 +2848,10 @@ Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp) } -Value z_getnewaddress(const Array& params, bool fHelp) +UniValue z_getnewaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 0) throw runtime_error( @@ -2877,10 +2875,10 @@ Value z_getnewaddress(const Array& params, bool fHelp) } -Value z_listaddresses(const Array& params, bool fHelp) +UniValue z_listaddresses(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -2899,7 +2897,7 @@ Value z_listaddresses(const Array& params, bool fHelp) LOCK2(cs_main, pwalletMain->cs_wallet); - Array ret; + UniValue ret(UniValue::VARR); std::set addresses; pwalletMain->GetPaymentAddresses(addresses); for (auto addr : addresses ) { @@ -2959,10 +2957,10 @@ CAmount getBalanceZaddr(std::string address, int minDepth = 1) { } -Value z_listreceivedbyaddress(const Array& params, bool fHelp) +UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size()==0 || params.size() >2) throw runtime_error( @@ -3005,11 +3003,11 @@ Value z_listreceivedbyaddress(const Array& params, bool fHelp) } - Array result; + UniValue result(UniValue::VARR); std::vector entries; pwalletMain->GetFilteredNotes(entries, fromaddress, nMinDepth, false); for (CNotePlaintextEntry & entry : entries) { - Object obj; + UniValue obj(UniValue::VOBJ); obj.push_back(Pair("txid",entry.jsop.hash.ToString())); obj.push_back(Pair("amount", ValueFromAmount(CAmount(entry.plaintext.value)))); std::string data(entry.plaintext.memo.begin(), entry.plaintext.memo.end()); @@ -3020,10 +3018,10 @@ Value z_listreceivedbyaddress(const Array& params, bool fHelp) } -Value z_getbalance(const Array& params, bool fHelp) +UniValue z_getbalance(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size()==0 || params.size() >2) throw runtime_error( @@ -3082,10 +3080,10 @@ Value z_getbalance(const Array& params, bool fHelp) } -Value z_gettotalbalance(const Array& params, bool fHelp) +UniValue z_gettotalbalance(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -3125,17 +3123,17 @@ Value z_gettotalbalance(const Array& params, bool fHelp) CAmount nBalance = getBalanceTaddr("", nMinDepth); CAmount nPrivateBalance = getBalanceZaddr("", nMinDepth); CAmount nTotalBalance = nBalance + nPrivateBalance; - Object result; + UniValue result(UniValue::VOBJ); result.push_back(Pair("transparent", FormatMoney(nBalance, false))); result.push_back(Pair("private", FormatMoney(nPrivateBalance, false))); result.push_back(Pair("total", FormatMoney(nTotalBalance, false))); return result; } -Value z_getoperationresult(const Array& params, bool fHelp) +UniValue z_getoperationresult(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -3152,10 +3150,10 @@ Value z_getoperationresult(const Array& params, bool fHelp) return z_getoperationstatus_IMPL(params, true); } -Value z_getoperationstatus(const Array& params, bool fHelp) +UniValue z_getoperationstatus(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -3172,20 +3170,20 @@ Value z_getoperationstatus(const Array& params, bool fHelp) return z_getoperationstatus_IMPL(params, false); } -Value z_getoperationstatus_IMPL(const Array& params, bool fRemoveFinishedOperations=false) +UniValue z_getoperationstatus_IMPL(const UniValue& params, bool fRemoveFinishedOperations=false) { LOCK2(cs_main, pwalletMain->cs_wallet); std::set filter; if (params.size()==1) { - Array ids = params[0].get_array(); - for (Value & v : ids) { + UniValue ids = params[0].get_array(); + for (UniValue & v : ids.getValues()) { filter.insert(v.get_str()); } } bool useFilter = (filter.size()>0); - Array ret; + UniValue ret(UniValue::VARR); std::shared_ptr q = getAsyncRPCQueue(); std::vector ids = q->getAllOperationIds(); @@ -3200,7 +3198,7 @@ Value z_getoperationstatus_IMPL(const Array& params, bool fRemoveFinishedOperati // throw JSONRPCError(RPC_INVALID_PARAMETER, "No operation exists for that id."); } - Value status = operation->getStatus(); + UniValue status = operation->getStatus(); if (fRemoveFinishedOperations) { // Caller is only interested in retrieving finished results @@ -3213,13 +3211,19 @@ Value z_getoperationstatus_IMPL(const Array& params, bool fRemoveFinishedOperati } } + std::vector arrTmp = ret.getValues(); + // sort results chronologically by creation_time - std::sort(ret.begin(), ret.end(), [](Value a, Value b) -> bool { + std::sort(arrTmp.begin(), arrTmp.end(), [](UniValue a, UniValue b) -> bool { const int64_t t1 = find_value(a.get_obj(), "creation_time").get_int64(); const int64_t t2 = find_value(b.get_obj(), "creation_time").get_int64(); return t1 < t2; }); + ret.clear(); + ret.setArray(); + ret.push_backV(arrTmp); + return ret; } @@ -3234,10 +3238,10 @@ Value z_getoperationstatus_IMPL(const Array& params, bool fRemoveFinishedOperati #define CTXIN_SPEND_DUST_SIZE 148 #define CTXOUT_REGULAR_SIZE 34 -Value z_sendmany(const Array& params, bool fHelp) +UniValue z_sendmany(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() < 2 || params.size() > 4) throw runtime_error( @@ -3287,7 +3291,7 @@ Value z_sendmany(const Array& params, bool fHelp) } } - Array outputs = params[1].get_array(); + UniValue outputs = params[1].get_array(); if (outputs.size()==0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, amounts array is empty."); @@ -3300,15 +3304,13 @@ Value z_sendmany(const Array& params, bool fHelp) std::vector zaddrRecipients; CAmount nTotalOut = 0; - BOOST_FOREACH(Value& output, outputs) - { - if (output.type() != obj_type) + for (const UniValue& o : outputs.getValues()) { + if (!o.isObject()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); - const Object& o = output.get_obj(); // sanity check, report error if unknown key-value pairs - for (const Pair& p : o) { - std::string s = p.name_; + for (const string& name_ : o.getKeys()) { + std::string s = name_; if (s != "address" && s != "amount" && s!="memo") throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown key: ")+s); } @@ -3330,9 +3332,9 @@ Value z_sendmany(const Array& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+address); setAddress.insert(address); - Value memoValue = find_value(o, "memo"); + UniValue memoValue = find_value(o, "memo"); string memo; - if (!memoValue.is_null()) { + if (!memoValue.isNull()) { memo = memoValue.get_str(); if (!isZaddr) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo can not be used with a taddr. It can only be used with a zaddr."); @@ -3344,7 +3346,7 @@ Value z_sendmany(const Array& params, bool fHelp) } } - Value av = find_value(o, "amount"); + UniValue av = find_value(o, "amount"); CAmount nAmount = AmountFromValue( av ); if (nAmount < 0) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, amount must be positive"); @@ -3407,12 +3409,12 @@ Value z_sendmany(const Array& params, bool fHelp) } // Use input parameters as the optional context info to be returned by z_getoperationstatus and z_getoperationresult. - Object o; + UniValue o(UniValue::VOBJ); o.push_back(Pair("fromaddress", params[0])); o.push_back(Pair("amounts", params[1])); o.push_back(Pair("minconf", nMinDepth)); o.push_back(Pair("fee", std::stod(FormatMoney(nFee)))); - Value contextInfo = Value(o); + UniValue contextInfo = o; // Create operation and add to global queue std::shared_ptr q = getAsyncRPCQueue(); @@ -3423,10 +3425,10 @@ Value z_sendmany(const Array& params, bool fHelp) } -Value z_listoperationids(const Array& params, bool fHelp) +UniValue z_listoperationids(const UniValue& params, bool fHelp) { if (!EnsureWalletIsAvailable(fHelp)) - return Value::null; + return NullUniValue; if (fHelp || params.size() > 1) throw runtime_error( @@ -3453,7 +3455,7 @@ Value z_listoperationids(const Array& params, bool fHelp) useFilter = true; } - Array ret; + UniValue ret(UniValue::VARR); std::shared_ptr q = getAsyncRPCQueue(); std::vector ids = q->getAllOperationIds(); for (auto id : ids) { From 5fb326d41d1994b6583959658347a91facb6cae0 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sat, 7 Jan 2017 10:11:31 +0100 Subject: [PATCH 22/26] Manually iterate over UniValue arrays in tests --- src/gtest/json_test_vectors.h | 4 ++-- src/gtest/test_merkletree.cpp | 20 ++++++++------------ src/gtest/test_proofs.cpp | 6 ++---- 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/src/gtest/json_test_vectors.h b/src/gtest/json_test_vectors.h index 623dab5e1..27c8757ec 100644 --- a/src/gtest/json_test_vectors.h +++ b/src/gtest/json_test_vectors.h @@ -31,7 +31,7 @@ void expect_deser_same(const T& expected) } template -void expect_test_vector(T& it, const U& expected) +void expect_test_vector(T& v, const U& expected) { expect_deser_same(expected); @@ -42,7 +42,7 @@ void expect_test_vector(T& it, const U& expected) std::cout << "\t\"" ; std::cout << HexStr(ss1.begin(), ss1.end()) << "\",\n"; #else - std::string raw = (it++)->get_str(); + std::string raw = v.get_str(); CDataStream ss2(ParseHex(raw), SER_NETWORK, PROTOCOL_VERSION); ASSERT_TRUE(ss1.size() == ss2.size()); diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index bd60d37c4..a8960d762 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -64,11 +64,8 @@ void test_tree( UniValue path_tests ) { - vector::iterator commitment_iterator = commitment_tests.getValues().begin(); - vector::iterator root_iterator = root_tests.getValues().begin(); - vector::iterator ser_iterator = ser_tests.getValues().begin(); - vector::iterator witness_ser_iterator = witness_ser_tests.getValues().begin(); - vector::iterator path_iterator = path_tests.getValues().begin(); + size_t witness_ser_i = 0; + size_t path_i = 0; Tree tree; @@ -88,7 +85,7 @@ void test_tree( vector witnesses; for (size_t i = 0; i < 16; i++) { - uint256 test_commitment = uint256S((commitment_iterator++)->get_str()); + uint256 test_commitment = uint256S(commitment_tests[i].get_str()); // Witness here witnesses.push_back(tree.witness()); @@ -103,10 +100,10 @@ void test_tree( ASSERT_TRUE(tree.last() == test_commitment); // Check tree root consistency - expect_test_vector(root_iterator, tree.root()); + expect_test_vector(root_tests[i], tree.root()); // Check serialization of tree - expect_ser_test_vector(ser_iterator, tree, tree); + expect_ser_test_vector(ser_tests[i], tree, tree); bool first = true; // The first witness can never form a path BOOST_FOREACH(Witness& wit, witnesses) @@ -121,7 +118,7 @@ void test_tree( auto path = wit.path(); { - expect_test_vector(path_iterator, path); + expect_test_vector(path_tests[path_i++], path); typedef Fr FieldT; @@ -173,7 +170,7 @@ void test_tree( } // Check witness serialization - expect_ser_test_vector(witness_ser_iterator, wit, tree); + expect_ser_test_vector(witness_ser_tests[witness_ser_i++], wit, tree); ASSERT_TRUE(wit.root() == tree.root()); @@ -204,12 +201,11 @@ TEST(merkletree, vectors) { TEST(merkletree, emptyroots) { UniValue empty_roots = read_json(std::string(json_tests::merkle_roots_empty, json_tests::merkle_roots_empty + sizeof(json_tests::merkle_roots_empty))); - vector::iterator root_iterator = empty_roots.getValues().begin(); libzcash::EmptyMerkleRoots<64, libzcash::SHA256Compress> emptyroots; for (size_t depth = 0; depth <= 64; depth++) { - expect_test_vector(root_iterator, emptyroots.empty_root(depth)); + expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth)); } // Double check that we're testing (at least) all the empty roots we'll use. diff --git a/src/gtest/test_proofs.cpp b/src/gtest/test_proofs.cpp index 69ffdbe54..49202f1f6 100644 --- a/src/gtest/test_proofs.cpp +++ b/src/gtest/test_proofs.cpp @@ -630,14 +630,13 @@ TEST(proofs, g2_deserialization) TEST(proofs, g1_test_vectors) { UniValue v = read_json(std::string(json_tests::g1_compressed, json_tests::g1_compressed + sizeof(json_tests::g1_compressed))); - std::vector::iterator v_iterator = v.getValues().begin(); curve_G1 e = curve_Fr("34958239045823") * curve_G1::one(); for (size_t i = 0; i < 10000; i++) { e = (curve_Fr("34958239045823") ^ i) * e; auto expected = CompressedG1(e); - expect_test_vector(v_iterator, expected); + expect_test_vector(v[i], expected); ASSERT_TRUE(expected.to_libsnark_g1() == e); } } @@ -647,14 +646,13 @@ TEST(proofs, g1_test_vectors) TEST(proofs, g2_test_vectors) { UniValue v = read_json(std::string(json_tests::g2_compressed, json_tests::g2_compressed + sizeof(json_tests::g2_compressed))); - std::vector::iterator v_iterator = v.getValues().begin(); curve_G2 e = curve_Fr("34958239045823") * curve_G2::one(); for (size_t i = 0; i < 10000; i++) { e = (curve_Fr("34958239045823") ^ i) * e; auto expected = CompressedG2(e); - expect_test_vector(v_iterator, expected); + expect_test_vector(v[i], expected); ASSERT_TRUE(expected.to_libsnark_g2() == e); } } From 0821ddb0dec8296f6c89ac95983f3b242e452fea Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Mon, 6 Feb 2017 14:39:14 +0000 Subject: [PATCH 23/26] Remove JSON Spirit from contrib/debian/copyright --- contrib/debian/copyright | 4 ---- 1 file changed, 4 deletions(-) diff --git a/contrib/debian/copyright b/contrib/debian/copyright index fc94e2399..67cb3d67f 100644 --- a/contrib/debian/copyright +++ b/contrib/debian/copyright @@ -11,10 +11,6 @@ Comment: The Bitcoin Core developers encompasses the current developers listed o as well as the numerous contributors to the project. The Zcash developers are listed at https://z.cash/team.html. -Files: src/json/* -Copyright: 2007-2009, John W. Wilkinson -License: Expat - Files: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png, src/qt/res/src/*.svg Copyright: Wladimir van der Laan From cc71666a51ceb2d4a59ceb9f7002044a158ce71b Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Tue, 7 Feb 2017 00:43:10 +0000 Subject: [PATCH 24/26] unsigned int -> size_t for comparing with UniValue.size() --- src/bitcoin-tx.cpp | 4 ++-- src/rpcrawtransaction.cpp | 8 ++++---- src/rpcserver.cpp | 4 ++-- src/test/base58_tests.cpp | 10 +++++----- src/test/script_tests.cpp | 8 ++++---- src/test/sighash_tests.cpp | 2 +- src/test/transaction_tests.cpp | 8 ++++---- src/wallet/rpcwallet.cpp | 6 +++--- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 4fed20865..b36a01b73 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -347,7 +347,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) UniValue keysObj = registers["privatekeys"]; fGivenKeys = true; - for (unsigned int kidx = 0; kidx < keysObj.size(); kidx++) { + for (size_t kidx = 0; kidx < keysObj.size(); kidx++) { if (!keysObj[kidx].isStr()) throw runtime_error("privatekey not a string"); CBitcoinSecret vchSecret; @@ -364,7 +364,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr) throw runtime_error("prevtxs register variable must be set."); UniValue prevtxsObj = registers["prevtxs"]; { - for (unsigned int previdx = 0; previdx < prevtxsObj.size(); previdx++) { + for (size_t previdx = 0; previdx < prevtxsObj.size(); previdx++) { UniValue prevOut = prevtxsObj[previdx]; if (!prevOut.isObject()) throw runtime_error("expected prevtxs internal object"); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 597da3763..a23c1d8ee 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -306,7 +306,7 @@ UniValue gettxoutproof(const UniValue& params, bool fHelp) set setTxids; uint256 oneTxid; UniValue txids = params[0].get_array(); - for (unsigned int idx = 0; idx < txids.size(); idx++) { + for (size_t idx = 0; idx < txids.size(); idx++) { const UniValue& txid = txids[idx]; if (txid.get_str().length() != 64 || !IsHex(txid.get_str())) throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str()); @@ -436,7 +436,7 @@ UniValue createrawtransaction(const UniValue& params, bool fHelp) CMutableTransaction rawTx; - for (unsigned int idx = 0; idx < inputs.size(); idx++) { + for (size_t idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; const UniValue& o = input.get_obj(); @@ -731,7 +731,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) if (params.size() > 2 && !params[2].isNull()) { fGivenKeys = true; UniValue keys = params[2].get_array(); - for (unsigned int idx = 0; idx < keys.size(); idx++) { + for (size_t idx = 0; idx < keys.size(); idx++) { UniValue k = keys[idx]; CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(k.get_str()); @@ -751,7 +751,7 @@ UniValue signrawtransaction(const UniValue& params, bool fHelp) // Add previous txouts given in the RPC call: if (params.size() > 1 && !params[1].isNull()) { UniValue prevTxs = params[1].get_array(); - for (unsigned int idx = 0; idx < prevTxs.size(); idx++) { + for (size_t idx = 0; idx < prevTxs.size(); idx++) { const UniValue& p = prevTxs[idx]; if (!p.isObject()) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}"); diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index d5b66471d..6fe41193e 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -85,7 +85,7 @@ void RPCTypeCheck(const UniValue& params, const list& typesExpected, bool fAllowNull) { - unsigned int i = 0; + size_t i = 0; BOOST_FOREACH(UniValue::VType t, typesExpected) { if (params.size() <= i) @@ -928,7 +928,7 @@ static UniValue JSONRPCExecOne(const UniValue& req) static string JSONRPCExecBatch(const UniValue& vReq) { UniValue ret(UniValue::VARR); - for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++) + for (size_t reqIdx = 0; reqIdx < vReq.size(); reqIdx++) ret.push_back(JSONRPCExecOne(vReq[reqIdx])); return ret.write() + "\n"; diff --git a/src/test/base58_tests.cpp b/src/test/base58_tests.cpp index 9e74f5f42..bd754cafe 100644 --- a/src/test/base58_tests.cpp +++ b/src/test/base58_tests.cpp @@ -28,7 +28,7 @@ BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(base58_EncodeBase58) { UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) @@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58) UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode))); std::vector result; - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 2) // Allow for extra stuff (useful for comments) @@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse) CBitcoinAddress addr; SelectParams(CBaseChainParams::MAIN); - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) @@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen) UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid))); std::vector result; - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 3) // Allow for extra stuff (useful for comments) @@ -251,7 +251,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_invalid) CBitcoinSecret secret; CBitcoinAddress addr; - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 02cd878d8..dfb4c2f65 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -583,11 +583,11 @@ BOOST_AUTO_TEST_CASE(script_build) UniValue json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); UniValue json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - for (unsigned int idx = 0; idx < json_good.size(); idx++) { + for (size_t idx = 0; idx < json_good.size(); idx++) { const UniValue& tv = json_good[idx]; tests_good.insert(tv.get_array().write()); } - for (unsigned int idx = 0; idx < json_bad.size(); idx++) { + for (size_t idx = 0; idx < json_bad.size(); idx++) { const UniValue& tv = json_bad[idx]; tests_bad.insert(tv.get_array().write()); } @@ -636,7 +636,7 @@ BOOST_AUTO_TEST_CASE(script_valid) // scripts. UniValue tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid))); - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments) @@ -661,7 +661,7 @@ BOOST_AUTO_TEST_CASE(script_invalid) // Scripts that should evaluate as invalid UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid))); - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); if (test.size() < 3) // Allow size > 2; extra stuff ignored (useful for comments) diff --git a/src/test/sighash_tests.cpp b/src/test/sighash_tests.cpp index 9b3a82557..ce554ee3e 100644 --- a/src/test/sighash_tests.cpp +++ b/src/test/sighash_tests.cpp @@ -205,7 +205,7 @@ BOOST_AUTO_TEST_CASE(sighash_from_data) { UniValue tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash))); - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; std::string strTest = test.write(); if (test.size() < 1) // Allow for extra stuff (useful for comments) diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index 514982980..d2e9a3388 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -101,7 +101,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) auto verifier = libzcash::ProofVerifier::Strict(); ScriptError err; - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) @@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(tx_valid) map mapprevOutScriptPubKeys; UniValue inputs = test[0].get_array(); bool fValid = true; - for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { + for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { const UniValue& input = inputs[inpIdx]; if (!input.isArray()) { @@ -177,7 +177,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) auto verifier = libzcash::ProofVerifier::Strict(); ScriptError err; - for (unsigned int idx = 0; idx < tests.size(); idx++) { + for (size_t idx = 0; idx < tests.size(); idx++) { UniValue test = tests[idx]; string strTest = test.write(); if (test[0].isArray()) @@ -191,7 +191,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid) map mapprevOutScriptPubKeys; UniValue inputs = test[0].get_array(); bool fValid = true; - for (unsigned int inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { + for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) { const UniValue& input = inputs[inpIdx]; if (!input.isArray()) { diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 90b6d04fa..5e1efe2db 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -1005,7 +1005,7 @@ UniValue sendmany(const UniValue& params, bool fHelp) totalAmount += nAmount; bool fSubtractFeeFromAmount = false; - for (unsigned int idx = 0; idx < subtractFeeFromAmount.size(); idx++) { + for (size_t idx = 0; idx < subtractFeeFromAmount.size(); idx++) { const UniValue& addr = subtractFeeFromAmount[idx]; if (addr.get_str() == name_) fSubtractFeeFromAmount = true; @@ -2130,7 +2130,7 @@ UniValue lockunspent(const UniValue& params, bool fHelp) } UniValue outputs = params[1].get_array(); - for (unsigned int idx = 0; idx < outputs.size(); idx++) { + for (size_t idx = 0; idx < outputs.size(); idx++) { const UniValue& output = outputs[idx]; if (!output.isObject()) throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected object"); @@ -2354,7 +2354,7 @@ UniValue listunspent(const UniValue& params, bool fHelp) set setAddress; if (params.size() > 2) { UniValue inputs = params[2].get_array(); - for (unsigned int idx = 0; idx < inputs.size(); idx++) { + for (size_t idx = 0; idx < inputs.size(); idx++) { const UniValue& input = inputs[idx]; CBitcoinAddress address(input.get_str()); if (!address.IsValid()) From 873c40365ab38ed9c8d2d234361226739f383020 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 9 Feb 2017 17:54:16 +0000 Subject: [PATCH 25/26] [cleanup] Remove unused import --- src/rpcclient.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 1f780bcb0..f0c6611ae 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -11,7 +11,6 @@ #include #include -#include // for to_lower() #include "univalue/univalue.h" using namespace std; From 02972a1bcd97c94f11ce172f87d2337cc2e96715 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 9 Feb 2017 21:10:08 +0000 Subject: [PATCH 26/26] [cleanup] Simplify test code --- src/gtest/test_merkletree.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/gtest/test_merkletree.cpp b/src/gtest/test_merkletree.cpp index a8960d762..6bac9ab3c 100644 --- a/src/gtest/test_merkletree.cpp +++ b/src/gtest/test_merkletree.cpp @@ -189,18 +189,20 @@ void test_tree( } } +#define MAKE_STRING(x) std::string((x), (x)+sizeof(x)) + TEST(merkletree, vectors) { - UniValue root_tests = read_json(std::string(json_tests::merkle_roots, json_tests::merkle_roots + sizeof(json_tests::merkle_roots))); - UniValue ser_tests = read_json(std::string(json_tests::merkle_serialization, json_tests::merkle_serialization + sizeof(json_tests::merkle_serialization))); - UniValue witness_ser_tests = read_json(std::string(json_tests::merkle_witness_serialization, json_tests::merkle_witness_serialization + sizeof(json_tests::merkle_witness_serialization))); - UniValue path_tests = read_json(std::string(json_tests::merkle_path, json_tests::merkle_path + sizeof(json_tests::merkle_path))); - UniValue commitment_tests = read_json(std::string(json_tests::merkle_commitments, json_tests::merkle_commitments + sizeof(json_tests::merkle_commitments))); + UniValue root_tests = read_json(MAKE_STRING(json_tests::merkle_roots)); + UniValue ser_tests = read_json(MAKE_STRING(json_tests::merkle_serialization)); + UniValue witness_ser_tests = read_json(MAKE_STRING(json_tests::merkle_witness_serialization)); + UniValue path_tests = read_json(MAKE_STRING(json_tests::merkle_path)); + UniValue commitment_tests = read_json(MAKE_STRING(json_tests::merkle_commitments)); test_tree(commitment_tests, root_tests, ser_tests, witness_ser_tests, path_tests); } TEST(merkletree, emptyroots) { - UniValue empty_roots = read_json(std::string(json_tests::merkle_roots_empty, json_tests::merkle_roots_empty + sizeof(json_tests::merkle_roots_empty))); + UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty)); libzcash::EmptyMerkleRoots<64, libzcash::SHA256Compress> emptyroots;