aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile.am1
-rw-r--r--src/bitcoin-cli.cpp20
-rw-r--r--src/json_spirit_wrapper.h17
-rw-r--r--src/qt/rpcconsole.cpp18
-rw-r--r--src/rpcblockchain.cpp16
-rw-r--r--src/rpcclient.cpp2
-rw-r--r--src/rpcclient.h4
-rw-r--r--src/rpcmining.cpp19
-rw-r--r--src/rpcmisc.cpp5
-rw-r--r--src/rpcnet.cpp8
-rw-r--r--src/rpcprotocol.cpp10
-rw-r--r--src/rpcprotocol.h4
-rw-r--r--src/rpcrawtransaction.cpp47
-rw-r--r--src/rpcserver.cpp51
-rw-r--r--src/rpcserver.h18
-rw-r--r--src/test/base58_tests.cpp40
-rw-r--r--src/test/rpc_tests.cpp18
-rw-r--r--src/test/script_tests.cpp22
-rw-r--r--src/test/sighash_tests.cpp11
-rw-r--r--src/test/transaction_tests.cpp33
-rw-r--r--src/univalue/univalue.h84
-rw-r--r--src/wallet/rpcdump.cpp14
-rw-r--r--src/wallet/rpcwallet.cpp64
23 files changed, 321 insertions, 205 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 1c2f770418..63332f9acd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -342,6 +342,7 @@ endif
bitcoin_cli_LDADD = \
$(LIBBITCOIN_CLI) \
+ $(LIBBITCOIN_UNIVALUE) \
$(LIBBITCOIN_UTIL) \
$(LIBSECP256K1)
diff --git a/src/bitcoin-cli.cpp b/src/bitcoin-cli.cpp
index 1269d7a119..9950153a65 100644
--- a/src/bitcoin-cli.cpp
+++ b/src/bitcoin-cli.cpp
@@ -143,7 +143,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())
@@ -176,29 +176,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 0000000000..1962cf6431
--- /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 29c971ec79..29b1e8f262 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 <openssl/crypto.h>
+#include "univalue/univalue.h"
+
#ifdef ENABLE_WALLET
#include <db_cxx.h>
#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<std::string>(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);
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
- emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false)));
+ 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 79528db2fe..2f9fd5e045 100644
--- a/src/rpcblockchain.cpp
+++ b/src/rpcblockchain.cpp
@@ -13,7 +13,7 @@
#include <stdint.h>
-#include "json/json_spirit_value.h"
+#include "json_spirit_wrapper.h"
using namespace json_spirit;
using namespace std;
@@ -206,7 +206,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));
}
@@ -412,14 +418,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 4b576b3707..d8c4da4207 100644
--- a/src/rpcclient.cpp
+++ b/src/rpcclient.cpp
@@ -135,7 +135,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
// parse string as JSON, insert bool/number/object/etc. value
else {
Value jVal;
- if (!read_string(strVal, jVal))
+ if (!jVal.read(strVal))
throw runtime_error(string("Error parsing JSON:")+strVal);
params.push_back(jVal);
}
diff --git a/src/rpcclient.h b/src/rpcclient.h
index 42fa2d06fe..29c1260272 100644
--- a/src/rpcclient.h
+++ b/src/rpcclient.h
@@ -6,9 +6,7 @@
#ifndef BITCOIN_RPCCLIENT_H
#define BITCOIN_RPCCLIENT_H
-#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"
json_spirit::Array RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams);
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 528d5406f4..4571269c3f 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -24,8 +24,7 @@
#include <boost/assign/list_of.hpp>
-#include "json/json_spirit_utils.h"
-#include "json/json_spirit_value.h"
+#include "json_spirit_wrapper.h"
using namespace json_spirit;
using namespace std;
@@ -216,7 +215,7 @@ Value setgenerate(const Array& params, bool fHelp)
mapArgs ["-genproclimit"] = itostr(nGenProcLimit);
GenerateBitcoins(fGenerate, pwalletMain, nGenProcLimit);
- return Value::null;
+ return NullUniValue;
}
#endif
@@ -382,14 +381,14 @@ Value getblocktemplate(const Array& params, bool fHelp)
LOCK(cs_main);
std::string strMode = "template";
- Value lpval = Value::null;
+ Value lpval = NullUniValue;
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 */
}
@@ -439,14 +438,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: <hashBestChain><nTransactionsUpdatedLast>
std::string lpstr = lpval.get_str();
@@ -686,7 +685,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)
@@ -718,7 +717,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 f5bef2a077..f7bd3e0d5a 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -20,8 +20,7 @@
#include <stdint.h>
#include <boost/assign/list_of.hpp>
-#include "json/json_spirit_utils.h"
-#include "json/json_spirit_value.h"
+#include "json_spirit_wrapper.h"
using namespace json_spirit;
using namespace std;
@@ -204,7 +203,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 bdee5b9f2e..3f46be0ccb 100644
--- a/src/rpcnet.cpp
+++ b/src/rpcnet.cpp
@@ -16,7 +16,7 @@
#include <boost/foreach.hpp>
-#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<CNodeStats>& 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 95d6b9e531..72a7b76343 100644
--- a/src/rpcprotocol.cpp
+++ b/src/rpcprotocol.cpp
@@ -23,7 +23,7 @@
#include <boost/iostreams/concepts.hpp>
#include <boost/iostreams/stream.hpp>
#include <boost/shared_ptr.hpp>
-#include "json/json_spirit_writer_template.h"
+#include "json_spirit_wrapper.h"
using namespace std;
using namespace json_spirit;
@@ -260,14 +260,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));
@@ -278,7 +278,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 4f3f70fb37..496e19ed53 100644
--- a/src/rpcprotocol.h
+++ b/src/rpcprotocol.h
@@ -15,9 +15,7 @@
#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>
-#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 3e37b797e8..8d2b035f31 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -25,8 +25,7 @@
#include <stdint.h>
#include <boost/assign/list_of.hpp>
-#include "json/json_spirit_utils.h"
-#include "json/json_spirit_value.h"
+#include "json_spirit_wrapper.h"
using namespace json_spirit;
using namespace std;
@@ -343,20 +342,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)
@@ -367,17 +367,18 @@ Value createrawtransaction(const Array& params, bool fHelp)
}
set<CBitcoinAddress> setAddress;
- BOOST_FOREACH(const Pair& s, sendTo) {
- CBitcoinAddress address(s.name_);
+ vector<string> 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);
@@ -438,7 +439,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;
@@ -570,7 +571,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<unsigned char> txData(ParseHexV(params[0], "argument 1"));
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
@@ -613,10 +614,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)
@@ -633,15 +635,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");
@@ -669,9 +672,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<unsigned char> rsData(ParseHexV(v, "redeemScript"));
CScript redeemScript(rsData.begin(), rsData.end());
tempKeystore.AddCScript(redeemScript);
@@ -687,7 +690,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<string, int> mapSigHashValues =
boost::assign::map_list_of
(string("ALL"), int(SIGHASH_ALL))
@@ -769,7 +772,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 3f74517a67..da0a8048b2 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -27,7 +27,8 @@
#include <boost/shared_ptr.hpp>
#include <boost/signals2/signal.hpp>
#include <boost/thread.hpp>
-#include "json/json_spirit_writer_template.h"
+
+#include "json_spirit_wrapper.h"
using namespace boost::asio;
using namespace json_spirit;
@@ -89,30 +90,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<string, Value_type>& typesExpected,
+void RPCTypeCheckObj(const UniValue& o,
+ const map<string, UniValue::VType>& 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);
}
}
@@ -142,7 +143,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+"')");
@@ -157,7 +158,7 @@ uint256 ParseHashO(const Object& o, string strKey)
vector<unsigned char> 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+"')");
@@ -417,7 +418,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;
}
@@ -828,14 +829,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();
@@ -844,9 +845,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")
@@ -854,9 +855,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");
@@ -872,15 +873,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);
}
@@ -893,7 +894,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,
@@ -925,7 +926,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
@@ -938,16 +939,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 30a5b28db7..c9982bb8ca 100644
--- a/src/rpcserver.h
+++ b/src/rpcserver.h
@@ -15,9 +15,8 @@
#include <stdint.h>
#include <string>
-#include "json/json_spirit_reader_template.h"
-#include "json/json_spirit_utils.h"
-#include "json/json_spirit_writer_template.h"
+#include <boost/function.hpp>
+#include "json_spirit_wrapper.h"
class CRPCCommand;
@@ -73,12 +72,13 @@ bool RPCIsInWarmup(std::string *statusOut);
*/
void RPCTypeCheck(const json_spirit::Array& params,
const std::list<json_spirit::Value_type>& 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<std::string, json_spirit::Value_type>& 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<std::string, UniValue::VType>& 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 f07dd7a7db..a806fe7b05 100644
--- a/src/test/base58_tests.cpp
+++ b/src/test/base58_tests.cpp
@@ -17,9 +17,7 @@
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-#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<unsigned char> 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<unsigned char> 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 5899671d2f..fea826b65a 100644
--- a/src/test/rpc_tests.cpp
+++ b/src/test/rpc_tests.cpp
@@ -111,20 +111,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 c0614cca43..b4cab3245c 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -26,9 +26,7 @@
#include <boost/foreach.hpp>
#include <boost/test/unit_test.hpp>
-#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 87be2217c4..121644ddc4 100644
--- a/src/test/sighash_tests.cpp
+++ b/src/test/sighash_tests.cpp
@@ -16,9 +16,7 @@
#include <iostream>
#include <boost/test/unit_test.hpp>
-#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);
@@ -170,10 +168,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 d12535e438..cdd88f348d 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -22,7 +22,8 @@
#include <boost/algorithm/string/split.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/assign/list_of.hpp>
-#include "json/json_spirit_writer_template.h"
+
+#include "json_spirit_wrapper.h"
using namespace std;
using namespace json_spirit;
@@ -90,14 +91,21 @@ BOOST_AUTO_TEST_CASE(tx_valid)
// 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)));
+<<<<<<< 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;
@@ -106,9 +114,9 @@ BOOST_AUTO_TEST_CASE(tx_valid)
map<COutPoint, CScript> 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;
@@ -166,14 +174,21 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
// 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)));
+<<<<<<< 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;
@@ -182,9 +197,9 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
map<COutPoint, CScript> 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 afe751ed9d..28d6e3d3cd 100644
--- a/src/univalue/univalue.h
+++ b/src/univalue/univalue.h
@@ -11,6 +11,10 @@
#include <map>
#include <cassert>
+#include <sstream> // .get_int64()
+#include <utility> // std::pair
+#include <stdlib.h> // 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<std::string> getKeys() const { return keys; }
+ std::vector<UniValue> 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<std::string,UniValue> 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<std::string,UniValue> Pair(const char *cKey, const char *cVal)
+{
+ std::string key(cKey);
+ UniValue uVal(cVal);
+ return std::make_pair(key, uVal);
+}
+
+static inline std::pair<std::string,UniValue> Pair(const char *cKey, std::string strVal)
+{
+ std::string key(cKey);
+ UniValue uVal(strVal);
+ return std::make_pair(key, uVal);
+}
+
+static inline std::pair<std::string,UniValue> Pair(const char *cKey, uint64_t u64Val)
+{
+ std::string key(cKey);
+ UniValue uVal(u64Val);
+ return std::make_pair(key, uVal);
+}
+
+static inline std::pair<std::string,UniValue> Pair(const char *cKey, int64_t i64Val)
+{
+ std::string key(cKey);
+ UniValue uVal(i64Val);
+ return std::make_pair(key, uVal);
+}
+
+static inline std::pair<std::string,UniValue> Pair(const char *cKey, int iVal)
+{
+ std::string key(cKey);
+ UniValue uVal(iVal);
+ return std::make_pair(key, uVal);
+}
+
+static inline std::pair<std::string,UniValue> Pair(const char *cKey, double dVal)
+{
+ std::string key(cKey);
+ UniValue uVal(dVal);
+ return std::make_pair(key, uVal);
+}
+
+static inline std::pair<std::string,UniValue> Pair(const char *cKey, const UniValue& uVal)
+{
+ std::string key(cKey);
+ return std::make_pair(key, uVal);
+}
+
+static inline std::pair<std::string,UniValue> 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 ab951d1d7d..68d2a21c47 100644
--- a/src/wallet/rpcdump.cpp
+++ b/src/wallet/rpcdump.cpp
@@ -19,7 +19,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>
-#include "json/json_spirit_value.h"
+#include "json_spirit_wrapper.h"
using namespace json_spirit;
using namespace std;
@@ -126,7 +126,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;
@@ -141,7 +141,7 @@ Value importprivkey(const Array& params, bool fHelp)
}
}
- return Value::null;
+ return NullUniValue;
}
Value importaddress(const Array& params, bool fHelp)
@@ -200,7 +200,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();
@@ -214,7 +214,7 @@ Value importaddress(const Array& params, bool fHelp)
}
}
- return Value::null;
+ return NullUniValue;
}
Value importwallet(const Array& params, bool fHelp)
@@ -318,7 +318,7 @@ Value importwallet(const Array& params, bool fHelp)
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)
@@ -421,5 +421,5 @@ Value dumpwallet(const Array& params, bool fHelp)
file << "\n";
file << "# End of dump\n";
file.close();
- return Value::null;
+ return NullUniValue;
}
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
index 3f55b04273..e743b1fa1d 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -21,8 +21,7 @@
#include <boost/assign/list_of.hpp>
-#include "json/json_spirit_utils.h"
-#include "json/json_spirit_value.h"
+#include "json_spirit_wrapper.h"
using namespace std;
using namespace json_spirit;
@@ -275,7 +274,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;
}
@@ -419,9 +418,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;
@@ -896,9 +895,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();
@@ -965,7 +964,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;
@@ -976,18 +975,19 @@ Value sendmany(const Array& params, bool fHelp)
vector<CRecipient> vecSend;
CAmount totalAmount = 0;
- BOOST_FOREACH(const Pair& s, sendTo)
+ vector<string> 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 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_]);
totalAmount += nAmount;
bool fSubtractFeeFromAmount = false;
@@ -1472,15 +1472,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<UniValue> arrTmp = ret.getValues();
+
+ vector<UniValue>::iterator first = arrTmp.begin();
std::advance(first, nFrom);
- Array::iterator last = ret.begin();
+ vector<UniValue>::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;
}
@@ -1756,7 +1762,7 @@ Value backupwallet(const Array& params, bool fHelp)
if (!BackupWallet(*pwalletMain, strDest))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: Wallet backup failed!");
- return Value::null;
+ return NullUniValue;
}
@@ -1793,7 +1799,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;
}
@@ -1860,7 +1866,7 @@ Value walletpassphrase(const Array& params, bool fHelp)
nWalletUnlockTime = GetTime() + nSleepTime;
RPCRunLater("lockwallet", boost::bind(LockWallet, pwalletMain), nSleepTime);
- return Value::null;
+ return NullUniValue;
}
@@ -1906,7 +1912,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;
}
@@ -1945,7 +1951,7 @@ Value walletlock(const Array& params, bool fHelp)
nWalletUnlockTime = 0;
}
- return Value::null;
+ return NullUniValue;
}
@@ -2050,9 +2056,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();
@@ -2063,13 +2069,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))