Convert tree to using univalue. Eliminate all json_spirit uses.
This commit is contained in:
parent
5e3060c0d1
commit
15982a8b69
23 changed files with 321 additions and 205 deletions
|
@ -342,6 +342,7 @@ endif
|
|||
|
||||
bitcoin_cli_LDADD = \
|
||||
$(LIBBITCOIN_CLI) \
|
||||
$(LIBBITCOIN_UNIVALUE) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(LIBSECP256K1)
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
17
src/json_spirit_wrapper.h
Normal file
17
src/json_spirit_wrapper.h
Normal file
|
@ -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__
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in a new issue