]> Git Repo - VerusCoin.git/blob - src/rpcnet.cpp
Merge pull request #4513
[VerusCoin.git] / src / rpcnet.cpp
1 // Copyright (c) 2009-2014 The Bitcoin developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include "rpcserver.h"
6
7 #include "main.h"
8 #include "net.h"
9 #include "netbase.h"
10 #include "protocol.h"
11 #include "sync.h"
12 #include "timedata.h"
13 #include "util.h"
14
15 #include <boost/foreach.hpp>
16 #include "json/json_spirit_value.h"
17
18 using namespace json_spirit;
19 using namespace std;
20
21 Value getconnectioncount(const Array& params, bool fHelp)
22 {
23     if (fHelp || params.size() != 0)
24         throw runtime_error(
25             "getconnectioncount\n"
26             "\nReturns the number of connections to other nodes.\n"
27             "\nbResult:\n"
28             "n          (numeric) The connection count\n"
29             "\nExamples:\n"
30             + HelpExampleCli("getconnectioncount", "")
31             + HelpExampleRpc("getconnectioncount", "")
32         );
33
34     LOCK(cs_vNodes);
35     return (int)vNodes.size();
36 }
37
38 Value ping(const Array& params, bool fHelp)
39 {
40     if (fHelp || params.size() != 0)
41         throw runtime_error(
42             "ping\n"
43             "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
44             "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
45             "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
46             "\nExamples:\n"
47             + HelpExampleCli("ping", "")
48             + HelpExampleRpc("ping", "")
49         );
50
51     // Request that each node send a ping during next message processing pass
52     LOCK(cs_vNodes);
53     BOOST_FOREACH(CNode* pNode, vNodes) {
54         pNode->fPingQueued = true;
55     }
56
57     return Value::null;
58 }
59
60 static void CopyNodeStats(std::vector<CNodeStats>& vstats)
61 {
62     vstats.clear();
63
64     LOCK(cs_vNodes);
65     vstats.reserve(vNodes.size());
66     BOOST_FOREACH(CNode* pnode, vNodes) {
67         CNodeStats stats;
68         pnode->copyStats(stats);
69         vstats.push_back(stats);
70     }
71 }
72
73 Value getpeerinfo(const Array& params, bool fHelp)
74 {
75     if (fHelp || params.size() != 0)
76         throw runtime_error(
77             "getpeerinfo\n"
78             "\nReturns data about each connected network node as a json array of objects.\n"
79             "\nbResult:\n"
80             "[\n"
81             "  {\n"
82             "    \"addr\":\"host:port\",      (string) The ip address and port of the peer\n"
83             "    \"addrlocal\":\"ip:port\",   (string) local address\n"
84             "    \"services\":\"xxxxxxxxxxxxxxxx\",   (string) The services offered\n"
85             "    \"lastsend\": ttt,           (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
86             "    \"lastrecv\": ttt,           (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
87             "    \"bytessent\": n,            (numeric) The total bytes sent\n"
88             "    \"bytesrecv\": n,            (numeric) The total bytes received\n"
89             "    \"conntime\": ttt,           (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
90             "    \"pingtime\": n,             (numeric) ping time\n"
91             "    \"pingwait\": n,             (numeric) ping wait\n"
92             "    \"version\": v,              (numeric) The peer version, such as 7001\n"
93             "    \"subver\": \"/Satoshi:0.8.5/\",  (string) The string version\n"
94             "    \"inbound\": true|false,     (boolean) Inbound (true) or Outbound (false)\n"
95             "    \"startingheight\": n,       (numeric) The starting height (block) of the peer\n"
96             "    \"banscore\": n,              (numeric) The ban score (stats.nMisbehavior)\n"
97             "    \"syncnode\" : true|false     (booleamn) if sync node\n"
98             "  }\n"
99             "  ,...\n"
100             "}\n"
101
102             "\nExamples:\n"
103             + HelpExampleCli("getpeerinfo", "")
104             + HelpExampleRpc("getpeerinfo", "")
105         );
106
107     vector<CNodeStats> vstats;
108     CopyNodeStats(vstats);
109
110     Array ret;
111
112     BOOST_FOREACH(const CNodeStats& stats, vstats) {
113         Object obj;
114         CNodeStateStats statestats;
115         bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
116         obj.push_back(Pair("addr", stats.addrName));
117         if (!(stats.addrLocal.empty()))
118             obj.push_back(Pair("addrlocal", stats.addrLocal));
119         obj.push_back(Pair("services", strprintf("%016x", stats.nServices)));
120         obj.push_back(Pair("lastsend", stats.nLastSend));
121         obj.push_back(Pair("lastrecv", stats.nLastRecv));
122         obj.push_back(Pair("bytessent", stats.nSendBytes));
123         obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
124         obj.push_back(Pair("conntime", stats.nTimeConnected));
125         obj.push_back(Pair("pingtime", stats.dPingTime));
126         if (stats.dPingWait > 0.0)
127             obj.push_back(Pair("pingwait", stats.dPingWait));
128         obj.push_back(Pair("version", stats.nVersion));
129         // Use the sanitized form of subver here, to avoid tricksy remote peers from
130         // corrupting or modifiying the JSON output by putting special characters in
131         // their ver message.
132         obj.push_back(Pair("subver", stats.cleanSubVer));
133         obj.push_back(Pair("inbound", stats.fInbound));
134         obj.push_back(Pair("startingheight", stats.nStartingHeight));
135         if (fStateStats) {
136             obj.push_back(Pair("banscore", statestats.nMisbehavior));
137             obj.push_back(Pair("syncheight", statestats.nSyncHeight));
138         }
139         obj.push_back(Pair("syncnode", stats.fSyncNode));
140         obj.push_back(Pair("whitelisted", stats.fWhitelisted));
141
142         ret.push_back(obj);
143     }
144
145     return ret;
146 }
147
148 Value addnode(const Array& params, bool fHelp)
149 {
150     string strCommand;
151     if (params.size() == 2)
152         strCommand = params[1].get_str();
153     if (fHelp || params.size() != 2 ||
154         (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
155         throw runtime_error(
156             "addnode \"node\" \"add|remove|onetry\"\n"
157             "\nAttempts add or remove a node from the addnode list.\n"
158             "Or try a connection to a node once.\n"
159             "\nArguments:\n"
160             "1. \"node\"     (string, required) The node (see getpeerinfo for nodes)\n"
161             "2. \"command\"  (string, required) 'add' to add a node to the list, 'remove' to remove a node from the list, 'onetry' to try a connection to the node once\n"
162             "\nExamples:\n"
163             + HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
164             + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
165         );
166
167     string strNode = params[0].get_str();
168
169     if (strCommand == "onetry")
170     {
171         CAddress addr;
172         OpenNetworkConnection(addr, NULL, strNode.c_str());
173         return Value::null;
174     }
175
176     LOCK(cs_vAddedNodes);
177     vector<string>::iterator it = vAddedNodes.begin();
178     for(; it != vAddedNodes.end(); it++)
179         if (strNode == *it)
180             break;
181
182     if (strCommand == "add")
183     {
184         if (it != vAddedNodes.end())
185             throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
186         vAddedNodes.push_back(strNode);
187     }
188     else if(strCommand == "remove")
189     {
190         if (it == vAddedNodes.end())
191             throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
192         vAddedNodes.erase(it);
193     }
194
195     return Value::null;
196 }
197
198 Value getaddednodeinfo(const Array& params, bool fHelp)
199 {
200     if (fHelp || params.size() < 1 || params.size() > 2)
201         throw runtime_error(
202             "getaddednodeinfo dns ( \"node\" )\n"
203             "\nReturns information about the given added node, or all added nodes\n"
204             "(note that onetry addnodes are not listed here)\n"
205             "If dns is false, only a list of added nodes will be provided,\n"
206             "otherwise connected information will also be available.\n"
207             "\nArguments:\n"
208             "1. dns        (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
209             "2. \"node\"   (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
210             "\nResult:\n"
211             "[\n"
212             "  {\n"
213             "    \"addednode\" : \"192.168.0.201\",   (string) The node ip address\n"
214             "    \"connected\" : true|false,          (boolean) If connected\n"
215             "    \"addresses\" : [\n"
216             "       {\n"
217             "         \"address\" : \"192.168.0.201:8333\",  (string) The bitcoin server host and port\n"
218             "         \"connected\" : \"outbound\"           (string) connection, inbound or outbound\n"
219             "       }\n"
220             "       ,...\n"
221             "     ]\n"
222             "  }\n"
223             "  ,...\n"
224             "]\n"
225             "\nExamples:\n"
226             + HelpExampleCli("getaddednodeinfo", "true")
227             + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
228             + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
229         );
230
231     bool fDns = params[0].get_bool();
232
233     list<string> laddedNodes(0);
234     if (params.size() == 1)
235     {
236         LOCK(cs_vAddedNodes);
237         BOOST_FOREACH(string& strAddNode, vAddedNodes)
238             laddedNodes.push_back(strAddNode);
239     }
240     else
241     {
242         string strNode = params[1].get_str();
243         LOCK(cs_vAddedNodes);
244         BOOST_FOREACH(string& strAddNode, vAddedNodes)
245             if (strAddNode == strNode)
246             {
247                 laddedNodes.push_back(strAddNode);
248                 break;
249             }
250         if (laddedNodes.size() == 0)
251             throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
252     }
253
254     Array ret;
255     if (!fDns)
256     {
257         BOOST_FOREACH(string& strAddNode, laddedNodes)
258         {
259             Object obj;
260             obj.push_back(Pair("addednode", strAddNode));
261             ret.push_back(obj);
262         }
263         return ret;
264     }
265
266     list<pair<string, vector<CService> > > laddedAddreses(0);
267     BOOST_FOREACH(string& strAddNode, laddedNodes)
268     {
269         vector<CService> vservNode(0);
270         if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
271             laddedAddreses.push_back(make_pair(strAddNode, vservNode));
272         else
273         {
274             Object obj;
275             obj.push_back(Pair("addednode", strAddNode));
276             obj.push_back(Pair("connected", false));
277             Array addresses;
278             obj.push_back(Pair("addresses", addresses));
279         }
280     }
281
282     LOCK(cs_vNodes);
283     for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
284     {
285         Object obj;
286         obj.push_back(Pair("addednode", it->first));
287
288         Array addresses;
289         bool fConnected = false;
290         BOOST_FOREACH(CService& addrNode, it->second)
291         {
292             bool fFound = false;
293             Object node;
294             node.push_back(Pair("address", addrNode.ToString()));
295             BOOST_FOREACH(CNode* pnode, vNodes)
296                 if (pnode->addr == addrNode)
297                 {
298                     fFound = true;
299                     fConnected = true;
300                     node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
301                     break;
302                 }
303             if (!fFound)
304                 node.push_back(Pair("connected", "false"));
305             addresses.push_back(node);
306         }
307         obj.push_back(Pair("connected", fConnected));
308         obj.push_back(Pair("addresses", addresses));
309         ret.push_back(obj);
310     }
311
312     return ret;
313 }
314
315 Value getnettotals(const Array& params, bool fHelp)
316 {
317     if (fHelp || params.size() > 0)
318         throw runtime_error(
319             "getnettotals\n"
320             "\nReturns information about network traffic, including bytes in, bytes out,\n"
321             "and current time.\n"
322             "\nResult:\n"
323             "{\n"
324             "  \"totalbytesrecv\": n,   (numeric) Total bytes received\n"
325             "  \"totalbytessent\": n,   (numeric) Total bytes sent\n"
326             "  \"timemillis\": t        (numeric) Total cpu time\n"
327             "}\n"
328             "\nExamples:\n"
329             + HelpExampleCli("getnettotals", "")
330             + HelpExampleRpc("getnettotals", "")
331        );
332
333     Object obj;
334     obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
335     obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
336     obj.push_back(Pair("timemillis", GetTimeMillis()));
337     return obj;
338 }
339
340 Value getnetworkinfo(const Array& params, bool fHelp)
341 {
342     if (fHelp || params.size() != 0)
343         throw runtime_error(
344             "getnetworkinfo\n"
345             "Returns an object containing various state info regarding P2P networking.\n"
346             "\nResult:\n"
347             "{\n"
348             "  \"version\": xxxxx,           (numeric) the server version\n"
349             "  \"protocolversion\": xxxxx,   (numeric) the protocol version\n"
350             "  \"localservices\": \"xxxxxxxxxxxxxxxx\",   (string) the services we offer to the network\n"
351             "  \"timeoffset\": xxxxx,        (numeric) the time offset\n"
352             "  \"connections\": xxxxx,       (numeric) the number of connections\n"
353             "  \"proxy\": \"host:port\",     (string, optional) the proxy used by the server\n"
354             "  \"relayfee\": x.xxxx,         (numeric) minimum relay fee for non-free transactions in btc/kb\n"
355             "  \"localaddresses\": [,        (array) list of local addresses\n"
356             "    \"address\": \"xxxx\",      (string) network address\n"
357             "    \"port\": xxx,              (numeric) network port\n"
358             "    \"score\": xxx              (numeric) relative score\n"
359             "  ]\n"
360             "}\n"
361             "\nExamples:\n"
362             + HelpExampleCli("getnetworkinfo", "")
363             + HelpExampleRpc("getnetworkinfo", "")
364         );
365
366     proxyType proxy;
367     GetProxy(NET_IPV4, proxy);
368
369     Object obj;
370     obj.push_back(Pair("version",       (int)CLIENT_VERSION));
371     obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
372     obj.push_back(Pair("localservices",       strprintf("%016x", nLocalServices)));
373     obj.push_back(Pair("timeoffset",    GetTimeOffset()));
374     obj.push_back(Pair("connections",   (int)vNodes.size()));
375     obj.push_back(Pair("proxy",         (proxy.IsValid() ? proxy.ToStringIPPort() : string())));
376     obj.push_back(Pair("relayfee",      ValueFromAmount(::minRelayTxFee.GetFeePerK())));
377     Array localAddresses;
378     {
379         LOCK(cs_mapLocalHost);
380         BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
381         {
382             Object rec;
383             rec.push_back(Pair("address", item.first.ToString()));
384             rec.push_back(Pair("port", item.second.nPort));
385             rec.push_back(Pair("score", item.second.nScore));
386             localAddresses.push_back(rec);
387         }
388     }
389     obj.push_back(Pair("localaddresses", localAddresses));
390     return obj;
391 }
This page took 0.045688 seconds and 4 git commands to generate.