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.
15 #include <boost/foreach.hpp>
16 #include "json/json_spirit_value.h"
18 using namespace json_spirit;
21 Value getconnectioncount(const Array& params, bool fHelp)
23 if (fHelp || params.size() != 0)
25 "getconnectioncount\n"
26 "\nReturns the number of connections to other nodes.\n"
28 "n (numeric) The connection count\n"
30 + HelpExampleCli("getconnectioncount", "")
31 + HelpExampleRpc("getconnectioncount", "")
35 return (int)vNodes.size();
38 Value ping(const Array& params, bool fHelp)
40 if (fHelp || params.size() != 0)
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"
47 + HelpExampleCli("ping", "")
48 + HelpExampleRpc("ping", "")
51 // Request that each node send a ping during next message processing pass
53 BOOST_FOREACH(CNode* pNode, vNodes) {
54 pNode->fPingQueued = true;
60 static void CopyNodeStats(std::vector<CNodeStats>& vstats)
65 vstats.reserve(vNodes.size());
66 BOOST_FOREACH(CNode* pnode, vNodes) {
68 pnode->copyStats(stats);
69 vstats.push_back(stats);
73 Value getpeerinfo(const Array& params, bool fHelp)
75 if (fHelp || params.size() != 0)
78 "\nReturns data about each connected network node as a json array of objects.\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"
103 + HelpExampleCli("getpeerinfo", "")
104 + HelpExampleRpc("getpeerinfo", "")
107 vector<CNodeStats> vstats;
108 CopyNodeStats(vstats);
112 BOOST_FOREACH(const CNodeStats& stats, vstats) {
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));
136 obj.push_back(Pair("banscore", statestats.nMisbehavior));
137 obj.push_back(Pair("syncheight", statestats.nSyncHeight));
139 obj.push_back(Pair("syncnode", stats.fSyncNode));
140 obj.push_back(Pair("whitelisted", stats.fWhitelisted));
148 Value addnode(const Array& params, bool fHelp)
151 if (params.size() == 2)
152 strCommand = params[1].get_str();
153 if (fHelp || params.size() != 2 ||
154 (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
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"
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"
163 + HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
164 + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
167 string strNode = params[0].get_str();
169 if (strCommand == "onetry")
172 OpenNetworkConnection(addr, NULL, strNode.c_str());
176 LOCK(cs_vAddedNodes);
177 vector<string>::iterator it = vAddedNodes.begin();
178 for(; it != vAddedNodes.end(); it++)
182 if (strCommand == "add")
184 if (it != vAddedNodes.end())
185 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
186 vAddedNodes.push_back(strNode);
188 else if(strCommand == "remove")
190 if (it == vAddedNodes.end())
191 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
192 vAddedNodes.erase(it);
198 Value getaddednodeinfo(const Array& params, bool fHelp)
200 if (fHelp || params.size() < 1 || params.size() > 2)
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"
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"
213 " \"addednode\" : \"192.168.0.201\", (string) The node ip address\n"
214 " \"connected\" : true|false, (boolean) If connected\n"
215 " \"addresses\" : [\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"
226 + HelpExampleCli("getaddednodeinfo", "true")
227 + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
228 + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
231 bool fDns = params[0].get_bool();
233 list<string> laddedNodes(0);
234 if (params.size() == 1)
236 LOCK(cs_vAddedNodes);
237 BOOST_FOREACH(string& strAddNode, vAddedNodes)
238 laddedNodes.push_back(strAddNode);
242 string strNode = params[1].get_str();
243 LOCK(cs_vAddedNodes);
244 BOOST_FOREACH(string& strAddNode, vAddedNodes)
245 if (strAddNode == strNode)
247 laddedNodes.push_back(strAddNode);
250 if (laddedNodes.size() == 0)
251 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
257 BOOST_FOREACH(string& strAddNode, laddedNodes)
260 obj.push_back(Pair("addednode", strAddNode));
266 list<pair<string, vector<CService> > > laddedAddreses(0);
267 BOOST_FOREACH(string& strAddNode, laddedNodes)
269 vector<CService> vservNode(0);
270 if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
271 laddedAddreses.push_back(make_pair(strAddNode, vservNode));
275 obj.push_back(Pair("addednode", strAddNode));
276 obj.push_back(Pair("connected", false));
278 obj.push_back(Pair("addresses", addresses));
283 for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
286 obj.push_back(Pair("addednode", it->first));
289 bool fConnected = false;
290 BOOST_FOREACH(CService& addrNode, it->second)
294 node.push_back(Pair("address", addrNode.ToString()));
295 BOOST_FOREACH(CNode* pnode, vNodes)
296 if (pnode->addr == addrNode)
300 node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
304 node.push_back(Pair("connected", "false"));
305 addresses.push_back(node);
307 obj.push_back(Pair("connected", fConnected));
308 obj.push_back(Pair("addresses", addresses));
315 Value getnettotals(const Array& params, bool fHelp)
317 if (fHelp || params.size() > 0)
320 "\nReturns information about network traffic, including bytes in, bytes out,\n"
321 "and current time.\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"
329 + HelpExampleCli("getnettotals", "")
330 + HelpExampleRpc("getnettotals", "")
334 obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
335 obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
336 obj.push_back(Pair("timemillis", GetTimeMillis()));
340 Value getnetworkinfo(const Array& params, bool fHelp)
342 if (fHelp || params.size() != 0)
345 "Returns an object containing various state info regarding P2P networking.\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"
362 + HelpExampleCli("getnetworkinfo", "")
363 + HelpExampleRpc("getnetworkinfo", "")
367 GetProxy(NET_IPV4, proxy);
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;
379 LOCK(cs_mapLocalHost);
380 BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
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);
389 obj.push_back(Pair("localaddresses", localAddresses));