Merge #11923: Wallet : remove unused fNoncriticalErrors variable from CWalletDB:...
[bitcoinplatinum.git] / src / rpc / protocol.cpp
blobd999a08d74b5a90191e4184c9cbb4cb334149f19
1 // Copyright (c) 2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2016 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 #include <rpc/protocol.h>
8 #include <random.h>
9 #include <tinyformat.h>
10 #include <util.h>
11 #include <utilstrencodings.h>
12 #include <utiltime.h>
13 #include <version.h>
15 #include <fstream>
17 /**
18 * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility,
19 * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were
20 * unspecified (HTTP errors and contents of 'error').
22 * 1.0 spec: http://json-rpc.org/wiki/specification
23 * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html
26 UniValue JSONRPCRequestObj(const std::string& strMethod, const UniValue& params, const UniValue& id)
28 UniValue request(UniValue::VOBJ);
29 request.push_back(Pair("method", strMethod));
30 request.push_back(Pair("params", params));
31 request.push_back(Pair("id", id));
32 return request;
35 UniValue JSONRPCReplyObj(const UniValue& result, const UniValue& error, const UniValue& id)
37 UniValue reply(UniValue::VOBJ);
38 if (!error.isNull())
39 reply.push_back(Pair("result", NullUniValue));
40 else
41 reply.push_back(Pair("result", result));
42 reply.push_back(Pair("error", error));
43 reply.push_back(Pair("id", id));
44 return reply;
47 std::string JSONRPCReply(const UniValue& result, const UniValue& error, const UniValue& id)
49 UniValue reply = JSONRPCReplyObj(result, error, id);
50 return reply.write() + "\n";
53 UniValue JSONRPCError(int code, const std::string& message)
55 UniValue error(UniValue::VOBJ);
56 error.push_back(Pair("code", code));
57 error.push_back(Pair("message", message));
58 return error;
61 /** Username used when cookie authentication is in use (arbitrary, only for
62 * recognizability in debugging/logging purposes)
64 static const std::string COOKIEAUTH_USER = "__cookie__";
65 /** Default name for auth cookie file */
66 static const std::string COOKIEAUTH_FILE = ".cookie";
68 /** Get name of RPC authentication cookie file */
69 static fs::path GetAuthCookieFile(bool temp=false)
71 std::string arg = gArgs.GetArg("-rpccookiefile", COOKIEAUTH_FILE);
72 if (temp) {
73 arg += ".tmp";
75 fs::path path(arg);
76 if (!path.is_complete()) path = GetDataDir() / path;
77 return path;
80 bool GenerateAuthCookie(std::string *cookie_out)
82 const size_t COOKIE_SIZE = 32;
83 unsigned char rand_pwd[COOKIE_SIZE];
84 GetRandBytes(rand_pwd, COOKIE_SIZE);
85 std::string cookie = COOKIEAUTH_USER + ":" + HexStr(rand_pwd, rand_pwd+COOKIE_SIZE);
87 /** the umask determines what permissions are used to create this file -
88 * these are set to 077 in init.cpp unless overridden with -sysperms.
90 std::ofstream file;
91 fs::path filepath_tmp = GetAuthCookieFile(true);
92 file.open(filepath_tmp.string().c_str());
93 if (!file.is_open()) {
94 LogPrintf("Unable to open cookie authentication file %s for writing\n", filepath_tmp.string());
95 return false;
97 file << cookie;
98 file.close();
100 fs::path filepath = GetAuthCookieFile(false);
101 if (!RenameOver(filepath_tmp, filepath)) {
102 LogPrintf("Unable to rename cookie authentication file %s to %s\n", filepath_tmp.string(), filepath.string());
103 return false;
105 LogPrintf("Generated RPC authentication cookie %s\n", filepath.string());
107 if (cookie_out)
108 *cookie_out = cookie;
109 return true;
112 bool GetAuthCookie(std::string *cookie_out)
114 std::ifstream file;
115 std::string cookie;
116 fs::path filepath = GetAuthCookieFile();
117 file.open(filepath.string().c_str());
118 if (!file.is_open())
119 return false;
120 std::getline(file, cookie);
121 file.close();
123 if (cookie_out)
124 *cookie_out = cookie;
125 return true;
128 void DeleteAuthCookie()
130 try {
131 fs::remove(GetAuthCookieFile());
132 } catch (const fs::filesystem_error& e) {
133 LogPrintf("%s: Unable to remove random auth cookie file: %s\n", __func__, e.what());
137 std::vector<UniValue> JSONRPCProcessBatchReply(const UniValue &in, size_t num)
139 if (!in.isArray()) {
140 throw std::runtime_error("Batch must be an array");
142 std::vector<UniValue> batch(num);
143 for (size_t i=0; i<in.size(); ++i) {
144 const UniValue &rec = in[i];
145 if (!rec.isObject()) {
146 throw std::runtime_error("Batch member must be object");
148 size_t id = rec["id"].get_int();
149 if (id >= num) {
150 throw std::runtime_error("Batch member id larger than size");
152 batch[id] = rec;
154 return batch;