aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bitcoinrpc.cpp26
-rw-r--r--src/bitcoinrpc.h4
-rw-r--r--src/rpcrawtransaction.cpp20
-rw-r--r--src/test/test_bitcoin.cpp2
-rw-r--r--src/util.cpp2
5 files changed, 30 insertions, 24 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp
index d59deacd86..8991de7dea 100644
--- a/src/bitcoinrpc.cpp
+++ b/src/bitcoinrpc.cpp
@@ -49,7 +49,8 @@ Object JSONRPCError(int code, const string& message)
}
void RPCTypeCheck(const Array& params,
- const list<Value_type>& typesExpected)
+ const list<Value_type>& typesExpected,
+ bool fAllowNull)
{
unsigned int i = 0;
BOOST_FOREACH(Value_type t, typesExpected)
@@ -57,8 +58,8 @@ void RPCTypeCheck(const Array& params,
if (params.size() <= i)
break;
- const Value& v = params[i];
- if (v.type() != t)
+ const Value& v = params[i];
+ if (!((v.type() == t) || (fAllowNull && (v.type() == null_type))))
{
string err = strprintf("Expected type %s, got %s",
Value_type_name[t], Value_type_name[v.type()]);
@@ -69,14 +70,16 @@ void RPCTypeCheck(const Array& params,
}
void RPCTypeCheck(const Object& o,
- const map<string, Value_type>& typesExpected)
+ const map<string, Value_type>& typesExpected,
+ bool fAllowNull)
{
BOOST_FOREACH(const PAIRTYPE(string, Value_type)& t, typesExpected)
{
const Value& v = find_value(o, t.first);
- if (v.type() == null_type)
+ if (!fAllowNull && v.type() == null_type)
throw JSONRPCError(-3, strprintf("Missing %s", t.first.c_str()));
- if (v.type() != t.second)
+
+ if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type))))
{
string err = strprintf("Expected type %s for %s, got %s",
Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]);
@@ -1072,8 +1075,10 @@ Object CallRPC(const string& strMethod, const Array& params)
template<typename T>
-void ConvertTo(Value& value)
+void ConvertTo(Value& value, bool fAllowNull=false)
{
+ if (fAllowNull && value.type() == null_type)
+ return;
if (value.type() == str_type)
{
// reinterpret string as unquoted json value
@@ -1081,7 +1086,8 @@ void ConvertTo(Value& value)
string strJSON = value.get_str();
if (!read_string(strJSON, value2))
throw runtime_error(string("Error parsing JSON:")+strJSON);
- value = value2.get_value<T>();
+ ConvertTo<T>(value2, fAllowNull);
+ value = value2;
}
else
{
@@ -1132,8 +1138,8 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
- if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1]);
- if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2]);
+ if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
+ if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
return params;
}
diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h
index c845f1bc16..4abda7eda6 100644
--- a/src/bitcoinrpc.h
+++ b/src/bitcoinrpc.h
@@ -30,13 +30,13 @@ json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vec
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);
+ 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);
+ const std::map<std::string, json_spirit::Value_type>& typesExpected, bool fAllowNull=false);
typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool fHelp);
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index a6b8553896..29b9d072d6 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -273,21 +273,18 @@ Value signrawtransaction(const Array& params, bool fHelp)
throw runtime_error(
"signrawtransaction <hex string> [{\"txid\":txid,\"vout\":n,\"scriptPubKey\":hex},...] [<privatekey1>,...] [sighashtype=\"ALL\"]\n"
"Sign inputs for raw transaction (serialized, hex-encoded).\n"
- "Second optional argument is an array of previous transaction outputs that\n"
+ "Second optional argument (may be null) is an array of previous transaction outputs that\n"
"this transaction depends on but may not yet be in the blockchain.\n"
- "Third optional argument is an array of base58-encoded private\n"
+ "Third optional argument (may be null) is an array of base58-encoded private\n"
"keys that, if given, will be the only keys used to sign the transaction.\n"
- "Fourth option is a string that is one of six values; ALL, NONE, SINGLE or\n"
+ "Fourth optional argument is a string that is one of six values; ALL, NONE, SINGLE or\n"
"ALL|ANYONECANPAY, NONE|ANYONECANPAY, SINGLE|ANYONECANPAY.\n"
"Returns json object with keys:\n"
" hex : raw transaction with signature(s) (hex-encoded string)\n"
" complete : 1 if transaction has a complete set of signature (0 if not)"
+ HelpRequiringPassphrase());
- if (params.size() < 3)
- EnsureWalletIsUnlocked();
-
- RPCTypeCheck(params, list_of(str_type)(array_type)(array_type));
+ RPCTypeCheck(params, list_of(str_type)(array_type)(array_type)(str_type), true);
vector<unsigned char> txData(ParseHex(params[0].get_str()));
CDataStream ssData(txData, SER_NETWORK, PROTOCOL_VERSION);
@@ -336,7 +333,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
}
// Add previous txouts given in the RPC call:
- if (params.size() > 1)
+ if (params.size() > 1 && params[1].type() != null_type)
{
Array prevTxs = params[1].get_array();
BOOST_FOREACH(Value& p, prevTxs)
@@ -383,7 +380,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
bool fGivenKeys = false;
CBasicKeyStore tempKeystore;
- if (params.size() > 2)
+ if (params.size() > 2 && params[2].type() != null_type)
{
fGivenKeys = true;
Array keys = params[2].get_array();
@@ -400,10 +397,13 @@ Value signrawtransaction(const Array& params, bool fHelp)
tempKeystore.AddKey(key);
}
}
+ else
+ EnsureWalletIsUnlocked();
+
const CKeyStore& keystore = (fGivenKeys ? tempKeystore : *pwalletMain);
int nHashType = SIGHASH_ALL;
- if (params.size() > 3)
+ if (params.size() > 3 && params[3].type() != null_type)
{
static map<string, int> mapSigHashValues =
boost::assign::map_list_of
diff --git a/src/test/test_bitcoin.cpp b/src/test/test_bitcoin.cpp
index cae0bb6baf..bcf0907871 100644
--- a/src/test/test_bitcoin.cpp
+++ b/src/test/test_bitcoin.cpp
@@ -13,7 +13,7 @@ extern void noui_connect();
struct TestingSetup {
TestingSetup() {
- fPrintToConsole = true; // don't want to write to debug.log file
+ fPrintToDebugger = true; // don't want to write to debug.log file
noui_connect();
bitdb.MakeMock();
LoadBlockIndex(true);
diff --git a/src/util.cpp b/src/util.cpp
index c9654989af..69cc5f3424 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -204,7 +204,7 @@ inline int OutputDebugStringF(const char* pszFormat, ...)
ret = vprintf(pszFormat, arg_ptr);
va_end(arg_ptr);
}
- else
+ else if (!fPrintToDebugger)
{
// print to debug.log
static FILE* fileout = NULL;