Skip to content

Commit 5f083af

Browse files
committed
Merge pull request #3284
fb78cc2 Split up bitcoinrpc (code movement only) (Wladimir J. van der Laan)
2 parents e1169d7 + fb78cc2 commit 5f083af

18 files changed

+692
-629
lines changed

src/Makefile.am

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ DIST_SUBDIRS = . qt test
1212
.PHONY: FORCE
1313
# bitcoin core #
1414
BITCOIN_CORE_H = addrman.h alert.h allocators.h base58.h bignum.h \
15-
bitcoinrpc.h bloom.h chainparams.h checkpoints.h checkqueue.h \
15+
rpcclient.h \
16+
rpcprotocol.h \
17+
rpcserver.h \
18+
bloom.h chainparams.h checkpoints.h checkqueue.h \
1619
clientversion.h coincontrol.h compat.h core.h coins.h crypter.h db.h hash.h init.h \
1720
key.h keystore.h leveldbwrapper.h limitedmap.h main.h miner.h mruset.h \
1821
netbase.h net.h noui.h protocol.h script.h serialize.h sync.h threadsafety.h \
@@ -30,7 +33,11 @@ obj/build.h: FORCE
3033
$(abs_top_srcdir)
3134
version.o: obj/build.h
3235

33-
libbitcoin_a_SOURCES = addrman.cpp alert.cpp allocators.cpp bitcoinrpc.cpp bloom.cpp \
36+
libbitcoin_a_SOURCES = addrman.cpp alert.cpp allocators.cpp \
37+
rpcclient.cpp \
38+
rpcprotocol.cpp \
39+
rpcserver.cpp \
40+
bloom.cpp \
3441
chainparams.cpp checkpoints.cpp core.cpp coins.cpp crypter.cpp db.cpp hash.cpp \
3542
init.cpp key.cpp keystore.cpp leveldbwrapper.cpp main.cpp miner.cpp \
3643
netbase.cpp net.cpp noui.cpp protocol.cpp rpcblockchain.cpp rpcdump.cpp \

src/bitcoin-cli.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
#include "util.h"
77
#include "init.h"
8-
#include "bitcoinrpc.h"
8+
#include "rpcclient.h"
99
#include "ui_interface.h" /* for _(...) */
1010

1111
#include <boost/filesystem/operations.hpp>

src/bitcoind.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
// Distributed under the MIT/X11 software license, see the accompanying
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

6-
#include "bitcoinrpc.h"
6+
#include "rpcserver.h"
7+
#include "rpcclient.h"
78
#include "init.h"
89
#include "main.h"
910
#include "noui.h"

src/init.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include "init.h"
1111

1212
#include "addrman.h"
13-
#include "bitcoinrpc.h"
13+
#include "rpcserver.h"
1414
#include "checkpoints.h"
1515
#include "miner.h"
1616
#include "net.h"

src/qt/rpcconsole.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#include "clientmodel.h"
99
#include "guiutil.h"
1010

11-
#include "bitcoinrpc.h"
11+
#include "rpcserver.h"
12+
#include "rpcclient.h"
1213

1314
#include "json/json_spirit_value.h"
1415
#include <openssl/crypto.h>

src/rpcblockchain.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
// Distributed under the MIT/X11 software license, see the accompanying
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

6-
7-
8-
#include "bitcoinrpc.h"
6+
#include "rpcserver.h"
97
#include "main.h"
108
#include "sync.h"
119

src/rpcclient.cpp

Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
// Copyright (c) 2010 Satoshi Nakamoto
2+
// Copyright (c) 2009-2013 The Bitcoin developers
3+
// Distributed under the MIT/X11 software license, see the accompanying
4+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#include "rpcclient.h"
7+
8+
#include "rpcprotocol.h"
9+
#include "util.h"
10+
#include "ui_interface.h"
11+
#include "chainparams.h" // for Params().RPCPort()
12+
13+
#include <stdint.h>
14+
15+
#include <boost/algorithm/string.hpp>
16+
#include <boost/asio.hpp>
17+
#include <boost/asio/ssl.hpp>
18+
#include <boost/bind.hpp>
19+
#include <boost/filesystem.hpp>
20+
#include <boost/foreach.hpp>
21+
#include <boost/iostreams/concepts.hpp>
22+
#include <boost/iostreams/stream.hpp>
23+
#include <boost/lexical_cast.hpp>
24+
#include <boost/shared_ptr.hpp>
25+
#include "json/json_spirit_writer_template.h"
26+
27+
using namespace std;
28+
using namespace boost;
29+
using namespace boost::asio;
30+
using namespace json_spirit;
31+
32+
Object CallRPC(const string& strMethod, const Array& params)
33+
{
34+
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
35+
throw runtime_error(strprintf(
36+
_("You must set rpcpassword=<password> in the configuration file:\n%s\n"
37+
"If the file does not exist, create it with owner-readable-only file permissions."),
38+
GetConfigFile().string().c_str()));
39+
40+
// Connect to localhost
41+
bool fUseSSL = GetBoolArg("-rpcssl", false);
42+
asio::io_service io_service;
43+
ssl::context context(io_service, ssl::context::sslv23);
44+
context.set_options(ssl::context::no_sslv2);
45+
asio::ssl::stream<asio::ip::tcp::socket> sslStream(io_service, context);
46+
SSLIOStreamDevice<asio::ip::tcp> d(sslStream, fUseSSL);
47+
iostreams::stream< SSLIOStreamDevice<asio::ip::tcp> > stream(d);
48+
49+
bool fWait = GetBoolArg("-rpcwait", false); // -rpcwait means try until server has started
50+
do {
51+
bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(Params().RPCPort())));
52+
if (fConnected) break;
53+
if (fWait)
54+
MilliSleep(1000);
55+
else
56+
throw runtime_error("couldn't connect to server");
57+
} while (fWait);
58+
59+
// HTTP basic authentication
60+
string strUserPass64 = EncodeBase64(mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"]);
61+
map<string, string> mapRequestHeaders;
62+
mapRequestHeaders["Authorization"] = string("Basic ") + strUserPass64;
63+
64+
// Send request
65+
string strRequest = JSONRPCRequest(strMethod, params, 1);
66+
string strPost = HTTPPost(strRequest, mapRequestHeaders);
67+
stream << strPost << std::flush;
68+
69+
// Receive HTTP reply status
70+
int nProto = 0;
71+
int nStatus = ReadHTTPStatus(stream, nProto);
72+
73+
// Receive HTTP reply message headers and body
74+
map<string, string> mapHeaders;
75+
string strReply;
76+
ReadHTTPMessage(stream, mapHeaders, strReply, nProto);
77+
78+
if (nStatus == HTTP_UNAUTHORIZED)
79+
throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
80+
else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR)
81+
throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
82+
else if (strReply.empty())
83+
throw runtime_error("no response from server");
84+
85+
// Parse reply
86+
Value valReply;
87+
if (!read_string(strReply, valReply))
88+
throw runtime_error("couldn't parse reply from server");
89+
const Object& reply = valReply.get_obj();
90+
if (reply.empty())
91+
throw runtime_error("expected reply to have result, error and id properties");
92+
93+
return reply;
94+
}
95+
96+
template<typename T>
97+
void ConvertTo(Value& value, bool fAllowNull=false)
98+
{
99+
if (fAllowNull && value.type() == null_type)
100+
return;
101+
if (value.type() == str_type)
102+
{
103+
// reinterpret string as unquoted json value
104+
Value value2;
105+
string strJSON = value.get_str();
106+
if (!read_string(strJSON, value2))
107+
throw runtime_error(string("Error parsing JSON:")+strJSON);
108+
ConvertTo<T>(value2, fAllowNull);
109+
value = value2;
110+
}
111+
else
112+
{
113+
value = value.get_value<T>();
114+
}
115+
}
116+
117+
// Convert strings to command-specific RPC representation
118+
Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams)
119+
{
120+
Array params;
121+
BOOST_FOREACH(const std::string &param, strParams)
122+
params.push_back(param);
123+
124+
int n = params.size();
125+
126+
//
127+
// Special case non-string parameter types
128+
//
129+
if (strMethod == "stop" && n > 0) ConvertTo<bool>(params[0]);
130+
if (strMethod == "getaddednodeinfo" && n > 0) ConvertTo<bool>(params[0]);
131+
if (strMethod == "setgenerate" && n > 0) ConvertTo<bool>(params[0]);
132+
if (strMethod == "setgenerate" && n > 1) ConvertTo<boost::int64_t>(params[1]);
133+
if (strMethod == "getnetworkhashps" && n > 0) ConvertTo<boost::int64_t>(params[0]);
134+
if (strMethod == "getnetworkhashps" && n > 1) ConvertTo<boost::int64_t>(params[1]);
135+
if (strMethod == "sendtoaddress" && n > 1) ConvertTo<double>(params[1]);
136+
if (strMethod == "settxfee" && n > 0) ConvertTo<double>(params[0]);
137+
if (strMethod == "getreceivedbyaddress" && n > 1) ConvertTo<boost::int64_t>(params[1]);
138+
if (strMethod == "getreceivedbyaccount" && n > 1) ConvertTo<boost::int64_t>(params[1]);
139+
if (strMethod == "listreceivedbyaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
140+
if (strMethod == "listreceivedbyaddress" && n > 1) ConvertTo<bool>(params[1]);
141+
if (strMethod == "listreceivedbyaccount" && n > 0) ConvertTo<boost::int64_t>(params[0]);
142+
if (strMethod == "listreceivedbyaccount" && n > 1) ConvertTo<bool>(params[1]);
143+
if (strMethod == "getbalance" && n > 1) ConvertTo<boost::int64_t>(params[1]);
144+
if (strMethod == "getblockhash" && n > 0) ConvertTo<boost::int64_t>(params[0]);
145+
if (strMethod == "move" && n > 2) ConvertTo<double>(params[2]);
146+
if (strMethod == "move" && n > 3) ConvertTo<boost::int64_t>(params[3]);
147+
if (strMethod == "sendfrom" && n > 2) ConvertTo<double>(params[2]);
148+
if (strMethod == "sendfrom" && n > 3) ConvertTo<boost::int64_t>(params[3]);
149+
if (strMethod == "listtransactions" && n > 1) ConvertTo<boost::int64_t>(params[1]);
150+
if (strMethod == "listtransactions" && n > 2) ConvertTo<boost::int64_t>(params[2]);
151+
if (strMethod == "listaccounts" && n > 0) ConvertTo<boost::int64_t>(params[0]);
152+
if (strMethod == "walletpassphrase" && n > 1) ConvertTo<boost::int64_t>(params[1]);
153+
if (strMethod == "getblocktemplate" && n > 0) ConvertTo<Object>(params[0]);
154+
if (strMethod == "listsinceblock" && n > 1) ConvertTo<boost::int64_t>(params[1]);
155+
if (strMethod == "sendmany" && n > 1) ConvertTo<Object>(params[1]);
156+
if (strMethod == "sendmany" && n > 2) ConvertTo<boost::int64_t>(params[2]);
157+
if (strMethod == "addmultisigaddress" && n > 0) ConvertTo<boost::int64_t>(params[0]);
158+
if (strMethod == "addmultisigaddress" && n > 1) ConvertTo<Array>(params[1]);
159+
if (strMethod == "createmultisig" && n > 0) ConvertTo<boost::int64_t>(params[0]);
160+
if (strMethod == "createmultisig" && n > 1) ConvertTo<Array>(params[1]);
161+
if (strMethod == "listunspent" && n > 0) ConvertTo<boost::int64_t>(params[0]);
162+
if (strMethod == "listunspent" && n > 1) ConvertTo<boost::int64_t>(params[1]);
163+
if (strMethod == "listunspent" && n > 2) ConvertTo<Array>(params[2]);
164+
if (strMethod == "getblock" && n > 1) ConvertTo<bool>(params[1]);
165+
if (strMethod == "getrawtransaction" && n > 1) ConvertTo<boost::int64_t>(params[1]);
166+
if (strMethod == "createrawtransaction" && n > 0) ConvertTo<Array>(params[0]);
167+
if (strMethod == "createrawtransaction" && n > 1) ConvertTo<Object>(params[1]);
168+
if (strMethod == "signrawtransaction" && n > 1) ConvertTo<Array>(params[1], true);
169+
if (strMethod == "signrawtransaction" && n > 2) ConvertTo<Array>(params[2], true);
170+
if (strMethod == "sendrawtransaction" && n > 1) ConvertTo<bool>(params[1], true);
171+
if (strMethod == "gettxout" && n > 1) ConvertTo<boost::int64_t>(params[1]);
172+
if (strMethod == "gettxout" && n > 2) ConvertTo<bool>(params[2]);
173+
if (strMethod == "lockunspent" && n > 0) ConvertTo<bool>(params[0]);
174+
if (strMethod == "lockunspent" && n > 1) ConvertTo<Array>(params[1]);
175+
if (strMethod == "importprivkey" && n > 2) ConvertTo<bool>(params[2]);
176+
if (strMethod == "verifychain" && n > 0) ConvertTo<boost::int64_t>(params[0]);
177+
if (strMethod == "verifychain" && n > 1) ConvertTo<boost::int64_t>(params[1]);
178+
if (strMethod == "keypoolrefill" && n > 0) ConvertTo<boost::int64_t>(params[0]);
179+
180+
return params;
181+
}
182+
183+
int CommandLineRPC(int argc, char *argv[])
184+
{
185+
string strPrint;
186+
int nRet = 0;
187+
try
188+
{
189+
// Skip switches
190+
while (argc > 1 && IsSwitchChar(argv[1][0]))
191+
{
192+
argc--;
193+
argv++;
194+
}
195+
196+
// Method
197+
if (argc < 2)
198+
throw runtime_error("too few parameters");
199+
string strMethod = argv[1];
200+
201+
// Parameters default to strings
202+
std::vector<std::string> strParams(&argv[2], &argv[argc]);
203+
Array params = RPCConvertValues(strMethod, strParams);
204+
205+
// Execute
206+
Object reply = CallRPC(strMethod, params);
207+
208+
// Parse reply
209+
const Value& result = find_value(reply, "result");
210+
const Value& error = find_value(reply, "error");
211+
212+
if (error.type() != null_type)
213+
{
214+
// Error
215+
strPrint = "error: " + write_string(error, false);
216+
int code = find_value(error.get_obj(), "code").get_int();
217+
nRet = abs(code);
218+
}
219+
else
220+
{
221+
// Result
222+
if (result.type() == null_type)
223+
strPrint = "";
224+
else if (result.type() == str_type)
225+
strPrint = result.get_str();
226+
else
227+
strPrint = write_string(result, true);
228+
}
229+
}
230+
catch (boost::thread_interrupted) {
231+
throw;
232+
}
233+
catch (std::exception& e) {
234+
strPrint = string("error: ") + e.what();
235+
nRet = 87;
236+
}
237+
catch (...) {
238+
PrintException(NULL, "CommandLineRPC()");
239+
}
240+
241+
if (strPrint != "")
242+
{
243+
fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
244+
}
245+
return nRet;
246+
}

src/rpcclient.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// Copyright (c) 2010 Satoshi Nakamoto
2+
// Copyright (c) 2009-2013 The Bitcoin developers
3+
// Distributed under the MIT/X11 software license, see the accompanying
4+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
#ifndef _BITCOINRPC_CLIENT_H_
7+
#define _BITCOINRPC_CLIENT_H_ 1
8+
9+
#include "json/json_spirit_reader_template.h"
10+
#include "json/json_spirit_utils.h"
11+
#include "json/json_spirit_writer_template.h"
12+
13+
int CommandLineRPC(int argc, char *argv[]);
14+
15+
json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams);
16+
17+
#endif

src/rpcdump.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@
22
// Distributed under the MIT/X11 software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5-
6-
75
#include "base58.h"
8-
#include "bitcoinrpc.h"
6+
#include "rpcserver.h"
97
#include "init.h"
108
#include "main.h"
119
#include "sync.h"

src/rpcmining.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Distributed under the MIT/X11 software license, see the accompanying
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

6-
#include "bitcoinrpc.h"
6+
#include "rpcserver.h"
77
#include "chainparams.h"
88
#include "db.h"
99
#include "init.h"

0 commit comments

Comments
 (0)