]> Git Repo - VerusCoin.git/blob - src/bitcoin-cli.cpp
test
[VerusCoin.git] / src / bitcoin-cli.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2013 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.
5
6 #include "chainparamsbase.h"
7 #include "clientversion.h"
8 #include "rpcclient.h"
9 #include "rpcprotocol.h"
10 #include "util.h"
11 #include "utilstrencodings.h"
12
13 #include <boost/filesystem/operations.hpp>
14
15 using namespace std;
16 using namespace json_spirit;
17 int64_t MAX_MONEY = 200000000 * 100000000LL;
18 uint64_t komodo_maxallowed(int32_t baseid) { return(100000000LL * 1000000); } // stub
19
20 std::string HelpMessageCli()
21 {
22     string strUsage;
23     strUsage += HelpMessageGroup(_("Options:"));
24     strUsage += HelpMessageOpt("-?", _("This help message"));
25     strUsage += HelpMessageOpt("-conf=<file>", strprintf(_("Specify configuration file (default: %s)"), "komodo.conf"));
26     strUsage += HelpMessageOpt("-datadir=<dir>", _("Specify data directory"));
27     strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
28     strUsage += HelpMessageOpt("-regtest", _("Enter regression test mode, which uses a special chain in which blocks can be "
29                                              "solved instantly. This is intended for regression testing tools and app development."));
30     strUsage += HelpMessageOpt("-rpcconnect=<ip>", strprintf(_("Send commands to node running on <ip> (default: %s)"), "127.0.0.1"));
31     strUsage += HelpMessageOpt("-rpcport=<port>", strprintf(_("Connect to JSON-RPC on <port> (default: %u or testnet: %u)"), 8232, 18232));
32     strUsage += HelpMessageOpt("-rpcwait", _("Wait for RPC server to start"));
33     strUsage += HelpMessageOpt("-rpcuser=<user>", _("Username for JSON-RPC connections"));
34     strUsage += HelpMessageOpt("-rpcpassword=<pw>", _("Password for JSON-RPC connections"));
35
36     strUsage += HelpMessageGroup(_("SSL options: (see the Bitcoin Wiki for SSL setup instructions)"));
37     strUsage += HelpMessageOpt("-rpcssl", _("Use OpenSSL (https) for JSON-RPC connections"));
38
39     return strUsage;
40 }
41
42 //////////////////////////////////////////////////////////////////////////////
43 //
44 // Start
45 //
46
47 //
48 // Exception thrown on connection error.  This error is used to determine
49 // when to wait if -rpcwait is given.
50 //
51 class CConnectionFailed : public std::runtime_error
52 {
53 public:
54
55     explicit inline CConnectionFailed(const std::string& msg) :
56         std::runtime_error(msg)
57     {}
58
59 };
60
61 #include "uint256.h"
62 #include "arith_uint256.h"
63
64 #include "komodo_structs.h"
65
66 #include "komodo_globals.h"
67 #include "komodo_utils.h"
68 #include "cJSON.c"
69 #include "komodo_notary.h"
70
71 void komodo_stateupdate(int32_t height,uint8_t notarypubs[][33],uint8_t numnotaries,uint8_t notaryid,uint256 txhash,uint64_t voutmask,uint8_t numvouts,uint32_t *pvals,uint8_t numpvals,int32_t KMDheight,uint32_t KMDtimestamp,uint64_t opretvalue,uint8_t *opretbuf,uint16_t opretlen,uint16_t vout)
72 {
73     
74 }
75
76 static bool AppInitRPC(int argc, char* argv[])
77 {
78     //
79     // Parameters
80     //
81     ParseParameters(argc, argv);
82     komodo_args();
83     if (argc<2 || mapArgs.count("-?") || mapArgs.count("-h") || mapArgs.count("-help") || mapArgs.count("-version")) {
84         std::string strUsage = _("Komodo RPC client version") + " " + FormatFullVersion() + "\n";
85         if (!mapArgs.count("-version")) {
86             strUsage += "\n" + _("Usage:") + "\n" +
87                   "  komodo-cli [options] <command> [params]  " + _("Send command to Komodo") + "\n" +
88                   "  komodo-cli [options] help                " + _("List commands") + "\n" +
89                   "  komodo-cli [options] help <command>      " + _("Get help for a command") + "\n";
90
91             strUsage += "\n" + HelpMessageCli();
92         } else {
93             strUsage += LicenseInfo();
94         }
95
96         fprintf(stdout, "%s", strUsage.c_str());
97         return false;
98     }
99     if (!boost::filesystem::is_directory(GetDataDir(false))) {
100         fprintf(stderr, "Error: Specified data directory \"%s\" does not exist.\n", mapArgs["-datadir"].c_str());
101         return false;
102     }
103     try {
104         ReadConfigFile(mapArgs, mapMultiArgs);
105     } catch (const std::exception& e) {
106         fprintf(stderr,"Error reading configuration file: %s\n", e.what());
107         return false;
108     }
109     // Check for -testnet or -regtest parameter (BaseParams() calls are only valid after this clause)
110     if (!SelectBaseParamsFromCommandLine()) {
111         fprintf(stderr, "Error: Invalid combination of -regtest and -testnet.\n");
112         return false;
113     }
114     return true;
115 }
116
117 Object CallRPC(const string& strMethod, const Array& params)
118 {
119     // Connect to localhost
120     bool fUseSSL = GetBoolArg("-rpcssl", false);
121     boost::asio::io_service io_service;
122     boost::asio::ssl::context context(io_service, boost::asio::ssl::context::sslv23);
123     context.set_options(boost::asio::ssl::context::no_sslv2 | boost::asio::ssl::context::no_sslv3);
124     boost::asio::ssl::stream<boost::asio::ip::tcp::socket> sslStream(io_service, context);
125     SSLIOStreamDevice<boost::asio::ip::tcp> d(sslStream, fUseSSL);
126     boost::iostreams::stream< SSLIOStreamDevice<boost::asio::ip::tcp> > stream(d);
127
128     const bool fConnected = d.connect(GetArg("-rpcconnect", "127.0.0.1"), GetArg("-rpcport", itostr(BaseParams().RPCPort())));
129     if (!fConnected)
130         throw CConnectionFailed("couldn't connect to server");
131
132     // Find credentials to use
133     std::string strRPCUserColonPass;
134     if (mapArgs["-rpcpassword"] == "") {
135         // Try fall back to cookie-based authentication if no password is provided
136         if (!GetAuthCookie(&strRPCUserColonPass)) {
137             throw runtime_error(strprintf(
138                 _("You must set rpcpassword=<password> in the configuration file:\n%s\n"
139                   "If the file does not exist, create it with owner-readable-only file permissions."),
140                     GetConfigFile().string().c_str()));
141
142         }
143     } else {
144         strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
145     }
146
147     // HTTP basic authentication
148     map<string, string> mapRequestHeaders;
149     mapRequestHeaders["Authorization"] = string("Basic ") + EncodeBase64(strRPCUserColonPass);
150
151     // Send request
152     string strRequest = JSONRPCRequest(strMethod, params, 1);
153     string strPost = HTTPPost(strRequest, mapRequestHeaders);
154     stream << strPost << std::flush;
155
156     // Receive HTTP reply status
157     int nProto = 0;
158     int nStatus = ReadHTTPStatus(stream, nProto);
159
160     // Receive HTTP reply message headers and body
161     map<string, string> mapHeaders;
162     string strReply;
163     ReadHTTPMessage(stream, mapHeaders, strReply, nProto, std::numeric_limits<size_t>::max());
164
165     if (nStatus == HTTP_UNAUTHORIZED)
166         throw runtime_error("incorrect rpcuser or rpcpassword (authorization failed)");
167     else if (nStatus >= 400 && nStatus != HTTP_BAD_REQUEST && nStatus != HTTP_NOT_FOUND && nStatus != HTTP_INTERNAL_SERVER_ERROR)
168         throw runtime_error(strprintf("server returned HTTP error %d", nStatus));
169     else if (strReply.empty())
170         throw runtime_error("no response from server");
171
172     // Parse reply
173     Value valReply;
174     if (!read_string(strReply, valReply))
175         throw runtime_error("couldn't parse reply from server");
176     const Object& reply = valReply.get_obj();
177     if (reply.empty())
178         throw runtime_error("expected reply to have result, error and id properties");
179
180     return reply;
181 }
182
183 int CommandLineRPC(int argc, char *argv[])
184 {
185     string strPrint;
186     int nRet = 0;
187     try {
188         // Skip switches
189         while (argc > 1 && IsSwitchChar(argv[1][0])) {
190             argc--;
191             argv++;
192         }
193
194         // Method
195         if (argc < 2)
196             throw runtime_error("too few parameters");
197         string strMethod = argv[1];
198
199         // Parameters default to strings
200         std::vector<std::string> strParams(&argv[2], &argv[argc]);
201         Array params = RPCConvertValues(strMethod, strParams);
202
203         // Execute and handle connection failures with -rpcwait
204         const bool fWait = GetBoolArg("-rpcwait", false);
205         do {
206             try {
207                 const Object reply = CallRPC(strMethod, params);
208
209                 // Parse reply
210                 const Value& result = find_value(reply, "result");
211                 const Value& error  = find_value(reply, "error");
212
213                 if (error.type() != null_type) {
214                     // Error
215                     const int code = find_value(error.get_obj(), "code").get_int();
216                     if (fWait && code == RPC_IN_WARMUP)
217                         throw CConnectionFailed("server in warmup");
218                     strPrint = "error: " + write_string(error, false);
219                     nRet = abs(code);
220                 } else {
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                 // Connection succeeded, no need to retry.
231                 break;
232             }
233             catch (const CConnectionFailed&) {
234                 if (fWait)
235                     MilliSleep(1000);
236                 else
237                     throw;
238             }
239         } while (fWait);
240     }
241     catch (const boost::thread_interrupted&) {
242         throw;
243     }
244     catch (const std::exception& e) {
245         strPrint = string("error: ") + e.what();
246         nRet = EXIT_FAILURE;
247     }
248     catch (...) {
249         PrintExceptionContinue(NULL, "CommandLineRPC()");
250         throw;
251     }
252
253     if (strPrint != "") {
254         fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
255     }
256     return nRet;
257 }
258
259 int main(int argc, char* argv[])
260 {
261     SetupEnvironment();
262
263     try {
264         if(!AppInitRPC(argc, argv))
265             return EXIT_FAILURE;
266     }
267     catch (const std::exception& e) {
268         PrintExceptionContinue(&e, "AppInitRPC()");
269         return EXIT_FAILURE;
270     } catch (...) {
271         PrintExceptionContinue(NULL, "AppInitRPC()");
272         return EXIT_FAILURE;
273     }
274
275     int ret = EXIT_FAILURE;
276     try {
277         ret = CommandLineRPC(argc, argv);
278     }
279     catch (const std::exception& e) {
280         PrintExceptionContinue(&e, "CommandLineRPC()");
281     } catch (...) {
282         PrintExceptionContinue(NULL, "CommandLineRPC()");
283     }
284     return ret;
285 }
This page took 0.040259 seconds and 4 git commands to generate.