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 " \"id\": n, (numeric) Peer index\n"
83 " \"addr\":\"host:port\", (string) The ip address and port of the peer\n"
84 " \"addrlocal\":\"ip:port\", (string) local address\n"
85 " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n"
86 " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
87 " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
88 " \"bytessent\": n, (numeric) The total bytes sent\n"
89 " \"bytesrecv\": n, (numeric) The total bytes received\n"
90 " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
91 " \"pingtime\": n, (numeric) ping time\n"
92 " \"pingwait\": n, (numeric) ping wait\n"
93 " \"version\": v, (numeric) The peer version, such as 7001\n"
94 " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
95 " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
96 " \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
97 " \"banscore\": n, (numeric) The ban score (stats.nMisbehavior)\n"
98 " \"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("id", stats
.nodeid
));
117 obj
.push_back(Pair("addr", stats
.addrName
));
118 if (!(stats
.addrLocal
.empty()))
119 obj
.push_back(Pair("addrlocal", stats
.addrLocal
));
120 obj
.push_back(Pair("services", strprintf("%016x", stats
.nServices
)));
121 obj
.push_back(Pair("lastsend", stats
.nLastSend
));
122 obj
.push_back(Pair("lastrecv", stats
.nLastRecv
));
123 obj
.push_back(Pair("bytessent", stats
.nSendBytes
));
124 obj
.push_back(Pair("bytesrecv", stats
.nRecvBytes
));
125 obj
.push_back(Pair("conntime", stats
.nTimeConnected
));
126 obj
.push_back(Pair("pingtime", stats
.dPingTime
));
127 if (stats
.dPingWait
> 0.0)
128 obj
.push_back(Pair("pingwait", stats
.dPingWait
));
129 obj
.push_back(Pair("version", stats
.nVersion
));
130 // Use the sanitized form of subver here, to avoid tricksy remote peers from
131 // corrupting or modifiying the JSON output by putting special characters in
132 // their ver message.
133 obj
.push_back(Pair("subver", stats
.cleanSubVer
));
134 obj
.push_back(Pair("inbound", stats
.fInbound
));
135 obj
.push_back(Pair("startingheight", stats
.nStartingHeight
));
137 obj
.push_back(Pair("banscore", statestats
.nMisbehavior
));
138 obj
.push_back(Pair("syncheight", statestats
.nSyncHeight
));
140 obj
.push_back(Pair("syncnode", stats
.fSyncNode
));
141 obj
.push_back(Pair("whitelisted", stats
.fWhitelisted
));
149 Value
addnode(const Array
& params
, bool fHelp
)
152 if (params
.size() == 2)
153 strCommand
= params
[1].get_str();
154 if (fHelp
|| params
.size() != 2 ||
155 (strCommand
!= "onetry" && strCommand
!= "add" && strCommand
!= "remove"))
157 "addnode \"node\" \"add|remove|onetry\"\n"
158 "\nAttempts add or remove a node from the addnode list.\n"
159 "Or try a connection to a node once.\n"
161 "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
162 "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"
164 + HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
165 + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
168 string strNode
= params
[0].get_str();
170 if (strCommand
== "onetry")
173 OpenNetworkConnection(addr
, NULL
, strNode
.c_str());
177 LOCK(cs_vAddedNodes
);
178 vector
<string
>::iterator it
= vAddedNodes
.begin();
179 for(; it
!= vAddedNodes
.end(); it
++)
183 if (strCommand
== "add")
185 if (it
!= vAddedNodes
.end())
186 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED
, "Error: Node already added");
187 vAddedNodes
.push_back(strNode
);
189 else if(strCommand
== "remove")
191 if (it
== vAddedNodes
.end())
192 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED
, "Error: Node has not been added.");
193 vAddedNodes
.erase(it
);
199 Value
getaddednodeinfo(const Array
& params
, bool fHelp
)
201 if (fHelp
|| params
.size() < 1 || params
.size() > 2)
203 "getaddednodeinfo dns ( \"node\" )\n"
204 "\nReturns information about the given added node, or all added nodes\n"
205 "(note that onetry addnodes are not listed here)\n"
206 "If dns is false, only a list of added nodes will be provided,\n"
207 "otherwise connected information will also be available.\n"
209 "1. dns (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
210 "2. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
214 " \"addednode\" : \"192.168.0.201\", (string) The node ip address\n"
215 " \"connected\" : true|false, (boolean) If connected\n"
216 " \"addresses\" : [\n"
218 " \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server host and port\n"
219 " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
227 + HelpExampleCli("getaddednodeinfo", "true")
228 + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
229 + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
232 bool fDns
= params
[0].get_bool();
234 list
<string
> laddedNodes(0);
235 if (params
.size() == 1)
237 LOCK(cs_vAddedNodes
);
238 BOOST_FOREACH(string
& strAddNode
, vAddedNodes
)
239 laddedNodes
.push_back(strAddNode
);
243 string strNode
= params
[1].get_str();
244 LOCK(cs_vAddedNodes
);
245 BOOST_FOREACH(string
& strAddNode
, vAddedNodes
)
246 if (strAddNode
== strNode
)
248 laddedNodes
.push_back(strAddNode
);
251 if (laddedNodes
.size() == 0)
252 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED
, "Error: Node has not been added.");
258 BOOST_FOREACH(string
& strAddNode
, laddedNodes
)
261 obj
.push_back(Pair("addednode", strAddNode
));
267 list
<pair
<string
, vector
<CService
> > > laddedAddreses(0);
268 BOOST_FOREACH(string
& strAddNode
, laddedNodes
)
270 vector
<CService
> vservNode(0);
271 if(Lookup(strAddNode
.c_str(), vservNode
, Params().GetDefaultPort(), fNameLookup
, 0))
272 laddedAddreses
.push_back(make_pair(strAddNode
, vservNode
));
276 obj
.push_back(Pair("addednode", strAddNode
));
277 obj
.push_back(Pair("connected", false));
279 obj
.push_back(Pair("addresses", addresses
));
284 for (list
<pair
<string
, vector
<CService
> > >::iterator it
= laddedAddreses
.begin(); it
!= laddedAddreses
.end(); it
++)
287 obj
.push_back(Pair("addednode", it
->first
));
290 bool fConnected
= false;
291 BOOST_FOREACH(CService
& addrNode
, it
->second
)
295 node
.push_back(Pair("address", addrNode
.ToString()));
296 BOOST_FOREACH(CNode
* pnode
, vNodes
)
297 if (pnode
->addr
== addrNode
)
301 node
.push_back(Pair("connected", pnode
->fInbound
? "inbound" : "outbound"));
305 node
.push_back(Pair("connected", "false"));
306 addresses
.push_back(node
);
308 obj
.push_back(Pair("connected", fConnected
));
309 obj
.push_back(Pair("addresses", addresses
));
316 Value
getnettotals(const Array
& params
, bool fHelp
)
318 if (fHelp
|| params
.size() > 0)
321 "\nReturns information about network traffic, including bytes in, bytes out,\n"
322 "and current time.\n"
325 " \"totalbytesrecv\": n, (numeric) Total bytes received\n"
326 " \"totalbytessent\": n, (numeric) Total bytes sent\n"
327 " \"timemillis\": t (numeric) Total cpu time\n"
330 + HelpExampleCli("getnettotals", "")
331 + HelpExampleRpc("getnettotals", "")
335 obj
.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
336 obj
.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
337 obj
.push_back(Pair("timemillis", GetTimeMillis()));
341 static Array
GetNetworksInfo()
344 for(int n
=0; n
<NET_MAX
; ++n
)
346 enum Network network
= static_cast<enum Network
>(n
);
347 if(network
== NET_UNROUTABLE
)
351 GetProxy(network
, proxy
);
352 obj
.push_back(Pair("name", GetNetworkName(network
)));
353 obj
.push_back(Pair("limited", IsLimited(network
)));
354 obj
.push_back(Pair("reachable", IsReachable(network
)));
355 obj
.push_back(Pair("proxy", proxy
.IsValid() ? proxy
.ToStringIPPort() : string()));
356 networks
.push_back(obj
);
361 Value
getnetworkinfo(const Array
& params
, bool fHelp
)
363 if (fHelp
|| params
.size() != 0)
366 "Returns an object containing various state info regarding P2P networking.\n"
369 " \"version\": xxxxx, (numeric) the server version\n"
370 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
371 " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
372 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
373 " \"connections\": xxxxx, (numeric) the number of connections\n"
374 " \"networks\": [ (array) information per network\n"
375 " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n"
376 " \"limited\": xxx, (boolean) is the network limited using -onlynet?\n"
377 " \"reachable\": xxx, (boolean) is the network reachable?\n"
378 " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n"
381 " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
382 " \"localaddresses\": [, (array) list of local addresses\n"
383 " \"address\": \"xxxx\", (string) network address\n"
384 " \"port\": xxx, (numeric) network port\n"
385 " \"score\": xxx (numeric) relative score\n"
389 + HelpExampleCli("getnetworkinfo", "")
390 + HelpExampleRpc("getnetworkinfo", "")
394 obj
.push_back(Pair("version", (int)CLIENT_VERSION
));
395 obj
.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION
));
396 obj
.push_back(Pair("localservices", strprintf("%016x", nLocalServices
)));
397 obj
.push_back(Pair("timeoffset", GetTimeOffset()));
398 obj
.push_back(Pair("connections", (int)vNodes
.size()));
399 obj
.push_back(Pair("networks", GetNetworksInfo()));
400 obj
.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee
.GetFeePerK())));
401 Array localAddresses
;
403 LOCK(cs_mapLocalHost
);
404 BOOST_FOREACH(const PAIRTYPE(CNetAddr
, LocalServiceInfo
) &item
, mapLocalHost
)
407 rec
.push_back(Pair("address", item
.first
.ToString()));
408 rec
.push_back(Pair("port", item
.second
.nPort
));
409 rec
.push_back(Pair("score", item
.second
.nScore
));
410 localAddresses
.push_back(rec
);
413 obj
.push_back(Pair("localaddresses", localAddresses
));