Merge pull request #1908 from laanwj/2012_10_rpcerrors
Document RPC error codes
This commit is contained in:
commit
39930ca6ae
7 changed files with 159 additions and 112 deletions
|
@ -69,7 +69,7 @@ void RPCTypeCheck(const Array& params,
|
||||||
{
|
{
|
||||||
string err = strprintf("Expected type %s, got %s",
|
string err = strprintf("Expected type %s, got %s",
|
||||||
Value_type_name[t], Value_type_name[v.type()]);
|
Value_type_name[t], Value_type_name[v.type()]);
|
||||||
throw JSONRPCError(-3, err);
|
throw JSONRPCError(RPC_TYPE_ERROR, err);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -83,13 +83,13 @@ void RPCTypeCheck(const Object& o,
|
||||||
{
|
{
|
||||||
const Value& v = find_value(o, t.first);
|
const Value& v = find_value(o, t.first);
|
||||||
if (!fAllowNull && v.type() == null_type)
|
if (!fAllowNull && v.type() == null_type)
|
||||||
throw JSONRPCError(-3, strprintf("Missing %s", t.first.c_str()));
|
throw JSONRPCError(RPC_TYPE_ERROR, strprintf("Missing %s", t.first.c_str()));
|
||||||
|
|
||||||
if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type))))
|
if (!((v.type() == t.second) || (fAllowNull && (v.type() == null_type))))
|
||||||
{
|
{
|
||||||
string err = strprintf("Expected type %s for %s, got %s",
|
string err = strprintf("Expected type %s for %s, got %s",
|
||||||
Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]);
|
Value_type_name[t.second], t.first.c_str(), Value_type_name[v.type()]);
|
||||||
throw JSONRPCError(-3, err);
|
throw JSONRPCError(RPC_TYPE_ERROR, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,10 +98,10 @@ int64 AmountFromValue(const Value& value)
|
||||||
{
|
{
|
||||||
double dAmount = value.get_real();
|
double dAmount = value.get_real();
|
||||||
if (dAmount <= 0.0 || dAmount > 21000000.0)
|
if (dAmount <= 0.0 || dAmount > 21000000.0)
|
||||||
throw JSONRPCError(-3, "Invalid amount");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
|
||||||
int64 nAmount = roundint64(dAmount * COIN);
|
int64 nAmount = roundint64(dAmount * COIN);
|
||||||
if (!MoneyRange(nAmount))
|
if (!MoneyRange(nAmount))
|
||||||
throw JSONRPCError(-3, "Invalid amount");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount");
|
||||||
return nAmount;
|
return nAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,7 +317,7 @@ string rfc1123Time()
|
||||||
|
|
||||||
static string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
|
static string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
|
||||||
{
|
{
|
||||||
if (nStatus == 401)
|
if (nStatus == HTTP_UNAUTHORIZED)
|
||||||
return strprintf("HTTP/1.0 401 Authorization Required\r\n"
|
return strprintf("HTTP/1.0 401 Authorization Required\r\n"
|
||||||
"Date: %s\r\n"
|
"Date: %s\r\n"
|
||||||
"Server: bitcoin-json-rpc/%s\r\n"
|
"Server: bitcoin-json-rpc/%s\r\n"
|
||||||
|
@ -335,11 +335,11 @@ static string HTTPReply(int nStatus, const string& strMsg, bool keepalive)
|
||||||
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
|
"<BODY><H1>401 Unauthorized.</H1></BODY>\r\n"
|
||||||
"</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
|
"</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str());
|
||||||
const char *cStatus;
|
const char *cStatus;
|
||||||
if (nStatus == 200) cStatus = "OK";
|
if (nStatus == HTTP_OK) cStatus = "OK";
|
||||||
else if (nStatus == 400) cStatus = "Bad Request";
|
else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request";
|
||||||
else if (nStatus == 403) cStatus = "Forbidden";
|
else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden";
|
||||||
else if (nStatus == 404) cStatus = "Not Found";
|
else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found";
|
||||||
else if (nStatus == 500) cStatus = "Internal Server Error";
|
else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error";
|
||||||
else cStatus = "";
|
else cStatus = "";
|
||||||
return strprintf(
|
return strprintf(
|
||||||
"HTTP/1.1 %d %s\r\n"
|
"HTTP/1.1 %d %s\r\n"
|
||||||
|
@ -366,7 +366,7 @@ int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto)
|
||||||
vector<string> vWords;
|
vector<string> vWords;
|
||||||
boost::split(vWords, str, boost::is_any_of(" "));
|
boost::split(vWords, str, boost::is_any_of(" "));
|
||||||
if (vWords.size() < 2)
|
if (vWords.size() < 2)
|
||||||
return 500;
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
proto = 0;
|
proto = 0;
|
||||||
const char *ver = strstr(str.c_str(), "HTTP/1.");
|
const char *ver = strstr(str.c_str(), "HTTP/1.");
|
||||||
if (ver != NULL)
|
if (ver != NULL)
|
||||||
|
@ -411,7 +411,7 @@ int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRe
|
||||||
// Read header
|
// Read header
|
||||||
int nLen = ReadHTTPHeader(stream, mapHeadersRet);
|
int nLen = ReadHTTPHeader(stream, mapHeadersRet);
|
||||||
if (nLen < 0 || nLen > (int)MAX_SIZE)
|
if (nLen < 0 || nLen > (int)MAX_SIZE)
|
||||||
return 500;
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
// Read message
|
// Read message
|
||||||
if (nLen > 0)
|
if (nLen > 0)
|
||||||
|
@ -484,10 +484,10 @@ string JSONRPCReply(const Value& result, const Value& error, const Value& id)
|
||||||
void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
|
void ErrorReply(std::ostream& stream, const Object& objError, const Value& id)
|
||||||
{
|
{
|
||||||
// Send error reply from json-rpc error object
|
// Send error reply from json-rpc error object
|
||||||
int nStatus = 500;
|
int nStatus = HTTP_INTERNAL_SERVER_ERROR;
|
||||||
int code = find_value(objError, "code").get_int();
|
int code = find_value(objError, "code").get_int();
|
||||||
if (code == -32600) nStatus = 400;
|
if (code == RPC_INVALID_REQUEST) nStatus = HTTP_BAD_REQUEST;
|
||||||
else if (code == -32601) nStatus = 404;
|
else if (code == RPC_METHOD_NOT_FOUND) nStatus = HTTP_NOT_FOUND;
|
||||||
string strReply = JSONRPCReply(Value::null, objError, id);
|
string strReply = JSONRPCReply(Value::null, objError, id);
|
||||||
stream << HTTPReply(nStatus, strReply, false) << std::flush;
|
stream << HTTPReply(nStatus, strReply, false) << std::flush;
|
||||||
}
|
}
|
||||||
|
@ -699,7 +699,7 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol,
|
||||||
{
|
{
|
||||||
// Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
|
// Only send a 403 if we're not using SSL to prevent a DoS during the SSL handshake.
|
||||||
if (!fUseSSL)
|
if (!fUseSSL)
|
||||||
conn->stream() << HTTPReply(403, "", false) << std::flush;
|
conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush;
|
||||||
delete conn;
|
delete conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,7 +854,7 @@ void JSONRequest::parse(const Value& valRequest)
|
||||||
{
|
{
|
||||||
// Parse request
|
// Parse request
|
||||||
if (valRequest.type() != obj_type)
|
if (valRequest.type() != obj_type)
|
||||||
throw JSONRPCError(-32600, "Invalid Request object");
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Invalid Request object");
|
||||||
const Object& request = valRequest.get_obj();
|
const Object& request = valRequest.get_obj();
|
||||||
|
|
||||||
// Parse id now so errors from here on will have the id
|
// Parse id now so errors from here on will have the id
|
||||||
|
@ -863,9 +863,9 @@ void JSONRequest::parse(const Value& valRequest)
|
||||||
// Parse method
|
// Parse method
|
||||||
Value valMethod = find_value(request, "method");
|
Value valMethod = find_value(request, "method");
|
||||||
if (valMethod.type() == null_type)
|
if (valMethod.type() == null_type)
|
||||||
throw JSONRPCError(-32600, "Missing method");
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method");
|
||||||
if (valMethod.type() != str_type)
|
if (valMethod.type() != str_type)
|
||||||
throw JSONRPCError(-32600, "Method must be a string");
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
|
||||||
strMethod = valMethod.get_str();
|
strMethod = valMethod.get_str();
|
||||||
if (strMethod != "getwork" && strMethod != "getblocktemplate")
|
if (strMethod != "getwork" && strMethod != "getblocktemplate")
|
||||||
printf("ThreadRPCServer method=%s\n", strMethod.c_str());
|
printf("ThreadRPCServer method=%s\n", strMethod.c_str());
|
||||||
|
@ -877,7 +877,7 @@ void JSONRequest::parse(const Value& valRequest)
|
||||||
else if (valParams.type() == null_type)
|
else if (valParams.type() == null_type)
|
||||||
params = Array();
|
params = Array();
|
||||||
else
|
else
|
||||||
throw JSONRPCError(-32600, "Params must be an array");
|
throw JSONRPCError(RPC_INVALID_REQUEST, "Params must be an array");
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object JSONRPCExecOne(const Value& req)
|
static Object JSONRPCExecOne(const Value& req)
|
||||||
|
@ -898,7 +898,7 @@ static Object JSONRPCExecOne(const Value& req)
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
rpc_result = JSONRPCReplyObj(Value::null,
|
rpc_result = JSONRPCReplyObj(Value::null,
|
||||||
JSONRPCError(-32700, e.what()), jreq.id);
|
JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rpc_result;
|
return rpc_result;
|
||||||
|
@ -946,7 +946,7 @@ void ThreadRPCServer3(void* parg)
|
||||||
// Check authorization
|
// Check authorization
|
||||||
if (mapHeaders.count("authorization") == 0)
|
if (mapHeaders.count("authorization") == 0)
|
||||||
{
|
{
|
||||||
conn->stream() << HTTPReply(401, "", false) << std::flush;
|
conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!HTTPAuthorized(mapHeaders))
|
if (!HTTPAuthorized(mapHeaders))
|
||||||
|
@ -958,7 +958,7 @@ void ThreadRPCServer3(void* parg)
|
||||||
if (mapArgs["-rpcpassword"].size() < 20)
|
if (mapArgs["-rpcpassword"].size() < 20)
|
||||||
Sleep(250);
|
Sleep(250);
|
||||||
|
|
||||||
conn->stream() << HTTPReply(401, "", false) << std::flush;
|
conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (mapHeaders["connection"] == "close")
|
if (mapHeaders["connection"] == "close")
|
||||||
|
@ -970,7 +970,7 @@ void ThreadRPCServer3(void* parg)
|
||||||
// Parse request
|
// Parse request
|
||||||
Value valRequest;
|
Value valRequest;
|
||||||
if (!read_string(strRequest, valRequest))
|
if (!read_string(strRequest, valRequest))
|
||||||
throw JSONRPCError(-32700, "Parse error");
|
throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
|
||||||
|
|
||||||
string strReply;
|
string strReply;
|
||||||
|
|
||||||
|
@ -987,9 +987,9 @@ void ThreadRPCServer3(void* parg)
|
||||||
} else if (valRequest.type() == array_type)
|
} else if (valRequest.type() == array_type)
|
||||||
strReply = JSONRPCExecBatch(valRequest.get_array());
|
strReply = JSONRPCExecBatch(valRequest.get_array());
|
||||||
else
|
else
|
||||||
throw JSONRPCError(-32700, "Top-level object parse error");
|
throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
|
||||||
|
|
||||||
conn->stream() << HTTPReply(200, strReply, fRun) << std::flush;
|
conn->stream() << HTTPReply(HTTP_OK, strReply, fRun) << std::flush;
|
||||||
}
|
}
|
||||||
catch (Object& objError)
|
catch (Object& objError)
|
||||||
{
|
{
|
||||||
|
@ -998,7 +998,7 @@ void ThreadRPCServer3(void* parg)
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
ErrorReply(conn->stream(), JSONRPCError(-32700, e.what()), jreq.id);
|
ErrorReply(conn->stream(), JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1015,13 +1015,13 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
|
||||||
// Find method
|
// Find method
|
||||||
const CRPCCommand *pcmd = tableRPC[strMethod];
|
const CRPCCommand *pcmd = tableRPC[strMethod];
|
||||||
if (!pcmd)
|
if (!pcmd)
|
||||||
throw JSONRPCError(-32601, "Method not found");
|
throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found");
|
||||||
|
|
||||||
// Observe safe mode
|
// Observe safe mode
|
||||||
string strWarning = GetWarnings("rpc");
|
string strWarning = GetWarnings("rpc");
|
||||||
if (strWarning != "" && !GetBoolArg("-disablesafemode") &&
|
if (strWarning != "" && !GetBoolArg("-disablesafemode") &&
|
||||||
!pcmd->okSafeMode)
|
!pcmd->okSafeMode)
|
||||||
throw JSONRPCError(-2, string("Safe mode: ") + strWarning);
|
throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1039,7 +1039,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
throw JSONRPCError(-1, e.what());
|
throw JSONRPCError(RPC_MISC_ERROR, e.what());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1077,9 +1077,9 @@ Object CallRPC(const string& strMethod, const Array& params)
|
||||||
map<string, string> mapHeaders;
|
map<string, string> mapHeaders;
|
||||||
string strReply;
|
string strReply;
|
||||||
int nStatus = ReadHTTP(stream, mapHeaders, strReply);
|
int nStatus = ReadHTTP(stream, mapHeaders, strReply);
|
||||||
if (nStatus == 401)
|
if (nStatus == HTTP_UNAUTHORIZED)
|
||||||
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
|
||||||
else if (nStatus >= 400 && nStatus != 400 && nStatus != 404 && nStatus != 500)
|
else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR)
|
||||||
throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
|
throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
|
||||||
else if (strReply.empty())
|
else if (strReply.empty())
|
||||||
throw runtime_error("no response from server");
|
throw runtime_error("no response from server");
|
||||||
|
|
|
@ -18,6 +18,53 @@ class CBlockIndex;
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
// HTTP status codes
|
||||||
|
enum HTTPStatusCode
|
||||||
|
{
|
||||||
|
HTTP_OK = 200,
|
||||||
|
HTTP_BAD_REQUEST = 400,
|
||||||
|
HTTP_UNAUTHORIZED = 401,
|
||||||
|
HTTP_FORBIDDEN = 403,
|
||||||
|
HTTP_NOT_FOUND = 404,
|
||||||
|
HTTP_INTERNAL_SERVER_ERROR = 500,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Bitcoin RPC error codes
|
||||||
|
enum RPCErrorCode
|
||||||
|
{
|
||||||
|
// Standard JSON-RPC 2.0 errors
|
||||||
|
RPC_INVALID_REQUEST = -32600,
|
||||||
|
RPC_METHOD_NOT_FOUND = -32601,
|
||||||
|
RPC_INVALID_PARAMS = -32602,
|
||||||
|
RPC_INTERNAL_ERROR = -32603,
|
||||||
|
RPC_PARSE_ERROR = -32700,
|
||||||
|
|
||||||
|
// General application defined errors
|
||||||
|
RPC_MISC_ERROR = -1, // std::exception thrown in command handling
|
||||||
|
RPC_FORBIDDEN_BY_SAFE_MODE = -2, // Server is in safe mode, and command is not allowed in safe mode
|
||||||
|
RPC_TYPE_ERROR = -3, // Unexpected type was passed as parameter
|
||||||
|
RPC_INVALID_ADDRESS_OR_KEY = -5, // Invalid address or key
|
||||||
|
RPC_OUT_OF_MEMORY = -7, // Ran out of memory during operation
|
||||||
|
RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter
|
||||||
|
RPC_DATABASE_ERROR = -20, // Database error
|
||||||
|
RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format
|
||||||
|
|
||||||
|
// P2P client errors
|
||||||
|
RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected
|
||||||
|
RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, // Still downloading initial blocks
|
||||||
|
|
||||||
|
// Wallet errors
|
||||||
|
RPC_WALLET_ERROR = -4, // Unspecified problem with wallet (key not found etc.)
|
||||||
|
RPC_WALLET_INSUFFICIENT_FUNDS = -6, // Not enough funds in wallet or account
|
||||||
|
RPC_WALLET_INVALID_ACCOUNT_NAME = -11, // Invalid account name
|
||||||
|
RPC_WALLET_KEYPOOL_RAN_OUT = -12, // Keypool ran out, call keypoolrefill first
|
||||||
|
RPC_WALLET_UNLOCK_NEEDED = -13, // Enter the wallet passphrase with walletpassphrase first
|
||||||
|
RPC_WALLET_PASSPHRASE_INCORRECT = -14, // The wallet passphrase entered was incorrect
|
||||||
|
RPC_WALLET_WRONG_ENC_STATE = -15, // Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.)
|
||||||
|
RPC_WALLET_ENCRYPTION_FAILED = -16, // Failed to encrypt the wallet
|
||||||
|
RPC_WALLET_ALREADY_UNLOCKED = -17, // Wallet is already unlocked
|
||||||
|
};
|
||||||
|
|
||||||
json_spirit::Object JSONRPCError(int code, const std::string& message);
|
json_spirit::Object JSONRPCError(int code, const std::string& message);
|
||||||
|
|
||||||
void ThreadRPCServer(void* parg);
|
void ThreadRPCServer(void* parg);
|
||||||
|
|
|
@ -150,7 +150,7 @@ Value getblock(const Array& params, bool fHelp)
|
||||||
uint256 hash(strHash);
|
uint256 hash(strHash);
|
||||||
|
|
||||||
if (mapBlockIndex.count(hash) == 0)
|
if (mapBlockIndex.count(hash) == 0)
|
||||||
throw JSONRPCError(-5, "Block not found");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found");
|
||||||
|
|
||||||
CBlock block;
|
CBlock block;
|
||||||
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
CBlockIndex* pblockindex = mapBlockIndex[hash];
|
||||||
|
|
|
@ -46,7 +46,7 @@ Value importprivkey(const Array& params, bool fHelp)
|
||||||
CBitcoinSecret vchSecret;
|
CBitcoinSecret vchSecret;
|
||||||
bool fGood = vchSecret.SetString(strSecret);
|
bool fGood = vchSecret.SetString(strSecret);
|
||||||
|
|
||||||
if (!fGood) throw JSONRPCError(-5,"Invalid private key");
|
if (!fGood) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
|
||||||
|
|
||||||
CKey key;
|
CKey key;
|
||||||
bool fCompressed;
|
bool fCompressed;
|
||||||
|
@ -60,7 +60,7 @@ Value importprivkey(const Array& params, bool fHelp)
|
||||||
pwalletMain->SetAddressBookName(vchAddress, strLabel);
|
pwalletMain->SetAddressBookName(vchAddress, strLabel);
|
||||||
|
|
||||||
if (!pwalletMain->AddKey(key))
|
if (!pwalletMain->AddKey(key))
|
||||||
throw JSONRPCError(-4,"Error adding key to wallet");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error adding key to wallet");
|
||||||
|
|
||||||
pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true);
|
pwalletMain->ScanForWalletTransactions(pindexGenesisBlock, true);
|
||||||
pwalletMain->ReacceptWalletTransactions();
|
pwalletMain->ReacceptWalletTransactions();
|
||||||
|
@ -79,13 +79,13 @@ Value dumpprivkey(const Array& params, bool fHelp)
|
||||||
string strAddress = params[0].get_str();
|
string strAddress = params[0].get_str();
|
||||||
CBitcoinAddress address;
|
CBitcoinAddress address;
|
||||||
if (!address.SetString(strAddress))
|
if (!address.SetString(strAddress))
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||||
CKeyID keyID;
|
CKeyID keyID;
|
||||||
if (!address.GetKeyID(keyID))
|
if (!address.GetKeyID(keyID))
|
||||||
throw JSONRPCError(-3, "Address does not refer to a key");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to a key");
|
||||||
CSecret vchSecret;
|
CSecret vchSecret;
|
||||||
bool fCompressed;
|
bool fCompressed;
|
||||||
if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed))
|
if (!pwalletMain->GetSecret(keyID, vchSecret, fCompressed))
|
||||||
throw JSONRPCError(-4,"Private key for address " + strAddress + " is not known");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Private key for address " + strAddress + " is not known");
|
||||||
return CBitcoinSecret(vchSecret, fCompressed).ToString();
|
return CBitcoinSecret(vchSecret, fCompressed).ToString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,10 +96,10 @@ Value getwork(const Array& params, bool fHelp)
|
||||||
"If [data] is specified, tries to solve the block and returns true if it was successful.");
|
"If [data] is specified, tries to solve the block and returns true if it was successful.");
|
||||||
|
|
||||||
if (vNodes.empty())
|
if (vNodes.empty())
|
||||||
throw JSONRPCError(-9, "Bitcoin is not connected!");
|
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
|
||||||
|
|
||||||
if (IsInitialBlockDownload())
|
if (IsInitialBlockDownload())
|
||||||
throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
|
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
|
||||||
|
|
||||||
typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
|
typedef map<uint256, pair<CBlock*, CScript> > mapNewBlock_t;
|
||||||
static mapNewBlock_t mapNewBlock; // FIXME: thread safety
|
static mapNewBlock_t mapNewBlock; // FIXME: thread safety
|
||||||
|
@ -136,7 +136,7 @@ Value getwork(const Array& params, bool fHelp)
|
||||||
// Create new block
|
// Create new block
|
||||||
pblock = CreateNewBlock(reservekey);
|
pblock = CreateNewBlock(reservekey);
|
||||||
if (!pblock)
|
if (!pblock)
|
||||||
throw JSONRPCError(-7, "Out of memory");
|
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
||||||
vNewBlock.push_back(pblock);
|
vNewBlock.push_back(pblock);
|
||||||
|
|
||||||
// Need to update only after we know CreateNewBlock succeeded
|
// Need to update only after we know CreateNewBlock succeeded
|
||||||
|
@ -174,7 +174,7 @@ Value getwork(const Array& params, bool fHelp)
|
||||||
// Parse parameters
|
// Parse parameters
|
||||||
vector<unsigned char> vchData = ParseHex(params[0].get_str());
|
vector<unsigned char> vchData = ParseHex(params[0].get_str());
|
||||||
if (vchData.size() != 128)
|
if (vchData.size() != 128)
|
||||||
throw JSONRPCError(-8, "Invalid parameter");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
|
||||||
CBlock* pdata = (CBlock*)&vchData[0];
|
CBlock* pdata = (CBlock*)&vchData[0];
|
||||||
|
|
||||||
// Byte reverse
|
// Byte reverse
|
||||||
|
@ -230,17 +230,17 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
||||||
/* Do nothing */
|
/* Do nothing */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw JSONRPCError(-8, "Invalid mode");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strMode != "template")
|
if (strMode != "template")
|
||||||
throw JSONRPCError(-8, "Invalid mode");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
|
||||||
|
|
||||||
if (vNodes.empty())
|
if (vNodes.empty())
|
||||||
throw JSONRPCError(-9, "Bitcoin is not connected!");
|
throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!");
|
||||||
|
|
||||||
if (IsInitialBlockDownload())
|
if (IsInitialBlockDownload())
|
||||||
throw JSONRPCError(-10, "Bitcoin is downloading blocks...");
|
throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks...");
|
||||||
|
|
||||||
static CReserveKey reservekey(pwalletMain);
|
static CReserveKey reservekey(pwalletMain);
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ Value getblocktemplate(const Array& params, bool fHelp)
|
||||||
}
|
}
|
||||||
pblock = CreateNewBlock(reservekey);
|
pblock = CreateNewBlock(reservekey);
|
||||||
if (!pblock)
|
if (!pblock)
|
||||||
throw JSONRPCError(-7, "Out of memory");
|
throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory");
|
||||||
|
|
||||||
// Need to update only after we know CreateNewBlock succeeded
|
// Need to update only after we know CreateNewBlock succeeded
|
||||||
pindexPrev = pindexPrevNew;
|
pindexPrev = pindexPrevNew;
|
||||||
|
@ -369,7 +369,7 @@ Value submitblock(const Array& params, bool fHelp)
|
||||||
ssBlock >> block;
|
ssBlock >> block;
|
||||||
}
|
}
|
||||||
catch (std::exception &e) {
|
catch (std::exception &e) {
|
||||||
throw JSONRPCError(-22, "Block decode failed");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fAccepted = ProcessBlock(NULL, &block);
|
bool fAccepted = ProcessBlock(NULL, &block);
|
||||||
|
|
|
@ -119,7 +119,7 @@ Value getrawtransaction(const Array& params, bool fHelp)
|
||||||
CTransaction tx;
|
CTransaction tx;
|
||||||
uint256 hashBlock = 0;
|
uint256 hashBlock = 0;
|
||||||
if (!GetTransaction(hash, tx, hashBlock))
|
if (!GetTransaction(hash, tx, hashBlock))
|
||||||
throw JSONRPCError(-5, "No information available about transaction");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "No information available about transaction");
|
||||||
|
|
||||||
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
CDataStream ssTx(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
ssTx << tx;
|
ssTx << tx;
|
||||||
|
@ -163,9 +163,9 @@ Value listunspent(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
CBitcoinAddress address(input.get_str());
|
CBitcoinAddress address(input.get_str());
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, string("Invalid Bitcoin address: ")+input.get_str());
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+input.get_str());
|
||||||
if (setAddress.count(address))
|
if (setAddress.count(address))
|
||||||
throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+input.get_str());
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+input.get_str());
|
||||||
setAddress.insert(address);
|
setAddress.insert(address);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,17 +227,17 @@ Value createrawtransaction(const Array& params, bool fHelp)
|
||||||
|
|
||||||
const Value& txid_v = find_value(o, "txid");
|
const Value& txid_v = find_value(o, "txid");
|
||||||
if (txid_v.type() != str_type)
|
if (txid_v.type() != str_type)
|
||||||
throw JSONRPCError(-8, "Invalid parameter, missing txid key");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing txid key");
|
||||||
string txid = txid_v.get_str();
|
string txid = txid_v.get_str();
|
||||||
if (!IsHex(txid))
|
if (!IsHex(txid))
|
||||||
throw JSONRPCError(-8, "Invalid parameter, expected hex txid");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected hex txid");
|
||||||
|
|
||||||
const Value& vout_v = find_value(o, "vout");
|
const Value& vout_v = find_value(o, "vout");
|
||||||
if (vout_v.type() != int_type)
|
if (vout_v.type() != int_type)
|
||||||
throw JSONRPCError(-8, "Invalid parameter, missing vout key");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, missing vout key");
|
||||||
int nOutput = vout_v.get_int();
|
int nOutput = vout_v.get_int();
|
||||||
if (nOutput < 0)
|
if (nOutput < 0)
|
||||||
throw JSONRPCError(-8, "Invalid parameter, vout must be positive");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, vout must be positive");
|
||||||
|
|
||||||
CTxIn in(COutPoint(uint256(txid), nOutput));
|
CTxIn in(COutPoint(uint256(txid), nOutput));
|
||||||
rawTx.vin.push_back(in);
|
rawTx.vin.push_back(in);
|
||||||
|
@ -248,10 +248,10 @@ Value createrawtransaction(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
CBitcoinAddress address(s.name_);
|
CBitcoinAddress address(s.name_);
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, string("Invalid Bitcoin address: ")+s.name_);
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
|
||||||
|
|
||||||
if (setAddress.count(address))
|
if (setAddress.count(address))
|
||||||
throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
|
||||||
setAddress.insert(address);
|
setAddress.insert(address);
|
||||||
|
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
|
@ -283,7 +283,7 @@ Value decoderawtransaction(const Array& params, bool fHelp)
|
||||||
ssData >> tx;
|
ssData >> tx;
|
||||||
}
|
}
|
||||||
catch (std::exception &e) {
|
catch (std::exception &e) {
|
||||||
throw JSONRPCError(-22, "TX decode failed");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
Object result;
|
Object result;
|
||||||
|
@ -322,12 +322,12 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||||
txVariants.push_back(tx);
|
txVariants.push_back(tx);
|
||||||
}
|
}
|
||||||
catch (std::exception &e) {
|
catch (std::exception &e) {
|
||||||
throw JSONRPCError(-22, "TX decode failed");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txVariants.empty())
|
if (txVariants.empty())
|
||||||
throw JSONRPCError(-22, "Missing transaction");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction");
|
||||||
|
|
||||||
// mergedTx will end up with all the signatures; it
|
// mergedTx will end up with all the signatures; it
|
||||||
// starts as a clone of the rawtx:
|
// starts as a clone of the rawtx:
|
||||||
|
@ -364,7 +364,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||||
BOOST_FOREACH(Value& p, prevTxs)
|
BOOST_FOREACH(Value& p, prevTxs)
|
||||||
{
|
{
|
||||||
if (p.type() != obj_type)
|
if (p.type() != obj_type)
|
||||||
throw JSONRPCError(-22, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "expected object with {\"txid'\",\"vout\",\"scriptPubKey\"}");
|
||||||
|
|
||||||
Object prevOut = p.get_obj();
|
Object prevOut = p.get_obj();
|
||||||
|
|
||||||
|
@ -372,17 +372,17 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||||
|
|
||||||
string txidHex = find_value(prevOut, "txid").get_str();
|
string txidHex = find_value(prevOut, "txid").get_str();
|
||||||
if (!IsHex(txidHex))
|
if (!IsHex(txidHex))
|
||||||
throw JSONRPCError(-22, "txid must be hexadecimal");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "txid must be hexadecimal");
|
||||||
uint256 txid;
|
uint256 txid;
|
||||||
txid.SetHex(txidHex);
|
txid.SetHex(txidHex);
|
||||||
|
|
||||||
int nOut = find_value(prevOut, "vout").get_int();
|
int nOut = find_value(prevOut, "vout").get_int();
|
||||||
if (nOut < 0)
|
if (nOut < 0)
|
||||||
throw JSONRPCError(-22, "vout must be positive");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "vout must be positive");
|
||||||
|
|
||||||
string pkHex = find_value(prevOut, "scriptPubKey").get_str();
|
string pkHex = find_value(prevOut, "scriptPubKey").get_str();
|
||||||
if (!IsHex(pkHex))
|
if (!IsHex(pkHex))
|
||||||
throw JSONRPCError(-22, "scriptPubKey must be hexadecimal");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "scriptPubKey must be hexadecimal");
|
||||||
vector<unsigned char> pkData(ParseHex(pkHex));
|
vector<unsigned char> pkData(ParseHex(pkHex));
|
||||||
CScript scriptPubKey(pkData.begin(), pkData.end());
|
CScript scriptPubKey(pkData.begin(), pkData.end());
|
||||||
|
|
||||||
|
@ -395,7 +395,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||||
string err("Previous output scriptPubKey mismatch:\n");
|
string err("Previous output scriptPubKey mismatch:\n");
|
||||||
err = err + mapPrevOut[outpoint].ToString() + "\nvs:\n"+
|
err = err + mapPrevOut[outpoint].ToString() + "\nvs:\n"+
|
||||||
scriptPubKey.ToString();
|
scriptPubKey.ToString();
|
||||||
throw JSONRPCError(-22, err);
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -414,7 +414,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||||
CBitcoinSecret vchSecret;
|
CBitcoinSecret vchSecret;
|
||||||
bool fGood = vchSecret.SetString(k.get_str());
|
bool fGood = vchSecret.SetString(k.get_str());
|
||||||
if (!fGood)
|
if (!fGood)
|
||||||
throw JSONRPCError(-5,"Invalid private key");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,"Invalid private key");
|
||||||
CKey key;
|
CKey key;
|
||||||
bool fCompressed;
|
bool fCompressed;
|
||||||
CSecret secret = vchSecret.GetSecret(fCompressed);
|
CSecret secret = vchSecret.GetSecret(fCompressed);
|
||||||
|
@ -443,7 +443,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
|
||||||
if (mapSigHashValues.count(strHashType))
|
if (mapSigHashValues.count(strHashType))
|
||||||
nHashType = mapSigHashValues[strHashType];
|
nHashType = mapSigHashValues[strHashType];
|
||||||
else
|
else
|
||||||
throw JSONRPCError(-8, "Invalid sighash param");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
|
bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE);
|
||||||
|
@ -501,7 +501,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
||||||
ssData >> tx;
|
ssData >> tx;
|
||||||
}
|
}
|
||||||
catch (std::exception &e) {
|
catch (std::exception &e) {
|
||||||
throw JSONRPCError(-22, "TX decode failed");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed");
|
||||||
}
|
}
|
||||||
uint256 hashTx = tx.GetHash();
|
uint256 hashTx = tx.GetHash();
|
||||||
|
|
||||||
|
@ -512,7 +512,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
||||||
if (GetTransaction(hashTx, existingTx, hashBlock))
|
if (GetTransaction(hashTx, existingTx, hashBlock))
|
||||||
{
|
{
|
||||||
if (hashBlock != 0)
|
if (hashBlock != 0)
|
||||||
throw JSONRPCError(-5, string("transaction already in block ")+hashBlock.GetHex());
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("transaction already in block ")+hashBlock.GetHex());
|
||||||
// Not in block, but already in the memory pool; will drop
|
// Not in block, but already in the memory pool; will drop
|
||||||
// through to re-relay it.
|
// through to re-relay it.
|
||||||
}
|
}
|
||||||
|
@ -521,7 +521,7 @@ Value sendrawtransaction(const Array& params, bool fHelp)
|
||||||
// push to local node
|
// push to local node
|
||||||
CTxDB txdb("r");
|
CTxDB txdb("r");
|
||||||
if (!tx.AcceptToMemoryPool(txdb))
|
if (!tx.AcceptToMemoryPool(txdb))
|
||||||
throw JSONRPCError(-22, "TX rejected");
|
throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected");
|
||||||
|
|
||||||
SyncWithWallets(tx, NULL, true);
|
SyncWithWallets(tx, NULL, true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ std::string HelpRequiringPassphrase()
|
||||||
void EnsureWalletIsUnlocked()
|
void EnsureWalletIsUnlocked()
|
||||||
{
|
{
|
||||||
if (pwalletMain->IsLocked())
|
if (pwalletMain->IsLocked())
|
||||||
throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
|
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
|
void WalletTxToJSON(const CWalletTx& wtx, Object& entry)
|
||||||
|
@ -51,7 +51,7 @@ string AccountFromValue(const Value& value)
|
||||||
{
|
{
|
||||||
string strAccount = value.get_str();
|
string strAccount = value.get_str();
|
||||||
if (strAccount == "*")
|
if (strAccount == "*")
|
||||||
throw JSONRPCError(-11, "Invalid account name");
|
throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name");
|
||||||
return strAccount;
|
return strAccount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ Value getnewaddress(const Array& params, bool fHelp)
|
||||||
// Generate a new key that is added to wallet
|
// Generate a new key that is added to wallet
|
||||||
CPubKey newKey;
|
CPubKey newKey;
|
||||||
if (!pwalletMain->GetKeyFromPool(newKey, false))
|
if (!pwalletMain->GetKeyFromPool(newKey, false))
|
||||||
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
|
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
|
||||||
CKeyID keyID = newKey.GetID();
|
CKeyID keyID = newKey.GetID();
|
||||||
|
|
||||||
pwalletMain->SetAddressBookName(keyID, strAccount);
|
pwalletMain->SetAddressBookName(keyID, strAccount);
|
||||||
|
@ -144,7 +144,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false)
|
||||||
if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
|
if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed)
|
||||||
{
|
{
|
||||||
if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
|
if (!pwalletMain->GetKeyFromPool(account.vchPubKey, false))
|
||||||
throw JSONRPCError(-12, "Error: Keypool ran out, please call keypoolrefill first");
|
throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first");
|
||||||
|
|
||||||
pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount);
|
pwalletMain->SetAddressBookName(account.vchPubKey.GetID(), strAccount);
|
||||||
walletdb.WriteAccount(strAccount, account);
|
walletdb.WriteAccount(strAccount, account);
|
||||||
|
@ -181,7 +181,7 @@ Value setaccount(const Array& params, bool fHelp)
|
||||||
|
|
||||||
CBitcoinAddress address(params[0].get_str());
|
CBitcoinAddress address(params[0].get_str());
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||||
|
|
||||||
|
|
||||||
string strAccount;
|
string strAccount;
|
||||||
|
@ -211,7 +211,7 @@ Value getaccount(const Array& params, bool fHelp)
|
||||||
|
|
||||||
CBitcoinAddress address(params[0].get_str());
|
CBitcoinAddress address(params[0].get_str());
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||||
|
|
||||||
string strAccount;
|
string strAccount;
|
||||||
map<CTxDestination, string>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
|
map<CTxDestination, string>::iterator mi = pwalletMain->mapAddressBook.find(address.Get());
|
||||||
|
@ -252,7 +252,7 @@ Value sendtoaddress(const Array& params, bool fHelp)
|
||||||
|
|
||||||
CBitcoinAddress address(params[0].get_str());
|
CBitcoinAddress address(params[0].get_str());
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||||
|
|
||||||
// Amount
|
// Amount
|
||||||
int64 nAmount = AmountFromValue(params[1]);
|
int64 nAmount = AmountFromValue(params[1]);
|
||||||
|
@ -265,11 +265,11 @@ Value sendtoaddress(const Array& params, bool fHelp)
|
||||||
wtx.mapValue["to"] = params[3].get_str();
|
wtx.mapValue["to"] = params[3].get_str();
|
||||||
|
|
||||||
if (pwalletMain->IsLocked())
|
if (pwalletMain->IsLocked())
|
||||||
throw JSONRPCError(-13, "Error: Please enter the wallet passphrase with walletpassphrase first.");
|
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, "Error: Please enter the wallet passphrase with walletpassphrase first.");
|
||||||
|
|
||||||
string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
|
string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
|
||||||
if (strError != "")
|
if (strError != "")
|
||||||
throw JSONRPCError(-4, strError);
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
|
|
||||||
return wtx.GetHash().GetHex();
|
return wtx.GetHash().GetHex();
|
||||||
}
|
}
|
||||||
|
@ -319,15 +319,15 @@ Value signmessage(const Array& params, bool fHelp)
|
||||||
|
|
||||||
CBitcoinAddress addr(strAddress);
|
CBitcoinAddress addr(strAddress);
|
||||||
if (!addr.IsValid())
|
if (!addr.IsValid())
|
||||||
throw JSONRPCError(-3, "Invalid address");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
|
||||||
|
|
||||||
CKeyID keyID;
|
CKeyID keyID;
|
||||||
if (!addr.GetKeyID(keyID))
|
if (!addr.GetKeyID(keyID))
|
||||||
throw JSONRPCError(-3, "Address does not refer to key");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
|
||||||
|
|
||||||
CKey key;
|
CKey key;
|
||||||
if (!pwalletMain->GetKey(keyID, key))
|
if (!pwalletMain->GetKey(keyID, key))
|
||||||
throw JSONRPCError(-4, "Private key not available");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Private key not available");
|
||||||
|
|
||||||
CDataStream ss(SER_GETHASH, 0);
|
CDataStream ss(SER_GETHASH, 0);
|
||||||
ss << strMessageMagic;
|
ss << strMessageMagic;
|
||||||
|
@ -335,7 +335,7 @@ Value signmessage(const Array& params, bool fHelp)
|
||||||
|
|
||||||
vector<unsigned char> vchSig;
|
vector<unsigned char> vchSig;
|
||||||
if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
|
if (!key.SignCompact(Hash(ss.begin(), ss.end()), vchSig))
|
||||||
throw JSONRPCError(-5, "Sign failed");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Sign failed");
|
||||||
|
|
||||||
return EncodeBase64(&vchSig[0], vchSig.size());
|
return EncodeBase64(&vchSig[0], vchSig.size());
|
||||||
}
|
}
|
||||||
|
@ -353,17 +353,17 @@ Value verifymessage(const Array& params, bool fHelp)
|
||||||
|
|
||||||
CBitcoinAddress addr(strAddress);
|
CBitcoinAddress addr(strAddress);
|
||||||
if (!addr.IsValid())
|
if (!addr.IsValid())
|
||||||
throw JSONRPCError(-3, "Invalid address");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address");
|
||||||
|
|
||||||
CKeyID keyID;
|
CKeyID keyID;
|
||||||
if (!addr.GetKeyID(keyID))
|
if (!addr.GetKeyID(keyID))
|
||||||
throw JSONRPCError(-3, "Address does not refer to key");
|
throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
|
||||||
|
|
||||||
bool fInvalid = false;
|
bool fInvalid = false;
|
||||||
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
|
vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid);
|
||||||
|
|
||||||
if (fInvalid)
|
if (fInvalid)
|
||||||
throw JSONRPCError(-5, "Malformed base64 encoding");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding");
|
||||||
|
|
||||||
CDataStream ss(SER_GETHASH, 0);
|
CDataStream ss(SER_GETHASH, 0);
|
||||||
ss << strMessageMagic;
|
ss << strMessageMagic;
|
||||||
|
@ -388,7 +388,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp)
|
||||||
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
|
CBitcoinAddress address = CBitcoinAddress(params[0].get_str());
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||||
scriptPubKey.SetDestination(address.Get());
|
scriptPubKey.SetDestination(address.Get());
|
||||||
if (!IsMine(*pwalletMain,scriptPubKey))
|
if (!IsMine(*pwalletMain,scriptPubKey))
|
||||||
return (double)0.0;
|
return (double)0.0;
|
||||||
|
@ -567,7 +567,7 @@ Value movecmd(const Array& params, bool fHelp)
|
||||||
|
|
||||||
CWalletDB walletdb(pwalletMain->strWalletFile);
|
CWalletDB walletdb(pwalletMain->strWalletFile);
|
||||||
if (!walletdb.TxnBegin())
|
if (!walletdb.TxnBegin())
|
||||||
throw JSONRPCError(-20, "database error");
|
throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
|
||||||
|
|
||||||
int64 nNow = GetAdjustedTime();
|
int64 nNow = GetAdjustedTime();
|
||||||
|
|
||||||
|
@ -592,7 +592,7 @@ Value movecmd(const Array& params, bool fHelp)
|
||||||
walletdb.WriteAccountingEntry(credit);
|
walletdb.WriteAccountingEntry(credit);
|
||||||
|
|
||||||
if (!walletdb.TxnCommit())
|
if (!walletdb.TxnCommit())
|
||||||
throw JSONRPCError(-20, "database error");
|
throw JSONRPCError(RPC_DATABASE_ERROR, "database error");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -609,7 +609,7 @@ Value sendfrom(const Array& params, bool fHelp)
|
||||||
string strAccount = AccountFromValue(params[0]);
|
string strAccount = AccountFromValue(params[0]);
|
||||||
CBitcoinAddress address(params[1].get_str());
|
CBitcoinAddress address(params[1].get_str());
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, "Invalid Bitcoin address");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
|
||||||
int64 nAmount = AmountFromValue(params[2]);
|
int64 nAmount = AmountFromValue(params[2]);
|
||||||
int nMinDepth = 1;
|
int nMinDepth = 1;
|
||||||
if (params.size() > 3)
|
if (params.size() > 3)
|
||||||
|
@ -627,12 +627,12 @@ Value sendfrom(const Array& params, bool fHelp)
|
||||||
// Check funds
|
// Check funds
|
||||||
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
||||||
if (nAmount > nBalance)
|
if (nAmount > nBalance)
|
||||||
throw JSONRPCError(-6, "Account has insufficient funds");
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
|
string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx);
|
||||||
if (strError != "")
|
if (strError != "")
|
||||||
throw JSONRPCError(-4, strError);
|
throw JSONRPCError(RPC_WALLET_ERROR, strError);
|
||||||
|
|
||||||
return wtx.GetHash().GetHex();
|
return wtx.GetHash().GetHex();
|
||||||
}
|
}
|
||||||
|
@ -665,10 +665,10 @@ Value sendmany(const Array& params, bool fHelp)
|
||||||
{
|
{
|
||||||
CBitcoinAddress address(s.name_);
|
CBitcoinAddress address(s.name_);
|
||||||
if (!address.IsValid())
|
if (!address.IsValid())
|
||||||
throw JSONRPCError(-5, string("Invalid Bitcoin address: ")+s.name_);
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, string("Invalid Bitcoin address: ")+s.name_);
|
||||||
|
|
||||||
if (setAddress.count(address))
|
if (setAddress.count(address))
|
||||||
throw JSONRPCError(-8, string("Invalid parameter, duplicated address: ")+s.name_);
|
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, duplicated address: ")+s.name_);
|
||||||
setAddress.insert(address);
|
setAddress.insert(address);
|
||||||
|
|
||||||
CScript scriptPubKey;
|
CScript scriptPubKey;
|
||||||
|
@ -684,7 +684,7 @@ Value sendmany(const Array& params, bool fHelp)
|
||||||
// Check funds
|
// Check funds
|
||||||
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
int64 nBalance = GetAccountBalance(strAccount, nMinDepth);
|
||||||
if (totalAmount > nBalance)
|
if (totalAmount > nBalance)
|
||||||
throw JSONRPCError(-6, "Account has insufficient funds");
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds");
|
||||||
|
|
||||||
// Send
|
// Send
|
||||||
CReserveKey keyChange(pwalletMain);
|
CReserveKey keyChange(pwalletMain);
|
||||||
|
@ -693,11 +693,11 @@ Value sendmany(const Array& params, bool fHelp)
|
||||||
if (!fCreated)
|
if (!fCreated)
|
||||||
{
|
{
|
||||||
if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
|
if (totalAmount + nFeeRequired > pwalletMain->GetBalance())
|
||||||
throw JSONRPCError(-6, "Insufficient funds");
|
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
|
||||||
throw JSONRPCError(-4, "Transaction creation failed");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Transaction creation failed");
|
||||||
}
|
}
|
||||||
if (!pwalletMain->CommitTransaction(wtx, keyChange))
|
if (!pwalletMain->CommitTransaction(wtx, keyChange))
|
||||||
throw JSONRPCError(-4, "Transaction commit failed");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed");
|
||||||
|
|
||||||
return wtx.GetHash().GetHex();
|
return wtx.GetHash().GetHex();
|
||||||
}
|
}
|
||||||
|
@ -1000,9 +1000,9 @@ Value listtransactions(const Array& params, bool fHelp)
|
||||||
nFrom = params[2].get_int();
|
nFrom = params[2].get_int();
|
||||||
|
|
||||||
if (nCount < 0)
|
if (nCount < 0)
|
||||||
throw JSONRPCError(-8, "Negative count");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count");
|
||||||
if (nFrom < 0)
|
if (nFrom < 0)
|
||||||
throw JSONRPCError(-8, "Negative from");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from");
|
||||||
|
|
||||||
Array ret;
|
Array ret;
|
||||||
|
|
||||||
|
@ -1113,7 +1113,7 @@ Value listsinceblock(const Array& params, bool fHelp)
|
||||||
target_confirms = params[1].get_int();
|
target_confirms = params[1].get_int();
|
||||||
|
|
||||||
if (target_confirms < 1)
|
if (target_confirms < 1)
|
||||||
throw JSONRPCError(-8, "Invalid parameter");
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter");
|
||||||
}
|
}
|
||||||
|
|
||||||
int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1;
|
int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1;
|
||||||
|
@ -1165,7 +1165,7 @@ Value gettransaction(const Array& params, bool fHelp)
|
||||||
|
|
||||||
Object entry;
|
Object entry;
|
||||||
if (!pwalletMain->mapWallet.count(hash))
|
if (!pwalletMain->mapWallet.count(hash))
|
||||||
throw JSONRPCError(-5, "Invalid or non-wallet transaction id");
|
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id");
|
||||||
const CWalletTx& wtx = pwalletMain->mapWallet[hash];
|
const CWalletTx& wtx = pwalletMain->mapWallet[hash];
|
||||||
|
|
||||||
int64 nCredit = wtx.GetCredit();
|
int64 nCredit = wtx.GetCredit();
|
||||||
|
@ -1214,7 +1214,7 @@ Value keypoolrefill(const Array& params, bool fHelp)
|
||||||
pwalletMain->TopUpKeyPool();
|
pwalletMain->TopUpKeyPool();
|
||||||
|
|
||||||
if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
|
if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100))
|
||||||
throw JSONRPCError(-4, "Error refreshing keypool.");
|
throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool.");
|
||||||
|
|
||||||
return Value::null;
|
return Value::null;
|
||||||
}
|
}
|
||||||
|
@ -1281,10 +1281,10 @@ Value walletpassphrase(const Array& params, bool fHelp)
|
||||||
if (fHelp)
|
if (fHelp)
|
||||||
return true;
|
return true;
|
||||||
if (!pwalletMain->IsCrypted())
|
if (!pwalletMain->IsCrypted())
|
||||||
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
|
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrase was called.");
|
||||||
|
|
||||||
if (!pwalletMain->IsLocked())
|
if (!pwalletMain->IsLocked())
|
||||||
throw JSONRPCError(-17, "Error: Wallet is already unlocked.");
|
throw JSONRPCError(RPC_WALLET_ALREADY_UNLOCKED, "Error: Wallet is already unlocked.");
|
||||||
|
|
||||||
// Note that the walletpassphrase is stored in params[0] which is not mlock()ed
|
// Note that the walletpassphrase is stored in params[0] which is not mlock()ed
|
||||||
SecureString strWalletPass;
|
SecureString strWalletPass;
|
||||||
|
@ -1296,7 +1296,7 @@ Value walletpassphrase(const Array& params, bool fHelp)
|
||||||
if (strWalletPass.length() > 0)
|
if (strWalletPass.length() > 0)
|
||||||
{
|
{
|
||||||
if (!pwalletMain->Unlock(strWalletPass))
|
if (!pwalletMain->Unlock(strWalletPass))
|
||||||
throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
|
throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
|
@ -1320,7 +1320,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp)
|
||||||
if (fHelp)
|
if (fHelp)
|
||||||
return true;
|
return true;
|
||||||
if (!pwalletMain->IsCrypted())
|
if (!pwalletMain->IsCrypted())
|
||||||
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
|
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletpassphrasechange was called.");
|
||||||
|
|
||||||
// TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
|
// TODO: get rid of these .c_str() calls by implementing SecureString::operator=(std::string)
|
||||||
// Alternately, find a way to make params[0] mlock()'d to begin with.
|
// Alternately, find a way to make params[0] mlock()'d to begin with.
|
||||||
|
@ -1338,7 +1338,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp)
|
||||||
"Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
|
"Changes the wallet passphrase from <oldpassphrase> to <newpassphrase>.");
|
||||||
|
|
||||||
if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
|
if (!pwalletMain->ChangeWalletPassphrase(strOldWalletPass, strNewWalletPass))
|
||||||
throw JSONRPCError(-14, "Error: The wallet passphrase entered was incorrect.");
|
throw JSONRPCError(RPC_WALLET_PASSPHRASE_INCORRECT, "Error: The wallet passphrase entered was incorrect.");
|
||||||
|
|
||||||
return Value::null;
|
return Value::null;
|
||||||
}
|
}
|
||||||
|
@ -1355,7 +1355,7 @@ Value walletlock(const Array& params, bool fHelp)
|
||||||
if (fHelp)
|
if (fHelp)
|
||||||
return true;
|
return true;
|
||||||
if (!pwalletMain->IsCrypted())
|
if (!pwalletMain->IsCrypted())
|
||||||
throw JSONRPCError(-15, "Error: running with an unencrypted wallet, but walletlock was called.");
|
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an unencrypted wallet, but walletlock was called.");
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK(cs_nWalletUnlockTime);
|
LOCK(cs_nWalletUnlockTime);
|
||||||
|
@ -1376,7 +1376,7 @@ Value encryptwallet(const Array& params, bool fHelp)
|
||||||
if (fHelp)
|
if (fHelp)
|
||||||
return true;
|
return true;
|
||||||
if (pwalletMain->IsCrypted())
|
if (pwalletMain->IsCrypted())
|
||||||
throw JSONRPCError(-15, "Error: running with an encrypted wallet, but encryptwallet was called.");
|
throw JSONRPCError(RPC_WALLET_WRONG_ENC_STATE, "Error: running with an encrypted wallet, but encryptwallet was called.");
|
||||||
|
|
||||||
// TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
|
// TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
|
||||||
// Alternately, find a way to make params[0] mlock()'d to begin with.
|
// Alternately, find a way to make params[0] mlock()'d to begin with.
|
||||||
|
@ -1390,7 +1390,7 @@ Value encryptwallet(const Array& params, bool fHelp)
|
||||||
"Encrypts the wallet with <passphrase>.");
|
"Encrypts the wallet with <passphrase>.");
|
||||||
|
|
||||||
if (!pwalletMain->EncryptWallet(strWalletPass))
|
if (!pwalletMain->EncryptWallet(strWalletPass))
|
||||||
throw JSONRPCError(-16, "Error: Failed to encrypt the wallet.");
|
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, "Error: Failed to encrypt the wallet.");
|
||||||
|
|
||||||
// BDB seems to have a bad habit of writing old data into
|
// BDB seems to have a bad habit of writing old data into
|
||||||
// slack space in .dat files; that is bad if the old data is
|
// slack space in .dat files; that is bad if the old data is
|
||||||
|
|
Loading…
Reference in a new issue