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.
14 #include <boost/foreach.hpp>
15 #include "json/json_spirit_value.h"
17 using namespace json_spirit
;
20 Value
getconnectioncount(const Array
& params
, bool fHelp
)
22 if (fHelp
|| params
.size() != 0)
24 "getconnectioncount\n"
25 "\nReturns the number of connections to other nodes.\n"
27 "n (numeric) The connection count\n"
29 + HelpExampleCli("getconnectioncount", "")
30 + HelpExampleRpc("getconnectioncount", "")
34 return (int)vNodes
.size();
37 Value
ping(const Array
& params
, bool fHelp
)
39 if (fHelp
|| params
.size() != 0)
42 "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
43 "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
44 "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
46 + HelpExampleCli("ping", "")
47 + HelpExampleRpc("ping", "")
50 // Request that each node send a ping during next message processing pass
52 BOOST_FOREACH(CNode
* pNode
, vNodes
) {
53 pNode
->fPingQueued
= true;
59 static void CopyNodeStats(std::vector
<CNodeStats
>& vstats
)
64 vstats
.reserve(vNodes
.size());
65 BOOST_FOREACH(CNode
* pnode
, vNodes
) {
67 pnode
->copyStats(stats
);
68 vstats
.push_back(stats
);
72 Value
getpeerinfo(const Array
& params
, bool fHelp
)
74 if (fHelp
|| params
.size() != 0)
77 "\nReturns data about each connected network node as a json array of objects.\n"
81 " \"addr\":\"host:port\", (string) The ip address and port of the peer\n"
82 " \"addrlocal\":\"ip:port\", (string) local address\n"
83 " \"services\":\"00000001\", (string) The services\n"
84 " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
85 " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
86 " \"bytessent\": n, (numeric) The total bytes sent\n"
87 " \"bytesrecv\": n, (numeric) The total bytes received\n"
88 " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
89 " \"pingtime\": n, (numeric) ping time\n"
90 " \"pingwait\": n, (numeric) ping wait\n"
91 " \"version\": v, (numeric) The peer version, such as 7001\n"
92 " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
93 " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
94 " \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
95 " \"banscore\": n, (numeric) The ban score (stats.nMisbehavior)\n"
96 " \"syncnode\" : true|false (booleamn) if sync node\n"
102 + HelpExampleCli("getpeerinfo", "")
103 + HelpExampleRpc("getpeerinfo", "")
106 vector
<CNodeStats
> vstats
;
107 CopyNodeStats(vstats
);
111 BOOST_FOREACH(const CNodeStats
& stats
, vstats
) {
113 CNodeStateStats statestats
;
114 bool fStateStats
= GetNodeStateStats(stats
.nodeid
, statestats
);
115 obj
.push_back(Pair("addr", stats
.addrName
));
116 if (!(stats
.addrLocal
.empty()))
117 obj
.push_back(Pair("addrlocal", stats
.addrLocal
));
118 obj
.push_back(Pair("services", strprintf("%08x", stats
.nServices
)));
119 obj
.push_back(Pair("lastsend", (boost::int64_t)stats
.nLastSend
));
120 obj
.push_back(Pair("lastrecv", (boost::int64_t)stats
.nLastRecv
));
121 obj
.push_back(Pair("bytessent", (boost::int64_t)stats
.nSendBytes
));
122 obj
.push_back(Pair("bytesrecv", (boost::int64_t)stats
.nRecvBytes
));
123 obj
.push_back(Pair("conntime", (boost::int64_t)stats
.nTimeConnected
));
124 obj
.push_back(Pair("pingtime", stats
.dPingTime
));
125 if (stats
.dPingWait
> 0.0)
126 obj
.push_back(Pair("pingwait", stats
.dPingWait
));
127 obj
.push_back(Pair("version", stats
.nVersion
));
128 // Use the sanitized form of subver here, to avoid tricksy remote peers from
129 // corrupting or modifiying the JSON output by putting special characters in
130 // their ver message.
131 obj
.push_back(Pair("subver", stats
.cleanSubVer
));
132 obj
.push_back(Pair("inbound", stats
.fInbound
));
133 obj
.push_back(Pair("startingheight", stats
.nStartingHeight
));
135 obj
.push_back(Pair("banscore", statestats
.nMisbehavior
));
137 obj
.push_back(Pair("syncnode", stats
.fSyncNode
));
145 Value
addnode(const Array
& params
, bool fHelp
)
148 if (params
.size() == 2)
149 strCommand
= params
[1].get_str();
150 if (fHelp
|| params
.size() != 2 ||
151 (strCommand
!= "onetry" && strCommand
!= "add" && strCommand
!= "remove"))
153 "addnode \"node\" \"add|remove|onetry\"\n"
154 "\nAttempts add or remove a node from the addnode list.\n"
155 "Or try a connection to a node once.\n"
157 "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
158 "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"
160 + HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
161 + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
164 string strNode
= params
[0].get_str();
166 if (strCommand
== "onetry")
169 ConnectNode(addr
, strNode
.c_str());
173 LOCK(cs_vAddedNodes
);
174 vector
<string
>::iterator it
= vAddedNodes
.begin();
175 for(; it
!= vAddedNodes
.end(); it
++)
179 if (strCommand
== "add")
181 if (it
!= vAddedNodes
.end())
182 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED
, "Error: Node already added");
183 vAddedNodes
.push_back(strNode
);
185 else if(strCommand
== "remove")
187 if (it
== vAddedNodes
.end())
188 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED
, "Error: Node has not been added.");
189 vAddedNodes
.erase(it
);
195 Value
getaddednodeinfo(const Array
& params
, bool fHelp
)
197 if (fHelp
|| params
.size() < 1 || params
.size() > 2)
199 "getaddednodeinfo dns ( \"node\" )\n"
200 "\nReturns information about the given added node, or all added nodes\n"
201 "(note that onetry addnodes are not listed here)\n"
202 "If dns is false, only a list of added nodes will be provided,\n"
203 "otherwise connected information will also be available.\n"
205 "1. dns (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
206 "2. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
210 " \"addednode\" : \"192.168.0.201\", (string) The node ip address\n"
211 " \"connected\" : true|false, (boolean) If connected\n"
212 " \"addresses\" : [\n"
214 " \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server host and port\n"
215 " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
223 + HelpExampleCli("getaddednodeinfo", "true")
224 + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
225 + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
228 bool fDns
= params
[0].get_bool();
230 list
<string
> laddedNodes(0);
231 if (params
.size() == 1)
233 LOCK(cs_vAddedNodes
);
234 BOOST_FOREACH(string
& strAddNode
, vAddedNodes
)
235 laddedNodes
.push_back(strAddNode
);
239 string strNode
= params
[1].get_str();
240 LOCK(cs_vAddedNodes
);
241 BOOST_FOREACH(string
& strAddNode
, vAddedNodes
)
242 if (strAddNode
== strNode
)
244 laddedNodes
.push_back(strAddNode
);
247 if (laddedNodes
.size() == 0)
248 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED
, "Error: Node has not been added.");
254 BOOST_FOREACH(string
& strAddNode
, laddedNodes
)
257 obj
.push_back(Pair("addednode", strAddNode
));
263 list
<pair
<string
, vector
<CService
> > > laddedAddreses(0);
264 BOOST_FOREACH(string
& strAddNode
, laddedNodes
)
266 vector
<CService
> vservNode(0);
267 if(Lookup(strAddNode
.c_str(), vservNode
, Params().GetDefaultPort(), fNameLookup
, 0))
268 laddedAddreses
.push_back(make_pair(strAddNode
, vservNode
));
272 obj
.push_back(Pair("addednode", strAddNode
));
273 obj
.push_back(Pair("connected", false));
275 obj
.push_back(Pair("addresses", addresses
));
280 for (list
<pair
<string
, vector
<CService
> > >::iterator it
= laddedAddreses
.begin(); it
!= laddedAddreses
.end(); it
++)
283 obj
.push_back(Pair("addednode", it
->first
));
286 bool fConnected
= false;
287 BOOST_FOREACH(CService
& addrNode
, it
->second
)
291 node
.push_back(Pair("address", addrNode
.ToString()));
292 BOOST_FOREACH(CNode
* pnode
, vNodes
)
293 if (pnode
->addr
== addrNode
)
297 node
.push_back(Pair("connected", pnode
->fInbound
? "inbound" : "outbound"));
301 node
.push_back(Pair("connected", "false"));
302 addresses
.push_back(node
);
304 obj
.push_back(Pair("connected", fConnected
));
305 obj
.push_back(Pair("addresses", addresses
));
312 Value
getnettotals(const Array
& params
, bool fHelp
)
314 if (fHelp
|| params
.size() > 0)
317 "\nReturns information about network traffic, including bytes in, bytes out,\n"
318 "and current time.\n"
321 " \"totalbytesrecv\": n, (numeric) Total bytes received\n"
322 " \"totalbytessent\": n, (numeric) Total bytes sent\n"
323 " \"timemillis\": t (numeric) Total cpu time\n"
326 + HelpExampleCli("getnettotals", "")
327 + HelpExampleRpc("getnettotals", "")
331 obj
.push_back(Pair("totalbytesrecv", static_cast< boost::uint64_t>(CNode::GetTotalBytesRecv())));
332 obj
.push_back(Pair("totalbytessent", static_cast<boost::uint64_t>(CNode::GetTotalBytesSent())));
333 obj
.push_back(Pair("timemillis", static_cast<boost::int64_t>(GetTimeMillis())));