diff options
-rw-r--r-- | src/bitcoinrpc.cpp | 66 | ||||
-rw-r--r-- | src/bitcoinrpc.h | 47 | ||||
-rw-r--r-- | src/db.cpp | 19 | ||||
-rw-r--r-- | src/init.cpp | 17 | ||||
-rw-r--r-- | src/main.cpp | 1 | ||||
-rw-r--r-- | src/net.cpp | 4 | ||||
-rw-r--r-- | src/netbase.cpp | 41 | ||||
-rw-r--r-- | src/netbase.h | 6 | ||||
-rw-r--r-- | src/qt/bitcoin.cpp | 5 | ||||
-rw-r--r-- | src/qt/guiutil.cpp | 2 | ||||
-rw-r--r-- | src/qt/optionsdialog.cpp | 2 | ||||
-rw-r--r-- | src/qt/optionsmodel.cpp | 69 | ||||
-rw-r--r-- | src/rpcblockchain.cpp | 2 | ||||
-rw-r--r-- | src/rpcdump.cpp | 10 | ||||
-rw-r--r-- | src/rpcmining.cpp | 20 | ||||
-rw-r--r-- | src/rpcrawtransaction.cpp | 44 | ||||
-rw-r--r-- | src/rpcwallet.cpp | 88 |
17 files changed, 263 insertions, 180 deletions
diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 912f0c4113..0704173e54 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -69,7 +69,7 @@ void RPCTypeCheck(const Array& params, { string err = strprintf("Expected type %s, got %s", Value_type_name[t], Value_type_name[v.type()]); - throw JSONRPCError(-3, err); + throw JSONRPCError(RPC_TYPE_ERROR, err); } i++; } @@ -83,13 +83,13 @@ void RPCTypeCheck(const Object& o, { const Value& v = find_value(o, t.first); 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)))) { string err = strprintf("Expected type %s for %s, got %s", 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(); if (dAmount <= 0.0 || dAmount > 21000000.0) - throw JSONRPCError(-3, "Invalid amount"); + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); int64 nAmount = roundint64(dAmount * COIN); if (!MoneyRange(nAmount)) - throw JSONRPCError(-3, "Invalid amount"); + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid amount"); return nAmount; } @@ -317,7 +317,7 @@ string rfc1123Time() 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" "Date: %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" "</HTML>\r\n", rfc1123Time().c_str(), FormatFullVersion().c_str()); const char *cStatus; - if (nStatus == 200) cStatus = "OK"; - else if (nStatus == 400) cStatus = "Bad Request"; - else if (nStatus == 403) cStatus = "Forbidden"; - else if (nStatus == 404) cStatus = "Not Found"; - else if (nStatus == 500) cStatus = "Internal Server Error"; + if (nStatus == HTTP_OK) cStatus = "OK"; + else if (nStatus == HTTP_BAD_REQUEST) cStatus = "Bad Request"; + else if (nStatus == HTTP_FORBIDDEN) cStatus = "Forbidden"; + else if (nStatus == HTTP_NOT_FOUND) cStatus = "Not Found"; + else if (nStatus == HTTP_INTERNAL_SERVER_ERROR) cStatus = "Internal Server Error"; else cStatus = ""; return strprintf( "HTTP/1.1 %d %s\r\n" @@ -366,7 +366,7 @@ int ReadHTTPStatus(std::basic_istream<char>& stream, int &proto) vector<string> vWords; boost::split(vWords, str, boost::is_any_of(" ")); if (vWords.size() < 2) - return 500; + return HTTP_INTERNAL_SERVER_ERROR; proto = 0; const char *ver = strstr(str.c_str(), "HTTP/1."); if (ver != NULL) @@ -411,7 +411,7 @@ int ReadHTTP(std::basic_istream<char>& stream, map<string, string>& mapHeadersRe // Read header int nLen = ReadHTTPHeader(stream, mapHeadersRet); if (nLen < 0 || nLen > (int)MAX_SIZE) - return 500; + return HTTP_INTERNAL_SERVER_ERROR; // Read message 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) { // 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(); - if (code == -32600) nStatus = 400; - else if (code == -32601) nStatus = 404; + 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); 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. if (!fUseSSL) - conn->stream() << HTTPReply(403, "", false) << std::flush; + conn->stream() << HTTPReply(HTTP_FORBIDDEN, "", false) << std::flush; delete conn; } @@ -854,7 +854,7 @@ void JSONRequest::parse(const Value& valRequest) { // Parse request 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(); // Parse id now so errors from here on will have the id @@ -863,9 +863,9 @@ void JSONRequest::parse(const Value& valRequest) // Parse method Value valMethod = find_value(request, "method"); if (valMethod.type() == null_type) - throw JSONRPCError(-32600, "Missing method"); + throw JSONRPCError(RPC_INVALID_REQUEST, "Missing method"); 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(); if (strMethod != "getwork" && strMethod != "getblocktemplate") printf("ThreadRPCServer method=%s\n", strMethod.c_str()); @@ -877,7 +877,7 @@ void JSONRequest::parse(const Value& valRequest) else if (valParams.type() == null_type) params = Array(); 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) @@ -898,7 +898,7 @@ static Object JSONRPCExecOne(const Value& req) catch (std::exception& e) { rpc_result = JSONRPCReplyObj(Value::null, - JSONRPCError(-32700, e.what()), jreq.id); + JSONRPCError(RPC_PARSE_ERROR, e.what()), jreq.id); } return rpc_result; @@ -946,7 +946,7 @@ void ThreadRPCServer3(void* parg) // Check authorization if (mapHeaders.count("authorization") == 0) { - conn->stream() << HTTPReply(401, "", false) << std::flush; + conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; break; } if (!HTTPAuthorized(mapHeaders)) @@ -958,7 +958,7 @@ void ThreadRPCServer3(void* parg) if (mapArgs["-rpcpassword"].size() < 20) Sleep(250); - conn->stream() << HTTPReply(401, "", false) << std::flush; + conn->stream() << HTTPReply(HTTP_UNAUTHORIZED, "", false) << std::flush; break; } if (mapHeaders["connection"] == "close") @@ -970,7 +970,7 @@ void ThreadRPCServer3(void* parg) // Parse request Value valRequest; if (!read_string(strRequest, valRequest)) - throw JSONRPCError(-32700, "Parse error"); + throw JSONRPCError(RPC_PARSE_ERROR, "Parse error"); string strReply; @@ -987,9 +987,9 @@ void ThreadRPCServer3(void* parg) } else if (valRequest.type() == array_type) strReply = JSONRPCExecBatch(valRequest.get_array()); 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) { @@ -998,7 +998,7 @@ void ThreadRPCServer3(void* parg) } 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; } } @@ -1015,13 +1015,13 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s // Find method const CRPCCommand *pcmd = tableRPC[strMethod]; if (!pcmd) - throw JSONRPCError(-32601, "Method not found"); + throw JSONRPCError(RPC_METHOD_NOT_FOUND, "Method not found"); // Observe safe mode string strWarning = GetWarnings("rpc"); if (strWarning != "" && !GetBoolArg("-disablesafemode") && !pcmd->okSafeMode) - throw JSONRPCError(-2, string("Safe mode: ") + strWarning); + throw JSONRPCError(RPC_FORBIDDEN_BY_SAFE_MODE, string("Safe mode: ") + strWarning); try { @@ -1039,7 +1039,7 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s } 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; string strReply; int nStatus = ReadHTTP(stream, mapHeaders, strReply); - if (nStatus == 401) + if (nStatus == HTTP_UNAUTHORIZED) 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)); else if (strReply.empty()) throw runtime_error("no response from server"); diff --git a/src/bitcoinrpc.h b/src/bitcoinrpc.h index 94446c36bb..89ab976f56 100644 --- a/src/bitcoinrpc.h +++ b/src/bitcoinrpc.h @@ -18,6 +18,53 @@ class CBlockIndex; #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); void ThreadRPCServer(void* parg); diff --git a/src/db.cpp b/src/db.cpp index 867703fbd2..7ca9e34953 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -34,19 +34,14 @@ void CDBEnv::EnvShutdown() return; fDbEnvInit = false; - try - { - dbenv.close(0); - } - catch (const DbException& e) - { - printf("EnvShutdown exception: %s (%d)\n", e.what(), e.get_errno()); - } + int ret = dbenv.close(0); + if (ret != 0) + printf("EnvShutdown exception: %s (%d)\n", DbEnv::strerror(ret), ret); if (!fMockDb) DbEnv(0).remove(GetDataDir().string().c_str(), 0); } -CDBEnv::CDBEnv() : dbenv(0) +CDBEnv::CDBEnv() : dbenv(DB_CXX_NO_EXCEPTIONS) { } @@ -100,8 +95,8 @@ bool CDBEnv::Open(boost::filesystem::path pathEnv_) DB_RECOVER | nEnvFlags, S_IRUSR | S_IWUSR); - if (ret > 0) - return error("CDB() : error %d opening database environment", ret); + if (ret != 0) + return error("CDB() : error %s (%d) opening database environment", DbEnv::strerror(ret), ret); fDbEnvInit = true; fMockDb = false; @@ -191,7 +186,7 @@ CDB::CDB(const char *pszFile, const char* pszMode) : nFlags, // Flags 0); - if (ret > 0) + if (ret != 0) { delete pdb; pdb = NULL; diff --git a/src/init.cpp b/src/init.cpp index 7e2cda6297..d271893644 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -144,7 +144,7 @@ bool AppInit(int argc, char* argv[]) strUsage += "\n" + HelpMessage(); - fprintf(stderr, "%s", strUsage.c_str()); + fprintf(stdout, "%s", strUsage.c_str()); return false; } @@ -439,8 +439,9 @@ bool AppInit2() FILE* file = fopen(pathLockFile.string().c_str(), "a"); // empty lock file; created if it doesn't exist. if (file) fclose(file); static boost::interprocess::file_lock lock(pathLockFile.string().c_str()); + const char* pszDataDir = GetDataDir().string().c_str(); if (!lock.try_lock()) - return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), GetDataDir().string().c_str())); + return InitError(strprintf(_("Cannot obtain a lock on data directory %s. Bitcoin is probably already running."), pszDataDir)); #if !defined(WIN32) && !defined(QT_GUI) if (fDaemon) @@ -472,7 +473,7 @@ bool AppInit2() if (!fLogTimestamps) printf("Startup time: %s\n", DateTimeStrFormat("%x %H:%M:%S", GetTime()).c_str()); printf("Default data directory %s\n", GetDefaultDataDir().string().c_str()); - printf("Used data directory %s\n", GetDataDir().string().c_str()); + printf("Used data directory %s\n", pszDataDir); std::ostringstream strErrors; if (fDaemon) @@ -588,6 +589,14 @@ bool AppInit2() // ********************************************************* Step 6: load blockchain + if (!bitdb.Open(GetDataDir())) + { + string msg = strprintf(_("Error initializing database environment %s!" + " To recover, BACKUP THAT DIRECTORY, then remove" + " everything from it except for wallet.dat."), pszDataDir); + return InitError(msg); + } + if (GetBoolArg("-loadblockindextest")) { CTxDB txdb("r"); @@ -600,7 +609,7 @@ bool AppInit2() printf("Loading block index...\n"); nStart = GetTimeMillis(); if (!LoadBlockIndex()) - strErrors << _("Error loading blkindex.dat") << "\n"; + return InitError(_("Error loading blkindex.dat")); // as LoadBlockIndex can take several minutes, it's possible the user // requested to kill bitcoin-qt during the last operation. If so, exit. diff --git a/src/main.cpp b/src/main.cpp index da1072970c..28bf01a8cb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2513,6 +2513,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) // Ask the first connected node for block updates static int nAskedForBlocks = 0; if (!pfrom->fClient && !pfrom->fOneShot && + (pfrom->nStartingHeight > (nBestHeight - 144)) && (pfrom->nVersion < NOBLKS_VERSION_START || pfrom->nVersion >= NOBLKS_VERSION_END) && (nAskedForBlocks < 1 || vNodes.size() <= 1)) diff --git a/src/net.cpp b/src/net.cpp index 7c327f5d35..5b5510a5b2 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -1185,7 +1185,7 @@ void ThreadDNSAddressSeed2(void* parg) printf("Loading addresses from DNS seeds (could take a while)\n"); for (unsigned int seed_idx = 0; seed_idx < ARRAYLEN(strDNSSeed); seed_idx++) { - if (GetNameProxy()) { + if (HaveNameProxy()) { AddOneShot(strDNSSeed[seed_idx][1]); } else { vector<CNetAddr> vaddr; @@ -1529,7 +1529,7 @@ void ThreadOpenAddedConnections2(void* parg) if (mapArgs.count("-addnode") == 0) return; - if (GetNameProxy()) { + if (HaveNameProxy()) { while(!fShutdown) { BOOST_FOREACH(string& strAddNode, mapMultiArgs["-addnode"]) { CAddress addr; diff --git a/src/netbase.cpp b/src/netbase.cpp index daa8a8d07e..95d64939ba 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -5,6 +5,7 @@ #include "netbase.h" #include "util.h" +#include "sync.h" #ifndef WIN32 #include <sys/fcntl.h> @@ -16,9 +17,9 @@ using namespace std; // Settings -typedef std::pair<CService, int> proxyType; static proxyType proxyInfo[NET_MAX]; static proxyType nameproxyInfo; +static CCriticalSection cs_proxyInfos; int nConnectTimeout = 5000; bool fNameLookup = false; @@ -432,15 +433,17 @@ bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion) { return false; if (nSocksVersion != 0 && !addrProxy.IsValid()) return false; + LOCK(cs_proxyInfos); proxyInfo[net] = std::make_pair(addrProxy, nSocksVersion); return true; } -bool GetProxy(enum Network net, CService &addrProxy) { +bool GetProxy(enum Network net, proxyType &proxyInfoOut) { assert(net >= 0 && net < NET_MAX); + LOCK(cs_proxyInfos); if (!proxyInfo[net].second) return false; - addrProxy = proxyInfo[net].first; + proxyInfoOut = proxyInfo[net]; return true; } @@ -449,16 +452,27 @@ bool SetNameProxy(CService addrProxy, int nSocksVersion) { return false; if (nSocksVersion != 0 && !addrProxy.IsValid()) return false; + LOCK(cs_proxyInfos); nameproxyInfo = std::make_pair(addrProxy, nSocksVersion); return true; } -bool GetNameProxy() { +bool GetNameProxy(proxyType &nameproxyInfoOut) { + LOCK(cs_proxyInfos); + if (!nameproxyInfo.second) + return false; + nameproxyInfoOut = nameproxyInfo; + return true; +} + +bool HaveNameProxy() { + LOCK(cs_proxyInfos); return nameproxyInfo.second != 0; } bool IsProxy(const CNetAddr &addr) { - for (int i=0; i<NET_MAX; i++) { + LOCK(cs_proxyInfos); + for (int i = 0; i < NET_MAX; i++) { if (proxyInfo[i].second && (addr == (CNetAddr)proxyInfo[i].first)) return true; } @@ -467,10 +481,10 @@ bool IsProxy(const CNetAddr &addr) { bool ConnectSocket(const CService &addrDest, SOCKET& hSocketRet, int nTimeout) { - const proxyType &proxy = proxyInfo[addrDest.GetNetwork()]; + proxyType proxy; // no proxy needed - if (!proxy.second) + if (!GetProxy(addrDest.GetNetwork(), proxy)) return ConnectSocketDirectly(addrDest, hSocketRet, nTimeout); SOCKET hSocket = INVALID_SOCKET; @@ -504,19 +518,22 @@ bool ConnectSocketByName(CService &addr, SOCKET& hSocketRet, const char *pszDest SplitHostPort(string(pszDest), port, strDest); SOCKET hSocket = INVALID_SOCKET; - CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxyInfo.second), port); + + proxyType nameproxy; + GetNameProxy(nameproxy); + + CService addrResolved(CNetAddr(strDest, fNameLookup && !nameproxy.second), port); if (addrResolved.IsValid()) { addr = addrResolved; return ConnectSocket(addr, hSocketRet, nTimeout); } addr = CService("0.0.0.0:0"); - if (!nameproxyInfo.second) + if (!nameproxy.second) return false; - if (!ConnectSocketDirectly(nameproxyInfo.first, hSocket, nTimeout)) + if (!ConnectSocketDirectly(nameproxy.first, hSocket, nTimeout)) return false; - switch(nameproxyInfo.second) - { + switch(nameproxy.second) { default: case 4: return false; case 5: diff --git a/src/netbase.h b/src/netbase.h index 560e2182df..0a29d4ff0c 100644 --- a/src/netbase.h +++ b/src/netbase.h @@ -133,13 +133,15 @@ class CService : public CNetAddr ) }; +typedef std::pair<CService, int> proxyType; + enum Network ParseNetwork(std::string net); void SplitHostPort(std::string in, int &portOut, std::string &hostOut); bool SetProxy(enum Network net, CService addrProxy, int nSocksVersion = 5); -bool GetProxy(enum Network net, CService &addrProxy); +bool GetProxy(enum Network net, proxyType &proxyInfoOut); bool IsProxy(const CNetAddr &addr); bool SetNameProxy(CService addrProxy, int nSocksVersion = 5); -bool GetNameProxy(); +bool HaveNameProxy(); bool LookupHost(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0, bool fAllowLookup = true); bool LookupHostNumeric(const char *pszName, std::vector<CNetAddr>& vIP, unsigned int nMaxSolutions = 0); bool Lookup(const char *pszName, CService& addr, int portDefault = 0, bool fAllowLookup = true); diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index ad145fdf9d..cd1764a53f 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -132,7 +132,10 @@ int main(int argc, char *argv[]) // ... then bitcoin.conf: if (!boost::filesystem::is_directory(GetDataDir(false))) { - fprintf(stderr, "Error: Specified directory does not exist\n"); + // This message can not be translated, as translation is not initialized yet + // (which not yet possible because lang=XX can be overridden in bitcoin.conf in the data directory) + QMessageBox::critical(0, "Bitcoin", + QString("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(mapArgs["-datadir"]))); return 1; } ReadConfigFile(mapArgs, mapMultiArgs); diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index d2d7716dbd..ff70ca24af 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -439,7 +439,7 @@ void HelpMessageBox::printToConsole() { // On other operating systems, the expected action is to print the message to the console. QString strUsage = header + "\n" + coreOptions + "\n" + uiOptions; - fprintf(stderr, "%s", strUsage.toStdString().c_str()); + fprintf(stdout, "%s", strUsage.toStdString().c_str()); } void HelpMessageBox::showOrPrint() diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index 8025126c25..3fb30a9518 100644 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -139,7 +139,7 @@ void OptionsDialog::setMapper() mapper->addMapping(ui->socksVersion, OptionsModel::ProxySocksVersion); /* Window */ -#ifndef Q_WS_MAC +#ifndef Q_OS_MAC mapper->addMapping(ui->minimizeToTray, OptionsModel::MinimizeToTray); mapper->addMapping(ui->minimizeOnClose, OptionsModel::MinimizeOnClose); #endif diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index caa33414b2..756fe61ecd 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -145,18 +145,18 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const case ProxyUse: return settings.value("fUseProxy", false); case ProxyIP: { - CService addrProxy; - if (GetProxy(NET_IPV4, addrProxy)) - return QVariant(QString::fromStdString(addrProxy.ToStringIP())); + proxyType proxy; + if (GetProxy(NET_IPV4, proxy)) + return QVariant(QString::fromStdString(proxy.first.ToStringIP())); else return QVariant(QString::fromStdString("127.0.0.1")); } case ProxyPort: { - CService addrProxy; - if (GetProxy(NET_IPV4, addrProxy)) - return QVariant(addrProxy.GetPort()); + proxyType proxy; + if (GetProxy(NET_IPV4, proxy)) + return QVariant(proxy.first.GetPort()); else - return 9050; + return QVariant(9050); } case ProxySocksVersion: return settings.value("nSocksVersion", 5); @@ -176,6 +176,7 @@ QVariant OptionsModel::data(const QModelIndex & index, int role) const } return QVariant(); } + bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, int role) { bool successful = true; /* set to false on parse error */ @@ -204,29 +205,37 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in settings.setValue("fUseProxy", value.toBool()); ApplyProxySettings(); break; - case ProxyIP: - { - CService addrProxy("127.0.0.1", 9050); - GetProxy(NET_IPV4, addrProxy); - CNetAddr addr(value.toString().toStdString()); - addrProxy.SetIP(addr); - settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str()); - successful = ApplyProxySettings(); - } - break; - case ProxyPort: - { - CService addrProxy("127.0.0.1", 9050); - GetProxy(NET_IPV4, addrProxy); - addrProxy.SetPort(value.toInt()); - settings.setValue("addrProxy", addrProxy.ToStringIPPort().c_str()); - successful = ApplyProxySettings(); - } - break; - case ProxySocksVersion: - settings.setValue("nSocksVersion", value.toInt()); - ApplyProxySettings(); - break; + case ProxyIP: { + proxyType proxy; + proxy.first = CService("127.0.0.1", 9050); + GetProxy(NET_IPV4, proxy); + + CNetAddr addr(value.toString().toStdString()); + proxy.first.SetIP(addr); + settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str()); + successful = ApplyProxySettings(); + } + break; + case ProxyPort: { + proxyType proxy; + proxy.first = CService("127.0.0.1", 9050); + GetProxy(NET_IPV4, proxy); + + proxy.first.SetPort(value.toInt()); + settings.setValue("addrProxy", proxy.first.ToStringIPPort().c_str()); + successful = ApplyProxySettings(); + } + break; + case ProxySocksVersion: { + proxyType proxy; + proxy.second = 5; + GetProxy(NET_IPV4, proxy); + + proxy.second = value.toInt(); + settings.setValue("nSocksVersion", proxy.second); + successful = ApplyProxySettings(); + } + break; case Fee: nTransactionFee = value.toLongLong(); settings.setValue("nTransactionFee", nTransactionFee); diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 5469dd2952..2dfdf58422 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -150,7 +150,7 @@ Value getblock(const Array& params, bool fHelp) uint256 hash(strHash); if (mapBlockIndex.count(hash) == 0) - throw JSONRPCError(-5, "Block not found"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); CBlock block; CBlockIndex* pblockindex = mapBlockIndex[hash]; diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 30e504a095..55d5d79e23 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -46,7 +46,7 @@ Value importprivkey(const Array& params, bool fHelp) CBitcoinSecret vchSecret; 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; bool fCompressed; @@ -60,7 +60,7 @@ Value importprivkey(const Array& params, bool fHelp) pwalletMain->SetAddressBookName(vchAddress, strLabel); 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->ReacceptWalletTransactions(); @@ -79,13 +79,13 @@ Value dumpprivkey(const Array& params, bool fHelp) string strAddress = params[0].get_str(); CBitcoinAddress address; if (!address.SetString(strAddress)) - throw JSONRPCError(-5, "Invalid Bitcoin address"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); CKeyID 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; bool 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(); } diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 2954b9ee57..96712482d5 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -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 (vNodes.empty()) - throw JSONRPCError(-9, "Bitcoin is not connected!"); + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!"); 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; static mapNewBlock_t mapNewBlock; // FIXME: thread safety @@ -136,7 +136,7 @@ Value getwork(const Array& params, bool fHelp) // Create new block pblock = CreateNewBlock(reservekey); if (!pblock) - throw JSONRPCError(-7, "Out of memory"); + throw JSONRPCError(RPC_OUT_OF_MEMORY, "Out of memory"); vNewBlock.push_back(pblock); // Need to update only after we know CreateNewBlock succeeded @@ -174,7 +174,7 @@ Value getwork(const Array& params, bool fHelp) // Parse parameters vector<unsigned char> vchData = ParseHex(params[0].get_str()); if (vchData.size() != 128) - throw JSONRPCError(-8, "Invalid parameter"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter"); CBlock* pdata = (CBlock*)&vchData[0]; // Byte reverse @@ -230,17 +230,17 @@ Value getblocktemplate(const Array& params, bool fHelp) /* Do nothing */ } else - throw JSONRPCError(-8, "Invalid mode"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); } if (strMode != "template") - throw JSONRPCError(-8, "Invalid mode"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); if (vNodes.empty()) - throw JSONRPCError(-9, "Bitcoin is not connected!"); + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Bitcoin is not connected!"); if (IsInitialBlockDownload()) - throw JSONRPCError(-10, "Bitcoin is downloading blocks..."); + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Bitcoin is downloading blocks..."); static CReserveKey reservekey(pwalletMain); @@ -268,7 +268,7 @@ Value getblocktemplate(const Array& params, bool fHelp) } pblock = CreateNewBlock(reservekey); 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 pindexPrev = pindexPrevNew; @@ -369,7 +369,7 @@ Value submitblock(const Array& params, bool fHelp) ssBlock >> block; } catch (std::exception &e) { - throw JSONRPCError(-22, "Block decode failed"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); } bool fAccepted = ProcessBlock(NULL, &block); diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index 08b0049b08..e634ed7ddc 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -119,7 +119,7 @@ Value getrawtransaction(const Array& params, bool fHelp) CTransaction tx; uint256 hashBlock = 0; 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); ssTx << tx; @@ -163,9 +163,9 @@ Value listunspent(const Array& params, bool fHelp) { CBitcoinAddress address(input.get_str()); 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)) - 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); } } @@ -227,17 +227,17 @@ Value createrawtransaction(const Array& params, bool fHelp) const Value& txid_v = find_value(o, "txid"); 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(); 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"); 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(); 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)); rawTx.vin.push_back(in); @@ -248,10 +248,10 @@ Value createrawtransaction(const Array& params, bool fHelp) { CBitcoinAddress address(s.name_); 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)) - 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); CScript scriptPubKey; @@ -283,7 +283,7 @@ Value decoderawtransaction(const Array& params, bool fHelp) ssData >> tx; } catch (std::exception &e) { - throw JSONRPCError(-22, "TX decode failed"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } Object result; @@ -322,12 +322,12 @@ Value signrawtransaction(const Array& params, bool fHelp) txVariants.push_back(tx); } catch (std::exception &e) { - throw JSONRPCError(-22, "TX decode failed"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } } if (txVariants.empty()) - throw JSONRPCError(-22, "Missing transaction"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Missing transaction"); // mergedTx will end up with all the signatures; it // starts as a clone of the rawtx: @@ -364,7 +364,7 @@ Value signrawtransaction(const Array& params, bool fHelp) BOOST_FOREACH(Value& p, prevTxs) { 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(); @@ -372,17 +372,17 @@ Value signrawtransaction(const Array& params, bool fHelp) string txidHex = find_value(prevOut, "txid").get_str(); if (!IsHex(txidHex)) - throw JSONRPCError(-22, "txid must be hexadecimal"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "txid must be hexadecimal"); uint256 txid; txid.SetHex(txidHex); int nOut = find_value(prevOut, "vout").get_int(); 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(); 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)); CScript scriptPubKey(pkData.begin(), pkData.end()); @@ -395,7 +395,7 @@ Value signrawtransaction(const Array& params, bool fHelp) string err("Previous output scriptPubKey mismatch:\n"); err = err + mapPrevOut[outpoint].ToString() + "\nvs:\n"+ scriptPubKey.ToString(); - throw JSONRPCError(-22, err); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, err); } } else @@ -414,7 +414,7 @@ Value signrawtransaction(const Array& params, bool fHelp) CBitcoinSecret vchSecret; bool fGood = vchSecret.SetString(k.get_str()); if (!fGood) - throw JSONRPCError(-5,"Invalid private key"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY,"Invalid private key"); CKey key; bool fCompressed; CSecret secret = vchSecret.GetSecret(fCompressed); @@ -443,7 +443,7 @@ Value signrawtransaction(const Array& params, bool fHelp) if (mapSigHashValues.count(strHashType)) nHashType = mapSigHashValues[strHashType]; else - throw JSONRPCError(-8, "Invalid sighash param"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid sighash param"); } bool fHashSingle = ((nHashType & ~SIGHASH_ANYONECANPAY) == SIGHASH_SINGLE); @@ -501,7 +501,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) ssData >> tx; } catch (std::exception &e) { - throw JSONRPCError(-22, "TX decode failed"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX decode failed"); } uint256 hashTx = tx.GetHash(); @@ -512,7 +512,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) if (GetTransaction(hashTx, existingTx, hashBlock)) { 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 // through to re-relay it. } @@ -521,7 +521,7 @@ Value sendrawtransaction(const Array& params, bool fHelp) // push to local node CTxDB txdb("r"); if (!tx.AcceptToMemoryPool(txdb)) - throw JSONRPCError(-22, "TX rejected"); + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "TX rejected"); SyncWithWallets(tx, NULL, true); } diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 66670d0937..cc2e8ab46b 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -25,7 +25,7 @@ std::string HelpRequiringPassphrase() void EnsureWalletIsUnlocked() { 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) @@ -51,7 +51,7 @@ string AccountFromValue(const Value& value) { string strAccount = value.get_str(); if (strAccount == "*") - throw JSONRPCError(-11, "Invalid account name"); + throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name"); return strAccount; } @@ -62,8 +62,8 @@ Value getinfo(const Array& params, bool fHelp) "getinfo\n" "Returns an object containing various state info."); - CService addrProxy; - GetProxy(NET_IPV4, addrProxy); + proxyType proxy; + GetProxy(NET_IPV4, proxy); Object obj; obj.push_back(Pair("version", (int)CLIENT_VERSION)); @@ -72,7 +72,7 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("balance", ValueFromAmount(pwalletMain->GetBalance()))); obj.push_back(Pair("blocks", (int)nBestHeight)); obj.push_back(Pair("connections", (int)vNodes.size())); - obj.push_back(Pair("proxy", (addrProxy.IsValid() ? addrProxy.ToStringIPPort() : string()))); + obj.push_back(Pair("proxy", (proxy.first.IsValid() ? proxy.first.ToStringIPPort() : string()))); obj.push_back(Pair("difficulty", (double)GetDifficulty())); obj.push_back(Pair("testnet", fTestNet)); obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); @@ -106,7 +106,7 @@ Value getnewaddress(const Array& params, bool fHelp) // Generate a new key that is added to wallet CPubKey newKey; 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(); pwalletMain->SetAddressBookName(keyID, strAccount); @@ -144,7 +144,7 @@ CBitcoinAddress GetAccountAddress(string strAccount, bool bForceNew=false) if (!account.vchPubKey.IsValid() || bForceNew || bKeyUsed) { 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); walletdb.WriteAccount(strAccount, account); @@ -181,7 +181,7 @@ Value setaccount(const Array& params, bool fHelp) CBitcoinAddress address(params[0].get_str()); if (!address.IsValid()) - throw JSONRPCError(-5, "Invalid Bitcoin address"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); string strAccount; @@ -211,7 +211,7 @@ Value getaccount(const Array& params, bool fHelp) CBitcoinAddress address(params[0].get_str()); if (!address.IsValid()) - throw JSONRPCError(-5, "Invalid Bitcoin address"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); string strAccount; 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()); if (!address.IsValid()) - throw JSONRPCError(-5, "Invalid Bitcoin address"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); // Amount int64 nAmount = AmountFromValue(params[1]); @@ -265,11 +265,11 @@ Value sendtoaddress(const Array& params, bool fHelp) wtx.mapValue["to"] = params[3].get_str(); 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); if (strError != "") - throw JSONRPCError(-4, strError); + throw JSONRPCError(RPC_WALLET_ERROR, strError); return wtx.GetHash().GetHex(); } @@ -319,15 +319,15 @@ Value signmessage(const Array& params, bool fHelp) CBitcoinAddress addr(strAddress); if (!addr.IsValid()) - throw JSONRPCError(-3, "Invalid address"); + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); CKeyID 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; 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); ss << strMessageMagic; @@ -335,7 +335,7 @@ Value signmessage(const Array& params, bool fHelp) vector<unsigned char> 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()); } @@ -353,17 +353,17 @@ Value verifymessage(const Array& params, bool fHelp) CBitcoinAddress addr(strAddress); if (!addr.IsValid()) - throw JSONRPCError(-3, "Invalid address"); + throw JSONRPCError(RPC_TYPE_ERROR, "Invalid address"); CKeyID 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; vector<unsigned char> vchSig = DecodeBase64(strSign.c_str(), &fInvalid); if (fInvalid) - throw JSONRPCError(-5, "Malformed base64 encoding"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Malformed base64 encoding"); CDataStream ss(SER_GETHASH, 0); ss << strMessageMagic; @@ -388,7 +388,7 @@ Value getreceivedbyaddress(const Array& params, bool fHelp) CBitcoinAddress address = CBitcoinAddress(params[0].get_str()); CScript scriptPubKey; if (!address.IsValid()) - throw JSONRPCError(-5, "Invalid Bitcoin address"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); scriptPubKey.SetDestination(address.Get()); if (!IsMine(*pwalletMain,scriptPubKey)) return (double)0.0; @@ -567,7 +567,7 @@ Value movecmd(const Array& params, bool fHelp) CWalletDB walletdb(pwalletMain->strWalletFile); if (!walletdb.TxnBegin()) - throw JSONRPCError(-20, "database error"); + throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); int64 nNow = GetAdjustedTime(); @@ -592,7 +592,7 @@ Value movecmd(const Array& params, bool fHelp) walletdb.WriteAccountingEntry(credit); if (!walletdb.TxnCommit()) - throw JSONRPCError(-20, "database error"); + throw JSONRPCError(RPC_DATABASE_ERROR, "database error"); return true; } @@ -609,7 +609,7 @@ Value sendfrom(const Array& params, bool fHelp) string strAccount = AccountFromValue(params[0]); CBitcoinAddress address(params[1].get_str()); if (!address.IsValid()) - throw JSONRPCError(-5, "Invalid Bitcoin address"); + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address"); int64 nAmount = AmountFromValue(params[2]); int nMinDepth = 1; if (params.size() > 3) @@ -627,12 +627,12 @@ Value sendfrom(const Array& params, bool fHelp) // Check funds int64 nBalance = GetAccountBalance(strAccount, nMinDepth); if (nAmount > nBalance) - throw JSONRPCError(-6, "Account has insufficient funds"); + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); // Send string strError = pwalletMain->SendMoneyToDestination(address.Get(), nAmount, wtx); if (strError != "") - throw JSONRPCError(-4, strError); + throw JSONRPCError(RPC_WALLET_ERROR, strError); return wtx.GetHash().GetHex(); } @@ -665,10 +665,10 @@ Value sendmany(const Array& params, bool fHelp) { CBitcoinAddress address(s.name_); 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)) - 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); CScript scriptPubKey; @@ -684,7 +684,7 @@ Value sendmany(const Array& params, bool fHelp) // Check funds int64 nBalance = GetAccountBalance(strAccount, nMinDepth); if (totalAmount > nBalance) - throw JSONRPCError(-6, "Account has insufficient funds"); + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Account has insufficient funds"); // Send CReserveKey keyChange(pwalletMain); @@ -693,11 +693,11 @@ Value sendmany(const Array& params, bool fHelp) if (!fCreated) { if (totalAmount + nFeeRequired > pwalletMain->GetBalance()) - throw JSONRPCError(-6, "Insufficient funds"); - throw JSONRPCError(-4, "Transaction creation failed"); + throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds"); + throw JSONRPCError(RPC_WALLET_ERROR, "Transaction creation failed"); } if (!pwalletMain->CommitTransaction(wtx, keyChange)) - throw JSONRPCError(-4, "Transaction commit failed"); + throw JSONRPCError(RPC_WALLET_ERROR, "Transaction commit failed"); return wtx.GetHash().GetHex(); } @@ -1000,9 +1000,9 @@ Value listtransactions(const Array& params, bool fHelp) nFrom = params[2].get_int(); if (nCount < 0) - throw JSONRPCError(-8, "Negative count"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative count"); if (nFrom < 0) - throw JSONRPCError(-8, "Negative from"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Negative from"); Array ret; @@ -1113,7 +1113,7 @@ Value listsinceblock(const Array& params, bool fHelp) target_confirms = params[1].get_int(); if (target_confirms < 1) - throw JSONRPCError(-8, "Invalid parameter"); + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter"); } int depth = pindex ? (1 + nBestHeight - pindex->nHeight) : -1; @@ -1165,7 +1165,7 @@ Value gettransaction(const Array& params, bool fHelp) Object entry; 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]; int64 nCredit = wtx.GetCredit(); @@ -1214,7 +1214,7 @@ Value keypoolrefill(const Array& params, bool fHelp) pwalletMain->TopUpKeyPool(); if (pwalletMain->GetKeyPoolSize() < GetArg("-keypool", 100)) - throw JSONRPCError(-4, "Error refreshing keypool."); + throw JSONRPCError(RPC_WALLET_ERROR, "Error refreshing keypool."); return Value::null; } @@ -1281,10 +1281,10 @@ Value walletpassphrase(const Array& params, bool fHelp) if (fHelp) return true; 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()) - 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 SecureString strWalletPass; @@ -1296,7 +1296,7 @@ Value walletpassphrase(const Array& params, bool fHelp) if (strWalletPass.length() > 0) { 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 throw runtime_error( @@ -1320,7 +1320,7 @@ Value walletpassphrasechange(const Array& params, bool fHelp) if (fHelp) return true; 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) // 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>."); 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; } @@ -1355,7 +1355,7 @@ Value walletlock(const Array& params, bool fHelp) if (fHelp) return true; 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); @@ -1376,7 +1376,7 @@ Value encryptwallet(const Array& params, bool fHelp) if (fHelp) return true; 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) // 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>."); 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 // slack space in .dat files; that is bad if the old data is |