Auto merge of #1990 - str4d:1985-replace-json-spirit-with-univalue, r=str4d
Convert entire source tree from json_spirit to UniValue This PR cherry-picks bitcoin/bitcoin#6121 and then migrates the Zcash-specific code to UniValue. Also cherry-picks: - bitcoin/bitcoin#6241 - bitcoin/bitcoin#6234 Closes #1985.
This commit is contained in:
commit
e51bd1b556
|
@ -11,10 +11,6 @@ Comment: The Bitcoin Core developers encompasses the current developers listed o
|
|||
as well as the numerous contributors to the project.
|
||||
The Zcash developers are listed at https://z.cash/team.html.
|
||||
|
||||
Files: src/json/*
|
||||
Copyright: 2007-2009, John W. Wilkinson
|
||||
License: Expat
|
||||
|
||||
Files: src/qt/res/icons/clock*.png, src/qt/res/icons/tx*.png,
|
||||
src/qt/res/src/*.svg
|
||||
Copyright: Wladimir van der Laan
|
||||
|
|
|
@ -182,17 +182,6 @@ BITCOIN_CORE_H = \
|
|||
zmq/zmqpublishnotifier.h
|
||||
|
||||
|
||||
JSON_H = \
|
||||
json/json_spirit.h \
|
||||
json/json_spirit_error_position.h \
|
||||
json/json_spirit_reader.h \
|
||||
json/json_spirit_reader_template.h \
|
||||
json/json_spirit_stream_reader.h \
|
||||
json/json_spirit_utils.h \
|
||||
json/json_spirit_value.h \
|
||||
json/json_spirit_writer.h \
|
||||
json/json_spirit_writer_template.h
|
||||
|
||||
obj/build.h: FORCE
|
||||
@$(MKDIR_P) $(builddir)/obj
|
||||
@$(top_srcdir)/share/genbuild.sh $(abs_top_builddir)/src/obj/build.h \
|
||||
|
@ -233,7 +222,6 @@ libbitcoin_server_a_SOURCES = \
|
|||
txdb.cpp \
|
||||
txmempool.cpp \
|
||||
validationinterface.cpp \
|
||||
$(JSON_H) \
|
||||
$(BITCOIN_CORE_H) \
|
||||
$(LIBZCASH_H)
|
||||
|
||||
|
@ -423,6 +411,7 @@ endif
|
|||
|
||||
zcash_cli_LDADD = \
|
||||
$(LIBBITCOIN_CLI) \
|
||||
$(LIBBITCOIN_UNIVALUE) \
|
||||
$(LIBBITCOIN_UTIL) \
|
||||
$(BOOST_LIBS) \
|
||||
$(SSL_LIBS) \
|
||||
|
|
|
@ -18,7 +18,6 @@ zcash_gtest_SOURCES += \
|
|||
wallet/gtest/test_wallet_zkeys.cpp
|
||||
endif
|
||||
zcash_gtest_SOURCES += \
|
||||
gtest/test_jsonspirit.cpp \
|
||||
gtest/test_tautology.cpp \
|
||||
gtest/test_equihash.cpp \
|
||||
gtest/test_joinsplit.cpp \
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <chrono>
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
static boost::uuids::random_generator uuidgen;
|
||||
|
||||
|
@ -109,34 +108,34 @@ void AsyncRPCOperation::main() {
|
|||
*/
|
||||
|
||||
// Otherwise, if the operation was a success:
|
||||
Value v("We have a result!");
|
||||
UniValue v(UniValue::VSTR, "We have a result!");
|
||||
set_result(v);
|
||||
set_state(OperationStatus::SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the error of the completed operation as a Value object.
|
||||
* If there is no error, return null Value.
|
||||
* Return the error of the completed operation as a UniValue object.
|
||||
* If there is no error, return null UniValue.
|
||||
*/
|
||||
Value AsyncRPCOperation::getError() const {
|
||||
UniValue AsyncRPCOperation::getError() const {
|
||||
if (!isFailed()) {
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
Object error;
|
||||
UniValue error(UniValue::VOBJ);
|
||||
error.push_back(Pair("code", this->error_code_));
|
||||
error.push_back(Pair("message", this->error_message_));
|
||||
return Value(error);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the result of the completed operation as a Value object.
|
||||
* If the operation did not succeed, return null Value.
|
||||
* Return the result of the completed operation as a UniValue object.
|
||||
* If the operation did not succeed, return null UniValue.
|
||||
*/
|
||||
Value AsyncRPCOperation::getResult() const {
|
||||
UniValue AsyncRPCOperation::getResult() const {
|
||||
if (!isSuccess()) {
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
|
@ -145,24 +144,24 @@ Value AsyncRPCOperation::getResult() const {
|
|||
|
||||
|
||||
/**
|
||||
* Returns a status Value object.
|
||||
* Returns a status UniValue object.
|
||||
* If the operation has failed, it will include an error object.
|
||||
* If the operation has succeeded, it will include the result value.
|
||||
* If the operation was cancelled, there will be no error object or result value.
|
||||
*/
|
||||
Value AsyncRPCOperation::getStatus() const {
|
||||
UniValue AsyncRPCOperation::getStatus() const {
|
||||
OperationStatus status = this->getState();
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("id", this->id_));
|
||||
obj.push_back(Pair("status", OperationStatusMap[status]));
|
||||
obj.push_back(Pair("creation_time", this->creation_time_));
|
||||
// TODO: Issue #1354: There may be other useful metadata to return to the user.
|
||||
Value err = this->getError();
|
||||
if (!err.is_null()) {
|
||||
UniValue err = this->getError();
|
||||
if (!err.isNull()) {
|
||||
obj.push_back(Pair("error", err.get_obj()));
|
||||
}
|
||||
Value result = this->getResult();
|
||||
if (!result.is_null()) {
|
||||
UniValue result = this->getResult();
|
||||
if (!result.isNull()) {
|
||||
obj.push_back(Pair("result", result));
|
||||
|
||||
// Include execution time for successful operation
|
||||
|
@ -170,7 +169,7 @@ Value AsyncRPCOperation::getStatus() const {
|
|||
obj.push_back(Pair("execution_secs", elapsed_seconds.count()));
|
||||
|
||||
}
|
||||
return Value(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -15,13 +15,9 @@
|
|||
#include <utility>
|
||||
#include <future>
|
||||
|
||||
#include "json/json_spirit_value.h"
|
||||
#include "json/json_spirit_utils.h"
|
||||
#include "json/json_spirit_reader_template.h"
|
||||
#include "json/json_spirit_writer_template.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
/**
|
||||
* AsyncRPCOperation objects are submitted to the AsyncRPCQueue for processing.
|
||||
|
@ -67,11 +63,11 @@ public:
|
|||
}
|
||||
|
||||
// Override this method to add data to the default status object.
|
||||
virtual Value getStatus() const;
|
||||
virtual UniValue getStatus() const;
|
||||
|
||||
Value getError() const;
|
||||
UniValue getError() const;
|
||||
|
||||
Value getResult() const;
|
||||
UniValue getResult() const;
|
||||
|
||||
std::string getStateAsString() const;
|
||||
|
||||
|
@ -114,7 +110,7 @@ protected:
|
|||
// internal state. Currently, all operations are executed in a single-thread
|
||||
// by a single worker.
|
||||
mutable std::mutex lock_; // lock on this when read/writing non-atomics
|
||||
Value result_;
|
||||
UniValue result_;
|
||||
int error_code_;
|
||||
std::string error_message_;
|
||||
std::atomic<OperationStatus> state_;
|
||||
|
@ -137,7 +133,7 @@ protected:
|
|||
this->error_message_ = errorMessage;
|
||||
}
|
||||
|
||||
void set_result(Value v) {
|
||||
void set_result(UniValue v) {
|
||||
std::lock_guard<std::mutex> guard(lock_);
|
||||
this->result_ = v;
|
||||
}
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
|
||||
#include <boost/filesystem/operations.hpp>
|
||||
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
std::string HelpMessageCli()
|
||||
{
|
||||
|
@ -96,7 +97,7 @@ static bool AppInitRPC(int argc, char* argv[])
|
|||
return true;
|
||||
}
|
||||
|
||||
Object CallRPC(const string& strMethod, const Array& params)
|
||||
UniValue CallRPC(const string& strMethod, const UniValue& params)
|
||||
{
|
||||
// Connect to localhost
|
||||
bool fUseSSL = GetBoolArg("-rpcssl", false);
|
||||
|
@ -152,10 +153,10 @@ Object CallRPC(const string& strMethod, const Array& params)
|
|||
throw runtime_error("no response from server");
|
||||
|
||||
// Parse reply
|
||||
Value valReply;
|
||||
if (!read_string(strReply, valReply))
|
||||
UniValue valReply(UniValue::VSTR);
|
||||
if (!valReply.read(strReply))
|
||||
throw runtime_error("couldn't parse reply from server");
|
||||
const Object& reply = valReply.get_obj();
|
||||
const UniValue& reply = valReply.get_obj();
|
||||
if (reply.empty())
|
||||
throw runtime_error("expected reply to have result, error and id properties");
|
||||
|
||||
|
@ -180,35 +181,34 @@ int CommandLineRPC(int argc, char *argv[])
|
|||
|
||||
// Parameters default to strings
|
||||
std::vector<std::string> strParams(&argv[2], &argv[argc]);
|
||||
Array params = RPCConvertValues(strMethod, strParams);
|
||||
UniValue params = RPCConvertValues(strMethod, strParams);
|
||||
|
||||
// Execute and handle connection failures with -rpcwait
|
||||
const bool fWait = GetBoolArg("-rpcwait", false);
|
||||
do {
|
||||
try {
|
||||
const Object reply = CallRPC(strMethod, params);
|
||||
const UniValue reply = CallRPC(strMethod, params);
|
||||
|
||||
// Parse reply
|
||||
const Value& result = find_value(reply, "result");
|
||||
const Value& error = find_value(reply, "error");
|
||||
const UniValue& result = find_value(reply, "result");
|
||||
const UniValue& error = find_value(reply, "error");
|
||||
|
||||
if (error.type() != null_type) {
|
||||
if (!error.isNull()) {
|
||||
// Error
|
||||
const int code = find_value(error.get_obj(), "code").get_int();
|
||||
int code = error["code"].get_int();
|
||||
if (fWait && code == RPC_IN_WARMUP)
|
||||
throw CConnectionFailed("server in warmup");
|
||||
strPrint = "error: " + write_string(error, false);
|
||||
strPrint = "error: " + error.write();
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -347,7 +347,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
|
|||
UniValue keysObj = registers["privatekeys"];
|
||||
fGivenKeys = true;
|
||||
|
||||
for (unsigned int kidx = 0; kidx < keysObj.count(); kidx++) {
|
||||
for (size_t kidx = 0; kidx < keysObj.size(); kidx++) {
|
||||
if (!keysObj[kidx].isStr())
|
||||
throw runtime_error("privatekey not a string");
|
||||
CBitcoinSecret vchSecret;
|
||||
|
@ -364,7 +364,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
|
|||
throw runtime_error("prevtxs register variable must be set.");
|
||||
UniValue prevtxsObj = registers["prevtxs"];
|
||||
{
|
||||
for (unsigned int previdx = 0; previdx < prevtxsObj.count(); previdx++) {
|
||||
for (size_t previdx = 0; previdx < prevtxsObj.size(); previdx++) {
|
||||
UniValue prevOut = prevtxsObj[previdx];
|
||||
if (!prevOut.isObject())
|
||||
throw runtime_error("expected prevtxs internal object");
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#include "json_test_vectors.h"
|
||||
|
||||
Array
|
||||
UniValue
|
||||
read_json(const std::string& jsondata)
|
||||
{
|
||||
Value v;
|
||||
UniValue v;
|
||||
|
||||
if (!read_string(jsondata, v) || v.type() != array_type)
|
||||
if (!(v.read(jsondata) && v.isArray()))
|
||||
{
|
||||
ADD_FAILURE();
|
||||
return Array();
|
||||
return UniValue(UniValue::VARR);
|
||||
}
|
||||
return v.get_array();
|
||||
}
|
||||
|
|
|
@ -5,12 +5,9 @@
|
|||
#include "serialize.h"
|
||||
#include "streams.h"
|
||||
|
||||
#include "json/json_spirit_reader_template.h"
|
||||
#include "json/json_spirit_utils.h"
|
||||
#include "json/json_spirit_writer_template.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
Array
|
||||
UniValue
|
||||
read_json(const std::string& jsondata);
|
||||
|
||||
// #define PRINT_JSON 1
|
||||
|
@ -34,7 +31,7 @@ void expect_deser_same(const T& expected)
|
|||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
void expect_test_vector(T& it, const U& expected)
|
||||
void expect_test_vector(T& v, const U& expected)
|
||||
{
|
||||
expect_deser_same(expected);
|
||||
|
||||
|
@ -45,7 +42,7 @@ void expect_test_vector(T& it, const U& expected)
|
|||
std::cout << "\t\"" ;
|
||||
std::cout << HexStr(ss1.begin(), ss1.end()) << "\",\n";
|
||||
#else
|
||||
std::string raw = (it++)->get_str();
|
||||
std::string raw = v.get_str();
|
||||
CDataStream ss2(ParseHex(raw), SER_NETWORK, PROTOCOL_VERSION);
|
||||
|
||||
ASSERT_TRUE(ss1.size() == ss2.size());
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
#include <gtest/gtest.h>
|
||||
|
||||
#include "json/json_spirit_reader_template.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
|
||||
// This test checks if we have fixed a stack overflow problem with json_spirit.
|
||||
// It was possible to try and create an unlimited number of nested compound elements.
|
||||
// Without the fix in json_spirit_reader_template.h, this test will segfault.
|
||||
TEST(json_spirit_tests, nested_input_segfault) {
|
||||
std::vector<char> v (100000);
|
||||
std::fill (v.begin(),v.end(), '[');
|
||||
std::string s(v.begin(), v.end());
|
||||
Value value;
|
||||
bool b = json_spirit::read_string(s, value);
|
||||
ASSERT_FALSE(b);
|
||||
}
|
|
@ -57,18 +57,15 @@ void expect_ser_test_vector(B& b, const C& c, const A& tree) {
|
|||
|
||||
template<typename Tree, typename Witness>
|
||||
void test_tree(
|
||||
Array commitment_tests,
|
||||
Array root_tests,
|
||||
Array ser_tests,
|
||||
Array witness_ser_tests,
|
||||
Array path_tests
|
||||
UniValue commitment_tests,
|
||||
UniValue root_tests,
|
||||
UniValue ser_tests,
|
||||
UniValue witness_ser_tests,
|
||||
UniValue path_tests
|
||||
)
|
||||
{
|
||||
Array::iterator commitment_iterator = commitment_tests.begin();
|
||||
Array::iterator root_iterator = root_tests.begin();
|
||||
Array::iterator ser_iterator = ser_tests.begin();
|
||||
Array::iterator witness_ser_iterator = witness_ser_tests.begin();
|
||||
Array::iterator path_iterator = path_tests.begin();
|
||||
size_t witness_ser_i = 0;
|
||||
size_t path_i = 0;
|
||||
|
||||
Tree tree;
|
||||
|
||||
|
@ -88,7 +85,7 @@ void test_tree(
|
|||
vector<Witness> witnesses;
|
||||
|
||||
for (size_t i = 0; i < 16; i++) {
|
||||
uint256 test_commitment = uint256S((commitment_iterator++)->get_str());
|
||||
uint256 test_commitment = uint256S(commitment_tests[i].get_str());
|
||||
|
||||
// Witness here
|
||||
witnesses.push_back(tree.witness());
|
||||
|
@ -103,10 +100,10 @@ void test_tree(
|
|||
ASSERT_TRUE(tree.last() == test_commitment);
|
||||
|
||||
// Check tree root consistency
|
||||
expect_test_vector(root_iterator, tree.root());
|
||||
expect_test_vector(root_tests[i], tree.root());
|
||||
|
||||
// Check serialization of tree
|
||||
expect_ser_test_vector(ser_iterator, tree, tree);
|
||||
expect_ser_test_vector(ser_tests[i], tree, tree);
|
||||
|
||||
bool first = true; // The first witness can never form a path
|
||||
BOOST_FOREACH(Witness& wit, witnesses)
|
||||
|
@ -121,7 +118,7 @@ void test_tree(
|
|||
auto path = wit.path();
|
||||
|
||||
{
|
||||
expect_test_vector(path_iterator, path);
|
||||
expect_test_vector(path_tests[path_i++], path);
|
||||
|
||||
typedef Fr<default_r1cs_ppzksnark_pp> FieldT;
|
||||
|
||||
|
@ -173,7 +170,7 @@ void test_tree(
|
|||
}
|
||||
|
||||
// Check witness serialization
|
||||
expect_ser_test_vector(witness_ser_iterator, wit, tree);
|
||||
expect_ser_test_vector(witness_ser_tests[witness_ser_i++], wit, tree);
|
||||
|
||||
ASSERT_TRUE(wit.root() == tree.root());
|
||||
|
||||
|
@ -192,24 +189,25 @@ void test_tree(
|
|||
}
|
||||
}
|
||||
|
||||
#define MAKE_STRING(x) std::string((x), (x)+sizeof(x))
|
||||
|
||||
TEST(merkletree, vectors) {
|
||||
Array root_tests = read_json(std::string(json_tests::merkle_roots, json_tests::merkle_roots + sizeof(json_tests::merkle_roots)));
|
||||
Array ser_tests = read_json(std::string(json_tests::merkle_serialization, json_tests::merkle_serialization + sizeof(json_tests::merkle_serialization)));
|
||||
Array witness_ser_tests = read_json(std::string(json_tests::merkle_witness_serialization, json_tests::merkle_witness_serialization + sizeof(json_tests::merkle_witness_serialization)));
|
||||
Array path_tests = read_json(std::string(json_tests::merkle_path, json_tests::merkle_path + sizeof(json_tests::merkle_path)));
|
||||
Array commitment_tests = read_json(std::string(json_tests::merkle_commitments, json_tests::merkle_commitments + sizeof(json_tests::merkle_commitments)));
|
||||
UniValue root_tests = read_json(MAKE_STRING(json_tests::merkle_roots));
|
||||
UniValue ser_tests = read_json(MAKE_STRING(json_tests::merkle_serialization));
|
||||
UniValue witness_ser_tests = read_json(MAKE_STRING(json_tests::merkle_witness_serialization));
|
||||
UniValue path_tests = read_json(MAKE_STRING(json_tests::merkle_path));
|
||||
UniValue commitment_tests = read_json(MAKE_STRING(json_tests::merkle_commitments));
|
||||
|
||||
test_tree<ZCTestingIncrementalMerkleTree, ZCTestingIncrementalWitness>(commitment_tests, root_tests, ser_tests, witness_ser_tests, path_tests);
|
||||
}
|
||||
|
||||
TEST(merkletree, emptyroots) {
|
||||
Array empty_roots = read_json(std::string(json_tests::merkle_roots_empty, json_tests::merkle_roots_empty + sizeof(json_tests::merkle_roots_empty)));
|
||||
Array::iterator root_iterator = empty_roots.begin();
|
||||
UniValue empty_roots = read_json(MAKE_STRING(json_tests::merkle_roots_empty));
|
||||
|
||||
libzcash::EmptyMerkleRoots<64, libzcash::SHA256Compress> emptyroots;
|
||||
|
||||
for (size_t depth = 0; depth <= 64; depth++) {
|
||||
expect_test_vector(root_iterator, emptyroots.empty_root(depth));
|
||||
expect_test_vector(empty_roots[depth], emptyroots.empty_root(depth));
|
||||
}
|
||||
|
||||
// Double check that we're testing (at least) all the empty roots we'll use.
|
||||
|
|
|
@ -629,15 +629,14 @@ TEST(proofs, g2_deserialization)
|
|||
|
||||
TEST(proofs, g1_test_vectors)
|
||||
{
|
||||
Array v = read_json(std::string(json_tests::g1_compressed, json_tests::g1_compressed + sizeof(json_tests::g1_compressed)));
|
||||
Array::iterator v_iterator = v.begin();
|
||||
UniValue v = read_json(std::string(json_tests::g1_compressed, json_tests::g1_compressed + sizeof(json_tests::g1_compressed)));
|
||||
|
||||
curve_G1 e = curve_Fr("34958239045823") * curve_G1::one();
|
||||
for (size_t i = 0; i < 10000; i++) {
|
||||
e = (curve_Fr("34958239045823") ^ i) * e;
|
||||
auto expected = CompressedG1(e);
|
||||
|
||||
expect_test_vector(v_iterator, expected);
|
||||
expect_test_vector(v[i], expected);
|
||||
ASSERT_TRUE(expected.to_libsnark_g1<curve_G1>() == e);
|
||||
}
|
||||
}
|
||||
|
@ -646,15 +645,14 @@ TEST(proofs, g1_test_vectors)
|
|||
|
||||
TEST(proofs, g2_test_vectors)
|
||||
{
|
||||
Array v = read_json(std::string(json_tests::g2_compressed, json_tests::g2_compressed + sizeof(json_tests::g2_compressed)));
|
||||
Array::iterator v_iterator = v.begin();
|
||||
UniValue v = read_json(std::string(json_tests::g2_compressed, json_tests::g2_compressed + sizeof(json_tests::g2_compressed)));
|
||||
|
||||
curve_G2 e = curve_Fr("34958239045823") * curve_G2::one();
|
||||
for (size_t i = 0; i < 10000; i++) {
|
||||
e = (curve_Fr("34958239045823") ^ i) * e;
|
||||
auto expected = CompressedG2(e);
|
||||
|
||||
expect_test_vector(v_iterator, expected);
|
||||
expect_test_vector(v[i], expected);
|
||||
ASSERT_TRUE(expected.to_libsnark_g2<curve_G2>() == e);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include "json/json_spirit_value.h"
|
||||
#include "json/json_spirit_utils.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
#include "chain.h"
|
||||
#include "chainparams.h"
|
||||
|
@ -10,7 +9,7 @@
|
|||
#include "streams.h"
|
||||
#include "utilstrencodings.h"
|
||||
|
||||
extern json_spirit::Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
|
||||
extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
|
||||
|
||||
TEST(rpc, check_blockToJSON_returns_minified_solution) {
|
||||
SelectParams(CBaseChainParams::TESTNET);
|
||||
|
@ -24,6 +23,6 @@ TEST(rpc, check_blockToJSON_returns_minified_solution) {
|
|||
CBlockIndex index {block};
|
||||
index.nHeight = 1391;
|
||||
|
||||
json_spirit::Object obj = blockToJSON(block, &index);
|
||||
EXPECT_EQ("009f44ff7505d789b964d6817734b8ce1377d456255994370d06e59ac99bd5791b6ad174a66fd71c70e60cfc7fd88243ffe06f80b1ad181625f210779c745524629448e25348a5fce4f346a1735e60fdf53e144c0157dbc47c700a21a236f1efb7ee75f65b8d9d9e29026cfd09048233175202b211b9a49de4ab46f1cac71b6ea57a686377bd612378746e70c61a659c9cd683269e9c2a5cbc1d19f1149345302bbd0a1e62bf4bab01e9caeea789a1519441a61b146de35a4cc75dbdf01029127e311ad5073e7e96397f47226a7df9df66b2086b70756db013bbaeb068260157014b2602fc7dc71336e1439c887d2742d9730b4e79b08ec7839c3e2a037ae1565d04e05e351bb3531e5ef42cf7b71ca1482a9205245dd41f4db0f71644f8bdb88e845558537c03834c06ac83f336651e54e2edfc12e15ea9b7ea2c074e6155654d44c4d3bd90d9511050e9ad87d170db01448e5be6f45419cd86008978db5e3ceab79890234f992648d69bf1053855387db646ccdee5575c65f81dd0f670b016d9f9a84707d91f77b862f697b8bb08365ba71fbe6bfa47af39155a75ebdcb1e5d69f59c40c9e3a64988c1ec26f7f5159eef5c244d504a9e46125948ecc389c2ec3028ac4ff39ffd66e7743970819272b21e0c2df75b308bc62896873952147e57ed79446db4cdb5a563e76ec4c25899d41128afb9a5f8fc8063621efb7a58b9dd666d30c73e318cdcf3393bfec200e160f500e645f7baac263db99fa4a7c1cb4fea219fc512193102034d379f244c21a81821301b8d47c90247713a3e902c762d7bafa6cdb744eeb6d3b50dd175599d02b6e9f5bbda59366e04862aa765135968426e7ac0116de7351940dc57c0ae451d63f667e39891bc81e09e6c76f6f8a7582f7447c6f5945f717b0e52a7e3dd0c6db4061362123cc53fd8ede4abed4865201dc4d8eb4e5d48baa565183b69a5304a44c0600bb24dcaeee9d95ceebd27c1b0a33e0b46f23797d7d7907300b2bb7d62ef2fc5aa139250c73930c621bb5f41fc235534ee8014dfaddd5245aeb01198420ba7b5c076545329c94d54fa725a8e807579f5f0cc9d98170598023268f5930893620190275e6b3c6f5181e36310a9a475208316911d78f917d724c5946c553b7ec042c563c540114b6b78bd4c6e808ee391a4a9d93e127032983c5b3708037b14aa604cfb034e7c8b0ffdd6936446fe80216178506a87402653a373926eeff66e704daf992a0a9a5c3ad80566c0339be9e5b8e35b3b3226b2f7767e20d992ea6c3d6e322eca37b0c7f7e60060802f5abcc1975841365cadbdc3867063addfc803766ae525375ecddee61f9df9ffcd20343c83ab82b0e91de039c59cb435c8d3159cc338b4901f40c9b5c27043bcf2bd5fa9b685b65c9ba5a1e11a51dd3f773051560341f9ec81d05bf259e2d4b7161f896fbb6812cfc924a32120b7367d5e40439e267adda6a1315bb0d6200ce6a503174c8d2a638ea6fd6b1f486d68db11bdca63c4f4a725d1ab6231ea875484e70b27d293c05803386924f283d4c12bb953474d92b7dd43d2d97193bd96281ebb63fa075d2f9ecd310c70ee1d97b5330bd8fb5791c5943ecf084e5f2c83915acac57519c46b166136068d6f9ec0dd598616e32c591128ce13705a283ca39d5b211409600e07b3713113374d9700207a45394eac5b3b7afc9b1b2bad7d89fd3f35f6b2413ce615ee7869b3569009403b96fdacdb32ef0a7e5229e2b666d51e95bdfb009b892e88bde70621a9b6509f068781392df4bdbc5723bb15071993f0d9a11575af5ff6ef85eaea39bc86805b35d8beee91b779354147f2d85304b8b49d053e7444fdd3deb9d16de331f2552af5b3be7766bb8f3f6a78c62148efb231f2268", json_spirit::find_value(obj, "solution").get_str());
|
||||
UniValue obj = blockToJSON(block, &index);
|
||||
EXPECT_EQ("009f44ff7505d789b964d6817734b8ce1377d456255994370d06e59ac99bd5791b6ad174a66fd71c70e60cfc7fd88243ffe06f80b1ad181625f210779c745524629448e25348a5fce4f346a1735e60fdf53e144c0157dbc47c700a21a236f1efb7ee75f65b8d9d9e29026cfd09048233175202b211b9a49de4ab46f1cac71b6ea57a686377bd612378746e70c61a659c9cd683269e9c2a5cbc1d19f1149345302bbd0a1e62bf4bab01e9caeea789a1519441a61b146de35a4cc75dbdf01029127e311ad5073e7e96397f47226a7df9df66b2086b70756db013bbaeb068260157014b2602fc7dc71336e1439c887d2742d9730b4e79b08ec7839c3e2a037ae1565d04e05e351bb3531e5ef42cf7b71ca1482a9205245dd41f4db0f71644f8bdb88e845558537c03834c06ac83f336651e54e2edfc12e15ea9b7ea2c074e6155654d44c4d3bd90d9511050e9ad87d170db01448e5be6f45419cd86008978db5e3ceab79890234f992648d69bf1053855387db646ccdee5575c65f81dd0f670b016d9f9a84707d91f77b862f697b8bb08365ba71fbe6bfa47af39155a75ebdcb1e5d69f59c40c9e3a64988c1ec26f7f5159eef5c244d504a9e46125948ecc389c2ec3028ac4ff39ffd66e7743970819272b21e0c2df75b308bc62896873952147e57ed79446db4cdb5a563e76ec4c25899d41128afb9a5f8fc8063621efb7a58b9dd666d30c73e318cdcf3393bfec200e160f500e645f7baac263db99fa4a7c1cb4fea219fc512193102034d379f244c21a81821301b8d47c90247713a3e902c762d7bafa6cdb744eeb6d3b50dd175599d02b6e9f5bbda59366e04862aa765135968426e7ac0116de7351940dc57c0ae451d63f667e39891bc81e09e6c76f6f8a7582f7447c6f5945f717b0e52a7e3dd0c6db4061362123cc53fd8ede4abed4865201dc4d8eb4e5d48baa565183b69a5304a44c0600bb24dcaeee9d95ceebd27c1b0a33e0b46f23797d7d7907300b2bb7d62ef2fc5aa139250c73930c621bb5f41fc235534ee8014dfaddd5245aeb01198420ba7b5c076545329c94d54fa725a8e807579f5f0cc9d98170598023268f5930893620190275e6b3c6f5181e36310a9a475208316911d78f917d724c5946c553b7ec042c563c540114b6b78bd4c6e808ee391a4a9d93e127032983c5b3708037b14aa604cfb034e7c8b0ffdd6936446fe80216178506a87402653a373926eeff66e704daf992a0a9a5c3ad80566c0339be9e5b8e35b3b3226b2f7767e20d992ea6c3d6e322eca37b0c7f7e60060802f5abcc1975841365cadbdc3867063addfc803766ae525375ecddee61f9df9ffcd20343c83ab82b0e91de039c59cb435c8d3159cc338b4901f40c9b5c27043bcf2bd5fa9b685b65c9ba5a1e11a51dd3f773051560341f9ec81d05bf259e2d4b7161f896fbb6812cfc924a32120b7367d5e40439e267adda6a1315bb0d6200ce6a503174c8d2a638ea6fd6b1f486d68db11bdca63c4f4a725d1ab6231ea875484e70b27d293c05803386924f283d4c12bb953474d92b7dd43d2d97193bd96281ebb63fa075d2f9ecd310c70ee1d97b5330bd8fb5791c5943ecf084e5f2c83915acac57519c46b166136068d6f9ec0dd598616e32c591128ce13705a283ca39d5b211409600e07b3713113374d9700207a45394eac5b3b7afc9b1b2bad7d89fd3f35f6b2413ce615ee7869b3569009403b96fdacdb32ef0a7e5229e2b666d51e95bdfb009b892e88bde70621a9b6509f068781392df4bdbc5723bb15071993f0d9a11575af5ff6ef85eaea39bc86805b35d8beee91b779354147f2d85304b8b49d053e7444fdd3deb9d16de331f2552af5b3be7766bb8f3f6a78c62148efb231f2268", find_value(obj, "solution").get_str());
|
||||
}
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2007 - 2009 John W. Wilkinson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -1,18 +0,0 @@
|
|||
#ifndef JSON_SPIRIT
|
||||
#define JSON_SPIRIT
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_reader.h"
|
||||
#include "json_spirit_writer.h"
|
||||
#include "json_spirit_utils.h"
|
||||
|
||||
#endif
|
|
@ -1,54 +0,0 @@
|
|||
#ifndef JSON_SPIRIT_ERROR_POSITION
|
||||
#define JSON_SPIRIT_ERROR_POSITION
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// An Error_position exception is thrown by the "read_or_throw" functions below on finding an error.
|
||||
// Note the "read_or_throw" functions are around 3 times slower than the standard functions "read"
|
||||
// functions that return a bool.
|
||||
//
|
||||
struct Error_position
|
||||
{
|
||||
Error_position();
|
||||
Error_position( unsigned int line, unsigned int column, const std::string& reason );
|
||||
bool operator==( const Error_position& lhs ) const;
|
||||
unsigned int line_;
|
||||
unsigned int column_;
|
||||
std::string reason_;
|
||||
};
|
||||
|
||||
inline Error_position::Error_position()
|
||||
: line_( 0 )
|
||||
, column_( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
inline Error_position::Error_position( unsigned int line, unsigned int column, const std::string& reason )
|
||||
: line_( line )
|
||||
, column_( column )
|
||||
, reason_( reason )
|
||||
{
|
||||
}
|
||||
|
||||
inline bool Error_position::operator==( const Error_position& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
return ( reason_ == lhs.reason_ ) &&
|
||||
( line_ == lhs.line_ ) &&
|
||||
( column_ == lhs.column_ );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,137 +0,0 @@
|
|||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_reader.h"
|
||||
#include "json_spirit_reader_template.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
|
||||
bool json_spirit::read( const std::string& s, Value& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::string& s, Value& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::istream& is, Value& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::istream& is, Value& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool json_spirit::read( const std::wstring& s, wValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::wstring& s, wValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wistream& is, wValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wistream& is, wValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool json_spirit::read( const std::string& s, mValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::string& s, mValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::istream& is, mValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::istream& is, mValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool json_spirit::read( const std::wstring& s, wmValue& value )
|
||||
{
|
||||
return read_string( s, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( const std::wstring& s, wmValue& value )
|
||||
{
|
||||
read_string_or_throw( s, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wistream& is, wmValue& value )
|
||||
{
|
||||
return read_stream( is, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wistream& is, wmValue& value )
|
||||
{
|
||||
read_stream_or_throw( is, value );
|
||||
}
|
||||
|
||||
bool json_spirit::read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
|
||||
{
|
||||
return read_range( begin, end, value );
|
||||
}
|
||||
|
||||
void json_spirit::read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value )
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,62 +0,0 @@
|
|||
#ifndef JSON_SPIRIT_READER
|
||||
#define JSON_SPIRIT_READER
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_error_position.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// functions to reads a JSON values
|
||||
|
||||
bool read( const std::string& s, Value& value );
|
||||
bool read( std::istream& is, Value& value );
|
||||
bool read( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
|
||||
|
||||
void read_or_throw( const std::string& s, Value& value );
|
||||
void read_or_throw( std::istream& is, Value& value );
|
||||
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, Value& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool read( const std::wstring& s, wValue& value );
|
||||
bool read( std::wistream& is, wValue& value );
|
||||
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
|
||||
|
||||
void read_or_throw( const std::wstring& s, wValue& value );
|
||||
void read_or_throw( std::wistream& is, wValue& value );
|
||||
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wValue& value );
|
||||
|
||||
#endif
|
||||
|
||||
bool read( const std::string& s, mValue& value );
|
||||
bool read( std::istream& is, mValue& value );
|
||||
bool read( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
|
||||
|
||||
void read_or_throw( const std::string& s, mValue& value );
|
||||
void read_or_throw( std::istream& is, mValue& value );
|
||||
void read_or_throw( std::string::const_iterator& begin, std::string::const_iterator end, mValue& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
bool read( const std::wstring& s, wmValue& value );
|
||||
bool read( std::wistream& is, wmValue& value );
|
||||
bool read( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
|
||||
|
||||
void read_or_throw( const std::wstring& s, wmValue& value );
|
||||
void read_or_throw( std::wistream& is, wmValue& value );
|
||||
void read_or_throw( std::wstring::const_iterator& begin, std::wstring::const_iterator end, wmValue& value );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,618 +0,0 @@
|
|||
#ifndef JSON_SPIRIT_READER_TEMPLATE
|
||||
#define JSON_SPIRIT_READER_TEMPLATE
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include "json_spirit_error_position.h"
|
||||
|
||||
//#define BOOST_SPIRIT_THREADSAFE // uncomment for multithreaded use, requires linking to boost.thread
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/version.hpp>
|
||||
|
||||
#if BOOST_VERSION >= 103800
|
||||
#include <boost/spirit/include/classic_core.hpp>
|
||||
#include <boost/spirit/include/classic_confix.hpp>
|
||||
#include <boost/spirit/include/classic_escape_char.hpp>
|
||||
#include <boost/spirit/include/classic_multi_pass.hpp>
|
||||
#include <boost/spirit/include/classic_position_iterator.hpp>
|
||||
#define spirit_namespace boost::spirit::classic
|
||||
#else
|
||||
#include <boost/spirit/core.hpp>
|
||||
#include <boost/spirit/utility/confix.hpp>
|
||||
#include <boost/spirit/utility/escape_char.hpp>
|
||||
#include <boost/spirit/iterator/multi_pass.hpp>
|
||||
#include <boost/spirit/iterator/position_iterator.hpp>
|
||||
#define spirit_namespace boost::spirit
|
||||
#endif
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
const spirit_namespace::int_parser < int64_t > int64_p = spirit_namespace::int_parser < int64_t >();
|
||||
const spirit_namespace::uint_parser< uint64_t > uint64_p = spirit_namespace::uint_parser< uint64_t >();
|
||||
|
||||
template< class Iter_type >
|
||||
bool is_eq( Iter_type first, Iter_type last, const char* c_str )
|
||||
{
|
||||
for( Iter_type i = first; i != last; ++i, ++c_str )
|
||||
{
|
||||
if( *c_str == 0 ) return false;
|
||||
|
||||
if( *i != *c_str ) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template< class Char_type >
|
||||
Char_type hex_to_num( const Char_type c )
|
||||
{
|
||||
if( ( c >= '0' ) && ( c <= '9' ) ) return c - '0';
|
||||
if( ( c >= 'a' ) && ( c <= 'f' ) ) return c - 'a' + 10;
|
||||
if( ( c >= 'A' ) && ( c <= 'F' ) ) return c - 'A' + 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template< class Char_type, class Iter_type >
|
||||
Char_type hex_str_to_char( Iter_type& begin )
|
||||
{
|
||||
const Char_type c1( *( ++begin ) );
|
||||
const Char_type c2( *( ++begin ) );
|
||||
|
||||
return ( hex_to_num( c1 ) << 4 ) + hex_to_num( c2 );
|
||||
}
|
||||
|
||||
template< class Char_type, class Iter_type >
|
||||
Char_type unicode_str_to_char( Iter_type& begin )
|
||||
{
|
||||
const Char_type c1( *( ++begin ) );
|
||||
const Char_type c2( *( ++begin ) );
|
||||
const Char_type c3( *( ++begin ) );
|
||||
const Char_type c4( *( ++begin ) );
|
||||
|
||||
return ( hex_to_num( c1 ) << 12 ) +
|
||||
( hex_to_num( c2 ) << 8 ) +
|
||||
( hex_to_num( c3 ) << 4 ) +
|
||||
hex_to_num( c4 );
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
void append_esc_char_and_incr_iter( String_type& s,
|
||||
typename String_type::const_iterator& begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
const Char_type c2( *begin );
|
||||
|
||||
switch( c2 )
|
||||
{
|
||||
case 't': s += '\t'; break;
|
||||
case 'b': s += '\b'; break;
|
||||
case 'f': s += '\f'; break;
|
||||
case 'n': s += '\n'; break;
|
||||
case 'r': s += '\r'; break;
|
||||
case '\\': s += '\\'; break;
|
||||
case '/': s += '/'; break;
|
||||
case '"': s += '"'; break;
|
||||
case 'x':
|
||||
{
|
||||
if( end - begin >= 3 ) // expecting "xHH..."
|
||||
{
|
||||
s += hex_str_to_char< Char_type >( begin );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
{
|
||||
if( end - begin >= 5 ) // expecting "uHHHH..."
|
||||
{
|
||||
s += unicode_str_to_char< Char_type >( begin );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type substitute_esc_chars( typename String_type::const_iterator begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
typedef typename String_type::const_iterator Iter_type;
|
||||
|
||||
if( end - begin < 2 ) return String_type( begin, end );
|
||||
|
||||
String_type result;
|
||||
|
||||
result.reserve( end - begin );
|
||||
|
||||
const Iter_type end_minus_1( end - 1 );
|
||||
|
||||
Iter_type substr_start = begin;
|
||||
Iter_type i = begin;
|
||||
|
||||
for( ; i < end_minus_1; ++i )
|
||||
{
|
||||
if( *i == '\\' )
|
||||
{
|
||||
result.append( substr_start, i );
|
||||
|
||||
++i; // skip the '\'
|
||||
|
||||
append_esc_char_and_incr_iter( result, i, end );
|
||||
|
||||
substr_start = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
result.append( substr_start, end );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type get_str_( typename String_type::const_iterator begin,
|
||||
typename String_type::const_iterator end )
|
||||
{
|
||||
assert( end - begin >= 2 );
|
||||
|
||||
typedef typename String_type::const_iterator Iter_type;
|
||||
|
||||
Iter_type str_without_quotes( ++begin );
|
||||
Iter_type end_without_quotes( --end );
|
||||
|
||||
return substitute_esc_chars< String_type >( str_without_quotes, end_without_quotes );
|
||||
}
|
||||
|
||||
inline std::string get_str( std::string::const_iterator begin, std::string::const_iterator end )
|
||||
{
|
||||
return get_str_< std::string >( begin, end );
|
||||
}
|
||||
|
||||
inline std::wstring get_str( std::wstring::const_iterator begin, std::wstring::const_iterator end )
|
||||
{
|
||||
return get_str_< std::wstring >( begin, end );
|
||||
}
|
||||
|
||||
template< class String_type, class Iter_type >
|
||||
String_type get_str( Iter_type begin, Iter_type end )
|
||||
{
|
||||
const String_type tmp( begin, end ); // convert multipass iterators to string iterators
|
||||
|
||||
return get_str( tmp.begin(), tmp.end() );
|
||||
}
|
||||
|
||||
// this class's methods get called by the spirit parse resulting
|
||||
// in the creation of a JSON object or array
|
||||
//
|
||||
// NB Iter_type could be a std::string iterator, wstring iterator, a position iterator or a multipass iterator
|
||||
//
|
||||
template< class Value_type, class Iter_type >
|
||||
class Semantic_actions
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename Value_type::Config_type Config_type;
|
||||
typedef typename Config_type::String_type String_type;
|
||||
typedef typename Config_type::Object_type Object_type;
|
||||
typedef typename Config_type::Array_type Array_type;
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
Semantic_actions( Value_type& value )
|
||||
: value_( value )
|
||||
, current_p_( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
void begin_obj( Char_type c )
|
||||
{
|
||||
assert( c == '{' );
|
||||
|
||||
begin_compound< Object_type >();
|
||||
}
|
||||
|
||||
void end_obj( Char_type c )
|
||||
{
|
||||
assert( c == '}' );
|
||||
|
||||
end_compound();
|
||||
}
|
||||
|
||||
void begin_array( Char_type c )
|
||||
{
|
||||
assert( c == '[' );
|
||||
|
||||
begin_compound< Array_type >();
|
||||
}
|
||||
|
||||
void end_array( Char_type c )
|
||||
{
|
||||
assert( c == ']' );
|
||||
|
||||
end_compound();
|
||||
}
|
||||
|
||||
void new_name( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( current_p_->type() == obj_type );
|
||||
|
||||
name_ = get_str< String_type >( begin, end );
|
||||
}
|
||||
|
||||
void new_str( Iter_type begin, Iter_type end )
|
||||
{
|
||||
add_to_current( get_str< String_type >( begin, end ) );
|
||||
}
|
||||
|
||||
void new_true( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "true" ) );
|
||||
|
||||
add_to_current( true );
|
||||
}
|
||||
|
||||
void new_false( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "false" ) );
|
||||
|
||||
add_to_current( false );
|
||||
}
|
||||
|
||||
void new_null( Iter_type begin, Iter_type end )
|
||||
{
|
||||
assert( is_eq( begin, end, "null" ) );
|
||||
|
||||
add_to_current( Value_type() );
|
||||
}
|
||||
|
||||
void new_int( int64_t i )
|
||||
{
|
||||
add_to_current( i );
|
||||
}
|
||||
|
||||
void new_uint64( uint64_t ui )
|
||||
{
|
||||
add_to_current( ui );
|
||||
}
|
||||
|
||||
void new_real( double d )
|
||||
{
|
||||
add_to_current( d );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Semantic_actions& operator=( const Semantic_actions& );
|
||||
// to prevent "assignment operator could not be generated" warning
|
||||
|
||||
Value_type* add_first( const Value_type& value )
|
||||
{
|
||||
assert( current_p_ == 0 );
|
||||
|
||||
value_ = value;
|
||||
current_p_ = &value_;
|
||||
return current_p_;
|
||||
}
|
||||
|
||||
template< class Array_or_obj >
|
||||
void begin_compound()
|
||||
{
|
||||
if( current_p_ == 0 )
|
||||
{
|
||||
add_first( Array_or_obj() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// ZCASH: Prevent potential stack overflow by setting a limit on the number of nested compound elements
|
||||
if (stack_.size() > 128) {
|
||||
throw std::domain_error("too many nested elements");
|
||||
}
|
||||
// ENDZCASH
|
||||
|
||||
stack_.push_back( current_p_ );
|
||||
|
||||
Array_or_obj new_array_or_obj; // avoid copy by building new array or object in place
|
||||
|
||||
current_p_ = add_to_current( new_array_or_obj );
|
||||
}
|
||||
}
|
||||
|
||||
void end_compound()
|
||||
{
|
||||
if( current_p_ != &value_ )
|
||||
{
|
||||
current_p_ = stack_.back();
|
||||
|
||||
stack_.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
Value_type* add_to_current( const Value_type& value )
|
||||
{
|
||||
if( current_p_ == 0 )
|
||||
{
|
||||
return add_first( value );
|
||||
}
|
||||
else if( current_p_->type() == array_type )
|
||||
{
|
||||
current_p_->get_array().push_back( value );
|
||||
|
||||
return ¤t_p_->get_array().back();
|
||||
}
|
||||
|
||||
assert( current_p_->type() == obj_type );
|
||||
|
||||
return &Config_type::add( current_p_->get_obj(), name_, value );
|
||||
}
|
||||
|
||||
Value_type& value_; // this is the object or array that is being created
|
||||
Value_type* current_p_; // the child object or array that is currently being constructed
|
||||
|
||||
std::vector< Value_type* > stack_; // previous child objects and arrays
|
||||
|
||||
String_type name_; // of current name/value pair
|
||||
};
|
||||
|
||||
template< typename Iter_type >
|
||||
void throw_error( spirit_namespace::position_iterator< Iter_type > i, const std::string& reason )
|
||||
{
|
||||
throw Error_position( i.get_position().line, i.get_position().column, reason );
|
||||
}
|
||||
|
||||
template< typename Iter_type >
|
||||
void throw_error( Iter_type i, const std::string& reason )
|
||||
{
|
||||
throw reason;
|
||||
}
|
||||
|
||||
// the spirit grammer
|
||||
//
|
||||
template< class Value_type, class Iter_type >
|
||||
class Json_grammer : public spirit_namespace::grammar< Json_grammer< Value_type, Iter_type > >
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Semantic_actions< Value_type, Iter_type > Semantic_actions_t;
|
||||
|
||||
Json_grammer( Semantic_actions_t& semantic_actions )
|
||||
: actions_( semantic_actions )
|
||||
{
|
||||
}
|
||||
|
||||
static void throw_not_value( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a value" );
|
||||
}
|
||||
|
||||
static void throw_not_array( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not an array" );
|
||||
}
|
||||
|
||||
static void throw_not_object( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not an object" );
|
||||
}
|
||||
|
||||
static void throw_not_pair( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a pair" );
|
||||
}
|
||||
|
||||
static void throw_not_colon( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "no colon in pair" );
|
||||
}
|
||||
|
||||
static void throw_not_string( Iter_type begin, Iter_type end )
|
||||
{
|
||||
throw_error( begin, "not a string" );
|
||||
}
|
||||
|
||||
template< typename ScannerT >
|
||||
class definition
|
||||
{
|
||||
public:
|
||||
|
||||
definition( const Json_grammer& self )
|
||||
{
|
||||
using namespace spirit_namespace;
|
||||
|
||||
typedef typename Value_type::String_type::value_type Char_type;
|
||||
|
||||
// first we convert the semantic action class methods to functors with the
|
||||
// parameter signature expected by spirit
|
||||
|
||||
typedef boost::function< void( Char_type ) > Char_action;
|
||||
typedef boost::function< void( Iter_type, Iter_type ) > Str_action;
|
||||
typedef boost::function< void( double ) > Real_action;
|
||||
typedef boost::function< void( int64_t ) > Int_action;
|
||||
typedef boost::function< void( uint64_t ) > Uint64_action;
|
||||
|
||||
Char_action begin_obj ( boost::bind( &Semantic_actions_t::begin_obj, &self.actions_, _1 ) );
|
||||
Char_action end_obj ( boost::bind( &Semantic_actions_t::end_obj, &self.actions_, _1 ) );
|
||||
Char_action begin_array( boost::bind( &Semantic_actions_t::begin_array, &self.actions_, _1 ) );
|
||||
Char_action end_array ( boost::bind( &Semantic_actions_t::end_array, &self.actions_, _1 ) );
|
||||
Str_action new_name ( boost::bind( &Semantic_actions_t::new_name, &self.actions_, _1, _2 ) );
|
||||
Str_action new_str ( boost::bind( &Semantic_actions_t::new_str, &self.actions_, _1, _2 ) );
|
||||
Str_action new_true ( boost::bind( &Semantic_actions_t::new_true, &self.actions_, _1, _2 ) );
|
||||
Str_action new_false ( boost::bind( &Semantic_actions_t::new_false, &self.actions_, _1, _2 ) );
|
||||
Str_action new_null ( boost::bind( &Semantic_actions_t::new_null, &self.actions_, _1, _2 ) );
|
||||
Real_action new_real ( boost::bind( &Semantic_actions_t::new_real, &self.actions_, _1 ) );
|
||||
Int_action new_int ( boost::bind( &Semantic_actions_t::new_int, &self.actions_, _1 ) );
|
||||
Uint64_action new_uint64 ( boost::bind( &Semantic_actions_t::new_uint64, &self.actions_, _1 ) );
|
||||
|
||||
// actual grammer
|
||||
|
||||
json_
|
||||
= value_ | eps_p[ &throw_not_value ]
|
||||
;
|
||||
|
||||
value_
|
||||
= string_[ new_str ]
|
||||
| number_
|
||||
| object_
|
||||
| array_
|
||||
| str_p( "true" ) [ new_true ]
|
||||
| str_p( "false" )[ new_false ]
|
||||
| str_p( "null" ) [ new_null ]
|
||||
;
|
||||
|
||||
object_
|
||||
= ch_p('{')[ begin_obj ]
|
||||
>> !members_
|
||||
>> ( ch_p('}')[ end_obj ] | eps_p[ &throw_not_object ] )
|
||||
;
|
||||
|
||||
members_
|
||||
= pair_ >> *( ',' >> pair_ )
|
||||
;
|
||||
|
||||
pair_
|
||||
= string_[ new_name ]
|
||||
>> ( ':' | eps_p[ &throw_not_colon ] )
|
||||
>> ( value_ | eps_p[ &throw_not_value ] )
|
||||
;
|
||||
|
||||
array_
|
||||
= ch_p('[')[ begin_array ]
|
||||
>> !elements_
|
||||
>> ( ch_p(']')[ end_array ] | eps_p[ &throw_not_array ] )
|
||||
;
|
||||
|
||||
elements_
|
||||
= value_ >> *( ',' >> value_ )
|
||||
;
|
||||
|
||||
string_
|
||||
= lexeme_d // this causes white space inside a string to be retained
|
||||
[
|
||||
confix_p
|
||||
(
|
||||
'"',
|
||||
*lex_escape_ch_p,
|
||||
'"'
|
||||
)
|
||||
]
|
||||
;
|
||||
|
||||
number_
|
||||
= strict_real_p[ new_real ]
|
||||
| int64_p [ new_int ]
|
||||
| uint64_p [ new_uint64 ]
|
||||
;
|
||||
}
|
||||
|
||||
spirit_namespace::rule< ScannerT > json_, object_, members_, pair_, array_, elements_, value_, string_, number_;
|
||||
|
||||
const spirit_namespace::rule< ScannerT >& start() const { return json_; }
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
Json_grammer& operator=( const Json_grammer& ); // to prevent "assignment operator could not be generated" warning
|
||||
|
||||
Semantic_actions_t& actions_;
|
||||
};
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
Iter_type read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
Semantic_actions< Value_type, Iter_type > semantic_actions( value );
|
||||
|
||||
const spirit_namespace::parse_info< Iter_type > info =
|
||||
spirit_namespace::parse( begin, end,
|
||||
Json_grammer< Value_type, Iter_type >( semantic_actions ) >> spirit_namespace::end_p,
|
||||
spirit_namespace::space_p );
|
||||
|
||||
if( !info.hit )
|
||||
{
|
||||
throw_error( info.stop, "error" );
|
||||
}
|
||||
|
||||
return info.stop;
|
||||
}
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
void add_posn_iter_and_read_range_or_throw( Iter_type begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
typedef spirit_namespace::position_iterator< Iter_type > Posn_iter_t;
|
||||
|
||||
const Posn_iter_t posn_begin( begin, end );
|
||||
const Posn_iter_t posn_end( end, end );
|
||||
|
||||
read_range_or_throw( posn_begin, posn_end, value );
|
||||
}
|
||||
|
||||
template< class Iter_type, class Value_type >
|
||||
bool read_range( Iter_type& begin, Iter_type end, Value_type& value )
|
||||
{
|
||||
try
|
||||
{
|
||||
begin = read_range_or_throw( begin, end, value );
|
||||
|
||||
return true;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template< class String_type, class Value_type >
|
||||
void read_string_or_throw( const String_type& s, Value_type& value )
|
||||
{
|
||||
add_posn_iter_and_read_range_or_throw( s.begin(), s.end(), value );
|
||||
}
|
||||
|
||||
template< class String_type, class Value_type >
|
||||
bool read_string( const String_type& s, Value_type& value )
|
||||
{
|
||||
typename String_type::const_iterator begin = s.begin();
|
||||
|
||||
bool success = read_range( begin, s.end(), value );
|
||||
return success && begin == s.end();
|
||||
}
|
||||
|
||||
template< class Istream_type >
|
||||
struct Multi_pass_iters
|
||||
{
|
||||
typedef typename Istream_type::char_type Char_type;
|
||||
typedef std::istream_iterator< Char_type, Char_type > istream_iter;
|
||||
typedef spirit_namespace::multi_pass< istream_iter > Mp_iter;
|
||||
|
||||
Multi_pass_iters( Istream_type& is )
|
||||
{
|
||||
is.unsetf( std::ios::skipws );
|
||||
|
||||
begin_ = spirit_namespace::make_multi_pass( istream_iter( is ) );
|
||||
end_ = spirit_namespace::make_multi_pass( istream_iter() );
|
||||
}
|
||||
|
||||
Mp_iter begin_;
|
||||
Mp_iter end_;
|
||||
};
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
bool read_stream( Istream_type& is, Value_type& value )
|
||||
{
|
||||
Multi_pass_iters< Istream_type > mp_iters( is );
|
||||
|
||||
return read_range( mp_iters.begin_, mp_iters.end_, value );
|
||||
}
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
void read_stream_or_throw( Istream_type& is, Value_type& value )
|
||||
{
|
||||
const Multi_pass_iters< Istream_type > mp_iters( is );
|
||||
|
||||
add_posn_iter_and_read_range_or_throw( mp_iters.begin_, mp_iters.end_, value );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,70 +0,0 @@
|
|||
#ifndef JSON_SPIRIT_READ_STREAM
|
||||
#define JSON_SPIRIT_READ_STREAM
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_reader_template.h"
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// these classes allows you to read multiple top level contiguous values from a stream,
|
||||
// the normal stream read functions have a bug that prevent multiple top level values
|
||||
// from being read unless they are separated by spaces
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
class Stream_reader
|
||||
{
|
||||
public:
|
||||
|
||||
Stream_reader( Istream_type& is )
|
||||
: iters_( is )
|
||||
{
|
||||
}
|
||||
|
||||
bool read_next( Value_type& value )
|
||||
{
|
||||
return read_range( iters_.begin_, iters_.end_, value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef Multi_pass_iters< Istream_type > Mp_iters;
|
||||
|
||||
Mp_iters iters_;
|
||||
};
|
||||
|
||||
template< class Istream_type, class Value_type >
|
||||
class Stream_reader_thrower
|
||||
{
|
||||
public:
|
||||
|
||||
Stream_reader_thrower( Istream_type& is )
|
||||
: iters_( is )
|
||||
, posn_begin_( iters_.begin_, iters_.end_ )
|
||||
, posn_end_( iters_.end_, iters_.end_ )
|
||||
{
|
||||
}
|
||||
|
||||
void read_next( Value_type& value )
|
||||
{
|
||||
posn_begin_ = read_range_or_throw( posn_begin_, posn_end_, value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
typedef Multi_pass_iters< Istream_type > Mp_iters;
|
||||
typedef spirit_namespace::position_iterator< typename Mp_iters::Mp_iter > Posn_iter_t;
|
||||
|
||||
Mp_iters iters_;
|
||||
Posn_iter_t posn_begin_, posn_end_;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,61 +0,0 @@
|
|||
#ifndef JSON_SPIRIT_UTILS
|
||||
#define JSON_SPIRIT_UTILS
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include <map>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
template< class Obj_t, class Map_t >
|
||||
void obj_to_map( const Obj_t& obj, Map_t& mp_obj )
|
||||
{
|
||||
mp_obj.clear();
|
||||
|
||||
for( typename Obj_t::const_iterator i = obj.begin(); i != obj.end(); ++i )
|
||||
{
|
||||
mp_obj[ i->name_ ] = i->value_;
|
||||
}
|
||||
}
|
||||
|
||||
template< class Obj_t, class Map_t >
|
||||
void map_to_obj( const Map_t& mp_obj, Obj_t& obj )
|
||||
{
|
||||
obj.clear();
|
||||
|
||||
for( typename Map_t::const_iterator i = mp_obj.begin(); i != mp_obj.end(); ++i )
|
||||
{
|
||||
obj.push_back( typename Obj_t::value_type( i->first, i->second ) );
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map< std::string, Value > Mapped_obj;
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
typedef std::map< std::wstring, wValue > wMapped_obj;
|
||||
#endif
|
||||
|
||||
template< class Object_type, class String_type >
|
||||
const typename Object_type::value_type::Value_type& find_value( const Object_type& obj, const String_type& name )
|
||||
{
|
||||
for( typename Object_type::const_iterator i = obj.begin(); i != obj.end(); ++i )
|
||||
{
|
||||
if( i->name_ == name )
|
||||
{
|
||||
return i->value_;
|
||||
}
|
||||
}
|
||||
|
||||
return Object_type::value_type::Value_type::null;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,8 +0,0 @@
|
|||
/* Copyright (c) 2007 John W Wilkinson
|
||||
|
||||
This source code can be used for any purpose as long as
|
||||
this comment is retained. */
|
||||
|
||||
// json spirit version 2.00
|
||||
|
||||
#include "json_spirit_value.h"
|
|
@ -1,534 +0,0 @@
|
|||
#ifndef JSON_SPIRIT_VALUE
|
||||
#define JSON_SPIRIT_VALUE
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include <stdint.h>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
|
||||
static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
|
||||
|
||||
template< class Config > // Config determines whether the value uses std::string or std::wstring and
|
||||
// whether JSON Objects are represented as vectors or maps
|
||||
class Value_impl
|
||||
{
|
||||
public:
|
||||
|
||||
typedef Config Config_type;
|
||||
typedef typename Config::String_type String_type;
|
||||
typedef typename Config::Object_type Object;
|
||||
typedef typename Config::Array_type Array;
|
||||
typedef typename String_type::const_pointer Const_str_ptr; // eg const char*
|
||||
|
||||
Value_impl(); // creates null value
|
||||
Value_impl( Const_str_ptr value );
|
||||
Value_impl( const String_type& value );
|
||||
Value_impl( const Object& value );
|
||||
Value_impl( const Array& value );
|
||||
Value_impl( bool value );
|
||||
Value_impl( int value );
|
||||
Value_impl( int64_t value );
|
||||
Value_impl( uint64_t value );
|
||||
Value_impl( double value );
|
||||
|
||||
Value_impl( const Value_impl& other );
|
||||
|
||||
bool operator==( const Value_impl& lhs ) const;
|
||||
|
||||
Value_impl& operator=( const Value_impl& lhs );
|
||||
|
||||
Value_type type() const;
|
||||
|
||||
bool is_uint64() const;
|
||||
bool is_null() const;
|
||||
|
||||
const String_type& get_str() const;
|
||||
const Object& get_obj() const;
|
||||
const Array& get_array() const;
|
||||
bool get_bool() const;
|
||||
int get_int() const;
|
||||
int64_t get_int64() const;
|
||||
uint64_t get_uint64() const;
|
||||
double get_real() const;
|
||||
|
||||
Object& get_obj();
|
||||
Array& get_array();
|
||||
|
||||
template< typename T > T get_value() const; // example usage: int i = value.get_value< int >();
|
||||
// or double d = value.get_value< double >();
|
||||
|
||||
static const Value_impl null;
|
||||
|
||||
private:
|
||||
|
||||
void check_type( const Value_type vtype ) const;
|
||||
|
||||
typedef boost::variant< String_type,
|
||||
boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >,
|
||||
bool, int64_t, double > Variant;
|
||||
|
||||
Value_type type_;
|
||||
Variant v_;
|
||||
bool is_uint64_;
|
||||
};
|
||||
|
||||
// vector objects
|
||||
|
||||
template< class Config >
|
||||
struct Pair_impl
|
||||
{
|
||||
typedef typename Config::String_type String_type;
|
||||
typedef typename Config::Value_type Value_type;
|
||||
|
||||
Pair_impl( const String_type& name, const Value_type& value );
|
||||
|
||||
bool operator==( const Pair_impl& lhs ) const;
|
||||
|
||||
String_type name_;
|
||||
Value_type value_;
|
||||
};
|
||||
|
||||
template< class String >
|
||||
struct Config_vector
|
||||
{
|
||||
typedef String String_type;
|
||||
typedef Value_impl< Config_vector > Value_type;
|
||||
typedef Pair_impl < Config_vector > Pair_type;
|
||||
typedef std::vector< Value_type > Array_type;
|
||||
typedef std::vector< Pair_type > Object_type;
|
||||
|
||||
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
|
||||
{
|
||||
obj.push_back( Pair_type( name , value ) );
|
||||
|
||||
return obj.back().value_;
|
||||
}
|
||||
|
||||
static String_type get_name( const Pair_type& pair )
|
||||
{
|
||||
return pair.name_;
|
||||
}
|
||||
|
||||
static Value_type get_value( const Pair_type& pair )
|
||||
{
|
||||
return pair.value_;
|
||||
}
|
||||
};
|
||||
|
||||
// typedefs for ASCII
|
||||
|
||||
typedef Config_vector< std::string > Config;
|
||||
|
||||
typedef Config::Value_type Value;
|
||||
typedef Config::Pair_type Pair;
|
||||
typedef Config::Object_type Object;
|
||||
typedef Config::Array_type Array;
|
||||
|
||||
// typedefs for Unicode
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
typedef Config_vector< std::wstring > wConfig;
|
||||
|
||||
typedef wConfig::Value_type wValue;
|
||||
typedef wConfig::Pair_type wPair;
|
||||
typedef wConfig::Object_type wObject;
|
||||
typedef wConfig::Array_type wArray;
|
||||
#endif
|
||||
|
||||
// map objects
|
||||
|
||||
template< class String >
|
||||
struct Config_map
|
||||
{
|
||||
typedef String String_type;
|
||||
typedef Value_impl< Config_map > Value_type;
|
||||
typedef std::vector< Value_type > Array_type;
|
||||
typedef std::map< String_type, Value_type > Object_type;
|
||||
typedef typename Object_type::value_type Pair_type;
|
||||
|
||||
static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
|
||||
{
|
||||
return obj[ name ] = value;
|
||||
}
|
||||
|
||||
static String_type get_name( const Pair_type& pair )
|
||||
{
|
||||
return pair.first;
|
||||
}
|
||||
|
||||
static Value_type get_value( const Pair_type& pair )
|
||||
{
|
||||
return pair.second;
|
||||
}
|
||||
};
|
||||
|
||||
// typedefs for ASCII
|
||||
|
||||
typedef Config_map< std::string > mConfig;
|
||||
|
||||
typedef mConfig::Value_type mValue;
|
||||
typedef mConfig::Object_type mObject;
|
||||
typedef mConfig::Array_type mArray;
|
||||
|
||||
// typedefs for Unicode
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
typedef Config_map< std::wstring > wmConfig;
|
||||
|
||||
typedef wmConfig::Value_type wmValue;
|
||||
typedef wmConfig::Object_type wmObject;
|
||||
typedef wmConfig::Array_type wmArray;
|
||||
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// implementation
|
||||
|
||||
template< class Config >
|
||||
const Value_impl< Config > Value_impl< Config >::null;
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl()
|
||||
: type_( null_type )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Const_str_ptr value )
|
||||
: type_( str_type )
|
||||
, v_( String_type( value ) )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const String_type& value )
|
||||
: type_( str_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Object& value )
|
||||
: type_( obj_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Array& value )
|
||||
: type_( array_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( bool value )
|
||||
: type_( bool_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( int value )
|
||||
: type_( int_type )
|
||||
, v_( static_cast< int64_t >( value ) )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( int64_t value )
|
||||
: type_( int_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( uint64_t value )
|
||||
: type_( int_type )
|
||||
, v_( static_cast< int64_t >( value ) )
|
||||
, is_uint64_( true )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( double value )
|
||||
: type_( real_type )
|
||||
, v_( value )
|
||||
, is_uint64_( false )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
|
||||
: type_( other.type() )
|
||||
, v_( other.v_ )
|
||||
, is_uint64_( other.is_uint64_ )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
|
||||
{
|
||||
Value_impl tmp( lhs );
|
||||
|
||||
std::swap( type_, tmp.type_ );
|
||||
std::swap( v_, tmp.v_ );
|
||||
std::swap( is_uint64_, tmp.is_uint64_ );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
if( type() != lhs.type() ) return false;
|
||||
|
||||
return v_ == lhs.v_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Value_type Value_impl< Config >::type() const
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::is_uint64() const
|
||||
{
|
||||
return is_uint64_;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::is_null() const
|
||||
{
|
||||
return type() == null_type;
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
void Value_impl< Config >::check_type( const Value_type vtype ) const
|
||||
{
|
||||
if( type() != vtype )
|
||||
{
|
||||
std::ostringstream os;
|
||||
|
||||
///// Bitcoin: Tell the types by name instead of by number
|
||||
os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
|
||||
|
||||
throw std::runtime_error( os.str() );
|
||||
}
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Config::String_type& Value_impl< Config >::get_str() const
|
||||
{
|
||||
check_type( str_type );
|
||||
|
||||
return *boost::get< String_type >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
|
||||
{
|
||||
check_type( obj_type );
|
||||
|
||||
return *boost::get< Object >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
|
||||
{
|
||||
check_type( array_type );
|
||||
|
||||
return *boost::get< Array >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Value_impl< Config >::get_bool() const
|
||||
{
|
||||
check_type( bool_type );
|
||||
|
||||
return boost::get< bool >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
int Value_impl< Config >::get_int() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return static_cast< int >( get_int64() );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
int64_t Value_impl< Config >::get_int64() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return boost::get< int64_t >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
uint64_t Value_impl< Config >::get_uint64() const
|
||||
{
|
||||
check_type( int_type );
|
||||
|
||||
return static_cast< uint64_t >( get_int64() );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
double Value_impl< Config >::get_real() const
|
||||
{
|
||||
if( type() == int_type )
|
||||
{
|
||||
return is_uint64() ? static_cast< double >( get_uint64() )
|
||||
: static_cast< double >( get_int64() );
|
||||
}
|
||||
|
||||
check_type( real_type );
|
||||
|
||||
return boost::get< double >( v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
|
||||
{
|
||||
check_type( obj_type );
|
||||
|
||||
return *boost::get< Object >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
|
||||
{
|
||||
check_type( array_type );
|
||||
|
||||
return *boost::get< Array >( &v_ );
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
|
||||
: name_( name )
|
||||
, value_( value )
|
||||
{
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
|
||||
{
|
||||
if( this == &lhs ) return true;
|
||||
|
||||
return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
|
||||
}
|
||||
|
||||
// converts a C string, ie. 8 bit char array, to a string object
|
||||
//
|
||||
template < class String_type >
|
||||
String_type to_str( const char* c_str )
|
||||
{
|
||||
String_type result;
|
||||
|
||||
for( const char* p = c_str; *p != 0; ++p )
|
||||
{
|
||||
result += *p;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
namespace internal_
|
||||
{
|
||||
template< typename T >
|
||||
struct Type_to_type
|
||||
{
|
||||
};
|
||||
|
||||
template< class Value >
|
||||
int get_value( const Value& value, Type_to_type< int > )
|
||||
{
|
||||
return value.get_int();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
int64_t get_value( const Value& value, Type_to_type< int64_t > )
|
||||
{
|
||||
return value.get_int64();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
uint64_t get_value( const Value& value, Type_to_type< uint64_t > )
|
||||
{
|
||||
return value.get_uint64();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
double get_value( const Value& value, Type_to_type< double > )
|
||||
{
|
||||
return value.get_real();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
|
||||
{
|
||||
return value.get_str();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
|
||||
{
|
||||
return value.get_array();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
|
||||
{
|
||||
return value.get_obj();
|
||||
}
|
||||
|
||||
template< class Value >
|
||||
bool get_value( const Value& value, Type_to_type< bool > )
|
||||
{
|
||||
return value.get_bool();
|
||||
}
|
||||
}
|
||||
|
||||
template< class Config >
|
||||
template< typename T >
|
||||
T Value_impl< Config >::get_value() const
|
||||
{
|
||||
return internal_::get_value( *this, internal_::Type_to_type< T >() );
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,95 +0,0 @@
|
|||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_writer.h"
|
||||
#include "json_spirit_writer_template.h"
|
||||
|
||||
void json_spirit::write( const Value& value, std::ostream& os )
|
||||
{
|
||||
write_stream( value, os, false );
|
||||
}
|
||||
|
||||
void json_spirit::write_formatted( const Value& value, std::ostream& os )
|
||||
{
|
||||
write_stream( value, os, true );
|
||||
}
|
||||
|
||||
std::string json_spirit::write( const Value& value )
|
||||
{
|
||||
return write_string( value, false );
|
||||
}
|
||||
|
||||
std::string json_spirit::write_formatted( const Value& value )
|
||||
{
|
||||
return write_string( value, true );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
void json_spirit::write( const wValue& value, std::wostream& os )
|
||||
{
|
||||
write_stream( value, os, false );
|
||||
}
|
||||
|
||||
void json_spirit::write_formatted( const wValue& value, std::wostream& os )
|
||||
{
|
||||
write_stream( value, os, true );
|
||||
}
|
||||
|
||||
std::wstring json_spirit::write( const wValue& value )
|
||||
{
|
||||
return write_string( value, false );
|
||||
}
|
||||
|
||||
std::wstring json_spirit::write_formatted( const wValue& value )
|
||||
{
|
||||
return write_string( value, true );
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void json_spirit::write( const mValue& value, std::ostream& os )
|
||||
{
|
||||
write_stream( value, os, false );
|
||||
}
|
||||
|
||||
void json_spirit::write_formatted( const mValue& value, std::ostream& os )
|
||||
{
|
||||
write_stream( value, os, true );
|
||||
}
|
||||
|
||||
std::string json_spirit::write( const mValue& value )
|
||||
{
|
||||
return write_string( value, false );
|
||||
}
|
||||
|
||||
std::string json_spirit::write_formatted( const mValue& value )
|
||||
{
|
||||
return write_string( value, true );
|
||||
}
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
void json_spirit::write( const wmValue& value, std::wostream& os )
|
||||
{
|
||||
write_stream( value, os, false );
|
||||
}
|
||||
|
||||
void json_spirit::write_formatted( const wmValue& value, std::wostream& os )
|
||||
{
|
||||
write_stream( value, os, true );
|
||||
}
|
||||
|
||||
std::wstring json_spirit::write( const wmValue& value )
|
||||
{
|
||||
return write_string( value, false );
|
||||
}
|
||||
|
||||
std::wstring json_spirit::write_formatted( const wmValue& value )
|
||||
{
|
||||
return write_string( value, true );
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,50 +0,0 @@
|
|||
#ifndef JSON_SPIRIT_WRITER
|
||||
#define JSON_SPIRIT_WRITER
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
# pragma once
|
||||
#endif
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
// functions to convert JSON Values to text,
|
||||
// the "formatted" versions add whitespace to format the output nicely
|
||||
|
||||
void write ( const Value& value, std::ostream& os );
|
||||
void write_formatted( const Value& value, std::ostream& os );
|
||||
std::string write ( const Value& value );
|
||||
std::string write_formatted( const Value& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
void write ( const wValue& value, std::wostream& os );
|
||||
void write_formatted( const wValue& value, std::wostream& os );
|
||||
std::wstring write ( const wValue& value );
|
||||
std::wstring write_formatted( const wValue& value );
|
||||
|
||||
#endif
|
||||
|
||||
void write ( const mValue& value, std::ostream& os );
|
||||
void write_formatted( const mValue& value, std::ostream& os );
|
||||
std::string write ( const mValue& value );
|
||||
std::string write_formatted( const mValue& value );
|
||||
|
||||
#ifndef BOOST_NO_STD_WSTRING
|
||||
|
||||
void write ( const wmValue& value, std::wostream& os );
|
||||
void write_formatted( const wmValue& value, std::wostream& os );
|
||||
std::wstring write ( const wmValue& value );
|
||||
std::wstring write_formatted( const wmValue& value );
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,249 +0,0 @@
|
|||
#ifndef JSON_SPIRIT_WRITER_TEMPLATE
|
||||
#define JSON_SPIRIT_WRITER_TEMPLATE
|
||||
|
||||
// Copyright John W. Wilkinson 2007 - 2009.
|
||||
// Distributed under the MIT License, see accompanying file LICENSE.txt
|
||||
|
||||
// json spirit version 4.03
|
||||
|
||||
#include "json_spirit_value.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
namespace json_spirit
|
||||
{
|
||||
inline char to_hex_char( unsigned int c )
|
||||
{
|
||||
assert( c <= 0xF );
|
||||
|
||||
const char ch = static_cast< char >( c );
|
||||
|
||||
if( ch < 10 ) return '0' + ch;
|
||||
|
||||
return 'A' - 10 + ch;
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type non_printable_to_string( unsigned int c )
|
||||
{
|
||||
// Silence the warning: typedef ‘Char_type’ locally defined but not used [-Wunused-local-typedefs]
|
||||
// typedef typename String_type::value_type Char_type;
|
||||
|
||||
String_type result( 6, '\\' );
|
||||
|
||||
result[1] = 'u';
|
||||
|
||||
result[ 5 ] = to_hex_char( c & 0x000F ); c >>= 4;
|
||||
result[ 4 ] = to_hex_char( c & 0x000F ); c >>= 4;
|
||||
result[ 3 ] = to_hex_char( c & 0x000F ); c >>= 4;
|
||||
result[ 2 ] = to_hex_char( c & 0x000F );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template< typename Char_type, class String_type >
|
||||
bool add_esc_char( Char_type c, String_type& s )
|
||||
{
|
||||
switch( c )
|
||||
{
|
||||
case '"': s += to_str< String_type >( "\\\"" ); return true;
|
||||
case '\\': s += to_str< String_type >( "\\\\" ); return true;
|
||||
case '\b': s += to_str< String_type >( "\\b" ); return true;
|
||||
case '\f': s += to_str< String_type >( "\\f" ); return true;
|
||||
case '\n': s += to_str< String_type >( "\\n" ); return true;
|
||||
case '\r': s += to_str< String_type >( "\\r" ); return true;
|
||||
case '\t': s += to_str< String_type >( "\\t" ); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
template< class String_type >
|
||||
String_type add_esc_chars( const String_type& s )
|
||||
{
|
||||
typedef typename String_type::const_iterator Iter_type;
|
||||
typedef typename String_type::value_type Char_type;
|
||||
|
||||
String_type result;
|
||||
|
||||
const Iter_type end( s.end() );
|
||||
|
||||
for( Iter_type i = s.begin(); i != end; ++i )
|
||||
{
|
||||
const Char_type c( *i );
|
||||
|
||||
if( add_esc_char( c, result ) ) continue;
|
||||
|
||||
const wint_t unsigned_c( ( c >= 0 ) ? c : 256 + c );
|
||||
|
||||
if( iswprint( unsigned_c ) )
|
||||
{
|
||||
result += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += non_printable_to_string< String_type >( unsigned_c );
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// this class generates the JSON text,
|
||||
// it keeps track of the indentation level etc.
|
||||
//
|
||||
template< class Value_type, class Ostream_type >
|
||||
class Generator
|
||||
{
|
||||
typedef typename Value_type::Config_type Config_type;
|
||||
typedef typename Config_type::String_type String_type;
|
||||
typedef typename Config_type::Object_type Object_type;
|
||||
typedef typename Config_type::Array_type Array_type;
|
||||
typedef typename String_type::value_type Char_type;
|
||||
typedef typename Object_type::value_type Obj_member_type;
|
||||
|
||||
public:
|
||||
|
||||
Generator( const Value_type& value, Ostream_type& os, bool pretty )
|
||||
: os_( os )
|
||||
, indentation_level_( 0 )
|
||||
, pretty_( pretty )
|
||||
{
|
||||
output( value );
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void output( const Value_type& value )
|
||||
{
|
||||
switch( value.type() )
|
||||
{
|
||||
case obj_type: output( value.get_obj() ); break;
|
||||
case array_type: output( value.get_array() ); break;
|
||||
case str_type: output( value.get_str() ); break;
|
||||
case bool_type: output( value.get_bool() ); break;
|
||||
case int_type: output_int( value ); break;
|
||||
|
||||
/// Bitcoin: Added std::fixed and changed precision from 16 to 8
|
||||
case real_type: os_ << std::showpoint << std::fixed << std::setprecision(8)
|
||||
<< value.get_real(); break;
|
||||
|
||||
case null_type: os_ << "null"; break;
|
||||
default: assert( false );
|
||||
}
|
||||
}
|
||||
|
||||
void output( const Object_type& obj )
|
||||
{
|
||||
output_array_or_obj( obj, '{', '}' );
|
||||
}
|
||||
|
||||
void output( const Array_type& arr )
|
||||
{
|
||||
output_array_or_obj( arr, '[', ']' );
|
||||
}
|
||||
|
||||
void output( const Obj_member_type& member )
|
||||
{
|
||||
output( Config_type::get_name( member ) ); space();
|
||||
os_ << ':'; space();
|
||||
output( Config_type::get_value( member ) );
|
||||
}
|
||||
|
||||
void output_int( const Value_type& value )
|
||||
{
|
||||
if( value.is_uint64() )
|
||||
{
|
||||
os_ << value.get_uint64();
|
||||
}
|
||||
else
|
||||
{
|
||||
os_ << value.get_int64();
|
||||
}
|
||||
}
|
||||
|
||||
void output( const String_type& s )
|
||||
{
|
||||
os_ << '"' << add_esc_chars( s ) << '"';
|
||||
}
|
||||
|
||||
void output( bool b )
|
||||
{
|
||||
os_ << to_str< String_type >( b ? "true" : "false" );
|
||||
}
|
||||
|
||||
template< class T >
|
||||
void output_array_or_obj( const T& t, Char_type start_char, Char_type end_char )
|
||||
{
|
||||
os_ << start_char; new_line();
|
||||
|
||||
++indentation_level_;
|
||||
|
||||
for( typename T::const_iterator i = t.begin(); i != t.end(); ++i )
|
||||
{
|
||||
indent(); output( *i );
|
||||
|
||||
typename T::const_iterator next = i;
|
||||
|
||||
if( ++next != t.end())
|
||||
{
|
||||
os_ << ',';
|
||||
}
|
||||
|
||||
new_line();
|
||||
}
|
||||
|
||||
--indentation_level_;
|
||||
|
||||
indent(); os_ << end_char;
|
||||
}
|
||||
|
||||
void indent()
|
||||
{
|
||||
if( !pretty_ ) return;
|
||||
|
||||
for( int i = 0; i < indentation_level_; ++i )
|
||||
{
|
||||
os_ << " ";
|
||||
}
|
||||
}
|
||||
|
||||
void space()
|
||||
{
|
||||
if( pretty_ ) os_ << ' ';
|
||||
}
|
||||
|
||||
void new_line()
|
||||
{
|
||||
if( pretty_ ) os_ << '\n';
|
||||
}
|
||||
|
||||
Generator& operator=( const Generator& ); // to prevent "assignment operator could not be generated" warning
|
||||
|
||||
Ostream_type& os_;
|
||||
int indentation_level_;
|
||||
bool pretty_;
|
||||
};
|
||||
|
||||
template< class Value_type, class Ostream_type >
|
||||
void write_stream( const Value_type& value, Ostream_type& os, bool pretty )
|
||||
{
|
||||
Generator< Value_type, Ostream_type >( value, os, pretty );
|
||||
}
|
||||
|
||||
template< class Value_type >
|
||||
typename Value_type::String_type write_string( const Value_type& value, bool pretty )
|
||||
{
|
||||
typedef typename Value_type::String_type::value_type Char_type;
|
||||
|
||||
std::basic_ostringstream< Char_type > os;
|
||||
|
||||
write_stream( value, os, pretty );
|
||||
|
||||
return os.str();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -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,21 @@ 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);
|
||||
|
||||
Q_EMIT reply(RPCConsole::CMD_REPLY, QString::fromStdString(strPrint));
|
||||
}
|
||||
catch (const json_spirit::Object& objError)
|
||||
catch (UniValue& objError)
|
||||
{
|
||||
try // Nice formatting for standard-format error
|
||||
{
|
||||
|
@ -191,7 +191,7 @@ void RPCExecutor::request(const QString &command)
|
|||
}
|
||||
catch (const std::runtime_error&) // raised when converting to invalid type, i.e. missing code or message
|
||||
{ // Show raw JSON object
|
||||
Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false)));
|
||||
Q_EMIT reply(RPCConsole::CMD_ERROR, QString::fromStdString(objError.write()));
|
||||
}
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
|
34
src/rest.cpp
34
src/rest.cpp
|
@ -16,8 +16,9 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
static const int MAX_GETUTXOS_OUTPOINTS = 15; //allow a max of 15 outpoints to be queried at once
|
||||
|
||||
|
@ -61,9 +62,9 @@ public:
|
|||
string message;
|
||||
};
|
||||
|
||||
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
|
||||
extern Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
|
||||
extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
|
||||
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
|
||||
extern UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false);
|
||||
extern void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
|
||||
|
||||
static RestErr RESTERR(enum HTTPStatusCode status, string message)
|
||||
{
|
||||
|
@ -221,8 +222,8 @@ static bool rest_block(AcceptedConnection* conn,
|
|||
}
|
||||
|
||||
case RF_JSON: {
|
||||
Object objBlock = blockToJSON(block, pblockindex, showTxDetails);
|
||||
string strJSON = write_string(Value(objBlock), false) + "\n";
|
||||
UniValue objBlock = blockToJSON(block, pblockindex, showTxDetails);
|
||||
string strJSON = objBlock.write() + "\n";
|
||||
conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
|
||||
return true;
|
||||
}
|
||||
|
@ -265,10 +266,9 @@ static bool rest_chaininfo(AcceptedConnection* conn,
|
|||
|
||||
switch (rf) {
|
||||
case RF_JSON: {
|
||||
Array rpcParams;
|
||||
Value chainInfoObject = getblockchaininfo(rpcParams, false);
|
||||
|
||||
string strJSON = write_string(chainInfoObject, false) + "\n";
|
||||
UniValue rpcParams(UniValue::VARR);
|
||||
UniValue chainInfoObject = getblockchaininfo(rpcParams, false);
|
||||
string strJSON = chainInfoObject.write() + "\n";
|
||||
conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
|
||||
return true;
|
||||
}
|
||||
|
@ -317,9 +317,9 @@ static bool rest_tx(AcceptedConnection* conn,
|
|||
}
|
||||
|
||||
case RF_JSON: {
|
||||
Object objTx;
|
||||
UniValue objTx(UniValue::VOBJ);
|
||||
TxToJSON(tx, hashBlock, objTx);
|
||||
string strJSON = write_string(Value(objTx), false) + "\n";
|
||||
string strJSON = objTx.write() + "\n";
|
||||
conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
|
||||
return true;
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ static bool rest_getutxos(AcceptedConnection* conn,
|
|||
}
|
||||
|
||||
case RF_JSON: {
|
||||
Object objGetUTXOResponse;
|
||||
UniValue objGetUTXOResponse(UniValue::VOBJ);
|
||||
|
||||
// pack in some essentials
|
||||
// use more or less the same output as mentioned in Bip64
|
||||
|
@ -500,15 +500,15 @@ static bool rest_getutxos(AcceptedConnection* conn,
|
|||
objGetUTXOResponse.push_back(Pair("chaintipHash", chainActive.Tip()->GetBlockHash().GetHex()));
|
||||
objGetUTXOResponse.push_back(Pair("bitmap", bitmapStringRepresentation));
|
||||
|
||||
Array utxos;
|
||||
UniValue utxos(UniValue::VARR);
|
||||
BOOST_FOREACH (const CCoin& coin, outs) {
|
||||
Object utxo;
|
||||
UniValue utxo(UniValue::VOBJ);
|
||||
utxo.push_back(Pair("txvers", (int32_t)coin.nTxVer));
|
||||
utxo.push_back(Pair("height", (int32_t)coin.nHeight));
|
||||
utxo.push_back(Pair("value", ValueFromAmount(coin.out.nValue)));
|
||||
|
||||
// include the script in a json output
|
||||
Object o;
|
||||
UniValue o(UniValue::VOBJ);
|
||||
ScriptPubKeyToJSON(coin.out.scriptPubKey, o, true);
|
||||
utxo.push_back(Pair("scriptPubKey", o));
|
||||
utxos.push_back(utxo);
|
||||
|
@ -516,7 +516,7 @@ static bool rest_getutxos(AcceptedConnection* conn,
|
|||
objGetUTXOResponse.push_back(Pair("utxos", utxos));
|
||||
|
||||
// return json string
|
||||
string strJSON = write_string(Value(objGetUTXOResponse), false) + "\n";
|
||||
string strJSON = objGetUTXOResponse.write() + "\n";
|
||||
conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -13,13 +13,12 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "json/json_spirit_value.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
using namespace std;
|
||||
|
||||
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry);
|
||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex);
|
||||
extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry);
|
||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex);
|
||||
|
||||
double GetDifficultyINTERNAL(const CBlockIndex* blockindex, bool networkDifficulty)
|
||||
{
|
||||
|
@ -74,9 +73,9 @@ double GetNetworkDifficulty(const CBlockIndex* blockindex)
|
|||
}
|
||||
|
||||
|
||||
Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
|
||||
UniValue blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDetails = false)
|
||||
{
|
||||
Object result;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("hash", block.GetHash().GetHex()));
|
||||
int confirmations = -1;
|
||||
// Only report confirmations if the block is on the main chain
|
||||
|
@ -87,12 +86,12 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe
|
|||
result.push_back(Pair("height", blockindex->nHeight));
|
||||
result.push_back(Pair("version", block.nVersion));
|
||||
result.push_back(Pair("merkleroot", block.hashMerkleRoot.GetHex()));
|
||||
Array txs;
|
||||
UniValue txs(UniValue::VARR);
|
||||
BOOST_FOREACH(const CTransaction&tx, block.vtx)
|
||||
{
|
||||
if(txDetails)
|
||||
{
|
||||
Object objTx;
|
||||
UniValue objTx(UniValue::VOBJ);
|
||||
TxToJSON(tx, uint256(), objTx);
|
||||
txs.push_back(objTx);
|
||||
}
|
||||
|
@ -116,7 +115,7 @@ Object blockToJSON(const CBlock& block, const CBlockIndex* blockindex, bool txDe
|
|||
}
|
||||
|
||||
|
||||
Value getblockcount(const Array& params, bool fHelp)
|
||||
UniValue getblockcount(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -133,7 +132,7 @@ Value getblockcount(const Array& params, bool fHelp)
|
|||
return chainActive.Height();
|
||||
}
|
||||
|
||||
Value getbestblockhash(const Array& params, bool fHelp)
|
||||
UniValue getbestblockhash(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -150,7 +149,7 @@ Value getbestblockhash(const Array& params, bool fHelp)
|
|||
return chainActive.Tip()->GetBlockHash().GetHex();
|
||||
}
|
||||
|
||||
Value getdifficulty(const Array& params, bool fHelp)
|
||||
UniValue getdifficulty(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -168,7 +167,7 @@ Value getdifficulty(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
|
||||
Value getrawmempool(const Array& params, bool fHelp)
|
||||
UniValue getrawmempool(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 1)
|
||||
throw runtime_error(
|
||||
|
@ -209,12 +208,12 @@ Value getrawmempool(const Array& params, bool fHelp)
|
|||
if (fVerbose)
|
||||
{
|
||||
LOCK(mempool.cs);
|
||||
Object o;
|
||||
UniValue o(UniValue::VOBJ);
|
||||
BOOST_FOREACH(const PAIRTYPE(uint256, CTxMemPoolEntry)& entry, mempool.mapTx)
|
||||
{
|
||||
const uint256& hash = entry.first;
|
||||
const CTxMemPoolEntry& e = entry.second;
|
||||
Object info;
|
||||
UniValue info(UniValue::VOBJ);
|
||||
info.push_back(Pair("size", (int)e.GetTxSize()));
|
||||
info.push_back(Pair("fee", ValueFromAmount(e.GetFee())));
|
||||
info.push_back(Pair("time", e.GetTime()));
|
||||
|
@ -228,7 +227,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(UniValue::VARR);
|
||||
BOOST_FOREACH(const string& dep, setDepends)
|
||||
{
|
||||
depends.push_back(dep);
|
||||
}
|
||||
|
||||
info.push_back(Pair("depends", depends));
|
||||
o.push_back(Pair(hash.ToString(), info));
|
||||
}
|
||||
|
@ -239,7 +244,7 @@ Value getrawmempool(const Array& params, bool fHelp)
|
|||
vector<uint256> vtxid;
|
||||
mempool.queryHashes(vtxid);
|
||||
|
||||
Array a;
|
||||
UniValue a(UniValue::VARR);
|
||||
BOOST_FOREACH(const uint256& hash, vtxid)
|
||||
a.push_back(hash.ToString());
|
||||
|
||||
|
@ -247,7 +252,7 @@ Value getrawmempool(const Array& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
Value getblockhash(const Array& params, bool fHelp)
|
||||
UniValue getblockhash(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -272,7 +277,7 @@ Value getblockhash(const Array& params, bool fHelp)
|
|||
return pblockindex->GetBlockHash().GetHex();
|
||||
}
|
||||
|
||||
Value getblock(const Array& params, bool fHelp)
|
||||
UniValue getblock(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -340,7 +345,7 @@ Value getblock(const Array& params, bool fHelp)
|
|||
return blockToJSON(block, pblockindex);
|
||||
}
|
||||
|
||||
Value gettxoutsetinfo(const Array& params, bool fHelp)
|
||||
UniValue gettxoutsetinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -364,7 +369,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp)
|
|||
|
||||
LOCK(cs_main);
|
||||
|
||||
Object ret;
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
CCoinsStats stats;
|
||||
FlushStateToDisk();
|
||||
|
@ -380,7 +385,7 @@ Value gettxoutsetinfo(const Array& params, bool fHelp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
Value gettxout(const Array& params, bool fHelp)
|
||||
UniValue gettxout(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 2 || params.size() > 3)
|
||||
throw runtime_error(
|
||||
|
@ -420,7 +425,7 @@ Value gettxout(const Array& params, bool fHelp)
|
|||
|
||||
LOCK(cs_main);
|
||||
|
||||
Object ret;
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
|
||||
std::string strHash = params[0].get_str();
|
||||
uint256 hash(uint256S(strHash));
|
||||
|
@ -434,14 +439,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;
|
||||
|
@ -451,7 +456,7 @@ Value gettxout(const Array& params, bool fHelp)
|
|||
else
|
||||
ret.push_back(Pair("confirmations", pindex->nHeight - coins.nHeight + 1));
|
||||
ret.push_back(Pair("value", ValueFromAmount(coins.vout[n].nValue)));
|
||||
Object o;
|
||||
UniValue o(UniValue::VOBJ);
|
||||
ScriptPubKeyToJSON(coins.vout[n].scriptPubKey, o, true);
|
||||
ret.push_back(Pair("scriptPubKey", o));
|
||||
ret.push_back(Pair("version", coins.nVersion));
|
||||
|
@ -460,7 +465,7 @@ Value gettxout(const Array& params, bool fHelp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
Value verifychain(const Array& params, bool fHelp)
|
||||
UniValue verifychain(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -489,7 +494,7 @@ Value verifychain(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
/** Implementation of IsSuperMajority with better feedback */
|
||||
Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
|
||||
static UniValue SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired, const Consensus::Params& consensusParams)
|
||||
{
|
||||
int nFound = 0;
|
||||
CBlockIndex* pstart = pindex;
|
||||
|
@ -500,7 +505,7 @@ Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired,
|
|||
pstart = pstart->pprev;
|
||||
}
|
||||
|
||||
Object rv;
|
||||
UniValue rv(UniValue::VOBJ);
|
||||
rv.push_back(Pair("status", nFound >= nRequired));
|
||||
rv.push_back(Pair("found", nFound));
|
||||
rv.push_back(Pair("required", nRequired));
|
||||
|
@ -508,9 +513,9 @@ Object SoftForkMajorityDesc(int minVersion, CBlockIndex* pindex, int nRequired,
|
|||
return rv;
|
||||
}
|
||||
|
||||
Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
|
||||
static UniValue SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, const Consensus::Params& consensusParams)
|
||||
{
|
||||
Object rv;
|
||||
UniValue rv(UniValue::VOBJ);
|
||||
rv.push_back(Pair("id", name));
|
||||
rv.push_back(Pair("version", version));
|
||||
rv.push_back(Pair("enforce", SoftForkMajorityDesc(version, pindex, consensusParams.nMajorityEnforceBlockUpgrade, consensusParams)));
|
||||
|
@ -518,7 +523,7 @@ Object SoftForkDesc(const std::string &name, int version, CBlockIndex* pindex, c
|
|||
return rv;
|
||||
}
|
||||
|
||||
Value getblockchaininfo(const Array& params, bool fHelp)
|
||||
UniValue getblockchaininfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -555,7 +560,7 @@ Value getblockchaininfo(const Array& params, bool fHelp)
|
|||
|
||||
LOCK(cs_main);
|
||||
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("chain", Params().NetworkIDString()));
|
||||
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
||||
obj.push_back(Pair("headers", pindexBestHeader ? pindexBestHeader->nHeight : -1));
|
||||
|
@ -571,7 +576,7 @@ Value getblockchaininfo(const Array& params, bool fHelp)
|
|||
|
||||
const Consensus::Params& consensusParams = Params().GetConsensus();
|
||||
CBlockIndex* tip = chainActive.Tip();
|
||||
Array softforks;
|
||||
UniValue softforks(UniValue::VARR);
|
||||
softforks.push_back(SoftForkDesc("bip34", 2, tip, consensusParams));
|
||||
softforks.push_back(SoftForkDesc("bip66", 3, tip, consensusParams));
|
||||
softforks.push_back(SoftForkDesc("bip65", 4, tip, consensusParams));
|
||||
|
@ -603,7 +608,7 @@ struct CompareBlocksByHeight
|
|||
}
|
||||
};
|
||||
|
||||
Value getchaintips(const Array& params, bool fHelp)
|
||||
UniValue getchaintips(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -655,10 +660,10 @@ Value getchaintips(const Array& params, bool fHelp)
|
|||
setTips.insert(chainActive.Tip());
|
||||
|
||||
/* Construct the output array. */
|
||||
Array res;
|
||||
UniValue res(UniValue::VARR);
|
||||
BOOST_FOREACH(const CBlockIndex* block, setTips)
|
||||
{
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("height", block->nHeight));
|
||||
obj.push_back(Pair("hash", block->phashBlock->GetHex()));
|
||||
|
||||
|
@ -693,7 +698,7 @@ Value getchaintips(const Array& params, bool fHelp)
|
|||
return res;
|
||||
}
|
||||
|
||||
Value getmempoolinfo(const Array& params, bool fHelp)
|
||||
UniValue getmempoolinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -709,14 +714,14 @@ Value getmempoolinfo(const Array& params, bool fHelp)
|
|||
+ HelpExampleRpc("getmempoolinfo", "")
|
||||
);
|
||||
|
||||
Object ret;
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.push_back(Pair("size", (int64_t) mempool.size()));
|
||||
ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize()));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Value invalidateblock(const Array& params, bool fHelp)
|
||||
UniValue invalidateblock(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -751,10 +756,10 @@ Value invalidateblock(const Array& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
|
||||
}
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
Value reconsiderblock(const Array& params, bool fHelp)
|
||||
UniValue reconsiderblock(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -790,5 +795,5 @@ Value reconsiderblock(const Array& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_DATABASE_ERROR, state.GetRejectReason());
|
||||
}
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,9 @@
|
|||
#include <set>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
class CRPCConvertParam
|
||||
{
|
||||
|
@ -135,25 +136,32 @@ CRPCConvertTable::CRPCConvertTable()
|
|||
|
||||
static CRPCConvertTable rpcCvtTable;
|
||||
|
||||
/** Convert strings to command-specific RPC representation */
|
||||
Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
|
||||
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
|
||||
* as well as objects and arrays.
|
||||
*/
|
||||
UniValue ParseNonRFCJSONValue(const std::string& strVal)
|
||||
{
|
||||
Array params;
|
||||
UniValue jVal;
|
||||
if (!jVal.read(std::string("[")+strVal+std::string("]")) ||
|
||||
!jVal.isArray() || jVal.size()!=1)
|
||||
throw runtime_error(string("Error parsing JSON:")+strVal);
|
||||
return jVal[0];
|
||||
}
|
||||
|
||||
/** Convert strings to command-specific RPC representation */
|
||||
UniValue RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
|
||||
{
|
||||
UniValue params(UniValue::VARR);
|
||||
|
||||
for (unsigned int idx = 0; idx < strParams.size(); idx++) {
|
||||
const std::string& strVal = strParams[idx];
|
||||
|
||||
// insert string value directly
|
||||
if (!rpcCvtTable.convert(strMethod, idx)) {
|
||||
// insert string value directly
|
||||
params.push_back(strVal);
|
||||
}
|
||||
|
||||
// parse string as JSON, insert bool/number/object/etc. value
|
||||
else {
|
||||
Value jVal;
|
||||
if (!read_string(strVal, jVal))
|
||||
throw runtime_error(string("Error parsing JSON:")+strVal);
|
||||
params.push_back(jVal);
|
||||
} else {
|
||||
// parse string as JSON, insert bool/number/object/etc. value
|
||||
params.push_back(ParseNonRFCJSONValue(strVal));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,12 @@
|
|||
#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 "univalue/univalue.h"
|
||||
|
||||
json_spirit::Array RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams);
|
||||
UniValue RPCConvertValues(const std::string& strMethod, const std::vector<std::string>& strParams);
|
||||
/** Non-RFC4627 JSON parser, accepts internal values (such as numbers, true, false, null)
|
||||
* as well as objects and arrays.
|
||||
*/
|
||||
UniValue ParseNonRFCJSONValue(const std::string& strVal);
|
||||
|
||||
#endif // BITCOIN_RPCCLIENT_H
|
||||
|
|
|
@ -28,10 +28,8 @@
|
|||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
|
||||
#include "json/json_spirit_utils.h"
|
||||
#include "json/json_spirit_value.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
|
@ -76,7 +74,7 @@ int64_t GetNetworkHashPS(int lookup, int height) {
|
|||
return (int64_t)(workDiff.getdouble() / timeDiff);
|
||||
}
|
||||
|
||||
Value getlocalsolps(const Array& params, bool fHelp)
|
||||
UniValue getlocalsolps(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp)
|
||||
throw runtime_error(
|
||||
|
@ -94,7 +92,7 @@ Value getlocalsolps(const Array& params, bool fHelp)
|
|||
return GetLocalSolPS();
|
||||
}
|
||||
|
||||
Value getnetworksolps(const Array& params, bool fHelp)
|
||||
UniValue getnetworksolps(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -116,7 +114,7 @@ Value getnetworksolps(const Array& params, bool fHelp)
|
|||
return GetNetworkHashPS(params.size() > 0 ? params[0].get_int() : 120, params.size() > 1 ? params[1].get_int() : -1);
|
||||
}
|
||||
|
||||
Value getnetworkhashps(const Array& params, bool fHelp)
|
||||
UniValue getnetworkhashps(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -140,7 +138,7 @@ Value getnetworkhashps(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
#ifdef ENABLE_MINING
|
||||
Value getgenerate(const Array& params, bool fHelp)
|
||||
UniValue getgenerate(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -159,7 +157,7 @@ Value getgenerate(const Array& params, bool fHelp)
|
|||
return GetBoolArg("-gen", false);
|
||||
}
|
||||
|
||||
Value generate(const Array& params, bool fHelp)
|
||||
UniValue generate(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 1)
|
||||
throw runtime_error(
|
||||
|
@ -202,7 +200,7 @@ Value generate(const Array& params, bool fHelp)
|
|||
nHeightEnd = nHeightStart+nGenerate;
|
||||
}
|
||||
unsigned int nExtraNonce = 0;
|
||||
Array blockHashes;
|
||||
UniValue blockHashes(UniValue::VARR);
|
||||
unsigned int n = Params().EquihashN();
|
||||
unsigned int k = Params().EquihashK();
|
||||
while (nHeight < nHeightEnd)
|
||||
|
@ -268,7 +266,7 @@ endloop:
|
|||
}
|
||||
|
||||
|
||||
Value setgenerate(const Array& params, bool fHelp)
|
||||
UniValue setgenerate(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -322,12 +320,12 @@ Value setgenerate(const Array& params, bool fHelp)
|
|||
GenerateBitcoins(fGenerate, nGenProcLimit);
|
||||
#endif
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Value getmininginfo(const Array& params, bool fHelp)
|
||||
UniValue getmininginfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -356,7 +354,7 @@ Value getmininginfo(const Array& params, bool fHelp)
|
|||
|
||||
LOCK(cs_main);
|
||||
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("blocks", (int)chainActive.Height()));
|
||||
obj.push_back(Pair("currentblocksize", (uint64_t)nLastBlockSize));
|
||||
obj.push_back(Pair("currentblocktx", (uint64_t)nLastBlockTx));
|
||||
|
@ -377,7 +375,7 @@ Value getmininginfo(const Array& params, bool fHelp)
|
|||
|
||||
|
||||
// NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts
|
||||
Value prioritisetransaction(const Array& params, bool fHelp)
|
||||
UniValue prioritisetransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 3)
|
||||
throw runtime_error(
|
||||
|
@ -409,10 +407,10 @@ Value prioritisetransaction(const Array& params, bool fHelp)
|
|||
|
||||
|
||||
// NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller
|
||||
static Value BIP22ValidationResult(const CValidationState& state)
|
||||
static UniValue BIP22ValidationResult(const CValidationState& state)
|
||||
{
|
||||
if (state.IsValid())
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
std::string strRejectReason = state.GetRejectReason();
|
||||
if (state.IsError())
|
||||
|
@ -427,7 +425,7 @@ static Value BIP22ValidationResult(const CValidationState& state)
|
|||
return "valid?";
|
||||
}
|
||||
|
||||
Value getblocktemplate(const Array& params, bool fHelp)
|
||||
UniValue getblocktemplate(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 1)
|
||||
throw runtime_error(
|
||||
|
@ -503,16 +501,16 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
std::string strMode = "template";
|
||||
Value lpval = Value::null;
|
||||
UniValue lpval = NullUniValue;
|
||||
// TODO: Re-enable coinbasevalue once a specification has been written
|
||||
bool coinbasetxn = true;
|
||||
if (params.size() > 0)
|
||||
{
|
||||
const Object& oparam = params[0].get_obj();
|
||||
const Value& modeval = find_value(oparam, "mode");
|
||||
if (modeval.type() == str_type)
|
||||
const UniValue& oparam = params[0].get_obj();
|
||||
const UniValue& modeval = find_value(oparam, "mode");
|
||||
if (modeval.isStr())
|
||||
strMode = modeval.get_str();
|
||||
else if (modeval.type() == null_type)
|
||||
else if (modeval.isNull())
|
||||
{
|
||||
/* Do nothing */
|
||||
}
|
||||
|
@ -522,8 +520,8 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
|||
|
||||
if (strMode == "proposal")
|
||||
{
|
||||
const Value& dataval = find_value(oparam, "data");
|
||||
if (dataval.type() != str_type)
|
||||
const UniValue& dataval = find_value(oparam, "data");
|
||||
if (!dataval.isStr())
|
||||
throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal");
|
||||
|
||||
CBlock block;
|
||||
|
@ -562,14 +560,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();
|
||||
|
@ -647,10 +645,10 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
|||
UpdateTime(pblock, Params().GetConsensus(), pindexPrev);
|
||||
pblock->nNonce = uint256();
|
||||
|
||||
static const Array aCaps = boost::assign::list_of("proposal");
|
||||
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
|
||||
|
||||
Value txCoinbase = Value::null;
|
||||
Array transactions;
|
||||
UniValue txCoinbase = NullUniValue;
|
||||
UniValue transactions(UniValue::VARR);
|
||||
map<uint256, int64_t> setTxIndex;
|
||||
int i = 0;
|
||||
BOOST_FOREACH (CTransaction& tx, pblock->vtx)
|
||||
|
@ -661,13 +659,13 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
|||
if (tx.IsCoinBase() && !coinbasetxn)
|
||||
continue;
|
||||
|
||||
Object entry;
|
||||
UniValue entry(UniValue::VOBJ);
|
||||
|
||||
entry.push_back(Pair("data", EncodeHexTx(tx)));
|
||||
|
||||
entry.push_back(Pair("hash", txHash.GetHex()));
|
||||
|
||||
Array deps;
|
||||
UniValue deps(UniValue::VARR);
|
||||
BOOST_FOREACH (const CTxIn &in, tx.vin)
|
||||
{
|
||||
if (setTxIndex.count(in.prevout.hash))
|
||||
|
@ -692,12 +690,12 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
Object aux;
|
||||
UniValue aux(UniValue::VOBJ);
|
||||
aux.push_back(Pair("flags", HexStr(COINBASE_FLAGS.begin(), COINBASE_FLAGS.end())));
|
||||
|
||||
arith_uint256 hashTarget = arith_uint256().SetCompact(pblock->nBits);
|
||||
|
||||
static Array aMutable;
|
||||
static UniValue aMutable(UniValue::VARR);
|
||||
if (aMutable.empty())
|
||||
{
|
||||
aMutable.push_back("time");
|
||||
|
@ -705,13 +703,13 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
|||
aMutable.push_back("prevblock");
|
||||
}
|
||||
|
||||
Object result;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("capabilities", aCaps));
|
||||
result.push_back(Pair("version", pblock->nVersion));
|
||||
result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex()));
|
||||
result.push_back(Pair("transactions", transactions));
|
||||
if (coinbasetxn) {
|
||||
assert(txCoinbase.type() == obj_type);
|
||||
assert(txCoinbase.isObject());
|
||||
result.push_back(Pair("coinbasetxn", txCoinbase));
|
||||
} else {
|
||||
result.push_back(Pair("coinbaseaux", aux));
|
||||
|
@ -749,7 +747,7 @@ protected:
|
|||
};
|
||||
};
|
||||
|
||||
Value submitblock(const Array& params, bool fHelp)
|
||||
UniValue submitblock(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -810,7 +808,7 @@ Value submitblock(const Array& params, bool fHelp)
|
|||
return BIP22ValidationResult(state);
|
||||
}
|
||||
|
||||
Value estimatefee(const Array& params, bool fHelp)
|
||||
UniValue estimatefee(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -829,7 +827,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)
|
||||
|
@ -842,7 +840,7 @@ Value estimatefee(const Array& params, bool fHelp)
|
|||
return ValueFromAmount(feeRate.GetFeePerK());
|
||||
}
|
||||
|
||||
Value estimatepriority(const Array& params, bool fHelp)
|
||||
UniValue estimatepriority(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -861,7 +859,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)
|
||||
|
@ -870,7 +868,7 @@ Value estimatepriority(const Array& params, bool fHelp)
|
|||
return mempool.estimatePriority(nBlocks);
|
||||
}
|
||||
|
||||
Value getblocksubsidy(const Array& params, bool fHelp)
|
||||
UniValue getblocksubsidy(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 1)
|
||||
throw runtime_error(
|
||||
|
@ -899,7 +897,7 @@ Value getblocksubsidy(const Array& params, bool fHelp)
|
|||
nFoundersReward = nReward/5;
|
||||
nReward -= nFoundersReward;
|
||||
}
|
||||
Object result;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("miner", ValueFromAmount(nReward)));
|
||||
result.push_back(Pair("founders", ValueFromAmount(nFoundersReward)));
|
||||
return result;
|
||||
|
|
|
@ -20,12 +20,10 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include "json/json_spirit_utils.h"
|
||||
#include "json/json_spirit_value.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
#include "zcash/Address.hpp"
|
||||
|
||||
using namespace json_spirit;
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
|
@ -41,7 +39,7 @@ using namespace std;
|
|||
*
|
||||
* Or alternatively, create a specific query method for the information.
|
||||
**/
|
||||
Value getinfo(const Array& params, bool fHelp)
|
||||
UniValue getinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -80,7 +78,7 @@ Value getinfo(const Array& params, bool fHelp)
|
|||
proxyType proxy;
|
||||
GetProxy(NET_IPV4, proxy);
|
||||
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("version", CLIENT_VERSION));
|
||||
obj.push_back(Pair("protocolversion", PROTOCOL_VERSION));
|
||||
#ifdef ENABLE_WALLET
|
||||
|
@ -110,7 +108,7 @@ Value getinfo(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
class DescribeAddressVisitor : public boost::static_visitor<Object>
|
||||
class DescribeAddressVisitor : public boost::static_visitor<UniValue>
|
||||
{
|
||||
private:
|
||||
isminetype mine;
|
||||
|
@ -118,10 +116,10 @@ private:
|
|||
public:
|
||||
DescribeAddressVisitor(isminetype mineIn) : mine(mineIn) {}
|
||||
|
||||
Object operator()(const CNoDestination &dest) const { return Object(); }
|
||||
UniValue operator()(const CNoDestination &dest) const { return UniValue(UniValue::VOBJ); }
|
||||
|
||||
Object operator()(const CKeyID &keyID) const {
|
||||
Object obj;
|
||||
UniValue operator()(const CKeyID &keyID) const {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CPubKey vchPubKey;
|
||||
obj.push_back(Pair("isscript", false));
|
||||
if (mine == ISMINE_SPENDABLE) {
|
||||
|
@ -132,8 +130,8 @@ public:
|
|||
return obj;
|
||||
}
|
||||
|
||||
Object operator()(const CScriptID &scriptID) const {
|
||||
Object obj;
|
||||
UniValue operator()(const CScriptID &scriptID) const {
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("isscript", true));
|
||||
if (mine != ISMINE_NO) {
|
||||
CScript subscript;
|
||||
|
@ -144,7 +142,7 @@ public:
|
|||
ExtractDestinations(subscript, whichType, addresses, nRequired);
|
||||
obj.push_back(Pair("script", GetTxnOutputType(whichType)));
|
||||
obj.push_back(Pair("hex", HexStr(subscript.begin(), subscript.end())));
|
||||
Array a;
|
||||
UniValue a(UniValue::VARR);
|
||||
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||
a.push_back(CBitcoinAddress(addr).ToString());
|
||||
obj.push_back(Pair("addresses", a));
|
||||
|
@ -156,7 +154,7 @@ public:
|
|||
};
|
||||
#endif
|
||||
|
||||
Value validateaddress(const Array& params, bool fHelp)
|
||||
UniValue validateaddress(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -189,7 +187,7 @@ Value validateaddress(const Array& params, bool fHelp)
|
|||
CBitcoinAddress address(params[0].get_str());
|
||||
bool isValid = address.IsValid();
|
||||
|
||||
Object ret;
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.push_back(Pair("isvalid", isValid));
|
||||
if (isValid)
|
||||
{
|
||||
|
@ -205,8 +203,8 @@ Value validateaddress(const Array& params, bool fHelp)
|
|||
ret.push_back(Pair("ismine", (mine & ISMINE_SPENDABLE) ? true : false));
|
||||
if (mine != ISMINE_NO) {
|
||||
ret.push_back(Pair("iswatchonly", (mine & ISMINE_WATCH_ONLY) ? true: false));
|
||||
Object detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
|
||||
ret.insert(ret.end(), detail.begin(), detail.end());
|
||||
UniValue detail = boost::apply_visitor(DescribeAddressVisitor(mine), dest);
|
||||
ret.pushKVs(detail);
|
||||
}
|
||||
if (pwalletMain && pwalletMain->mapAddressBook.count(dest))
|
||||
ret.push_back(Pair("account", pwalletMain->mapAddressBook[dest].name));
|
||||
|
@ -216,7 +214,7 @@ Value validateaddress(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
|
||||
Value z_validateaddress(const Array& params, bool fHelp)
|
||||
UniValue z_validateaddress(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -263,7 +261,7 @@ Value z_validateaddress(const Array& params, bool fHelp)
|
|||
// address is invalid, nop here as isValid is false.
|
||||
}
|
||||
|
||||
Object ret;
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.push_back(Pair("isvalid", isValid));
|
||||
if (isValid)
|
||||
{
|
||||
|
@ -281,10 +279,10 @@ Value z_validateaddress(const Array& params, bool fHelp)
|
|||
/**
|
||||
* Used by addmultisigaddress / createmultisig:
|
||||
*/
|
||||
CScript _createmultisig_redeemScript(const Array& params)
|
||||
CScript _createmultisig_redeemScript(const UniValue& params)
|
||||
{
|
||||
int nRequired = params[0].get_int();
|
||||
const Array& keys = params[1].get_array();
|
||||
const UniValue& keys = params[1].get_array();
|
||||
|
||||
// Gather public keys
|
||||
if (nRequired < 1)
|
||||
|
@ -342,7 +340,7 @@ CScript _createmultisig_redeemScript(const Array& params)
|
|||
return result;
|
||||
}
|
||||
|
||||
Value createmultisig(const Array& params, bool fHelp)
|
||||
UniValue createmultisig(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 2 || params.size() > 2)
|
||||
{
|
||||
|
@ -378,14 +376,14 @@ Value createmultisig(const Array& params, bool fHelp)
|
|||
CScriptID innerID(inner);
|
||||
CBitcoinAddress address(innerID);
|
||||
|
||||
Object result;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("address", address.ToString()));
|
||||
result.push_back(Pair("redeemScript", HexStr(inner.begin(), inner.end())));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Value verifymessage(const Array& params, bool fHelp)
|
||||
UniValue verifymessage(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 3)
|
||||
throw runtime_error(
|
||||
|
@ -439,7 +437,7 @@ Value verifymessage(const Array& params, bool fHelp)
|
|||
return (pubkey.GetID() == keyID);
|
||||
}
|
||||
|
||||
Value setmocktime(const Array& params, bool fHelp)
|
||||
UniValue setmocktime(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -455,8 +453,8 @@ Value setmocktime(const Array& params, bool fHelp)
|
|||
|
||||
LOCK(cs_main);
|
||||
|
||||
RPCTypeCheck(params, boost::assign::list_of(int_type));
|
||||
RPCTypeCheck(params, boost::assign::list_of(UniValue::VNUM));
|
||||
SetMockTime(params[0].get_int64());
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
|
|
@ -16,12 +16,11 @@
|
|||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "json/json_spirit_value.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
using namespace std;
|
||||
|
||||
Value getconnectioncount(const Array& params, bool fHelp)
|
||||
UniValue getconnectioncount(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -39,7 +38,7 @@ Value getconnectioncount(const Array& params, bool fHelp)
|
|||
return (int)vNodes.size();
|
||||
}
|
||||
|
||||
Value ping(const Array& params, bool fHelp)
|
||||
UniValue ping(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -59,7 +58,7 @@ Value ping(const Array& params, bool fHelp)
|
|||
pNode->fPingQueued = true;
|
||||
}
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
static void CopyNodeStats(std::vector<CNodeStats>& vstats)
|
||||
|
@ -75,7 +74,7 @@ static void CopyNodeStats(std::vector<CNodeStats>& vstats)
|
|||
}
|
||||
}
|
||||
|
||||
Value getpeerinfo(const Array& params, bool fHelp)
|
||||
UniValue getpeerinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -120,10 +119,10 @@ Value getpeerinfo(const Array& params, bool fHelp)
|
|||
vector<CNodeStats> vstats;
|
||||
CopyNodeStats(vstats);
|
||||
|
||||
Array ret;
|
||||
UniValue ret(UniValue::VARR);
|
||||
|
||||
BOOST_FOREACH(const CNodeStats& stats, vstats) {
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CNodeStateStats statestats;
|
||||
bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
|
||||
obj.push_back(Pair("id", stats.nodeid));
|
||||
|
@ -151,7 +150,7 @@ Value getpeerinfo(const Array& params, bool fHelp)
|
|||
obj.push_back(Pair("banscore", statestats.nMisbehavior));
|
||||
obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
|
||||
obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
|
||||
Array heights;
|
||||
UniValue heights(UniValue::VARR);
|
||||
BOOST_FOREACH(int height, statestats.vHeightInFlight) {
|
||||
heights.push_back(height);
|
||||
}
|
||||
|
@ -165,7 +164,7 @@ Value getpeerinfo(const Array& params, bool fHelp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
Value addnode(const Array& params, bool fHelp)
|
||||
UniValue addnode(const UniValue& params, bool fHelp)
|
||||
{
|
||||
string strCommand;
|
||||
if (params.size() == 2)
|
||||
|
@ -190,7 +189,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,10 +211,10 @@ Value addnode(const Array& params, bool fHelp)
|
|||
vAddedNodes.erase(it);
|
||||
}
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
Value getaddednodeinfo(const Array& params, bool fHelp)
|
||||
UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -271,12 +270,12 @@ Value getaddednodeinfo(const Array& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
|
||||
}
|
||||
|
||||
Array ret;
|
||||
UniValue ret(UniValue::VARR);
|
||||
if (!fDns)
|
||||
{
|
||||
BOOST_FOREACH(string& strAddNode, laddedNodes)
|
||||
{
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("addednode", strAddNode));
|
||||
ret.push_back(obj);
|
||||
}
|
||||
|
@ -291,10 +290,10 @@ Value getaddednodeinfo(const Array& params, bool fHelp)
|
|||
laddedAddreses.push_back(make_pair(strAddNode, vservNode));
|
||||
else
|
||||
{
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("addednode", strAddNode));
|
||||
obj.push_back(Pair("connected", false));
|
||||
Array addresses;
|
||||
UniValue addresses(UniValue::VARR);
|
||||
obj.push_back(Pair("addresses", addresses));
|
||||
}
|
||||
}
|
||||
|
@ -302,15 +301,15 @@ Value getaddednodeinfo(const Array& params, bool fHelp)
|
|||
LOCK(cs_vNodes);
|
||||
for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
|
||||
{
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("addednode", it->first));
|
||||
|
||||
Array addresses;
|
||||
UniValue addresses(UniValue::VARR);
|
||||
bool fConnected = false;
|
||||
BOOST_FOREACH(CService& addrNode, it->second)
|
||||
{
|
||||
bool fFound = false;
|
||||
Object node;
|
||||
UniValue node(UniValue::VOBJ);
|
||||
node.push_back(Pair("address", addrNode.ToString()));
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
if (pnode->addr == addrNode)
|
||||
|
@ -332,7 +331,7 @@ Value getaddednodeinfo(const Array& params, bool fHelp)
|
|||
return ret;
|
||||
}
|
||||
|
||||
Value getnettotals(const Array& params, bool fHelp)
|
||||
UniValue getnettotals(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 0)
|
||||
throw runtime_error(
|
||||
|
@ -350,23 +349,23 @@ Value getnettotals(const Array& params, bool fHelp)
|
|||
+ HelpExampleRpc("getnettotals", "")
|
||||
);
|
||||
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
|
||||
obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
|
||||
obj.push_back(Pair("timemillis", GetTimeMillis()));
|
||||
return obj;
|
||||
}
|
||||
|
||||
static Array GetNetworksInfo()
|
||||
static UniValue GetNetworksInfo()
|
||||
{
|
||||
Array networks;
|
||||
UniValue networks(UniValue::VARR);
|
||||
for(int n=0; n<NET_MAX; ++n)
|
||||
{
|
||||
enum Network network = static_cast<enum Network>(n);
|
||||
if(network == NET_UNROUTABLE)
|
||||
continue;
|
||||
proxyType proxy;
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
GetProxy(network, proxy);
|
||||
obj.push_back(Pair("name", GetNetworkName(network)));
|
||||
obj.push_back(Pair("limited", IsLimited(network)));
|
||||
|
@ -378,7 +377,7 @@ static Array GetNetworksInfo()
|
|||
return networks;
|
||||
}
|
||||
|
||||
Value getnetworkinfo(const Array& params, bool fHelp)
|
||||
UniValue getnetworkinfo(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 0)
|
||||
throw runtime_error(
|
||||
|
@ -418,7 +417,7 @@ Value getnetworkinfo(const Array& params, bool fHelp)
|
|||
|
||||
LOCK(cs_main);
|
||||
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("version", CLIENT_VERSION));
|
||||
obj.push_back(Pair("subversion",
|
||||
FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>())));
|
||||
|
@ -428,12 +427,12 @@ Value getnetworkinfo(const Array& params, bool fHelp)
|
|||
obj.push_back(Pair("connections", (int)vNodes.size()));
|
||||
obj.push_back(Pair("networks", GetNetworksInfo()));
|
||||
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
|
||||
Array localAddresses;
|
||||
UniValue localAddresses(UniValue::VARR);
|
||||
{
|
||||
LOCK(cs_mapLocalHost);
|
||||
BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
|
||||
{
|
||||
Object rec;
|
||||
UniValue rec(UniValue::VOBJ);
|
||||
rec.push_back(Pair("address", item.first.ToString()));
|
||||
rec.push_back(Pair("port", item.second.nPort));
|
||||
rec.push_back(Pair("score", item.second.nScore));
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
#include <boost/iostreams/concepts.hpp>
|
||||
#include <boost/iostreams/stream.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include "json/json_spirit_writer_template.h"
|
||||
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
//! Number of bytes to allocate and read at most at once in post data
|
||||
const size_t POST_READ_SIZE = 256 * 1024;
|
||||
|
@ -256,20 +256,20 @@ int ReadHTTPMessage(std::basic_istream<char>& stream, map<string,
|
|||
* http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx
|
||||
*/
|
||||
|
||||
string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id)
|
||||
string JSONRPCRequest(const string& strMethod, const UniValue& params, const UniValue& id)
|
||||
{
|
||||
Object request;
|
||||
UniValue request(UniValue::VOBJ);
|
||||
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)
|
||||
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id)
|
||||
{
|
||||
Object reply;
|
||||
if (error.type() != null_type)
|
||||
reply.push_back(Pair("result", Value::null));
|
||||
UniValue reply(UniValue::VOBJ);
|
||||
if (!error.isNull())
|
||||
reply.push_back(Pair("result", NullUniValue));
|
||||
else
|
||||
reply.push_back(Pair("result", result));
|
||||
reply.push_back(Pair("error", error));
|
||||
|
@ -277,15 +277,15 @@ Object JSONRPCReplyObj(const Value& result, const Value& error, const Value& id)
|
|||
return reply;
|
||||
}
|
||||
|
||||
string JSONRPCReply(const Value& result, const Value& error, const Value& id)
|
||||
string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id)
|
||||
{
|
||||
Object reply = JSONRPCReplyObj(result, error, id);
|
||||
return write_string(Value(reply), false) + "\n";
|
||||
UniValue reply = JSONRPCReplyObj(result, error, id);
|
||||
return reply.write() + "\n";
|
||||
}
|
||||
|
||||
Object JSONRPCError(int code, const string& message)
|
||||
UniValue JSONRPCError(int code, const string& message)
|
||||
{
|
||||
Object error;
|
||||
UniValue error(UniValue::VOBJ);
|
||||
error.push_back(Pair("code", code));
|
||||
error.push_back(Pair("message", message));
|
||||
return error;
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
#include <boost/asio/ssl.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include "json/json_spirit_reader_template.h"
|
||||
#include "json/json_spirit_utils.h"
|
||||
#include "json/json_spirit_writer_template.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
//! HTTP status codes
|
||||
enum HTTPStatusCode
|
||||
|
@ -161,10 +159,10 @@ int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto);
|
|||
int ReadHTTPHeaders(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet);
|
||||
int ReadHTTPMessage(std::basic_istream<char>& stream, std::map<std::string, std::string>& mapHeadersRet,
|
||||
std::string& strMessageRet, int nProto, size_t max_size);
|
||||
std::string JSONRPCRequest(const std::string& strMethod, const json_spirit::Array& params, const json_spirit::Value& id);
|
||||
json_spirit::Object JSONRPCReplyObj(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id);
|
||||
std::string JSONRPCReply(const json_spirit::Value& result, const json_spirit::Value& error, const json_spirit::Value& id);
|
||||
json_spirit::Object JSONRPCError(int code, const std::string& message);
|
||||
std::string JSONRPCRequest(const std::string& strMethod, const UniValue& params, const UniValue& id);
|
||||
UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id);
|
||||
std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id);
|
||||
UniValue JSONRPCError(int code, const std::string& message);
|
||||
|
||||
/** Get name of RPC authentication cookie file */
|
||||
boost::filesystem::path GetAuthCookieFile();
|
||||
|
|
|
@ -25,13 +25,12 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include "json/json_spirit_utils.h"
|
||||
#include "json/json_spirit_value.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeHex)
|
||||
void ScriptPubKeyToJSON(const CScript& scriptPubKey, UniValue& out, bool fIncludeHex)
|
||||
{
|
||||
txnouttype type;
|
||||
vector<CTxDestination> addresses;
|
||||
|
@ -49,18 +48,18 @@ void ScriptPubKeyToJSON(const CScript& scriptPubKey, Object& out, bool fIncludeH
|
|||
out.push_back(Pair("reqSigs", nRequired));
|
||||
out.push_back(Pair("type", GetTxnOutputType(type)));
|
||||
|
||||
Array a;
|
||||
UniValue a(UniValue::VARR);
|
||||
BOOST_FOREACH(const CTxDestination& addr, addresses)
|
||||
a.push_back(CBitcoinAddress(addr).ToString());
|
||||
out.push_back(Pair("addresses", a));
|
||||
}
|
||||
|
||||
|
||||
Array TxJoinSplitToJSON(const CTransaction& tx) {
|
||||
Array vjoinsplit;
|
||||
UniValue TxJoinSplitToJSON(const CTransaction& tx) {
|
||||
UniValue vjoinsplit(UniValue::VARR);
|
||||
for (unsigned int i = 0; i < tx.vjoinsplit.size(); i++) {
|
||||
const JSDescription& jsdescription = tx.vjoinsplit[i];
|
||||
Object joinsplit;
|
||||
UniValue joinsplit(UniValue::VOBJ);
|
||||
|
||||
joinsplit.push_back(Pair("vpub_old", ValueFromAmount(jsdescription.vpub_old)));
|
||||
joinsplit.push_back(Pair("vpub_new", ValueFromAmount(jsdescription.vpub_new)));
|
||||
|
@ -68,7 +67,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) {
|
|||
joinsplit.push_back(Pair("anchor", jsdescription.anchor.GetHex()));
|
||||
|
||||
{
|
||||
Array nullifiers;
|
||||
UniValue nullifiers(UniValue::VARR);
|
||||
BOOST_FOREACH(const uint256 nf, jsdescription.nullifiers) {
|
||||
nullifiers.push_back(nf.GetHex());
|
||||
}
|
||||
|
@ -76,7 +75,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) {
|
|||
}
|
||||
|
||||
{
|
||||
Array commitments;
|
||||
UniValue commitments(UniValue::VARR);
|
||||
BOOST_FOREACH(const uint256 commitment, jsdescription.commitments) {
|
||||
commitments.push_back(commitment.GetHex());
|
||||
}
|
||||
|
@ -87,7 +86,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) {
|
|||
joinsplit.push_back(Pair("randomSeed", jsdescription.randomSeed.GetHex()));
|
||||
|
||||
{
|
||||
Array macs;
|
||||
UniValue macs(UniValue::VARR);
|
||||
BOOST_FOREACH(const uint256 mac, jsdescription.macs) {
|
||||
macs.push_back(mac.GetHex());
|
||||
}
|
||||
|
@ -99,7 +98,7 @@ Array TxJoinSplitToJSON(const CTransaction& tx) {
|
|||
joinsplit.push_back(Pair("proof", HexStr(ssProof.begin(), ssProof.end())));
|
||||
|
||||
{
|
||||
Array ciphertexts;
|
||||
UniValue ciphertexts(UniValue::VARR);
|
||||
for (const ZCNoteEncryption::Ciphertext ct : jsdescription.ciphertexts) {
|
||||
ciphertexts.push_back(HexStr(ct.begin(), ct.end()));
|
||||
}
|
||||
|
@ -111,20 +110,20 @@ Array TxJoinSplitToJSON(const CTransaction& tx) {
|
|||
return vjoinsplit;
|
||||
}
|
||||
|
||||
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
||||
void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
|
||||
{
|
||||
entry.push_back(Pair("txid", tx.GetHash().GetHex()));
|
||||
entry.push_back(Pair("version", tx.nVersion));
|
||||
entry.push_back(Pair("locktime", (int64_t)tx.nLockTime));
|
||||
Array vin;
|
||||
UniValue vin(UniValue::VARR);
|
||||
BOOST_FOREACH(const CTxIn& txin, tx.vin) {
|
||||
Object in;
|
||||
UniValue in(UniValue::VOBJ);
|
||||
if (tx.IsCoinBase())
|
||||
in.push_back(Pair("coinbase", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
|
||||
else {
|
||||
in.push_back(Pair("txid", txin.prevout.hash.GetHex()));
|
||||
in.push_back(Pair("vout", (int64_t)txin.prevout.n));
|
||||
Object o;
|
||||
UniValue o(UniValue::VOBJ);
|
||||
o.push_back(Pair("asm", txin.scriptSig.ToString()));
|
||||
o.push_back(Pair("hex", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
|
||||
in.push_back(Pair("scriptSig", o));
|
||||
|
@ -133,20 +132,20 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
|||
vin.push_back(in);
|
||||
}
|
||||
entry.push_back(Pair("vin", vin));
|
||||
Array vout;
|
||||
UniValue vout(UniValue::VARR);
|
||||
for (unsigned int i = 0; i < tx.vout.size(); i++) {
|
||||
const CTxOut& txout = tx.vout[i];
|
||||
Object out;
|
||||
UniValue out(UniValue::VOBJ);
|
||||
out.push_back(Pair("value", ValueFromAmount(txout.nValue)));
|
||||
out.push_back(Pair("n", (int64_t)i));
|
||||
Object o;
|
||||
UniValue o(UniValue::VOBJ);
|
||||
ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
|
||||
out.push_back(Pair("scriptPubKey", o));
|
||||
vout.push_back(out);
|
||||
}
|
||||
entry.push_back(Pair("vout", vout));
|
||||
|
||||
Array vjoinsplit = TxJoinSplitToJSON(tx);
|
||||
UniValue vjoinsplit = TxJoinSplitToJSON(tx);
|
||||
entry.push_back(Pair("vjoinsplit", vjoinsplit));
|
||||
|
||||
if (!hashBlock.IsNull()) {
|
||||
|
@ -165,7 +164,7 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, Object& entry)
|
|||
}
|
||||
}
|
||||
|
||||
Value getrawtransaction(const Array& params, bool fHelp)
|
||||
UniValue getrawtransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -276,13 +275,13 @@ Value getrawtransaction(const Array& params, bool fHelp)
|
|||
if (!fVerbose)
|
||||
return strHex;
|
||||
|
||||
Object result;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("hex", strHex));
|
||||
TxToJSON(tx, hashBlock, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
Value gettxoutproof(const Array& params, bool fHelp)
|
||||
UniValue gettxoutproof(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || (params.size() != 1 && params.size() != 2))
|
||||
throw runtime_error(
|
||||
|
@ -306,8 +305,9 @@ Value gettxoutproof(const Array& params, bool fHelp)
|
|||
|
||||
set<uint256> setTxids;
|
||||
uint256 oneTxid;
|
||||
Array txids = params[0].get_array();
|
||||
BOOST_FOREACH(Value& txid, txids) {
|
||||
UniValue txids = params[0].get_array();
|
||||
for (size_t idx = 0; idx < txids.size(); idx++) {
|
||||
const UniValue& txid = txids[idx];
|
||||
if (txid.get_str().length() != 64 || !IsHex(txid.get_str()))
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid txid ")+txid.get_str());
|
||||
uint256 hash(uint256S(txid.get_str()));
|
||||
|
@ -362,7 +362,7 @@ Value gettxoutproof(const Array& params, bool fHelp)
|
|||
return strHex;
|
||||
}
|
||||
|
||||
Value verifytxoutproof(const Array& params, bool fHelp)
|
||||
UniValue verifytxoutproof(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -379,7 +379,7 @@ Value verifytxoutproof(const Array& params, bool fHelp)
|
|||
CMerkleBlock merkleBlock;
|
||||
ssMB >> merkleBlock;
|
||||
|
||||
Array res;
|
||||
UniValue res(UniValue::VARR);
|
||||
|
||||
vector<uint256> vMatch;
|
||||
if (merkleBlock.txn.ExtractMatches(vMatch) != merkleBlock.header.hashMerkleRoot)
|
||||
|
@ -395,7 +395,7 @@ Value verifytxoutproof(const Array& params, bool fHelp)
|
|||
return res;
|
||||
}
|
||||
|
||||
Value createrawtransaction(const Array& params, bool fHelp)
|
||||
UniValue createrawtransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 2)
|
||||
throw runtime_error(
|
||||
|
@ -429,20 +429,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();
|
||||
UniValue inputs = params[0].get_array();
|
||||
UniValue sendTo = params[1].get_obj();
|
||||
|
||||
CMutableTransaction rawTx;
|
||||
|
||||
BOOST_FOREACH(const Value& input, inputs) {
|
||||
const Object& o = input.get_obj();
|
||||
for (size_t idx = 0; idx < inputs.size(); idx++) {
|
||||
const UniValue& input = inputs[idx];
|
||||
const UniValue& o = input.get_obj();
|
||||
|
||||
uint256 txid = ParseHashO(o, "txid");
|
||||
|
||||
const Value& vout_v = find_value(o, "vout");
|
||||
if (vout_v.type() != int_type)
|
||||
const UniValue& vout_v = find_value(o, "vout");
|
||||
if (!vout_v.isNum())
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
|
||||
int nOutput = vout_v.get_int();
|
||||
if (nOutput < 0)
|
||||
|
@ -453,17 +454,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);
|
||||
|
@ -472,7 +474,7 @@ Value createrawtransaction(const Array& params, bool fHelp)
|
|||
return EncodeHexTx(rawTx);
|
||||
}
|
||||
|
||||
Value decoderawtransaction(const Array& params, bool fHelp)
|
||||
UniValue decoderawtransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -551,20 +553,20 @@ 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;
|
||||
|
||||
if (!DecodeHexTx(tx, params[0].get_str()))
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||
|
||||
Object result;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
TxToJSON(tx, uint256(), result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Value decodescript(const Array& params, bool fHelp)
|
||||
UniValue decodescript(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -590,9 +592,9 @@ Value decodescript(const Array& params, bool fHelp)
|
|||
);
|
||||
|
||||
LOCK(cs_main);
|
||||
RPCTypeCheck(params, boost::assign::list_of(str_type));
|
||||
RPCTypeCheck(params, boost::assign::list_of(UniValue::VSTR));
|
||||
|
||||
Object r;
|
||||
UniValue r(UniValue::VOBJ);
|
||||
CScript script;
|
||||
if (params[0].get_str().size() > 0){
|
||||
vector<unsigned char> scriptData(ParseHexV(params[0], "argument"));
|
||||
|
@ -607,9 +609,9 @@ Value decodescript(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
/** Pushes a JSON object for script verification or signing errors to vErrorsRet. */
|
||||
static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::string& strMessage)
|
||||
static void TxInErrorToJSON(const CTxIn& txin, UniValue& vErrorsRet, const std::string& strMessage)
|
||||
{
|
||||
Object entry;
|
||||
UniValue entry(UniValue::VOBJ);
|
||||
entry.push_back(Pair("txid", txin.prevout.hash.ToString()));
|
||||
entry.push_back(Pair("vout", (uint64_t)txin.prevout.n));
|
||||
entry.push_back(Pair("scriptSig", HexStr(txin.scriptSig.begin(), txin.scriptSig.end())));
|
||||
|
@ -618,7 +620,7 @@ static void TxInErrorToJSON(const CTxIn& txin, Array& vErrorsRet, const std::str
|
|||
vErrorsRet.push_back(entry);
|
||||
}
|
||||
|
||||
Value signrawtransaction(const Array& params, bool fHelp)
|
||||
UniValue signrawtransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 4)
|
||||
throw runtime_error(
|
||||
|
@ -683,7 +685,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);
|
||||
|
@ -726,10 +728,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) {
|
||||
UniValue keys = params[2].get_array();
|
||||
for (size_t idx = 0; idx < keys.size(); idx++) {
|
||||
UniValue k = keys[idx];
|
||||
CBitcoinSecret vchSecret;
|
||||
bool fGood = vchSecret.SetString(k.get_str());
|
||||
if (!fGood)
|
||||
|
@ -746,15 +749,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) {
|
||||
Array prevTxs = params[1].get_array();
|
||||
BOOST_FOREACH(Value& p, prevTxs) {
|
||||
if (p.type() != obj_type)
|
||||
if (params.size() > 1 && !params[1].isNull()) {
|
||||
UniValue prevTxs = params[1].get_array();
|
||||
for (size_t idx = 0; idx < prevTxs.size(); idx++) {
|
||||
const UniValue& p = prevTxs[idx];
|
||||
if (!p.isObject())
|
||||
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
|
||||
|
||||
Object prevOut = p.get_obj();
|
||||
UniValue prevOut = p.get_obj();
|
||||
|
||||
RPCTypeCheck(prevOut, boost::assign::map_list_of("txid", str_type)("vout", int_type)("scriptPubKey", str_type));
|
||||
RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR));
|
||||
|
||||
uint256 txid = ParseHashO(prevOut, "txid");
|
||||
|
||||
|
@ -782,9 +786,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));
|
||||
Value v = find_value(prevOut, "redeemScript");
|
||||
if (!(v == Value::null)) {
|
||||
RPCTypeCheckObj(prevOut, boost::assign::map_list_of("txid", UniValue::VSTR)("vout", UniValue::VNUM)("scriptPubKey", UniValue::VSTR)("redeemScript",UniValue::VSTR));
|
||||
UniValue v = find_value(prevOut, "redeemScript");
|
||||
if (!v.isNull()) {
|
||||
vector<unsigned char> rsData(ParseHexV(v, "redeemScript"));
|
||||
CScript redeemScript(rsData.begin(), rsData.end());
|
||||
tempKeystore.AddCScript(redeemScript);
|
||||
|
@ -800,7 +804,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))
|
||||
|
@ -820,7 +824,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
|||
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
|
||||
|
||||
// Script verification errors
|
||||
Array vErrors;
|
||||
UniValue vErrors(UniValue::VARR);
|
||||
|
||||
// Sign what we can:
|
||||
for (unsigned int i = 0; i < mergedTx.vin.size(); i++) {
|
||||
|
@ -848,7 +852,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
|||
}
|
||||
bool fComplete = vErrors.empty();
|
||||
|
||||
Object result;
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.push_back(Pair("hex", EncodeHexTx(mergedTx)));
|
||||
result.push_back(Pair("complete", fComplete));
|
||||
if (!vErrors.empty()) {
|
||||
|
@ -858,7 +862,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
|||
return result;
|
||||
}
|
||||
|
||||
Value sendrawtransaction(const Array& params, bool fHelp)
|
||||
UniValue sendrawtransaction(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -882,7 +886,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;
|
||||
|
|
|
@ -30,10 +30,10 @@
|
|||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/signals2/signal.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include "json/json_spirit_writer_template.h"
|
||||
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace boost::asio;
|
||||
using namespace json_spirit;
|
||||
using namespace RPCServer;
|
||||
using namespace std;
|
||||
|
||||
|
@ -81,41 +81,41 @@ void RPCServer::OnPostCommand(boost::function<void (const CRPCCommand&)> slot)
|
|||
g_rpcSignals.PostCommand.connect(boost::bind(slot, _1));
|
||||
}
|
||||
|
||||
void RPCTypeCheck(const Array& params,
|
||||
const list<Value_type>& typesExpected,
|
||||
void RPCTypeCheck(const UniValue& params,
|
||||
const list<UniValue::VType>& typesExpected,
|
||||
bool fAllowNull)
|
||||
{
|
||||
unsigned int i = 0;
|
||||
BOOST_FOREACH(Value_type t, typesExpected)
|
||||
size_t i = 0;
|
||||
BOOST_FOREACH(UniValue::VType t, typesExpected)
|
||||
{
|
||||
if (params.size() <= i)
|
||||
break;
|
||||
|
||||
const Value& v = params[i];
|
||||
if (!((v.type() == t) || (fAllowNull && (v.type() == null_type))))
|
||||
const UniValue& v = params[i];
|
||||
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)
|
||||
BOOST_FOREACH(const PAIRTYPE(string, UniValue::VType)& t, typesExpected)
|
||||
{
|
||||
const Value& v = find_value(o, t.first);
|
||||
if (!fAllowNull && v.type() == null_type)
|
||||
const UniValue& v = find_value(o, t.first);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ static inline int64_t roundint64(double d)
|
|||
return (int64_t)(d > 0 ? d + 0.5 : d - 0.5);
|
||||
}
|
||||
|
||||
CAmount AmountFromValue(const Value& value)
|
||||
CAmount AmountFromValue(const UniValue& value)
|
||||
{
|
||||
double dAmount = value.get_real();
|
||||
if (dAmount <= 0.0 || dAmount > 21000000.0)
|
||||
|
@ -137,15 +137,15 @@ CAmount AmountFromValue(const Value& value)
|
|||
return nAmount;
|
||||
}
|
||||
|
||||
Value ValueFromAmount(const CAmount& amount)
|
||||
UniValue ValueFromAmount(const CAmount& amount)
|
||||
{
|
||||
return (double)amount / (double)COIN;
|
||||
}
|
||||
|
||||
uint256 ParseHashV(const Value& v, string strName)
|
||||
uint256 ParseHashV(const UniValue& v, string strName)
|
||||
{
|
||||
string strHex;
|
||||
if (v.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+"')");
|
||||
|
@ -153,20 +153,20 @@ uint256 ParseHashV(const Value& v, string strName)
|
|||
result.SetHex(strHex);
|
||||
return result;
|
||||
}
|
||||
uint256 ParseHashO(const Object& o, string strKey)
|
||||
uint256 ParseHashO(const UniValue& o, string strKey)
|
||||
{
|
||||
return ParseHashV(find_value(o, strKey), strKey);
|
||||
}
|
||||
vector<unsigned char> ParseHexV(const Value& v, string strName)
|
||||
vector<unsigned char> ParseHexV(const UniValue& 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+"')");
|
||||
return ParseHex(strHex);
|
||||
}
|
||||
vector<unsigned char> ParseHexO(const Object& o, string strKey)
|
||||
vector<unsigned char> ParseHexO(const UniValue& o, string strKey)
|
||||
{
|
||||
return ParseHexV(find_value(o, strKey), strKey);
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ string CRPCTable::help(string strCommand) const
|
|||
continue;
|
||||
try
|
||||
{
|
||||
Array params;
|
||||
UniValue params;
|
||||
rpcfn_type pfn = pcmd->actor;
|
||||
if (setDone.insert(pfn).second)
|
||||
(*pfn)(params, true);
|
||||
|
@ -231,7 +231,7 @@ string CRPCTable::help(string strCommand) const
|
|||
return strRet;
|
||||
}
|
||||
|
||||
Value help(const Array& params, bool fHelp)
|
||||
UniValue help(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() > 1)
|
||||
throw runtime_error(
|
||||
|
@ -251,7 +251,7 @@ Value help(const Array& params, bool fHelp)
|
|||
}
|
||||
|
||||
|
||||
Value stop(const Array& params, bool fHelp)
|
||||
UniValue stop(const UniValue& params, bool fHelp)
|
||||
{
|
||||
// Accept the deprecated and ignored 'detach' boolean argument
|
||||
if (fHelp || params.size() > 1)
|
||||
|
@ -437,14 +437,14 @@ bool HTTPAuthorized(map<string, string>& mapHeaders)
|
|||
return TimingResistantEqual(strUserPass, strRPCUserColonPass);
|
||||
}
|
||||
|
||||
void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
|
||||
void ErrorReply(std::ostream& stream, const UniValue& objError, const UniValue& id)
|
||||
{
|
||||
// Send error reply from json-rpc error object
|
||||
int nStatus = HTTP_INTERNAL_SERVER_ERROR;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -862,76 +862,76 @@ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int6
|
|||
class JSONRequest
|
||||
{
|
||||
public:
|
||||
Value id;
|
||||
UniValue id;
|
||||
string strMethod;
|
||||
Array params;
|
||||
UniValue params;
|
||||
|
||||
JSONRequest() { id = Value::null; }
|
||||
void parse(const Value& valRequest);
|
||||
JSONRequest() { id = NullUniValue; }
|
||||
void parse(const UniValue& valRequest);
|
||||
};
|
||||
|
||||
void JSONRequest::parse(const Value& valRequest)
|
||||
void JSONRequest::parse(const UniValue& 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();
|
||||
const UniValue& request = valRequest.get_obj();
|
||||
|
||||
// Parse id now so errors from here on will have the id
|
||||
id = find_value(request, "id");
|
||||
|
||||
// Parse method
|
||||
Value valMethod = find_value(request, "method");
|
||||
if (valMethod.type() == null_type)
|
||||
UniValue valMethod = find_value(request, "method");
|
||||
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")
|
||||
LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
|
||||
|
||||
// Parse params
|
||||
Value valParams = find_value(request, "params");
|
||||
if (valParams.type() == array_type)
|
||||
UniValue valParams = find_value(request, "params");
|
||||
if (valParams.isArray())
|
||||
params = valParams.get_array();
|
||||
else if (valParams.type() == null_type)
|
||||
params = Array();
|
||||
else if (valParams.isNull())
|
||||
params = UniValue(UniValue::VARR);
|
||||
else
|
||||
throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array");
|
||||
}
|
||||
|
||||
|
||||
static Object JSONRPCExecOne(const Value& req)
|
||||
static UniValue JSONRPCExecOne(const UniValue& req)
|
||||
{
|
||||
Object rpc_result;
|
||||
UniValue rpc_result(UniValue::VOBJ);
|
||||
|
||||
JSONRequest jreq;
|
||||
try {
|
||||
jreq.parse(req);
|
||||
|
||||
Value result = tableRPC.execute(jreq.strMethod, jreq.params);
|
||||
rpc_result = JSONRPCReplyObj(result, Value::null, jreq.id);
|
||||
UniValue result = tableRPC.execute(jreq.strMethod, jreq.params);
|
||||
rpc_result = JSONRPCReplyObj(result, NullUniValue, jreq.id);
|
||||
}
|
||||
catch (const Object& objError)
|
||||
catch (const UniValue& objError)
|
||||
{
|
||||
rpc_result = JSONRPCReplyObj(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);
|
||||
}
|
||||
|
||||
return rpc_result;
|
||||
}
|
||||
|
||||
static string JSONRPCExecBatch(const Array& vReq)
|
||||
static string JSONRPCExecBatch(const UniValue& vReq)
|
||||
{
|
||||
Array ret;
|
||||
for (unsigned int reqIdx = 0; reqIdx < vReq.size(); reqIdx++)
|
||||
UniValue ret(UniValue::VARR);
|
||||
for (size_t 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,
|
||||
|
@ -962,8 +962,8 @@ static bool HTTPReq_JSONRPC(AcceptedConnection *conn,
|
|||
try
|
||||
{
|
||||
// Parse request
|
||||
Value valRequest;
|
||||
if (!read_string(strRequest, valRequest))
|
||||
UniValue valRequest;
|
||||
if (!valRequest.read(strRequest))
|
||||
throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
|
||||
|
||||
// Return immediately if in warmup
|
||||
|
@ -976,23 +976,23 @@ 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);
|
||||
UniValue 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");
|
||||
|
||||
conn->stream() << HTTPReplyHeader(HTTP_OK, fRun, strReply.size()) << strReply << std::flush;
|
||||
}
|
||||
catch (const Object& objError)
|
||||
catch (const UniValue& objError)
|
||||
{
|
||||
ErrorReply(conn->stream(), objError, jreq.id);
|
||||
return false;
|
||||
|
@ -1048,7 +1048,7 @@ void ServiceConnection(AcceptedConnection *conn)
|
|||
}
|
||||
}
|
||||
|
||||
json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_spirit::Array ¶ms) const
|
||||
UniValue CRPCTable::execute(const std::string &strMethod, const UniValue ¶ms) const
|
||||
{
|
||||
// Find method
|
||||
const CRPCCommand *pcmd = tableRPC[strMethod];
|
||||
|
|
255
src/rpcserver.h
255
src/rpcserver.h
|
@ -16,9 +16,9 @@
|
|||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#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 "univalue/univalue.h"
|
||||
|
||||
class AsyncRPCQueue;
|
||||
class CRPCCommand;
|
||||
|
@ -77,14 +77,15 @@ bool RPCIsInWarmup(std::string *statusOut);
|
|||
* the right number of arguments are passed, just that any passed are the correct type.
|
||||
* Use like: RPCTypeCheck(params, boost::assign::list_of(str_type)(int_type)(obj_type));
|
||||
*/
|
||||
void RPCTypeCheck(const json_spirit::Array& params,
|
||||
const std::list<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);
|
||||
void RPCTypeCheck(const UniValue& params,
|
||||
const std::list<UniValue::VType>& 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.
|
||||
|
@ -95,7 +96,7 @@ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int6
|
|||
//! Convert boost::asio address to CNetAddr
|
||||
extern CNetAddr BoostAsioToCNetAddr(boost::asio::ip::address address);
|
||||
|
||||
typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp);
|
||||
typedef UniValue(*rpcfn_type)(const UniValue& params, bool fHelp);
|
||||
|
||||
class CRPCCommand
|
||||
{
|
||||
|
@ -121,11 +122,11 @@ public:
|
|||
/**
|
||||
* Execute a method.
|
||||
* @param method Method to execute
|
||||
* @param params Array of arguments (JSON objects)
|
||||
* @param params UniValue Array of arguments (JSON objects)
|
||||
* @returns Result of the call.
|
||||
* @throws an exception (json_spirit::Value) when an error happens.
|
||||
* @throws an exception (UniValue) when an error happens.
|
||||
*/
|
||||
json_spirit::Value execute(const std::string &method, const json_spirit::Array ¶ms) const;
|
||||
UniValue execute(const std::string &method, const UniValue ¶ms) const;
|
||||
};
|
||||
|
||||
extern const CRPCTable tableRPC;
|
||||
|
@ -134,17 +135,17 @@ extern const CRPCTable tableRPC;
|
|||
* Utilities: convert hex-encoded Values
|
||||
* (throws error if not hex).
|
||||
*/
|
||||
extern uint256 ParseHashV(const json_spirit::Value& v, std::string strName);
|
||||
extern uint256 ParseHashO(const json_spirit::Object& o, std::string strKey);
|
||||
extern std::vector<unsigned char> ParseHexV(const json_spirit::Value& v, std::string strName);
|
||||
extern std::vector<unsigned char> ParseHexO(const json_spirit::Object& o, std::string strKey);
|
||||
extern uint256 ParseHashV(const UniValue& v, std::string strName);
|
||||
extern uint256 ParseHashO(const UniValue& o, std::string strKey);
|
||||
extern std::vector<unsigned char> ParseHexV(const UniValue& v, std::string strName);
|
||||
extern std::vector<unsigned char> ParseHexO(const UniValue& o, std::string strKey);
|
||||
|
||||
extern void InitRPCMining();
|
||||
extern void ShutdownRPCMining();
|
||||
|
||||
extern int64_t nWalletUnlockTime;
|
||||
extern CAmount AmountFromValue(const json_spirit::Value& value);
|
||||
extern json_spirit::Value ValueFromAmount(const CAmount& amount);
|
||||
extern CAmount AmountFromValue(const UniValue& value);
|
||||
extern UniValue ValueFromAmount(const CAmount& amount);
|
||||
extern double GetDifficulty(const CBlockIndex* blockindex = NULL);
|
||||
extern double GetNetworkDifficulty(const CBlockIndex* blockindex = NULL);
|
||||
extern std::string HelpRequiringPassphrase();
|
||||
|
@ -153,119 +154,119 @@ extern std::string HelpExampleRpc(std::string methodname, std::string args);
|
|||
|
||||
extern void EnsureWalletIsUnlocked();
|
||||
|
||||
extern json_spirit::Value getconnectioncount(const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp
|
||||
extern json_spirit::Value getpeerinfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value ping(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value addnode(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getaddednodeinfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getnettotals(const json_spirit::Array& params, bool fHelp);
|
||||
extern UniValue getconnectioncount(const UniValue& params, bool fHelp); // in rpcnet.cpp
|
||||
extern UniValue getpeerinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue ping(const UniValue& params, bool fHelp);
|
||||
extern UniValue addnode(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddednodeinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnettotals(const UniValue& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value dumpprivkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
|
||||
extern json_spirit::Value importprivkey(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value importaddress(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value dumpwallet(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value importwallet(const json_spirit::Array& params, bool fHelp);
|
||||
extern UniValue dumpprivkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue importprivkey(const UniValue& params, bool fHelp);
|
||||
extern UniValue importaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue dumpwallet(const UniValue& params, bool fHelp);
|
||||
extern UniValue importwallet(const UniValue& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value getgenerate(const json_spirit::Array& params, bool fHelp); // in rpcmining.cpp
|
||||
extern json_spirit::Value setgenerate(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value generate(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getlocalsolps(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getnetworksolps(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getnetworkhashps(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getmininginfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value prioritisetransaction(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getblocktemplate(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value submitblock(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value estimatefee(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value estimatepriority(const json_spirit::Array& params, bool fHelp);
|
||||
extern UniValue getgenerate(const UniValue& params, bool fHelp); // in rpcmining.cpp
|
||||
extern UniValue setgenerate(const UniValue& params, bool fHelp);
|
||||
extern UniValue generate(const UniValue& params, bool fHelp);
|
||||
extern UniValue getlocalsolps(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnetworksolps(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnetworkhashps(const UniValue& params, bool fHelp);
|
||||
extern UniValue getmininginfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue prioritisetransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblocktemplate(const UniValue& params, bool fHelp);
|
||||
extern UniValue submitblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue estimatefee(const UniValue& params, bool fHelp);
|
||||
extern UniValue estimatepriority(const UniValue& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value getaccountaddress(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getrawchangeaddress(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value setaccount(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getaccount(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getaddressesbyaccount(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value sendtoaddress(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value signmessage(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value verifymessage(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getreceivedbyaddress(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getreceivedbyaccount(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getbalance(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getunconfirmedbalance(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value movecmd(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value sendfrom(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value sendmany(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value addmultisigaddress(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value createmultisig(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value listreceivedbyaddress(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value listreceivedbyaccount(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value listtransactions(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value listaddressgroupings(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value listaccounts(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value listsinceblock(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value gettransaction(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value backupwallet(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value keypoolrefill(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value walletpassphrase(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value walletpassphrasechange(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value walletlock(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value encryptwallet(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value validateaddress(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getinfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getwalletinfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getblockchaininfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getnetworkinfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value setmocktime(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value resendwallettransactions(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value zc_benchmark(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value zc_raw_keygen(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value zc_raw_joinsplit(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value zc_raw_receive(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value zc_sample_joinsplit(const json_spirit::Array& params, bool fHelp);
|
||||
extern UniValue getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue getaccountaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue getrawchangeaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue setaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue getaddressesbyaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue sendtoaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue signmessage(const UniValue& params, bool fHelp);
|
||||
extern UniValue verifymessage(const UniValue& params, bool fHelp);
|
||||
extern UniValue getreceivedbyaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue getreceivedbyaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue getbalance(const UniValue& params, bool fHelp);
|
||||
extern UniValue getunconfirmedbalance(const UniValue& params, bool fHelp);
|
||||
extern UniValue movecmd(const UniValue& params, bool fHelp);
|
||||
extern UniValue sendfrom(const UniValue& params, bool fHelp);
|
||||
extern UniValue sendmany(const UniValue& params, bool fHelp);
|
||||
extern UniValue addmultisigaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue createmultisig(const UniValue& params, bool fHelp);
|
||||
extern UniValue listreceivedbyaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue listreceivedbyaccount(const UniValue& params, bool fHelp);
|
||||
extern UniValue listtransactions(const UniValue& params, bool fHelp);
|
||||
extern UniValue listaddressgroupings(const UniValue& params, bool fHelp);
|
||||
extern UniValue listaccounts(const UniValue& params, bool fHelp);
|
||||
extern UniValue listsinceblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue backupwallet(const UniValue& params, bool fHelp);
|
||||
extern UniValue keypoolrefill(const UniValue& params, bool fHelp);
|
||||
extern UniValue walletpassphrase(const UniValue& params, bool fHelp);
|
||||
extern UniValue walletpassphrasechange(const UniValue& params, bool fHelp);
|
||||
extern UniValue walletlock(const UniValue& params, bool fHelp);
|
||||
extern UniValue encryptwallet(const UniValue& params, bool fHelp);
|
||||
extern UniValue validateaddress(const UniValue& params, bool fHelp);
|
||||
extern UniValue getinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getwalletinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockchaininfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getnetworkinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue setmocktime(const UniValue& params, bool fHelp);
|
||||
extern UniValue resendwallettransactions(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_benchmark(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_raw_keygen(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_raw_joinsplit(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_raw_receive(const UniValue& params, bool fHelp);
|
||||
extern UniValue zc_sample_joinsplit(const UniValue& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value getrawtransaction(const json_spirit::Array& params, bool fHelp); // in rcprawtransaction.cpp
|
||||
extern json_spirit::Value listunspent(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value lockunspent(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value listlockunspent(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value createrawtransaction(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value decoderawtransaction(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value decodescript(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value signrawtransaction(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value sendrawtransaction(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value gettxoutproof(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value verifytxoutproof(const json_spirit::Array& params, bool fHelp);
|
||||
extern UniValue getrawtransaction(const UniValue& params, bool fHelp); // in rcprawtransaction.cpp
|
||||
extern UniValue listunspent(const UniValue& params, bool fHelp);
|
||||
extern UniValue lockunspent(const UniValue& params, bool fHelp);
|
||||
extern UniValue listlockunspent(const UniValue& params, bool fHelp);
|
||||
extern UniValue createrawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue decoderawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue decodescript(const UniValue& params, bool fHelp);
|
||||
extern UniValue signrawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue sendrawtransaction(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettxoutproof(const UniValue& params, bool fHelp);
|
||||
extern UniValue verifytxoutproof(const UniValue& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool fHelp); // in rpcblockchain.cpp
|
||||
extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getmempoolinfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value gettxoutsetinfo(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value gettxout(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value getchaintips(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value invalidateblock(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value reconsiderblock(const json_spirit::Array& params, bool fHelp);
|
||||
extern UniValue getblockcount(const UniValue& params, bool fHelp); // in rpcblockchain.cpp
|
||||
extern UniValue getbestblockhash(const UniValue& params, bool fHelp);
|
||||
extern UniValue getdifficulty(const UniValue& params, bool fHelp);
|
||||
extern UniValue settxfee(const UniValue& params, bool fHelp);
|
||||
extern UniValue getmempoolinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue getrawmempool(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblockhash(const UniValue& params, bool fHelp);
|
||||
extern UniValue getblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettxoutsetinfo(const UniValue& params, bool fHelp);
|
||||
extern UniValue gettxout(const UniValue& params, bool fHelp);
|
||||
extern UniValue verifychain(const UniValue& params, bool fHelp);
|
||||
extern UniValue getchaintips(const UniValue& params, bool fHelp);
|
||||
extern UniValue invalidateblock(const UniValue& params, bool fHelp);
|
||||
extern UniValue reconsiderblock(const UniValue& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value getblocksubsidy(const json_spirit::Array& params, bool fHelp);
|
||||
extern UniValue getblocksubsidy(const UniValue& params, bool fHelp);
|
||||
|
||||
extern json_spirit::Value z_exportkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
|
||||
extern json_spirit::Value z_importkey(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
|
||||
extern json_spirit::Value z_getnewaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_listaddresses(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_exportwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
|
||||
extern json_spirit::Value z_importwallet(const json_spirit::Array& params, bool fHelp); // in rpcdump.cpp
|
||||
extern json_spirit::Value z_listreceivedbyaddress(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_getbalance(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_gettotalbalance(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_sendmany(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_getoperationstatus(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_getoperationresult(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_listoperationids(const json_spirit::Array& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern json_spirit::Value z_validateaddress(const json_spirit::Array& params, bool fHelp); // in rpcmisc.cpp
|
||||
extern UniValue z_exportkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_importkey(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_getnewaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_listaddresses(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_exportwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_importwallet(const UniValue& params, bool fHelp); // in rpcdump.cpp
|
||||
extern UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_getbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_gettotalbalance(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_sendmany(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_getoperationstatus(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_getoperationresult(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_listoperationids(const UniValue& params, bool fHelp); // in rpcwallet.cpp
|
||||
extern UniValue z_validateaddress(const UniValue& params, bool fHelp); // in rpcmisc.cpp
|
||||
|
||||
|
||||
// in rest.cpp
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include <boost/filesystem/operations.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include "json/json_spirit_reader_template.h"
|
||||
|
||||
#include "key.h"
|
||||
#include "alertkeys.h"
|
||||
|
|
|
@ -17,23 +17,20 @@
|
|||
|
||||
#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"
|
||||
|
||||
using namespace json_spirit;
|
||||
extern Array read_json(const std::string& jsondata);
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
extern UniValue read_json(const std::string& jsondata);
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(base58_tests, BasicTestingSetup)
|
||||
|
||||
// Goal: test low-level base58 encoding functionality
|
||||
BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
|
||||
{
|
||||
Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
std::string strTest = test.write();
|
||||
if (test.size() < 2) // Allow for extra stuff (useful for comments)
|
||||
{
|
||||
BOOST_ERROR("Bad test: " << strTest);
|
||||
|
@ -50,13 +47,12 @@ BOOST_AUTO_TEST_CASE(base58_EncodeBase58)
|
|||
// Goal: test low-level base58 decoding functionality
|
||||
BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
|
||||
{
|
||||
Array tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
|
||||
UniValue tests = read_json(std::string(json_tests::base58_encode_decode, json_tests::base58_encode_decode + sizeof(json_tests::base58_encode_decode)));
|
||||
std::vector<unsigned char> result;
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
std::string strTest = test.write();
|
||||
if (test.size() < 2) // Allow for extra stuff (useful for comments)
|
||||
{
|
||||
BOOST_ERROR("Bad test: " << strTest);
|
||||
|
@ -124,16 +120,15 @@ public:
|
|||
// Goal: check that parsed keys match test payload
|
||||
BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
||||
{
|
||||
Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
|
||||
UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
|
||||
std::vector<unsigned char> result;
|
||||
CBitcoinSecret secret;
|
||||
CBitcoinAddress addr;
|
||||
SelectParams(CBaseChainParams::MAIN);
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
std::string strTest = test.write();
|
||||
if (test.size() < 3) // Allow for extra stuff (useful for comments)
|
||||
{
|
||||
BOOST_ERROR("Bad test: " << strTest);
|
||||
|
@ -141,7 +136,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
|||
}
|
||||
std::string exp_base58string = test[0].get_str();
|
||||
std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
|
||||
const Object &metadata = test[2].get_obj();
|
||||
const UniValue &metadata = test[2].get_obj();
|
||||
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
|
||||
bool isTestnet = find_value(metadata, "isTestnet").get_bool();
|
||||
if (isTestnet)
|
||||
|
@ -183,12 +178,12 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_parse)
|
|||
// Goal: check that generated keys match test vectors
|
||||
BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
||||
{
|
||||
Array tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
|
||||
UniValue tests = read_json(std::string(json_tests::base58_keys_valid, json_tests::base58_keys_valid + sizeof(json_tests::base58_keys_valid)));
|
||||
std::vector<unsigned char> result;
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
std::string strTest = test.write();
|
||||
if (test.size() < 3) // Allow for extra stuff (useful for comments)
|
||||
{
|
||||
BOOST_ERROR("Bad test: " << strTest);
|
||||
|
@ -196,7 +191,7 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
|||
}
|
||||
std::string exp_base58string = test[0].get_str();
|
||||
std::vector<unsigned char> exp_payload = ParseHex(test[1].get_str());
|
||||
const Object &metadata = test[2].get_obj();
|
||||
const UniValue &metadata = test[2].get_obj();
|
||||
bool isPrivkey = find_value(metadata, "isPrivkey").get_bool();
|
||||
bool isTestnet = find_value(metadata, "isTestnet").get_bool();
|
||||
if (isTestnet)
|
||||
|
@ -251,15 +246,14 @@ BOOST_AUTO_TEST_CASE(base58_keys_valid_gen)
|
|||
// Goal: check that base58 parsing code is robust against a variety of corrupted data
|
||||
BOOST_AUTO_TEST_CASE(base58_keys_invalid)
|
||||
{
|
||||
Array tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases
|
||||
UniValue tests = read_json(std::string(json_tests::base58_keys_invalid, json_tests::base58_keys_invalid + sizeof(json_tests::base58_keys_invalid))); // Negative testcases
|
||||
std::vector<unsigned char> result;
|
||||
CBitcoinSecret secret;
|
||||
CBitcoinAddress addr;
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
std::string strTest = test.write();
|
||||
if (test.size() < 1) // Allow for extra stuff (useful for comments)
|
||||
{
|
||||
BOOST_ERROR("Bad test: " << strTest);
|
||||
|
|
|
@ -13,22 +13,23 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
Array
|
||||
using namespace std;
|
||||
|
||||
UniValue
|
||||
createArgs(int nRequired, const char* address1=NULL, const char* address2=NULL)
|
||||
{
|
||||
Array result;
|
||||
UniValue result(UniValue::VARR);
|
||||
result.push_back(nRequired);
|
||||
Array addresses;
|
||||
UniValue addresses(UniValue::VARR);
|
||||
if (address1) addresses.push_back(address1);
|
||||
if (address2) addresses.push_back(address2);
|
||||
result.push_back(addresses);
|
||||
return result;
|
||||
}
|
||||
|
||||
Value CallRPC(string args)
|
||||
UniValue CallRPC(string args)
|
||||
{
|
||||
vector<string> vArgs;
|
||||
boost::split(vArgs, args, boost::is_any_of(" \t"));
|
||||
|
@ -40,14 +41,14 @@ Value CallRPC(string args)
|
|||
vArgs[i] = "";
|
||||
}
|
||||
}
|
||||
Array params = RPCConvertValues(strMethod, vArgs);
|
||||
UniValue params = RPCConvertValues(strMethod, vArgs);
|
||||
|
||||
rpcfn_type method = tableRPC[strMethod]->actor;
|
||||
try {
|
||||
Value result = (*method)(params, false);
|
||||
UniValue result = (*method)(params, false);
|
||||
return result;
|
||||
}
|
||||
catch (const Object& objError) {
|
||||
catch (const UniValue& objError) {
|
||||
throw runtime_error(find_value(objError, "message").get_str());
|
||||
}
|
||||
}
|
||||
|
@ -58,7 +59,7 @@ BOOST_FIXTURE_TEST_SUITE(rpc_tests, TestingSetup)
|
|||
BOOST_AUTO_TEST_CASE(rpc_rawparams)
|
||||
{
|
||||
// Test raw transaction API argument handling
|
||||
Value r;
|
||||
UniValue r;
|
||||
|
||||
BOOST_CHECK_THROW(CallRPC("getrawtransaction"), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("getrawtransaction not_hex"), runtime_error);
|
||||
|
@ -98,7 +99,7 @@ BOOST_AUTO_TEST_CASE(rpc_rawparams)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(rpc_rawsign)
|
||||
{
|
||||
Value r;
|
||||
UniValue r;
|
||||
// input is a 1-of-2 multisig (so is output):
|
||||
string prevout =
|
||||
"[{\"txid\":\"b4cc287e58f87cdae59417329f710f3ecd75a4ee1d2872b7248f50977c8493f3\","
|
||||
|
@ -117,20 +118,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)
|
||||
static UniValue ValueFromString(const std::string &str)
|
||||
{
|
||||
Value value;
|
||||
BOOST_CHECK(read_string(str, value));
|
||||
UniValue value;
|
||||
BOOST_CHECK(value.setNumStr(str));
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -148,20 +149,20 @@ BOOST_AUTO_TEST_CASE(rpc_parse_monetary_values)
|
|||
|
||||
BOOST_AUTO_TEST_CASE(json_parse_errors)
|
||||
{
|
||||
Value value;
|
||||
// Valid
|
||||
BOOST_CHECK_EQUAL(read_string(std::string("1.0"), value), true);
|
||||
// Valid, with trailing whitespace
|
||||
BOOST_CHECK_EQUAL(read_string(std::string("1.0 "), value), true);
|
||||
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0").get_real(), 1.0);
|
||||
// Valid, with leading or trailing whitespace
|
||||
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue(" 1.0").get_real(), 1.0);
|
||||
BOOST_CHECK_EQUAL(ParseNonRFCJSONValue("1.0 ").get_real(), 1.0);
|
||||
// Invalid, initial garbage
|
||||
BOOST_CHECK_EQUAL(read_string(std::string("[1.0"), value), false);
|
||||
BOOST_CHECK_EQUAL(read_string(std::string("a1.0"), value), false);
|
||||
BOOST_CHECK_THROW(ParseNonRFCJSONValue("[1.0"), std::runtime_error);
|
||||
BOOST_CHECK_THROW(ParseNonRFCJSONValue("a1.0"), std::runtime_error);
|
||||
// Invalid, trailing garbage
|
||||
BOOST_CHECK_EQUAL(read_string(std::string("1.0sds"), value), false);
|
||||
BOOST_CHECK_EQUAL(read_string(std::string("1.0]"), value), false);
|
||||
BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0sds"), std::runtime_error);
|
||||
BOOST_CHECK_THROW(ParseNonRFCJSONValue("1.0]"), std::runtime_error);
|
||||
// BTC addresses should fail parsing
|
||||
BOOST_CHECK_EQUAL(read_string(std::string("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), value), false);
|
||||
BOOST_CHECK_EQUAL(read_string(std::string("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), value), false);
|
||||
BOOST_CHECK_THROW(ParseNonRFCJSONValue("175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W"), std::runtime_error);
|
||||
BOOST_CHECK_THROW(ParseNonRFCJSONValue("3J98t1WpEZ73CNmQviecrnyiWrnqRhWNL"), std::runtime_error);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rpc_boostasiotocnetaddr)
|
||||
|
|
|
@ -31,15 +31,16 @@
|
|||
#include <boost/format.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
extern Array createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL);
|
||||
extern Value CallRPC(string args);
|
||||
using namespace std;
|
||||
|
||||
extern UniValue createArgs(int nRequired, const char* address1 = NULL, const char* address2 = NULL);
|
||||
extern UniValue CallRPC(string args);
|
||||
|
||||
extern CWallet* pwalletMain;
|
||||
|
||||
bool find_error(const Object& objError, const std::string& expected) {
|
||||
bool find_error(const UniValue& objError, const std::string& expected) {
|
||||
return find_value(objError, "message").get_str().find(expected) != string::npos;
|
||||
}
|
||||
|
||||
|
@ -56,7 +57,7 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig)
|
|||
// new, compressed:
|
||||
const char address2Hex[] = "0388c2037017c62240b6b72ac1a2a5f94da790596ebd06177c8572752922165cb4";
|
||||
|
||||
Value v;
|
||||
UniValue v;
|
||||
CBitcoinAddress address;
|
||||
BOOST_CHECK_NO_THROW(v = addmultisig(createArgs(1, address1Hex), false));
|
||||
address.SetString(v.get_str());
|
||||
|
@ -87,13 +88,13 @@ BOOST_AUTO_TEST_CASE(rpc_addmultisig)
|
|||
BOOST_AUTO_TEST_CASE(rpc_wallet)
|
||||
{
|
||||
// Test RPC calls for various wallet statistics
|
||||
Value r;
|
||||
UniValue r;
|
||||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
CPubKey demoPubkey = pwalletMain->GenerateNewKey();
|
||||
CBitcoinAddress demoAddress = CBitcoinAddress(CTxDestination(demoPubkey.GetID()));
|
||||
Value retValue;
|
||||
UniValue retValue;
|
||||
string strAccount = "";
|
||||
string strPurpose = "receive";
|
||||
BOOST_CHECK_NO_THROW({ /*Initialize Wallet with an account */
|
||||
|
@ -239,10 +240,10 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|||
*********************************/
|
||||
BOOST_CHECK_THROW(CallRPC("getaddressesbyaccount"), runtime_error);
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getaddressesbyaccount " + strAccount));
|
||||
Array arr = retValue.get_array();
|
||||
UniValue arr = retValue.get_array();
|
||||
BOOST_CHECK_EQUAL(4, arr.size());
|
||||
bool notFound = true;
|
||||
for (auto a : arr) {
|
||||
for (auto a : arr.getValues()) {
|
||||
notFound &= CBitcoinAddress(a.get_str()).Get() != demoAddress.Get();
|
||||
}
|
||||
BOOST_CHECK(!notFound);
|
||||
|
@ -253,17 +254,17 @@ BOOST_AUTO_TEST_CASE(rpc_wallet)
|
|||
BOOST_CHECK_THROW(CallRPC("getblocksubsidy too many args"), runtime_error);
|
||||
BOOST_CHECK_THROW(CallRPC("getblocksubsidy -1"), runtime_error);
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getblocksubsidy 50000"));
|
||||
Object obj = retValue.get_obj();
|
||||
BOOST_CHECK(find_value(obj, "miner") == 10.0);
|
||||
BOOST_CHECK(find_value(obj, "founders") == 2.5);
|
||||
UniValue obj = retValue.get_obj();
|
||||
BOOST_CHECK_EQUAL(find_value(obj, "miner").get_real(), 10.0);
|
||||
BOOST_CHECK_EQUAL(find_value(obj, "founders").get_real(), 2.5);
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getblocksubsidy 1000000"));
|
||||
obj = retValue.get_obj();
|
||||
BOOST_CHECK(find_value(obj, "miner") == 6.25);
|
||||
BOOST_CHECK(find_value(obj, "founders") == 0.0);
|
||||
BOOST_CHECK_EQUAL(find_value(obj, "miner").get_real(), 6.25);
|
||||
BOOST_CHECK_EQUAL(find_value(obj, "founders").get_real(), 0.0);
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getblocksubsidy 2000000"));
|
||||
obj = retValue.get_obj();
|
||||
BOOST_CHECK(find_value(obj, "miner") == 3.125);
|
||||
BOOST_CHECK(find_value(obj, "founders") == 0.0);
|
||||
BOOST_CHECK_EQUAL(find_value(obj, "miner").get_real(), 3.125);
|
||||
BOOST_CHECK_EQUAL(find_value(obj, "founders").get_real(), 0.0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rpc_wallet_getbalance)
|
||||
|
@ -304,7 +305,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_validateaddress)
|
|||
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
Value retValue;
|
||||
UniValue retValue;
|
||||
|
||||
// Check number of args
|
||||
BOOST_CHECK_THROW(CallRPC("z_validateaddress"), runtime_error);
|
||||
|
@ -317,7 +318,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_validateaddress)
|
|||
|
||||
// This address is not valid, it belongs to another network
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_validateaddress ztaaga95QAPyp1kSQ1hD2kguCpzyMHjxWZqaYDEkzbvo7uYQYAw2S8X4Kx98AvhhofMtQL8PAXKHuZsmhRcanavKRKmdCzk"));
|
||||
Object resultObj = retValue.get_obj();
|
||||
UniValue resultObj = retValue.get_obj();
|
||||
bool b = find_value(resultObj, "isvalid").get_bool();
|
||||
BOOST_CHECK_EQUAL(b, false);
|
||||
|
||||
|
@ -484,7 +485,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importwallet)
|
|||
BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
||||
{
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
Value retValue;
|
||||
UniValue retValue;
|
||||
int n1 = 1000; // number of times to import/export
|
||||
int n2 = 1000; // number of addresses to create and list
|
||||
|
||||
|
@ -515,12 +516,12 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
|||
|
||||
// Verify we can list the keys imported
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses"));
|
||||
Array arr = retValue.get_array();
|
||||
UniValue arr = retValue.get_array();
|
||||
BOOST_CHECK(arr.size() == n1);
|
||||
|
||||
// Put addresses into a set
|
||||
std::unordered_set<std::string> myaddrs;
|
||||
for (Value element : arr) {
|
||||
for (UniValue element : arr.getValues()) {
|
||||
myaddrs.insert(element.get_str());
|
||||
}
|
||||
|
||||
|
@ -542,7 +543,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_z_importexport)
|
|||
|
||||
// Create a set from them
|
||||
std::unordered_set<std::string> listaddrs;
|
||||
for (Value element : arr) {
|
||||
for (UniValue element : arr.getValues()) {
|
||||
listaddrs.insert(element.get_str());
|
||||
}
|
||||
|
||||
|
@ -581,7 +582,7 @@ public:
|
|||
start_execution_clock();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(naptime));
|
||||
stop_execution_clock();
|
||||
set_result(Value("done"));
|
||||
set_result(UniValue(UniValue::VSTR, "done"));
|
||||
set_state(OperationStatus::SUCCESS);
|
||||
}
|
||||
};
|
||||
|
@ -620,8 +621,8 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_async_operations)
|
|||
BOOST_CHECK_EQUAL(op1->isReady(), false);
|
||||
BOOST_CHECK_EQUAL(op1->isFailed(), false);
|
||||
BOOST_CHECK_EQUAL(op1->isSuccess(), true);
|
||||
BOOST_CHECK(op1->getError() == Value::null );
|
||||
BOOST_CHECK(op1->getResult().is_null() == false );
|
||||
BOOST_CHECK_EQUAL(op1->getError().isNull(), true);
|
||||
BOOST_CHECK_EQUAL(op1->getResult().isNull(), false);
|
||||
BOOST_CHECK_EQUAL(op1->getStateAsString(), "success");
|
||||
BOOST_CHECK_NE(op1->getStateAsString(), "executing");
|
||||
|
||||
|
@ -781,12 +782,12 @@ BOOST_AUTO_TEST_CASE(rpc_z_getoperations)
|
|||
// Check if too many args
|
||||
BOOST_CHECK_THROW(CallRPC("z_listoperationids toomany args"), runtime_error);
|
||||
|
||||
Value retValue;
|
||||
UniValue retValue;
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listoperationids"));
|
||||
BOOST_CHECK(retValue.get_array().size() == 2);
|
||||
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_getoperationstatus"));
|
||||
Array array = retValue.get_array();
|
||||
UniValue array = retValue.get_array();
|
||||
BOOST_CHECK(array.size() == 2);
|
||||
|
||||
// idempotent
|
||||
|
@ -794,18 +795,18 @@ BOOST_AUTO_TEST_CASE(rpc_z_getoperations)
|
|||
array = retValue.get_array();
|
||||
BOOST_CHECK(array.size() == 2);
|
||||
|
||||
for (Value v : array) {
|
||||
Object obj = v.get_obj();
|
||||
Value id = find_value(obj, "id");
|
||||
for (UniValue v : array.getValues()) {
|
||||
UniValue obj = v.get_obj();
|
||||
UniValue id = find_value(obj, "id");
|
||||
|
||||
Value result;
|
||||
UniValue result;
|
||||
// removes result from internal storage
|
||||
BOOST_CHECK_NO_THROW(result = CallRPC("z_getoperationresult [\"" + id.get_str() + "\"]"));
|
||||
Array resultArray = result.get_array();
|
||||
UniValue resultArray = result.get_array();
|
||||
BOOST_CHECK(resultArray.size() == 1);
|
||||
|
||||
Object resultObj = resultArray.front().get_obj();
|
||||
Value resultId = find_value(resultObj, "id");
|
||||
UniValue resultObj = resultArray[0].get_obj();
|
||||
UniValue resultId = find_value(resultObj, "id");
|
||||
BOOST_CHECK_EQUAL(id.get_str(), resultId.get_str());
|
||||
|
||||
// verify the operation has been removed
|
||||
|
@ -884,26 +885,26 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
|
|||
// Test constructor of AsyncRPCOperation_sendmany
|
||||
try {
|
||||
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_sendmany("",{}, {}, -1));
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "Minconf cannot be negative"));
|
||||
}
|
||||
|
||||
try {
|
||||
std::shared_ptr<AsyncRPCOperation> operation(new AsyncRPCOperation_sendmany("",{}, {}, 1));
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "From address parameter missing"));
|
||||
}
|
||||
|
||||
try {
|
||||
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany("tmRr6yJonqGK23UVhrKuyvTpF8qxQQjKigJ", {}, {}, 1) );
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "No recipients"));
|
||||
}
|
||||
|
||||
try {
|
||||
std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") };
|
||||
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany("INVALID", recipients, {}, 1) );
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "payment address is invalid"));
|
||||
}
|
||||
|
||||
|
@ -911,7 +912,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
|
|||
try {
|
||||
std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") };
|
||||
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany("zcMuhvq8sEkHALuSU2i4NbNQxshSAYrpCExec45ZjtivYPbuiFPwk6WHy4SvsbeZ4siy1WheuRGjtaJmoD1J8bFqNXhsG6U", recipients, {}, 1) );
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "payment address is for wrong network type"));
|
||||
}
|
||||
|
||||
|
@ -920,7 +921,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_parameters)
|
|||
try {
|
||||
std::vector<SendManyRecipient> recipients = { SendManyRecipient("dummy",1.0, "") };
|
||||
std::shared_ptr<AsyncRPCOperation> operation( new AsyncRPCOperation_sendmany("ztjiDe569DPNbyTE6TSdJTaSDhoXEHLGvYoUnBU1wfVNU52TEyT6berYtySkd21njAeEoh8fFJUT42kua9r8EnhBaEKqCpP", recipients, {}, 1) );
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "no spending key found for zaddr"));
|
||||
}
|
||||
}
|
||||
|
@ -933,7 +934,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
|||
|
||||
LOCK(pwalletMain->cs_wallet);
|
||||
|
||||
Value retValue;
|
||||
UniValue retValue;
|
||||
|
||||
// add keys manually
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("getnewaddress"));
|
||||
|
@ -985,7 +986,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
|||
|
||||
try {
|
||||
proxy.get_memo_from_hex_string(bigmemo);
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "too big"));
|
||||
}
|
||||
|
||||
|
@ -995,7 +996,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
|||
|
||||
try {
|
||||
proxy.get_memo_from_hex_string(badmemo);
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "hexadecimal format"));
|
||||
}
|
||||
|
||||
|
@ -1006,7 +1007,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
|||
std::string oddmemo(v.begin(), v.end());
|
||||
try {
|
||||
proxy.get_memo_from_hex_string(oddmemo);
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
BOOST_CHECK( find_error(objError, "hexadecimal format"));
|
||||
}
|
||||
}
|
||||
|
@ -1061,7 +1062,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
|||
// Raw joinsplit is a zaddr->zaddr
|
||||
{
|
||||
std::string raw = "020000000000000000000100000000000000001027000000000000183a0d4c46c369078705e39bcfebee59a978dbd210ce8de3efc9555a03fbabfd3cea16693d730c63850d7e48ccde79854c19adcb7e9dcd7b7d18805ee09083f6b16e1860729d2d4a90e2f2acd009cf78b5eb0f4a6ee4bdb64b1262d7ce9eb910c460b02022991e968d0c50ee44908e4ccccbc591d0053bcca154dd6d6fc400a29fa686af4682339832ccea362a62aeb9df0d5aa74f86a1e75ac0f48a8ccc41e0a940643c6c33e1d09223b0a46eaf47a1bb4407cfc12b1dcf83a29c0cef51e45c7876ca5b9e5bae86d92976eb3ef68f29cd29386a8be8451b50f82bf9da10c04651868655194da8f6ed3d241bb5b5ff93a3e2bbe44644544d88bcde5cc35978032ee92699c7a61fcbb395e7583f47e698c4d53ede54f956629400bf510fb5e22d03158cc10bdcaaf29e418ef18eb6480dd9c8b9e2a377809f9f32a556ef872febd0021d4ad013aa9f0b7255e98e408d302abefd33a71180b720271835b487ab309e160b06dfe51932120fb84a7ede16b20c53599a11071592109e10260f265ee60d48c62bfe24074020e9b586ce9e9356e68f2ad1a9538258234afe4b83a209f178f45202270eaeaeecaf2ce3100b2c5a714f75f35777a9ebff5ebf47059d2bbf6f3726190216468f2b152673b766225b093f3a2f827c86d6b48b42117fec1d0ac38dd7af700308dcfb02eba821612b16a2c164c47715b9b0c93900893b1aba2ea03765c94d87022db5be06ab338d1912e0936dfe87586d0a8ee49144a6cd2e306abdcb652faa3e0222739deb23154d778b50de75069a4a2cce1208cd1ced3cb4744c9888ce1c2fcd2e66dc31e62d3aa9e423d7275882525e9981f92e84ac85975b8660739407efbe1e34c2249420fde7e17db3096d5b22e83d051d01f0e6e7690dca7d168db338aadf0897fedac10de310db2b1bff762d322935dddbb60c2efb8b15d231fa17b84630371cb275c209f0c4c7d0c68b150ea5cd514122215e3f7fcfb351d69514788d67c2f3c8922581946e3a04bdf1f07f15696ca76eb95b10698bf1188fd882945c57657515889d042a6fc45d38cbc943540c4f0f6d1c45a1574c81f3e42d1eb8702328b729909adee8a5cfed7c79d54627d1fd389af941d878376f7927b9830ca659bf9ab18c5ca5192d52d02723008728d03701b8ab3e1c4a3109409ec0b13df334c7deec3523eeef4c97b5603e643de3a647b873f4c1b47fbfc6586ba66724f112e51fc93839648005043620aa3ce458e246d77977b19c53d98e3e812de006afc1a79744df236582943631d04cc02941ac4be500e4ed9fb9e3e7cc187b1c4050fad1d9d09d5fd70d5d01d615b439d8c0015d2eb10398bcdbf8c4b2bd559dbe4c288a186aed3f86f608da4d582e120c4a896e015e2241900d1daeccd05db968852677c71d752bec46de9962174b46f980e8cc603654daf8b98a3ee92dac066033954164a89568b70b1780c2ce2410b2f816dbeddb2cd463e0c8f21a52cf6427d9647a6fd4bafa8fb4cd4d47ac057b0160bee86c6b2fb8adce214c2bcdda277512200adf0eaa5d2114a2c077b009836a68ec254bfe56f51d147b9afe2ddd9cb917c0c2de19d81b7b8fd9f4574f51fa1207630dc13976f4d7587c962f761af267de71f3909a576e6bedaf6311633910d291ac292c467cc8331ef577aef7646a5d949322fa0367a49f20597a13def53136ee31610395e3e48d291fd8f58504374031fe9dcfba5e06086ebcf01a9106f6a4d6e16e19e4c5bb893f7da79419c94eca31a384be6fa1747284dee0fc3bbc8b1b860172c10b29c1594bb8c747d7fe05827358ff2160f49050001625ffe2e880bd7fc26cd0ffd89750745379a8e862816e08a5a2008043921ab6a4976064ac18f7ee37b6628bc0127d8d5ebd3548e41d8881a082d86f20b32e33094f15a0e6ea6074b08c6cd28142de94713451640a55985051f5577eb54572699d838cb34a79c8939e981c0c277d06a6e2ce69ccb74f8a691ff08f81d8b99e6a86223d29a2b7c8e7b041aba44ea678ae654277f7e91cbfa79158b989164a3d549d9f4feb0cc43169699c13e321fe3f4b94258c75d198ff9184269cd6986c55409e07528c93f64942c6c283ce3917b4bf4c3be2fe3173c8c38cccb35f1fbda0ca88b35a599c0678cb22aa8eabea8249dbd2e4f849fffe69803d299e435ebcd7df95854003d8eda17a74d98b4be0e62d45d7fe48c06a6f464a14f8e0570077cc631279092802a89823f031eef5e1028a6d6fdbd502869a731ee7d28b4d6c71b419462a30d31442d3ee444ffbcbd16d558c9000c97e949c2b1f9d6f6d8db7b9131ebd963620d3fc8595278d6f8fdf49084325373196d53e64142fa5a23eccd6ef908c4d80b8b3e6cc334b7f7012103a3682e4678e9b518163d262a39a2c1a69bf88514c52b7ccd7cc8dc80e71f7c2ec0701cff982573eb0c2c4daeb47fa0b586f4451c10d1da2e5d182b03dd067a5e971b3a6138ca6667aaf853d2ac03b80a1d5870905f2cfb6c78ec3c3719c02f973d638a0f973424a2b0f2b0023f136d60092fe15fba4bc180b9176bd0ff576e053f1af6939fe9ca256203ffaeb3e569f09774d2a6cbf91873e56651f4d6ff77e0b5374b0a1a201d7e523604e0247644544cc571d48c458a4f96f45580b";
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("rawtxn", raw));
|
||||
|
||||
// we have the spending key for the dummy recipient zaddr1
|
||||
|
@ -1079,9 +1080,9 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
|||
|
||||
// Verify test mode is returning output (since no input taddrs, signed and unsigned are the same).
|
||||
BOOST_CHECK_NO_THROW( proxy.sign_send_raw_transaction(obj) );
|
||||
Value result = operation->getResult();
|
||||
BOOST_CHECK(!result.is_null());
|
||||
Object resultObj = result.get_obj();
|
||||
UniValue result = operation->getResult();
|
||||
BOOST_CHECK(!result.isNull());
|
||||
UniValue resultObj = result.get_obj();
|
||||
std::string hex = find_value(resultObj, "hex").get_str();
|
||||
BOOST_CHECK_EQUAL(hex, raw);
|
||||
}
|
||||
|
@ -1149,7 +1150,7 @@ BOOST_AUTO_TEST_CASE(rpc_z_sendmany_internals)
|
|||
BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys)
|
||||
{
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
Value retValue;
|
||||
UniValue retValue;
|
||||
int n = 100;
|
||||
|
||||
// wallet should currently be empty
|
||||
|
@ -1164,7 +1165,7 @@ BOOST_AUTO_TEST_CASE(rpc_wallet_encrypted_wallet_zkeys)
|
|||
|
||||
// Verify we can list the keys imported
|
||||
BOOST_CHECK_NO_THROW(retValue = CallRPC("z_listaddresses"));
|
||||
Array arr = retValue.get_array();
|
||||
UniValue arr = retValue.get_array();
|
||||
BOOST_CHECK(arr.size() == n);
|
||||
|
||||
// Verify that the wallet encryption RPC is disabled
|
||||
|
|
|
@ -26,12 +26,10 @@
|
|||
|
||||
#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 "univalue/univalue.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
// Uncomment if you want to output updated JSON tests.
|
||||
// #define UPDATE_JSON_TESTS
|
||||
|
@ -41,15 +39,15 @@ static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC;
|
|||
unsigned int ParseScriptFlags(string strFlags);
|
||||
string FormatScriptFlags(unsigned int flags);
|
||||
|
||||
Array
|
||||
UniValue
|
||||
read_json(const std::string& jsondata)
|
||||
{
|
||||
Value v;
|
||||
UniValue v;
|
||||
|
||||
if (!read_string(jsondata, v) || v.type() != array_type)
|
||||
if (!v.read(jsondata) || !v.isArray())
|
||||
{
|
||||
BOOST_ERROR("Parse error.");
|
||||
return Array();
|
||||
return UniValue(UniValue::VARR);
|
||||
}
|
||||
return v.get_array();
|
||||
}
|
||||
|
@ -295,10 +293,10 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
Array GetJSON()
|
||||
UniValue GetJSON()
|
||||
{
|
||||
DoPush();
|
||||
Array array;
|
||||
UniValue array(UniValue::VARR);
|
||||
array.push_back(FormatScript(spendTx.vin[0].scriptSig));
|
||||
array.push_back(FormatScript(creditTx.vout[0].scriptPubKey));
|
||||
array.push_back(FormatScriptFlags(flags));
|
||||
|
@ -582,14 +580,16 @@ BOOST_AUTO_TEST_CASE(script_build)
|
|||
std::set<std::string> tests_bad;
|
||||
|
||||
{
|
||||
Array json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
|
||||
Array json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
|
||||
UniValue json_good = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
|
||||
UniValue json_bad = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
|
||||
|
||||
BOOST_FOREACH(Value& tv, json_good) {
|
||||
tests_good.insert(write_string(Value(tv.get_array()), true));
|
||||
for (size_t idx = 0; idx < json_good.size(); idx++) {
|
||||
const UniValue& tv = json_good[idx];
|
||||
tests_good.insert(tv.get_array().write());
|
||||
}
|
||||
BOOST_FOREACH(Value& tv, json_bad) {
|
||||
tests_bad.insert(write_string(Value(tv.get_array()), true));
|
||||
for (size_t idx = 0; idx < json_bad.size(); idx++) {
|
||||
const UniValue& tv = json_bad[idx];
|
||||
tests_bad.insert(tv.get_array().write());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,7 +598,7 @@ BOOST_AUTO_TEST_CASE(script_build)
|
|||
|
||||
BOOST_FOREACH(TestBuilder& test, good) {
|
||||
test.Test(true);
|
||||
std::string str = write_string(Value(test.GetJSON()), true);
|
||||
std::string str = test.GetJSON().write();
|
||||
#ifndef UPDATE_JSON_TESTS
|
||||
if (tests_good.count(str) == 0) {
|
||||
BOOST_CHECK_MESSAGE(false, "Missing auto script_valid test: " + test.GetComment());
|
||||
|
@ -608,7 +608,7 @@ BOOST_AUTO_TEST_CASE(script_build)
|
|||
}
|
||||
BOOST_FOREACH(TestBuilder& test, bad) {
|
||||
test.Test(false);
|
||||
std::string str = write_string(Value(test.GetJSON()), true);
|
||||
std::string str = test.GetJSON().write();
|
||||
#ifndef UPDATE_JSON_TESTS
|
||||
if (tests_bad.count(str) == 0) {
|
||||
BOOST_CHECK_MESSAGE(false, "Missing auto script_invalid test: " + test.GetComment());
|
||||
|
@ -634,12 +634,11 @@ BOOST_AUTO_TEST_CASE(script_valid)
|
|||
// Inner arrays are [ "scriptSig", "scriptPubKey", "flags" ]
|
||||
// ... where scriptSig and scriptPubKey are stringified
|
||||
// scripts.
|
||||
Array tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
|
||||
UniValue tests = read_json(std::string(json_tests::script_valid, json_tests::script_valid + sizeof(json_tests::script_valid)));
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
string strTest = write_string(tv, false);
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
string strTest = test.write();
|
||||
if (test.size() < 3) // Allow size > 3; extra stuff ignored (useful for comments)
|
||||
{
|
||||
if (test.size() != 1) {
|
||||
|
@ -660,13 +659,12 @@ BOOST_AUTO_TEST_CASE(script_valid)
|
|||
BOOST_AUTO_TEST_CASE(script_invalid)
|
||||
{
|
||||
// Scripts that should evaluate as invalid
|
||||
Array tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
|
||||
UniValue tests = read_json(std::string(json_tests::script_invalid, json_tests::script_invalid + sizeof(json_tests::script_invalid)));
|
||||
|
||||
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 (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
string strTest = test.write();
|
||||
if (test.size() < 3) // Allow size > 2; extra stuff ignored (useful for comments)
|
||||
{
|
||||
if (test.size() != 1) {
|
||||
BOOST_ERROR("Bad test: " << strTest);
|
||||
|
|
|
@ -17,12 +17,10 @@
|
|||
#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"
|
||||
|
||||
using namespace json_spirit;
|
||||
extern Array read_json(const std::string& jsondata);
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
extern UniValue read_json(const std::string& jsondata);
|
||||
|
||||
// Old script.cpp SignatureHash function
|
||||
uint256 static SignatureHashOld(CScript scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
|
||||
|
@ -205,12 +203,11 @@ BOOST_AUTO_TEST_CASE(sighash_test)
|
|||
// Goal: check that SignatureHash generates correct hash
|
||||
BOOST_AUTO_TEST_CASE(sighash_from_data)
|
||||
{
|
||||
Array tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash)));
|
||||
UniValue tests = read_json(std::string(json_tests::sighash, json_tests::sighash + sizeof(json_tests::sighash)));
|
||||
|
||||
BOOST_FOREACH(Value& tv, tests)
|
||||
{
|
||||
Array test = tv.get_array();
|
||||
std::string strTest = write_string(tv, false);
|
||||
for (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
std::string strTest = test.write();
|
||||
if (test.size() < 1) // Allow for extra stuff (useful for comments)
|
||||
{
|
||||
BOOST_ERROR("Bad test: " << strTest);
|
||||
|
|
|
@ -23,19 +23,20 @@
|
|||
|
||||
#include <boost/algorithm/string/classification.hpp>
|
||||
#include <boost/algorithm/string/split.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <boost/assign/list_of.hpp>
|
||||
#include "json/json_spirit_writer_template.h"
|
||||
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
#include "zcash/Note.hpp"
|
||||
#include "zcash/Address.hpp"
|
||||
#include "zcash/Proof.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace json_spirit;
|
||||
|
||||
// In script_tests.cpp
|
||||
extern Array read_json(const std::string& jsondata);
|
||||
extern UniValue read_json(const std::string& jsondata);
|
||||
|
||||
static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
|
||||
(string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE)
|
||||
|
@ -96,33 +97,32 @@ BOOST_AUTO_TEST_CASE(tx_valid)
|
|||
// ... where all scripts are stringified scripts.
|
||||
//
|
||||
// verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
|
||||
Array tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid)));
|
||||
UniValue tests = read_json(std::string(json_tests::tx_valid, json_tests::tx_valid + sizeof(json_tests::tx_valid)));
|
||||
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
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 (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
string strTest = test.write();
|
||||
if (test[0].isArray())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
map<COutPoint, CScript> mapprevOutScriptPubKeys;
|
||||
Array inputs = test[0].get_array();
|
||||
UniValue inputs = test[0].get_array();
|
||||
bool fValid = true;
|
||||
BOOST_FOREACH(Value& input, inputs)
|
||||
{
|
||||
if (input.type() != array_type)
|
||||
for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
|
||||
const UniValue& input = inputs[inpIdx];
|
||||
if (!input.isArray())
|
||||
{
|
||||
fValid = false;
|
||||
break;
|
||||
}
|
||||
Array vinput = input.get_array();
|
||||
UniValue vinput = input.get_array();
|
||||
if (vinput.size() != 3)
|
||||
{
|
||||
fValid = false;
|
||||
|
@ -173,33 +173,32 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
|
|||
// ... where all scripts are stringified scripts.
|
||||
//
|
||||
// verifyFlags is a comma separated list of script verification flags to apply, or "NONE"
|
||||
Array tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
|
||||
UniValue tests = read_json(std::string(json_tests::tx_invalid, json_tests::tx_invalid + sizeof(json_tests::tx_invalid)));
|
||||
|
||||
auto verifier = libzcash::ProofVerifier::Strict();
|
||||
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 (size_t idx = 0; idx < tests.size(); idx++) {
|
||||
UniValue test = tests[idx];
|
||||
string strTest = test.write();
|
||||
if (test[0].isArray())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
map<COutPoint, CScript> mapprevOutScriptPubKeys;
|
||||
Array inputs = test[0].get_array();
|
||||
UniValue inputs = test[0].get_array();
|
||||
bool fValid = true;
|
||||
BOOST_FOREACH(Value& input, inputs)
|
||||
{
|
||||
if (input.type() != array_type)
|
||||
for (size_t inpIdx = 0; inpIdx < inputs.size(); inpIdx++) {
|
||||
const UniValue& input = inputs[inpIdx];
|
||||
if (!input.isArray())
|
||||
{
|
||||
fValid = false;
|
||||
break;
|
||||
}
|
||||
Array vinput = input.get_array();
|
||||
UniValue vinput = input.get_array();
|
||||
if (vinput.size() != 3)
|
||||
{
|
||||
fValid = false;
|
||||
|
|
|
@ -49,7 +49,7 @@ BOOST_AUTO_TEST_CASE(univalue_constructor)
|
|||
|
||||
double vd = -7.21;
|
||||
UniValue v7(vd);
|
||||
BOOST_CHECK(v7.isNum());
|
||||
BOOST_CHECK(v7.isReal());
|
||||
BOOST_CHECK_EQUAL(v7.getValStr(), "-7.21");
|
||||
|
||||
string vs("yawn");
|
||||
|
@ -63,6 +63,48 @@ BOOST_AUTO_TEST_CASE(univalue_constructor)
|
|||
BOOST_CHECK_EQUAL(v9.getValStr(), "zappa");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(univalue_typecheck)
|
||||
{
|
||||
UniValue v1;
|
||||
BOOST_CHECK(v1.setNumStr("1"));
|
||||
BOOST_CHECK(v1.isNum());
|
||||
BOOST_CHECK_THROW(v1.get_bool(), runtime_error);
|
||||
|
||||
UniValue v2;
|
||||
BOOST_CHECK(v2.setBool(true));
|
||||
BOOST_CHECK_EQUAL(v2.get_bool(), true);
|
||||
BOOST_CHECK_THROW(v2.get_int(), runtime_error);
|
||||
|
||||
UniValue v3;
|
||||
BOOST_CHECK(v3.setNumStr("32482348723847471234"));
|
||||
BOOST_CHECK_THROW(v3.get_int64(), runtime_error);
|
||||
BOOST_CHECK(v3.setNumStr("1000"));
|
||||
BOOST_CHECK_EQUAL(v3.get_int64(), 1000);
|
||||
|
||||
UniValue v4;
|
||||
BOOST_CHECK(v4.setNumStr("2147483648"));
|
||||
BOOST_CHECK_EQUAL(v4.get_int64(), 2147483648);
|
||||
BOOST_CHECK_THROW(v4.get_int(), runtime_error);
|
||||
BOOST_CHECK(v4.setNumStr("1000"));
|
||||
BOOST_CHECK_EQUAL(v4.get_int(), 1000);
|
||||
BOOST_CHECK_THROW(v4.get_str(), runtime_error);
|
||||
BOOST_CHECK_EQUAL(v4.get_real(), 1000);
|
||||
BOOST_CHECK_THROW(v4.get_array(), runtime_error);
|
||||
BOOST_CHECK_THROW(v4.getKeys(), runtime_error);
|
||||
BOOST_CHECK_THROW(v4.getValues(), runtime_error);
|
||||
BOOST_CHECK_THROW(v4.get_obj(), runtime_error);
|
||||
|
||||
UniValue v5;
|
||||
BOOST_CHECK(v5.read("[true, 10]"));
|
||||
BOOST_CHECK_NO_THROW(v5.get_array());
|
||||
std::vector<UniValue> vals = v5.getValues();
|
||||
BOOST_CHECK_THROW(vals[0].get_int(), runtime_error);
|
||||
BOOST_CHECK_EQUAL(vals[0].get_bool(), true);
|
||||
|
||||
BOOST_CHECK_EQUAL(vals[1].get_int(), 10);
|
||||
BOOST_CHECK_THROW(vals[1].get_bool(), runtime_error);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(univalue_set)
|
||||
{
|
||||
UniValue v(UniValue::VSTR, "foo");
|
||||
|
@ -72,20 +114,20 @@ BOOST_AUTO_TEST_CASE(univalue_set)
|
|||
|
||||
BOOST_CHECK(v.setObject());
|
||||
BOOST_CHECK(v.isObject());
|
||||
BOOST_CHECK_EQUAL(v.count(), 0);
|
||||
BOOST_CHECK_EQUAL(v.size(), 0);
|
||||
BOOST_CHECK_EQUAL(v.getType(), UniValue::VOBJ);
|
||||
BOOST_CHECK(v.empty());
|
||||
|
||||
BOOST_CHECK(v.setArray());
|
||||
BOOST_CHECK(v.isArray());
|
||||
BOOST_CHECK_EQUAL(v.count(), 0);
|
||||
BOOST_CHECK_EQUAL(v.size(), 0);
|
||||
|
||||
BOOST_CHECK(v.setStr("zum"));
|
||||
BOOST_CHECK(v.isStr());
|
||||
BOOST_CHECK_EQUAL(v.getValStr(), "zum");
|
||||
|
||||
BOOST_CHECK(v.setFloat(-1.01));
|
||||
BOOST_CHECK(v.isNum());
|
||||
BOOST_CHECK(v.isReal());
|
||||
BOOST_CHECK_EQUAL(v.getValStr(), "-1.01");
|
||||
|
||||
BOOST_CHECK(v.setInt((int)1023));
|
||||
|
@ -145,7 +187,7 @@ BOOST_AUTO_TEST_CASE(univalue_array)
|
|||
BOOST_CHECK(arr.push_backV(vec));
|
||||
|
||||
BOOST_CHECK_EQUAL(arr.empty(), false);
|
||||
BOOST_CHECK_EQUAL(arr.count(), 5);
|
||||
BOOST_CHECK_EQUAL(arr.size(), 5);
|
||||
|
||||
BOOST_CHECK_EQUAL(arr[0].getValStr(), "1023");
|
||||
BOOST_CHECK_EQUAL(arr[1].getValStr(), "zippy");
|
||||
|
@ -157,7 +199,7 @@ BOOST_AUTO_TEST_CASE(univalue_array)
|
|||
|
||||
arr.clear();
|
||||
BOOST_CHECK(arr.empty());
|
||||
BOOST_CHECK_EQUAL(arr.count(), 0);
|
||||
BOOST_CHECK_EQUAL(arr.size(), 0);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(univalue_object)
|
||||
|
@ -197,7 +239,7 @@ BOOST_AUTO_TEST_CASE(univalue_object)
|
|||
BOOST_CHECK(obj.pushKVs(obj2));
|
||||
|
||||
BOOST_CHECK_EQUAL(obj.empty(), false);
|
||||
BOOST_CHECK_EQUAL(obj.count(), 9);
|
||||
BOOST_CHECK_EQUAL(obj.size(), 9);
|
||||
|
||||
BOOST_CHECK_EQUAL(obj["age"].getValStr(), "100");
|
||||
BOOST_CHECK_EQUAL(obj["first"].getValStr(), "John");
|
||||
|
@ -230,7 +272,7 @@ BOOST_AUTO_TEST_CASE(univalue_object)
|
|||
objTypes["distance"] = UniValue::VNUM;
|
||||
objTypes["time"] = UniValue::VNUM;
|
||||
objTypes["calories"] = UniValue::VNUM;
|
||||
objTypes["temperature"] = UniValue::VNUM;
|
||||
objTypes["temperature"] = UniValue::VREAL;
|
||||
objTypes["cat1"] = UniValue::VNUM;
|
||||
objTypes["cat2"] = UniValue::VNUM;
|
||||
BOOST_CHECK(obj.checkObject(objTypes));
|
||||
|
@ -240,11 +282,11 @@ BOOST_AUTO_TEST_CASE(univalue_object)
|
|||
|
||||
obj.clear();
|
||||
BOOST_CHECK(obj.empty());
|
||||
BOOST_CHECK_EQUAL(obj.count(), 0);
|
||||
BOOST_CHECK_EQUAL(obj.size(), 0);
|
||||
}
|
||||
|
||||
static const char *json1 =
|
||||
"[1.1,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]";
|
||||
"[1.10000000,{\"key1\":\"str\",\"key2\":800,\"key3\":{\"name\":\"martian\"}}]";
|
||||
|
||||
BOOST_AUTO_TEST_CASE(univalue_readwrite)
|
||||
{
|
||||
|
@ -255,13 +297,13 @@ BOOST_AUTO_TEST_CASE(univalue_readwrite)
|
|||
BOOST_CHECK(v.read(strJson1));
|
||||
|
||||
BOOST_CHECK(v.isArray());
|
||||
BOOST_CHECK_EQUAL(v.count(), 2);
|
||||
BOOST_CHECK_EQUAL(v.size(), 2);
|
||||
|
||||
BOOST_CHECK_EQUAL(v[0].getValStr(), "1.1");
|
||||
BOOST_CHECK_EQUAL(v[0].getValStr(), "1.10000000");
|
||||
|
||||
UniValue obj = v[1];
|
||||
BOOST_CHECK(obj.isObject());
|
||||
BOOST_CHECK_EQUAL(obj.count(), 3);
|
||||
BOOST_CHECK_EQUAL(obj.size(), 3);
|
||||
|
||||
BOOST_CHECK(obj["key1"].isStr());
|
||||
BOOST_CHECK_EQUAL(obj["key1"].getValStr(), "str");
|
||||
|
|
|
@ -322,9 +322,16 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32)
|
|||
BOOST_CHECK(ParseInt32("-2147483648", &n) && n == -2147483648);
|
||||
BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234);
|
||||
// Invalid values
|
||||
BOOST_CHECK(!ParseInt32("", &n));
|
||||
BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside
|
||||
BOOST_CHECK(!ParseInt32("1 ", &n));
|
||||
BOOST_CHECK(!ParseInt32("1a", &n));
|
||||
BOOST_CHECK(!ParseInt32("aap", &n));
|
||||
BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
|
||||
BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
|
||||
const char test_bytes[] = {'1', 0, '1'};
|
||||
std::string teststr(test_bytes, sizeof(test_bytes));
|
||||
BOOST_CHECK(!ParseInt32(teststr, &n)); // no embedded NULs
|
||||
// Overflow and underflow
|
||||
BOOST_CHECK(!ParseInt32("-2147483649", NULL));
|
||||
BOOST_CHECK(!ParseInt32("2147483648", NULL));
|
||||
|
@ -332,6 +339,64 @@ BOOST_AUTO_TEST_CASE(test_ParseInt32)
|
|||
BOOST_CHECK(!ParseInt32("32482348723847471234", NULL));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_ParseInt64)
|
||||
{
|
||||
int64_t n;
|
||||
// Valid values
|
||||
BOOST_CHECK(ParseInt64("1234", NULL));
|
||||
BOOST_CHECK(ParseInt64("0", &n) && n == 0LL);
|
||||
BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL);
|
||||
BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal
|
||||
BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL);
|
||||
BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL);
|
||||
BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == (int64_t)9223372036854775807);
|
||||
BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == (int64_t)-9223372036854775807-1);
|
||||
BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL);
|
||||
// Invalid values
|
||||
BOOST_CHECK(!ParseInt64("", &n));
|
||||
BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside
|
||||
BOOST_CHECK(!ParseInt64("1 ", &n));
|
||||
BOOST_CHECK(!ParseInt64("1a", &n));
|
||||
BOOST_CHECK(!ParseInt64("aap", &n));
|
||||
BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex
|
||||
const char test_bytes[] = {'1', 0, '1'};
|
||||
std::string teststr(test_bytes, sizeof(test_bytes));
|
||||
BOOST_CHECK(!ParseInt64(teststr, &n)); // no embedded NULs
|
||||
// Overflow and underflow
|
||||
BOOST_CHECK(!ParseInt64("-9223372036854775809", NULL));
|
||||
BOOST_CHECK(!ParseInt64("9223372036854775808", NULL));
|
||||
BOOST_CHECK(!ParseInt64("-32482348723847471234", NULL));
|
||||
BOOST_CHECK(!ParseInt64("32482348723847471234", NULL));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_ParseDouble)
|
||||
{
|
||||
double n;
|
||||
// Valid values
|
||||
BOOST_CHECK(ParseDouble("1234", NULL));
|
||||
BOOST_CHECK(ParseDouble("0", &n) && n == 0.0);
|
||||
BOOST_CHECK(ParseDouble("1234", &n) && n == 1234.0);
|
||||
BOOST_CHECK(ParseDouble("01234", &n) && n == 1234.0); // no octal
|
||||
BOOST_CHECK(ParseDouble("2147483647", &n) && n == 2147483647.0);
|
||||
BOOST_CHECK(ParseDouble("-2147483648", &n) && n == -2147483648.0);
|
||||
BOOST_CHECK(ParseDouble("-1234", &n) && n == -1234.0);
|
||||
BOOST_CHECK(ParseDouble("1e6", &n) && n == 1e6);
|
||||
BOOST_CHECK(ParseDouble("-1e6", &n) && n == -1e6);
|
||||
// Invalid values
|
||||
BOOST_CHECK(!ParseDouble("", &n));
|
||||
BOOST_CHECK(!ParseDouble(" 1", &n)); // no padding inside
|
||||
BOOST_CHECK(!ParseDouble("1 ", &n));
|
||||
BOOST_CHECK(!ParseDouble("1a", &n));
|
||||
BOOST_CHECK(!ParseDouble("aap", &n));
|
||||
BOOST_CHECK(!ParseDouble("0x1", &n)); // no hex
|
||||
const char test_bytes[] = {'1', 0, '1'};
|
||||
std::string teststr(test_bytes, sizeof(test_bytes));
|
||||
BOOST_CHECK(!ParseDouble(teststr, &n)); // no embedded NULs
|
||||
// Overflow and underflow
|
||||
BOOST_CHECK(!ParseDouble("-1e10000", NULL));
|
||||
BOOST_CHECK(!ParseDouble("1e10000", NULL));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_FormatParagraph)
|
||||
{
|
||||
BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
|
||||
|
|
|
@ -4,12 +4,17 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <ctype.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdexcept> // std::runtime_error
|
||||
|
||||
#include "univalue.h"
|
||||
|
||||
#include "utilstrencodings.h" // ParseXX
|
||||
|
||||
using namespace std;
|
||||
|
||||
static const UniValue nullValue;
|
||||
const UniValue NullUniValue;
|
||||
|
||||
void UniValue::clear()
|
||||
{
|
||||
|
@ -78,9 +83,11 @@ bool UniValue::setFloat(double val)
|
|||
string s;
|
||||
ostringstream oss;
|
||||
|
||||
oss << val;
|
||||
oss << std::setprecision(16) << val;
|
||||
|
||||
return setNumStr(oss.str());
|
||||
bool ret = setNumStr(oss.str());
|
||||
typ = VREAL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool UniValue::setStr(const string& val_)
|
||||
|
@ -175,11 +182,11 @@ bool UniValue::checkObject(const std::map<std::string,UniValue::VType>& t)
|
|||
const UniValue& UniValue::operator[](const std::string& key) const
|
||||
{
|
||||
if (typ != VOBJ)
|
||||
return nullValue;
|
||||
return NullUniValue;
|
||||
|
||||
int index = findKey(key);
|
||||
if (index < 0)
|
||||
return nullValue;
|
||||
return NullUniValue;
|
||||
|
||||
return values[index];
|
||||
}
|
||||
|
@ -187,9 +194,9 @@ const UniValue& UniValue::operator[](const std::string& key) const
|
|||
const UniValue& UniValue::operator[](unsigned int index) const
|
||||
{
|
||||
if (typ != VOBJ && typ != VARR)
|
||||
return nullValue;
|
||||
return NullUniValue;
|
||||
if (index >= values.size())
|
||||
return nullValue;
|
||||
return NullUniValue;
|
||||
|
||||
return values[index];
|
||||
}
|
||||
|
@ -203,9 +210,95 @@ const char *uvTypeName(UniValue::VType t)
|
|||
case UniValue::VARR: return "array";
|
||||
case UniValue::VSTR: return "string";
|
||||
case UniValue::VNUM: return "number";
|
||||
case UniValue::VREAL: return "number";
|
||||
}
|
||||
|
||||
// not reached
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const UniValue& find_value( const UniValue& obj, const std::string& name)
|
||||
{
|
||||
for (unsigned int i = 0; i < obj.keys.size(); i++)
|
||||
{
|
||||
if( obj.keys[i] == name )
|
||||
{
|
||||
return obj.values[i];
|
||||
}
|
||||
}
|
||||
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
std::vector<std::string> UniValue::getKeys() const
|
||||
{
|
||||
if (typ != VOBJ)
|
||||
throw std::runtime_error("JSON value is not an object as expected");
|
||||
return keys;
|
||||
}
|
||||
|
||||
std::vector<UniValue> UniValue::getValues() const
|
||||
{
|
||||
if (typ != VOBJ && typ != VARR)
|
||||
throw std::runtime_error("JSON value is not an object or array as expected");
|
||||
return values;
|
||||
}
|
||||
|
||||
bool UniValue::get_bool() const
|
||||
{
|
||||
if (typ != VBOOL)
|
||||
throw std::runtime_error("JSON value is not a boolean as expected");
|
||||
return getBool();
|
||||
}
|
||||
|
||||
std::string UniValue::get_str() const
|
||||
{
|
||||
if (typ != VSTR)
|
||||
throw std::runtime_error("JSON value is not a string as expected");
|
||||
return getValStr();
|
||||
}
|
||||
|
||||
int UniValue::get_int() const
|
||||
{
|
||||
if (typ != VNUM)
|
||||
throw std::runtime_error("JSON value is not an integer as expected");
|
||||
int32_t retval;
|
||||
if (!ParseInt32(getValStr(), &retval))
|
||||
throw std::runtime_error("JSON integer out of range");
|
||||
return retval;
|
||||
}
|
||||
|
||||
int64_t UniValue::get_int64() const
|
||||
{
|
||||
if (typ != VNUM)
|
||||
throw std::runtime_error("JSON value is not an integer as expected");
|
||||
int64_t retval;
|
||||
if (!ParseInt64(getValStr(), &retval))
|
||||
throw std::runtime_error("JSON integer out of range");
|
||||
return retval;
|
||||
}
|
||||
|
||||
double UniValue::get_real() const
|
||||
{
|
||||
if (typ != VREAL && typ != VNUM)
|
||||
throw std::runtime_error("JSON value is not a number as expected");
|
||||
double retval;
|
||||
if (!ParseDouble(getValStr(), &retval))
|
||||
throw std::runtime_error("JSON double out of range");
|
||||
return retval;
|
||||
}
|
||||
|
||||
const UniValue& UniValue::get_obj() const
|
||||
{
|
||||
if (typ != VOBJ)
|
||||
throw std::runtime_error("JSON value is not an object as expected");
|
||||
return *this;
|
||||
}
|
||||
|
||||
const UniValue& UniValue::get_array() const
|
||||
{
|
||||
if (typ != VARR)
|
||||
throw std::runtime_error("JSON value is not an array as expected");
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,12 @@
|
|||
#include <map>
|
||||
#include <cassert>
|
||||
|
||||
#include <sstream> // .get_int64()
|
||||
#include <utility> // std::pair
|
||||
|
||||
class UniValue {
|
||||
public:
|
||||
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VBOOL, };
|
||||
enum VType { VNULL, VOBJ, VARR, VSTR, VNUM, VREAL, VBOOL, };
|
||||
|
||||
UniValue() { typ = VNULL; }
|
||||
UniValue(UniValue::VType initialType, const std::string& initialStr = "") {
|
||||
|
@ -26,6 +29,9 @@ public:
|
|||
UniValue(int64_t val_) {
|
||||
setInt(val_);
|
||||
}
|
||||
UniValue(bool val_) {
|
||||
setBool(val_);
|
||||
}
|
||||
UniValue(int val_) {
|
||||
setInt(val_);
|
||||
}
|
||||
|
@ -58,7 +64,7 @@ public:
|
|||
std::string getValStr() const { return val; }
|
||||
bool empty() const { return (values.size() == 0); }
|
||||
|
||||
size_t count() const { return values.size(); }
|
||||
size_t size() const { return values.size(); }
|
||||
|
||||
bool getBool() const { return isTrue(); }
|
||||
bool checkObject(const std::map<std::string,UniValue::VType>& memberTypes);
|
||||
|
@ -68,10 +74,11 @@ public:
|
|||
|
||||
bool isNull() const { return (typ == VNULL); }
|
||||
bool isTrue() const { return (typ == VBOOL) && (val == "1"); }
|
||||
bool isFalse() const { return (!isTrue()); }
|
||||
bool isFalse() const { return (typ == VBOOL) && (val != "1"); }
|
||||
bool isBool() const { return (typ == VBOOL); }
|
||||
bool isStr() const { return (typ == VSTR); }
|
||||
bool isNum() const { return (typ == VNUM); }
|
||||
bool isReal() const { return (typ == VREAL); }
|
||||
bool isArray() const { return (typ == VARR); }
|
||||
bool isObject() const { return (typ == VOBJ); }
|
||||
|
||||
|
@ -130,8 +137,91 @@ 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:
|
||||
// Strict type-specific getters, these throw std::runtime_error if the
|
||||
// value is of unexpected type
|
||||
std::vector<std::string> getKeys() const;
|
||||
std::vector<UniValue> getValues() const;
|
||||
bool get_bool() const;
|
||||
std::string get_str() const;
|
||||
int get_int() const;
|
||||
int64_t get_int64() const;
|
||||
double get_real() const;
|
||||
const UniValue& get_obj() const;
|
||||
const UniValue& get_array() const;
|
||||
|
||||
enum VType type() const { return getType(); }
|
||||
bool push_back(std::pair<std::string,UniValue> pear) {
|
||||
return pushKV(pear.first, pear.second);
|
||||
}
|
||||
friend const UniValue& find_value( const UniValue& obj, const std::string& name);
|
||||
};
|
||||
|
||||
//
|
||||
// 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, bool 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, 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
|
||||
|
@ -152,4 +242,9 @@ extern enum jtokentype getJsonToken(std::string& tokenVal,
|
|||
unsigned int& consumed, const char *raw);
|
||||
extern const char *uvTypeName(UniValue::VType t);
|
||||
|
||||
extern const UniValue NullUniValue;
|
||||
|
||||
const UniValue& find_value( const UniValue& obj, const std::string& name);
|
||||
|
||||
#endif // BITCOIN_UNIVALUE_UNIVALUE_H
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
|
||||
#include <ctype.h>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include "univalue.h"
|
||||
#include "univalue_escapes.h"
|
||||
|
@ -59,6 +61,13 @@ string UniValue::write(unsigned int prettyIndent,
|
|||
case VSTR:
|
||||
s += "\"" + json_escape(val) + "\"";
|
||||
break;
|
||||
case VREAL:
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << std::showpoint << std::fixed << std::setprecision(8) << get_real();
|
||||
s += ss.str();
|
||||
}
|
||||
break;
|
||||
case VNUM:
|
||||
s += val;
|
||||
break;
|
||||
|
|
|
@ -432,12 +432,25 @@ string DecodeBase32(const string& str)
|
|||
return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
|
||||
}
|
||||
|
||||
static bool ParsePrechecks(const std::string& str)
|
||||
{
|
||||
if (str.empty()) // No empty string allowed
|
||||
return false;
|
||||
if (str.size() >= 1 && (isspace(str[0]) || isspace(str[str.size()-1]))) // No padding allowed
|
||||
return false;
|
||||
if (str.size() != strlen(str.c_str())) // No embedded NUL characters allowed
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParseInt32(const std::string& str, int32_t *out)
|
||||
{
|
||||
if (!ParsePrechecks(str))
|
||||
return false;
|
||||
char *endp = NULL;
|
||||
errno = 0; // strtol will not set errno if valid
|
||||
long int n = strtol(str.c_str(), &endp, 10);
|
||||
if(out) *out = (int)n;
|
||||
if(out) *out = (int32_t)n;
|
||||
// Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
|
||||
// we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
|
||||
// platforms the size of these types may be different.
|
||||
|
@ -446,6 +459,34 @@ bool ParseInt32(const std::string& str, int32_t *out)
|
|||
n <= std::numeric_limits<int32_t>::max();
|
||||
}
|
||||
|
||||
bool ParseInt64(const std::string& str, int64_t *out)
|
||||
{
|
||||
if (!ParsePrechecks(str))
|
||||
return false;
|
||||
char *endp = NULL;
|
||||
errno = 0; // strtoll will not set errno if valid
|
||||
long long int n = strtoll(str.c_str(), &endp, 10);
|
||||
if(out) *out = (int64_t)n;
|
||||
// Note that strtoll returns a *long long int*, so even if strtol doesn't report a over/underflow
|
||||
// we still have to check that the returned value is within the range of an *int64_t*.
|
||||
return endp && *endp == 0 && !errno &&
|
||||
n >= std::numeric_limits<int64_t>::min() &&
|
||||
n <= std::numeric_limits<int64_t>::max();
|
||||
}
|
||||
|
||||
bool ParseDouble(const std::string& str, double *out)
|
||||
{
|
||||
if (!ParsePrechecks(str))
|
||||
return false;
|
||||
if (str.size() >= 2 && str[0] == '0' && str[1] == 'x') // No hexadecimal floats allowed
|
||||
return false;
|
||||
char *endp = NULL;
|
||||
errno = 0; // strtod will not set errno if valid
|
||||
double n = strtod(str.c_str(), &endp);
|
||||
if(out) *out = n;
|
||||
return endp && *endp == 0 && !errno;
|
||||
}
|
||||
|
||||
std::string FormatParagraph(const std::string in, size_t width, size_t indent)
|
||||
{
|
||||
std::stringstream out;
|
||||
|
|
|
@ -50,6 +50,20 @@ int atoi(const std::string& str);
|
|||
*/
|
||||
bool ParseInt32(const std::string& str, int32_t *out);
|
||||
|
||||
/**
|
||||
* Convert string to signed 64-bit integer with strict parse error feedback.
|
||||
* @returns true if the entire string could be parsed as valid integer,
|
||||
* false if not the entire string could be parsed or when overflow or underflow occurred.
|
||||
*/
|
||||
bool ParseInt64(const std::string& str, int64_t *out);
|
||||
|
||||
/**
|
||||
* Convert string to double with strict parse error feedback.
|
||||
* @returns true if the entire string could be parsed as valid double,
|
||||
* false if not the entire string could be parsed or when overflow or underflow occurred.
|
||||
*/
|
||||
bool ParseDouble(const std::string& str, double *out);
|
||||
|
||||
template<typename T>
|
||||
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
|
||||
{
|
||||
|
|
|
@ -29,16 +29,16 @@
|
|||
|
||||
using namespace libzcash;
|
||||
|
||||
int find_output(Object obj, int n) {
|
||||
Value outputMapValue = find_value(obj, "outputmap");
|
||||
if (outputMapValue.type() != array_type) {
|
||||
int find_output(UniValue obj, int n) {
|
||||
UniValue outputMapValue = find_value(obj, "outputmap");
|
||||
if (!outputMapValue.isArray()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Missing outputmap for JoinSplit operation");
|
||||
}
|
||||
|
||||
Array outputMap = outputMapValue.get_array();
|
||||
UniValue outputMap = outputMapValue.get_array();
|
||||
assert(outputMap.size() == ZC_NUM_JS_OUTPUTS);
|
||||
for (size_t i = 0; i < outputMap.size(); i++) {
|
||||
if (outputMap[i] == n) {
|
||||
if (outputMap[i].get_int() == n) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
|||
std::vector<SendManyRecipient> zOutputs,
|
||||
int minDepth,
|
||||
CAmount fee,
|
||||
Value contextInfo) :
|
||||
UniValue contextInfo) :
|
||||
fromaddress_(fromAddress), t_outputs_(tOutputs), z_outputs_(zOutputs), mindepth_(minDepth), fee_(fee), contextinfo_(contextInfo)
|
||||
{
|
||||
assert(fee_ >= 0);
|
||||
|
@ -94,7 +94,7 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
|
|||
|
||||
// Log the context info i.e. the call parameters to z_sendmany
|
||||
if (LogAcceptCategory("zrpcunsafe")) {
|
||||
LogPrint("zrpcunsafe", "%s: z_sendmany initialized (params=%s)\n", getId(), json_spirit::write_string( contextInfo, false));
|
||||
LogPrint("zrpcunsafe", "%s: z_sendmany initialized (params=%s)\n", getId(), contextInfo.write());
|
||||
} else {
|
||||
LogPrint("zrpc", "%s: z_sendmany initialized\n", getId());
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ void AsyncRPCOperation_sendmany::main() {
|
|||
|
||||
try {
|
||||
success = main_impl();
|
||||
} catch (const Object& objError) {
|
||||
} catch (const UniValue& objError) {
|
||||
int code = find_value(objError, "code").get_int();
|
||||
std::string message = find_value(objError, "message").get_str();
|
||||
set_error_code(code);
|
||||
|
@ -307,7 +307,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
);
|
||||
}
|
||||
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("rawtxn", EncodeHexTx(tx_)));
|
||||
sign_send_raw_transaction(obj);
|
||||
return true;
|
||||
|
@ -385,7 +385,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
}
|
||||
|
||||
// Create joinsplits, where each output represents a zaddr recipient.
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
while (zOutputsDeque.size() > 0) {
|
||||
AsyncJoinSplitInfo info;
|
||||
info.vpub_old = 0;
|
||||
|
@ -434,7 +434,7 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
* SCENARIO #3
|
||||
* Part 1: Add to the transparent value pool.
|
||||
*/
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
CAmount jsChange = 0; // this is updated after each joinsplit
|
||||
int changeOutputIndex = -1; // this is updated after each joinsplit if jsChange > 0
|
||||
bool minersFeeProcessed = false;
|
||||
|
@ -757,42 +757,47 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
|||
* Sign and send a raw transaction.
|
||||
* Raw transaction as hex string should be in object field "rawtxn"
|
||||
*/
|
||||
void AsyncRPCOperation_sendmany::sign_send_raw_transaction(Object obj)
|
||||
void AsyncRPCOperation_sendmany::sign_send_raw_transaction(UniValue obj)
|
||||
{
|
||||
// Sign the raw transaction
|
||||
Value rawtxnValue = find_value(obj, "rawtxn");
|
||||
if (rawtxnValue.is_null()) {
|
||||
UniValue rawtxnValue = find_value(obj, "rawtxn");
|
||||
if (rawtxnValue.isNull()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for raw transaction");
|
||||
}
|
||||
std::string rawtxn = rawtxnValue.get_str();
|
||||
|
||||
Value signResultValue = signrawtransaction({Value(rawtxn)}, false);
|
||||
Object signResultObject = signResultValue.get_obj();
|
||||
Value completeValue = find_value(signResultObject, "complete");
|
||||
UniValue params = UniValue(UniValue::VARR);
|
||||
params.push_back(rawtxn);
|
||||
UniValue signResultValue = signrawtransaction(params, false);
|
||||
UniValue signResultObject = signResultValue.get_obj();
|
||||
UniValue completeValue = find_value(signResultObject, "complete");
|
||||
bool complete = completeValue.get_bool();
|
||||
if (!complete) {
|
||||
// TODO: #1366 Maybe get "errors" and print array vErrors into a string
|
||||
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Failed to sign transaction");
|
||||
}
|
||||
|
||||
Value hexValue = find_value(signResultObject, "hex");
|
||||
if (hexValue.is_null()) {
|
||||
UniValue hexValue = find_value(signResultObject, "hex");
|
||||
if (hexValue.isNull()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Missing hex data for signed transaction");
|
||||
}
|
||||
std::string signedtxn = hexValue.get_str();
|
||||
|
||||
// Send the signed transaction
|
||||
if (!testmode) {
|
||||
Value sendResultValue = sendrawtransaction({Value(signedtxn)}, false);
|
||||
if (sendResultValue.is_null()) {
|
||||
params.clear();
|
||||
params.setArray();
|
||||
params.push_back(signedtxn);
|
||||
UniValue sendResultValue = sendrawtransaction(params, false);
|
||||
if (sendResultValue.isNull()) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Send raw transaction did not return an error or a txid.");
|
||||
}
|
||||
|
||||
std::string txid = sendResultValue.get_str();
|
||||
|
||||
Object o;
|
||||
UniValue o(UniValue::VOBJ);
|
||||
o.push_back(Pair("txid", txid));
|
||||
set_result(Value(o));
|
||||
set_result(o);
|
||||
} else {
|
||||
// Test mode does not send the transaction to the network.
|
||||
|
||||
|
@ -800,11 +805,11 @@ void AsyncRPCOperation_sendmany::sign_send_raw_transaction(Object obj)
|
|||
CTransaction tx;
|
||||
stream >> tx;
|
||||
|
||||
Object o;
|
||||
UniValue o(UniValue::VOBJ);
|
||||
o.push_back(Pair("test", 1));
|
||||
o.push_back(Pair("txid", tx.GetHash().ToString()));
|
||||
o.push_back(Pair("hex", signedtxn));
|
||||
set_result(Value(o));
|
||||
set_result(o);
|
||||
}
|
||||
|
||||
// Keep the signed transaction so we can hash to the same txid
|
||||
|
@ -891,7 +896,7 @@ bool AsyncRPCOperation_sendmany::find_unspent_notes() {
|
|||
return true;
|
||||
}
|
||||
|
||||
Object AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info) {
|
||||
UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info) {
|
||||
std::vector<boost::optional < ZCIncrementalWitness>> witnesses;
|
||||
uint256 anchor;
|
||||
{
|
||||
|
@ -902,7 +907,7 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info)
|
|||
}
|
||||
|
||||
|
||||
Object AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info, std::vector<JSOutPoint> & outPoints) {
|
||||
UniValue AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info, std::vector<JSOutPoint> & outPoints) {
|
||||
std::vector<boost::optional < ZCIncrementalWitness>> witnesses;
|
||||
uint256 anchor;
|
||||
{
|
||||
|
@ -912,7 +917,7 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(AsyncJoinSplitInfo & info,
|
|||
return perform_joinsplit(info, witnesses, anchor);
|
||||
}
|
||||
|
||||
Object AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||
UniValue AsyncRPCOperation_sendmany::perform_joinsplit(
|
||||
AsyncJoinSplitInfo & info,
|
||||
std::vector<boost::optional < ZCIncrementalWitness>> witnesses,
|
||||
uint256 anchor)
|
||||
|
@ -1033,8 +1038,8 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
encryptedNote2 = HexStr(ss2.begin(), ss2.end());
|
||||
}
|
||||
|
||||
Array arrInputMap;
|
||||
Array arrOutputMap;
|
||||
UniValue arrInputMap(UniValue::VARR);
|
||||
UniValue arrOutputMap(UniValue::VARR);
|
||||
for (size_t i = 0; i < ZC_NUM_JS_INPUTS; i++) {
|
||||
arrInputMap.push_back(inputMap[i]);
|
||||
}
|
||||
|
@ -1042,7 +1047,7 @@ Object AsyncRPCOperation_sendmany::perform_joinsplit(
|
|||
arrOutputMap.push_back(outputMap[i]);
|
||||
}
|
||||
|
||||
Object obj;
|
||||
UniValue obj(UniValue::VOBJ);
|
||||
obj.push_back(Pair("encryptednote1", encryptedNote1));
|
||||
obj.push_back(Pair("encryptednote2", encryptedNote2));
|
||||
obj.push_back(Pair("rawtxn", HexStr(ss.begin(), ss.end())));
|
||||
|
@ -1118,15 +1123,15 @@ boost::array<unsigned char, ZC_MEMO_SIZE> AsyncRPCOperation_sendmany::get_memo_f
|
|||
/**
|
||||
* Override getStatus() to append the operation's input parameters to the default status object.
|
||||
*/
|
||||
Value AsyncRPCOperation_sendmany::getStatus() const {
|
||||
Value v = AsyncRPCOperation::getStatus();
|
||||
if (contextinfo_.is_null()) {
|
||||
UniValue AsyncRPCOperation_sendmany::getStatus() const {
|
||||
UniValue v = AsyncRPCOperation::getStatus();
|
||||
if (contextinfo_.isNull()) {
|
||||
return v;
|
||||
}
|
||||
|
||||
Object obj = v.get_obj();
|
||||
UniValue obj = v.get_obj();
|
||||
obj.push_back(Pair("method", "z_sendmany"));
|
||||
obj.push_back(Pair("params", contextinfo_ ));
|
||||
return Value(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,17 +11,17 @@
|
|||
#include "primitives/transaction.h"
|
||||
#include "zcash/JoinSplit.hpp"
|
||||
#include "zcash/Address.hpp"
|
||||
#include "json/json_spirit_value.h"
|
||||
#include "wallet.h"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <tuple>
|
||||
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
// Default transaction fee if caller does not specify one.
|
||||
#define ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE 10000
|
||||
|
||||
using namespace libzcash;
|
||||
using namespace json_spirit;
|
||||
|
||||
// A recipient is a tuple of address, amount, memo (optional if zaddr)
|
||||
typedef std::tuple<std::string, CAmount, std::string> SendManyRecipient;
|
||||
|
@ -50,7 +50,7 @@ struct WitnessAnchorData {
|
|||
|
||||
class AsyncRPCOperation_sendmany : public AsyncRPCOperation {
|
||||
public:
|
||||
AsyncRPCOperation_sendmany(std::string fromAddress, std::vector<SendManyRecipient> tOutputs, std::vector<SendManyRecipient> zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, Value contextInfo = Value::null);
|
||||
AsyncRPCOperation_sendmany(std::string fromAddress, std::vector<SendManyRecipient> tOutputs, std::vector<SendManyRecipient> zOutputs, int minDepth, CAmount fee = ASYNC_RPC_OPERATION_DEFAULT_MINERS_FEE, UniValue contextInfo = NullUniValue);
|
||||
virtual ~AsyncRPCOperation_sendmany();
|
||||
|
||||
// We don't want to be copied or moved around
|
||||
|
@ -61,14 +61,14 @@ public:
|
|||
|
||||
virtual void main();
|
||||
|
||||
virtual Value getStatus() const;
|
||||
virtual UniValue getStatus() const;
|
||||
|
||||
bool testmode = false; // Set to true to disable sending txs and generating proofs
|
||||
|
||||
private:
|
||||
friend class TEST_FRIEND_AsyncRPCOperation_sendmany; // class for unit testing
|
||||
|
||||
Value contextinfo_; // optional data to include in return value from getStatus()
|
||||
UniValue contextinfo_; // optional data to include in return value from getStatus()
|
||||
|
||||
CAmount fee_;
|
||||
int mindepth_;
|
||||
|
@ -100,18 +100,18 @@ private:
|
|||
bool main_impl();
|
||||
|
||||
// JoinSplit without any input notes to spend
|
||||
Object perform_joinsplit(AsyncJoinSplitInfo &);
|
||||
UniValue perform_joinsplit(AsyncJoinSplitInfo &);
|
||||
|
||||
// JoinSplit with input notes to spend (JSOutPoints))
|
||||
Object perform_joinsplit(AsyncJoinSplitInfo &, std::vector<JSOutPoint> & );
|
||||
UniValue perform_joinsplit(AsyncJoinSplitInfo &, std::vector<JSOutPoint> & );
|
||||
|
||||
// JoinSplit where you have the witnesses and anchor
|
||||
Object perform_joinsplit(
|
||||
UniValue perform_joinsplit(
|
||||
AsyncJoinSplitInfo & info,
|
||||
std::vector<boost::optional < ZCIncrementalWitness>> witnesses,
|
||||
uint256 anchor);
|
||||
|
||||
void sign_send_raw_transaction(Object obj); // throws exception if there was an error
|
||||
void sign_send_raw_transaction(UniValue obj); // throws exception if there was an error
|
||||
|
||||
};
|
||||
|
||||
|
@ -157,15 +157,15 @@ public:
|
|||
return delegate->main_impl();
|
||||
}
|
||||
|
||||
Object perform_joinsplit(AsyncJoinSplitInfo &info) {
|
||||
UniValue perform_joinsplit(AsyncJoinSplitInfo &info) {
|
||||
return delegate->perform_joinsplit(info);
|
||||
}
|
||||
|
||||
Object perform_joinsplit(AsyncJoinSplitInfo &info, std::vector<JSOutPoint> &v ) {
|
||||
UniValue perform_joinsplit(AsyncJoinSplitInfo &info, std::vector<JSOutPoint> &v ) {
|
||||
return delegate->perform_joinsplit(info, v);
|
||||
}
|
||||
|
||||
Object perform_joinsplit(
|
||||
UniValue perform_joinsplit(
|
||||
AsyncJoinSplitInfo & info,
|
||||
std::vector<boost::optional < ZCIncrementalWitness>> witnesses,
|
||||
uint256 anchor)
|
||||
|
@ -173,7 +173,7 @@ public:
|
|||
return delegate->perform_joinsplit(info, witnesses, anchor);
|
||||
}
|
||||
|
||||
void sign_send_raw_transaction(Object obj) {
|
||||
void sign_send_raw_transaction(UniValue obj) {
|
||||
delegate->sign_send_raw_transaction(obj);
|
||||
}
|
||||
|
||||
|
|
|
@ -19,16 +19,15 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
#include "json/json_spirit_value.h"
|
||||
#include "univalue/univalue.h"
|
||||
|
||||
using namespace json_spirit;
|
||||
using namespace std;
|
||||
|
||||
void EnsureWalletIsUnlocked();
|
||||
bool EnsureWalletIsAvailable(bool avoidException);
|
||||
|
||||
Value dumpwallet_impl(const Array& params, bool fHelp, bool fDumpZKeys);
|
||||
Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys);
|
||||
UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys);
|
||||
UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys);
|
||||
|
||||
|
||||
std::string static EncodeDumpTime(int64_t nTime) {
|
||||
|
@ -74,10 +73,10 @@ std::string DecodeDumpString(const std::string &str) {
|
|||
return ret.str();
|
||||
}
|
||||
|
||||
Value importprivkey(const Array& params, bool fHelp)
|
||||
UniValue importprivkey(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() < 1 || params.size() > 3)
|
||||
throw runtime_error(
|
||||
|
@ -130,7 +129,7 @@ Value importprivkey(const Array& params, bool fHelp)
|
|||
|
||||
// Don't throw error in case a key is already there
|
||||
if (pwalletMain->HaveKey(vchAddress))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1;
|
||||
|
||||
|
@ -145,13 +144,13 @@ Value importprivkey(const Array& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
Value importaddress(const Array& params, bool fHelp)
|
||||
UniValue importaddress(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() < 1 || params.size() > 3)
|
||||
throw runtime_error(
|
||||
|
@ -204,7 +203,7 @@ Value importaddress(const Array& params, bool fHelp)
|
|||
|
||||
// Don't throw error in case an address is already there
|
||||
if (pwalletMain->HaveWatchOnly(script))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
pwalletMain->MarkDirty();
|
||||
|
||||
|
@ -218,13 +217,13 @@ Value importaddress(const Array& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
Value z_importwallet(const Array& params, bool fHelp)
|
||||
UniValue z_importwallet(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -244,10 +243,10 @@ Value z_importwallet(const Array& params, bool fHelp)
|
|||
return importwallet_impl(params, fHelp, true);
|
||||
}
|
||||
|
||||
Value importwallet(const Array& params, bool fHelp)
|
||||
UniValue importwallet(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -267,7 +266,7 @@ Value importwallet(const Array& params, bool fHelp)
|
|||
return importwallet_impl(params, fHelp, false);
|
||||
}
|
||||
|
||||
Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys)
|
||||
UniValue importwallet_impl(const UniValue& params, bool fHelp, bool fImportZKeys)
|
||||
{
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
|
@ -378,13 +377,13 @@ Value importwallet_impl(const Array& params, bool fHelp, bool fImportZKeys)
|
|||
if (!fGood)
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding some keys to wallet");
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
Value dumpprivkey(const Array& params, bool fHelp)
|
||||
UniValue dumpprivkey(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -420,10 +419,10 @@ Value dumpprivkey(const Array& params, bool fHelp)
|
|||
|
||||
|
||||
|
||||
Value z_exportwallet(const Array& params, bool fHelp)
|
||||
UniValue z_exportwallet(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -441,10 +440,10 @@ Value z_exportwallet(const Array& params, bool fHelp)
|
|||
return dumpwallet_impl(params, fHelp, true);
|
||||
}
|
||||
|
||||
Value dumpwallet(const Array& params, bool fHelp)
|
||||
UniValue dumpwallet(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
@ -462,7 +461,7 @@ Value dumpwallet(const Array& params, bool fHelp)
|
|||
return dumpwallet_impl(params, fHelp, false);
|
||||
}
|
||||
|
||||
Value dumpwallet_impl(const Array& params, bool fHelp, bool fDumpZKeys)
|
||||
UniValue dumpwallet_impl(const UniValue& params, bool fHelp, bool fDumpZKeys)
|
||||
{
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
|
||||
|
@ -548,10 +547,10 @@ Value dumpwallet_impl(const Array& params, bool fHelp, bool fDumpZKeys)
|
|||
}
|
||||
|
||||
|
||||
Value z_importkey(const Array& params, bool fHelp)
|
||||
UniValue z_importkey(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() < 1 || params.size() > 2)
|
||||
throw runtime_error(
|
||||
|
@ -587,7 +586,7 @@ Value z_importkey(const Array& params, bool fHelp)
|
|||
{
|
||||
// Don't throw error in case a key is already there
|
||||
if (pwalletMain->HaveSpendingKey(addr))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
pwalletMain->MarkDirty();
|
||||
|
||||
|
@ -605,14 +604,14 @@ Value z_importkey(const Array& params, bool fHelp)
|
|||
}
|
||||
}
|
||||
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
}
|
||||
|
||||
|
||||
Value z_exportkey(const Array& params, bool fHelp)
|
||||
UniValue z_exportkey(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (!EnsureWalletIsAvailable(fHelp))
|
||||
return Value::null;
|
||||
return NullUniValue;
|
||||
|
||||
if (fHelp || params.size() != 1)
|
||||
throw runtime_error(
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue