]> Git Repo - VerusCoin.git/blame - src/rpc/net.cpp
fix finalization on accepted notarization
[VerusCoin.git] / src / rpc / net.cpp
CommitLineData
f914f1a7 1// Copyright (c) 2009-2014 The Bitcoin Core developers
72fb3d29 2// Distributed under the MIT software license, see the accompanying
70ab73a0 3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
b2864d2f 4
4519a766 5#include "rpc/server.h"
b2864d2f 6
71697f97 7#include "clientversion.h"
b2864d2f 8#include "main.h"
51ed9ec9
BD
9#include "net.h"
10#include "netbase.h"
11#include "protocol.h"
12#include "sync.h"
14f888ca 13#include "timedata.h"
51ed9ec9 14#include "util.h"
ff36cbe8 15#include "version.h"
9d2974ed 16#include "deprecation.h"
51ed9ec9 17
51ed9ec9 18#include <boost/foreach.hpp>
611116d4 19
a10a6e2a 20#include <univalue.h>
70ab73a0 21
70ab73a0
JG
22using namespace std;
23
d014114d 24UniValue getconnectioncount(const UniValue& params, bool fHelp)
70ab73a0
JG
25{
26 if (fHelp || params.size() != 0)
27 throw runtime_error(
28 "getconnectioncount\n"
a6099ef3 29 "\nReturns the number of connections to other nodes.\n"
30 "\nbResult:\n"
31 "n (numeric) The connection count\n"
32 "\nExamples:\n"
33 + HelpExampleCli("getconnectioncount", "")
34 + HelpExampleRpc("getconnectioncount", "")
35 );
70ab73a0 36
4401b2d7
EL
37 LOCK2(cs_main, cs_vNodes);
38
70ab73a0
JG
39 return (int)vNodes.size();
40}
41
d014114d 42UniValue ping(const UniValue& params, bool fHelp)
971bb3e9
JL
43{
44 if (fHelp || params.size() != 0)
45 throw runtime_error(
46 "ping\n"
a6099ef3 47 "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
971bb3e9 48 "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
6943cb9b 49 "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
a6099ef3 50 "\nExamples:\n"
51 + HelpExampleCli("ping", "")
52 + HelpExampleRpc("ping", "")
53 );
4315ec1a 54
971bb3e9 55 // Request that each node send a ping during next message processing pass
4401b2d7
EL
56 LOCK2(cs_main, cs_vNodes);
57
971bb3e9
JL
58 BOOST_FOREACH(CNode* pNode, vNodes) {
59 pNode->fPingQueued = true;
60 }
61
ed21d5bd 62 return NullUniValue;
971bb3e9
JL
63}
64
1006f070
JG
65static void CopyNodeStats(std::vector<CNodeStats>& vstats)
66{
67 vstats.clear();
68
69 LOCK(cs_vNodes);
70 vstats.reserve(vNodes.size());
71 BOOST_FOREACH(CNode* pnode, vNodes) {
72 CNodeStats stats;
73 pnode->copyStats(stats);
74 vstats.push_back(stats);
75 }
76}
77
d014114d 78UniValue getpeerinfo(const UniValue& params, bool fHelp)
1006f070
JG
79{
80 if (fHelp || params.size() != 0)
81 throw runtime_error(
82 "getpeerinfo\n"
a6099ef3 83 "\nReturns data about each connected network node as a json array of objects.\n"
84 "\nbResult:\n"
85 "[\n"
86 " {\n"
c4a321f5 87 " \"id\": n, (numeric) Peer index\n"
a6099ef3 88 " \"addr\":\"host:port\", (string) The ip address and port of the peer\n"
89 " \"addrlocal\":\"ip:port\", (string) local address\n"
99ddc6cb 90 " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n"
a6099ef3 91 " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
92 " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
93 " \"bytessent\": n, (numeric) The total bytes sent\n"
94 " \"bytesrecv\": n, (numeric) The total bytes received\n"
95 " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
26a6bae7 96 " \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
a6099ef3 97 " \"pingtime\": n, (numeric) ping time\n"
98 " \"pingwait\": n, (numeric) ping wait\n"
5bd677f5
S
99 " \"version\": v, (numeric) The peer version, such as 170002\n"
100 " \"subver\": \"/MagicBean:x.y.z[-v]/\", (string) The string version\n"
a6099ef3 101 " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
102 " \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
ee304b6e 103 " \"banscore\": n, (numeric) The ban score\n"
ad6e6017
PW
104 " \"synced_headers\": n, (numeric) The last header we have in common with this peer\n"
105 " \"synced_blocks\": n, (numeric) The last block we have in common with this peer\n"
106 " \"inflight\": [\n"
107 " n, (numeric) The heights of blocks we're currently asking from this peer\n"
108 " ...\n"
109 " ]\n"
a6099ef3 110 " }\n"
111 " ,...\n"
7de3f1cf 112 "]\n"
a6099ef3 113 "\nExamples:\n"
114 + HelpExampleCli("getpeerinfo", "")
115 + HelpExampleRpc("getpeerinfo", "")
116 );
1006f070 117
4401b2d7
EL
118 LOCK(cs_main);
119
1006f070
JG
120 vector<CNodeStats> vstats;
121 CopyNodeStats(vstats);
122
38fc4b70 123 UniValue ret(UniValue::VARR);
1006f070
JG
124
125 BOOST_FOREACH(const CNodeStats& stats, vstats) {
38fc4b70 126 UniValue obj(UniValue::VOBJ);
b2864d2f
PW
127 CNodeStateStats statestats;
128 bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
c4a321f5 129 obj.push_back(Pair("id", stats.nodeid));
1006f070 130 obj.push_back(Pair("addr", stats.addrName));
547c61f8
JL
131 if (!(stats.addrLocal.empty()))
132 obj.push_back(Pair("addrlocal", stats.addrLocal));
99ddc6cb 133 obj.push_back(Pair("services", strprintf("%016x", stats.nServices)));
d56e30ca
KD
134 obj.push_back(Pair("lastsend", stats.nLastSend));
135 obj.push_back(Pair("lastrecv", stats.nLastRecv));
136 obj.push_back(Pair("bytessent", stats.nSendBytes));
137 obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
138 obj.push_back(Pair("conntime", stats.nTimeConnected));
26a6bae7 139 obj.push_back(Pair("timeoffset", stats.nTimeOffset));
971bb3e9
JL
140 obj.push_back(Pair("pingtime", stats.dPingTime));
141 if (stats.dPingWait > 0.0)
142 obj.push_back(Pair("pingwait", stats.dPingWait));
1006f070 143 obj.push_back(Pair("version", stats.nVersion));
a946aa8d 144 // Use the sanitized form of subver here, to avoid tricksy remote peers from
c938fb1f 145 // corrupting or modifying the JSON output by putting special characters in
a946aa8d
MH
146 // their ver message.
147 obj.push_back(Pair("subver", stats.cleanSubVer));
1006f070 148 obj.push_back(Pair("inbound", stats.fInbound));
18e8e437 149 obj.push_back(Pair("startingheight", stats.nStartingHeight));
b2864d2f
PW
150 if (fStateStats) {
151 obj.push_back(Pair("banscore", statestats.nMisbehavior));
ad6e6017
PW
152 obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
153 obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
38fc4b70 154 UniValue heights(UniValue::VARR);
ad6e6017
PW
155 BOOST_FOREACH(int height, statestats.vHeightInFlight) {
156 heights.push_back(height);
157 }
158 obj.push_back(Pair("inflight", heights));
b2864d2f 159 }
dc942e6f 160 obj.push_back(Pair("whitelisted", stats.fWhitelisted));
1006f070
JG
161
162 ret.push_back(obj);
163 }
ea0796bd 164
1006f070
JG
165 return ret;
166}
70ab73a0 167
6477ad07 168int32_t KOMODO_LONGESTCHAIN;
f595c2e0 169int32_t komodo_longestchain()
170{
171 int32_t ht,n=0,num=0,maxheight=0,height = 0;
6bb74a02 172 vector<CNodeStats> vstats;
265660f7 173 {
174 LOCK(cs_main);
265660f7 175 CopyNodeStats(vstats);
176 }
f595c2e0 177 BOOST_FOREACH(const CNodeStats& stats, vstats)
178 {
6477ad07 179 //fprintf(stderr,"komodo_longestchain iter.%d\n",n);
f595c2e0 180 CNodeStateStats statestats;
181 bool fStateStats = GetNodeStateStats(stats.nodeid,statestats);
182 ht = 0;
183 if ( stats.nStartingHeight > ht )
184 ht = stats.nStartingHeight;
ffaeceae 185 if ( statestats.nSyncHeight > ht )
186 ht = statestats.nSyncHeight;
187 if ( statestats.nCommonHeight > ht )
188 ht = statestats.nCommonHeight;
f595c2e0 189 if ( maxheight == 0 || ht > maxheight*1.01 )
190 maxheight = ht, num = 1;
191 else if ( ht > maxheight*0.99 )
192 num++;
193 n++;
194 if ( ht > height )
195 height = ht;
196 }
197 if ( num > (n >> 1) )
6477ad07 198 {
20e2d0b7 199 extern char ASSETCHAINS_SYMBOL[];
6dcd15b5 200 if ( 0 && height != KOMODO_LONGESTCHAIN )
c3d91e3b 201 fprintf(stderr,"set %s KOMODO_LONGESTCHAIN <- %d\n",ASSETCHAINS_SYMBOL,height);
6477ad07 202 KOMODO_LONGESTCHAIN = height;
f595c2e0 203 return(height);
6477ad07 204 }
205 KOMODO_LONGESTCHAIN = 0;
206 return(0);
f595c2e0 207}
208
d014114d 209UniValue addnode(const UniValue& params, bool fHelp)
72a348fd
MC
210{
211 string strCommand;
212 if (params.size() == 2)
213 strCommand = params[1].get_str();
214 if (fHelp || params.size() != 2 ||
215 (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
216 throw runtime_error(
a6099ef3 217 "addnode \"node\" \"add|remove|onetry\"\n"
218 "\nAttempts add or remove a node from the addnode list.\n"
219 "Or try a connection to a node once.\n"
220 "\nArguments:\n"
221 "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
222 "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"
223 "\nExamples:\n"
3985a40d
JG
224 + HelpExampleCli("addnode", "\"192.168.0.6:8233\" \"onetry\"")
225 + HelpExampleRpc("addnode", "\"192.168.0.6:8233\", \"onetry\"")
a6099ef3 226 );
72a348fd
MC
227
228 string strNode = params[0].get_str();
229
230 if (strCommand == "onetry")
231 {
232 CAddress addr;
b641c9cd 233 OpenNetworkConnection(addr, NULL, strNode.c_str());
ed21d5bd 234 return NullUniValue;
72a348fd
MC
235 }
236
237 LOCK(cs_vAddedNodes);
238 vector<string>::iterator it = vAddedNodes.begin();
239 for(; it != vAddedNodes.end(); it++)
240 if (strNode == *it)
241 break;
242
243 if (strCommand == "add")
244 {
245 if (it != vAddedNodes.end())
4315ec1a 246 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
72a348fd
MC
247 vAddedNodes.push_back(strNode);
248 }
249 else if(strCommand == "remove")
250 {
251 if (it == vAddedNodes.end())
4315ec1a 252 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
72a348fd
MC
253 vAddedNodes.erase(it);
254 }
255
ed21d5bd 256 return NullUniValue;
72a348fd
MC
257}
258
94ee48c4
AP
259UniValue disconnectnode(const UniValue& params, bool fHelp)
260{
261 if (fHelp || params.size() != 1)
262 throw runtime_error(
263 "disconnectnode \"node\" \n"
264 "\nImmediately disconnects from the specified node.\n"
265 "\nArguments:\n"
266 "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
267 "\nExamples:\n"
4acd140e
JG
268 + HelpExampleCli("disconnectnode", "\"192.168.0.6:8233\"")
269 + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8233\"")
94ee48c4
AP
270 );
271
272 CNode* pNode = FindNode(params[0].get_str());
273 if (pNode == NULL)
274 throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
275
cbf3ab51 276 pNode->fDisconnect = true;
94ee48c4
AP
277
278 return NullUniValue;
279}
280
d014114d 281UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
67a11bd6
MC
282{
283 if (fHelp || params.size() < 1 || params.size() > 2)
284 throw runtime_error(
a6099ef3 285 "getaddednodeinfo dns ( \"node\" )\n"
286 "\nReturns information about the given added node, or all added nodes\n"
67a11bd6
MC
287 "(note that onetry addnodes are not listed here)\n"
288 "If dns is false, only a list of added nodes will be provided,\n"
a6099ef3 289 "otherwise connected information will also be available.\n"
290 "\nArguments:\n"
291 "1. dns (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
292 "2. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
293 "\nResult:\n"
294 "[\n"
295 " {\n"
296 " \"addednode\" : \"192.168.0.201\", (string) The node ip address\n"
297 " \"connected\" : true|false, (boolean) If connected\n"
298 " \"addresses\" : [\n"
299 " {\n"
a7322d77 300 " \"address\" : \"192.168.0.201:8233\", (string) The Komodo server host and port\n"
a6099ef3 301 " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
302 " }\n"
303 " ,...\n"
304 " ]\n"
305 " }\n"
306 " ,...\n"
307 "]\n"
308 "\nExamples:\n"
309 + HelpExampleCli("getaddednodeinfo", "true")
310 + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
311 + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
312 );
67a11bd6
MC
313
314 bool fDns = params[0].get_bool();
315
316 list<string> laddedNodes(0);
317 if (params.size() == 1)
318 {
319 LOCK(cs_vAddedNodes);
db954a65 320 BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
67a11bd6
MC
321 laddedNodes.push_back(strAddNode);
322 }
323 else
324 {
325 string strNode = params[1].get_str();
326 LOCK(cs_vAddedNodes);
db954a65 327 BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) {
67a11bd6
MC
328 if (strAddNode == strNode)
329 {
330 laddedNodes.push_back(strAddNode);
331 break;
332 }
db954a65 333 }
67a11bd6 334 if (laddedNodes.size() == 0)
4315ec1a 335 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
67a11bd6
MC
336 }
337
38fc4b70 338 UniValue ret(UniValue::VARR);
67a11bd6
MC
339 if (!fDns)
340 {
db954a65 341 BOOST_FOREACH (const std::string& strAddNode, laddedNodes) {
38fc4b70 342 UniValue obj(UniValue::VOBJ);
4412c5a7
WL
343 obj.push_back(Pair("addednode", strAddNode));
344 ret.push_back(obj);
345 }
67a11bd6
MC
346 return ret;
347 }
348
67a11bd6 349 list<pair<string, vector<CService> > > laddedAddreses(0);
db954a65 350 BOOST_FOREACH(const std::string& strAddNode, laddedNodes) {
67a11bd6 351 vector<CService> vservNode(0);
0e4b3175 352 if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
67a11bd6
MC
353 laddedAddreses.push_back(make_pair(strAddNode, vservNode));
354 else
355 {
38fc4b70 356 UniValue obj(UniValue::VOBJ);
67a11bd6
MC
357 obj.push_back(Pair("addednode", strAddNode));
358 obj.push_back(Pair("connected", false));
38fc4b70 359 UniValue addresses(UniValue::VARR);
67a11bd6
MC
360 obj.push_back(Pair("addresses", addresses));
361 }
362 }
363
364 LOCK(cs_vNodes);
365 for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
366 {
38fc4b70 367 UniValue obj(UniValue::VOBJ);
67a11bd6
MC
368 obj.push_back(Pair("addednode", it->first));
369
38fc4b70 370 UniValue addresses(UniValue::VARR);
67a11bd6 371 bool fConnected = false;
db954a65 372 BOOST_FOREACH(const CService& addrNode, it->second) {
67a11bd6 373 bool fFound = false;
38fc4b70 374 UniValue node(UniValue::VOBJ);
67a11bd6 375 node.push_back(Pair("address", addrNode.ToString()));
db954a65 376 BOOST_FOREACH(CNode* pnode, vNodes) {
67a11bd6
MC
377 if (pnode->addr == addrNode)
378 {
379 fFound = true;
380 fConnected = true;
381 node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
382 break;
383 }
db954a65 384 }
67a11bd6
MC
385 if (!fFound)
386 node.push_back(Pair("connected", "false"));
387 addresses.push_back(node);
388 }
389 obj.push_back(Pair("connected", fConnected));
390 obj.push_back(Pair("addresses", addresses));
391 ret.push_back(obj);
392 }
393
394 return ret;
395}
396
d014114d 397UniValue getnettotals(const UniValue& params, bool fHelp)
ce14345a
SE
398{
399 if (fHelp || params.size() > 0)
400 throw runtime_error(
401 "getnettotals\n"
a6099ef3 402 "\nReturns information about network traffic, including bytes in, bytes out,\n"
403 "and current time.\n"
404 "\nResult:\n"
405 "{\n"
406 " \"totalbytesrecv\": n, (numeric) Total bytes received\n"
38cbeab1 407 " \"totalbytessent\": n, (numeric) Total bytes sent\n"
a6099ef3 408 " \"timemillis\": t (numeric) Total cpu time\n"
409 "}\n"
410 "\nExamples:\n"
411 + HelpExampleCli("getnettotals", "")
412 + HelpExampleRpc("getnettotals", "")
413 );
ce14345a 414
38fc4b70 415 UniValue obj(UniValue::VOBJ);
d56e30ca
KD
416 obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
417 obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
418 obj.push_back(Pair("timemillis", GetTimeMillis()));
ce14345a
SE
419 return obj;
420}
d387b8ec 421
851f58f9 422static UniValue GetNetworksInfo()
aa827951 423{
38fc4b70 424 UniValue networks(UniValue::VARR);
aa827951
WL
425 for(int n=0; n<NET_MAX; ++n)
426 {
427 enum Network network = static_cast<enum Network>(n);
428 if(network == NET_UNROUTABLE)
429 continue;
430 proxyType proxy;
38fc4b70 431 UniValue obj(UniValue::VOBJ);
aa827951
WL
432 GetProxy(network, proxy);
433 obj.push_back(Pair("name", GetNetworkName(network)));
434 obj.push_back(Pair("limited", IsLimited(network)));
435 obj.push_back(Pair("reachable", IsReachable(network)));
67a79493
WL
436 obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()));
437 obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials));
aa827951
WL
438 networks.push_back(obj);
439 }
440 return networks;
441}
442
9d2974ed
JG
443UniValue getdeprecationinfo(const UniValue& params, bool fHelp)
444{
df46562f
JG
445 const CChainParams& chainparams = Params();
446 if (fHelp || params.size() != 0 || chainparams.NetworkIDString() != "main")
9d2974ed
JG
447 throw runtime_error(
448 "getdeprecationinfo\n"
df46562f 449 "Returns an object containing current version and deprecation block height. Applicable only on mainnet.\n"
9d2974ed
JG
450 "\nResult:\n"
451 "{\n"
452 " \"version\": xxxxx, (numeric) the server version\n"
453 " \"subversion\": \"/MagicBean:x.y.z[-v]/\", (string) the server subversion string\n"
c74ab335 454 " \"deprecationheight\": xxxxx, (numeric) the block height at which this version will deprecate and shut down\n"
9d2974ed
JG
455 "}\n"
456 "\nExamples:\n"
457 + HelpExampleCli("getdeprecationinfo", "")
458 + HelpExampleRpc("getdeprecationinfo", "")
459 );
460
9d2974ed 461 UniValue obj(UniValue::VOBJ);
df46562f 462 obj.push_back(Pair("version", CLIENT_VERSION));
9d2974ed
JG
463 obj.push_back(Pair("subversion",
464 FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>())));
465 obj.push_back(Pair("deprecationheight", DEPRECATION_HEIGHT));
466
467 return obj;
468}
469
d014114d 470UniValue getnetworkinfo(const UniValue& params, bool fHelp)
d387b8ec
WL
471{
472 if (fHelp || params.size() != 0)
473 throw runtime_error(
474 "getnetworkinfo\n"
475 "Returns an object containing various state info regarding P2P networking.\n"
476 "\nResult:\n"
477 "{\n"
b5ec5fe0 478 " \"version\": xxxxx, (numeric) the server version\n"
5bd677f5 479 " \"subversion\": \"/MagicBean:x.y.z[-v]/\", (string) the server subversion string\n"
b5ec5fe0
PK
480 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
481 " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
482 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
483 " \"connections\": xxxxx, (numeric) the number of connections\n"
484 " \"networks\": [ (array) information per network\n"
485 " {\n"
486 " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n"
487 " \"limited\": true|false, (boolean) is the network limited using -onlynet?\n"
488 " \"reachable\": true|false, (boolean) is the network reachable?\n"
489 " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n"
490 " }\n"
491 " ,...\n"
aa827951 492 " ],\n"
091b2116 493 " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
b5ec5fe0
PK
494 " \"localaddresses\": [ (array) list of local addresses\n"
495 " {\n"
496 " \"address\": \"xxxx\", (string) network address\n"
497 " \"port\": xxx, (numeric) network port\n"
498 " \"score\": xxx (numeric) relative score\n"
499 " }\n"
500 " ,...\n"
d387b8ec 501 " ]\n"
6699b425 502 " \"warnings\": \"...\" (string) any network warnings (such as alert messages) \n"
d387b8ec
WL
503 "}\n"
504 "\nExamples:\n"
505 + HelpExampleCli("getnetworkinfo", "")
506 + HelpExampleRpc("getnetworkinfo", "")
507 );
508
4401b2d7
EL
509 LOCK(cs_main);
510
38fc4b70 511 UniValue obj(UniValue::VOBJ);
b5ec5fe0 512 obj.push_back(Pair("version", CLIENT_VERSION));
2bc62dc4 513 obj.push_back(Pair("subversion", strSubVersion));
b5ec5fe0 514 obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
99ddc6cb 515 obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
d56e30ca 516 obj.push_back(Pair("timeoffset", GetTimeOffset()));
d387b8ec 517 obj.push_back(Pair("connections", (int)vNodes.size()));
aa827951 518 obj.push_back(Pair("networks", GetNetworksInfo()));
13fc83c7 519 obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
38fc4b70 520 UniValue localAddresses(UniValue::VARR);
d387b8ec
WL
521 {
522 LOCK(cs_mapLocalHost);
523 BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
524 {
38fc4b70 525 UniValue rec(UniValue::VOBJ);
d387b8ec
WL
526 rec.push_back(Pair("address", item.first.ToString()));
527 rec.push_back(Pair("port", item.second.nPort));
528 rec.push_back(Pair("score", item.second.nScore));
529 localAddresses.push_back(rec);
530 }
531 }
532 obj.push_back(Pair("localaddresses", localAddresses));
6699b425 533 obj.push_back(Pair("warnings", GetWarnings("statusbar")));
d387b8ec
WL
534 return obj;
535}
ed3f13a0 536
fcc8920f 537UniValue setban(const UniValue& params, bool fHelp)
ed3f13a0
JS
538{
539 string strCommand;
540 if (params.size() >= 2)
541 strCommand = params[1].get_str();
542 if (fHelp || params.size() < 2 ||
543 (strCommand != "add" && strCommand != "remove"))
544 throw runtime_error(
fcc8920f 545 "setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n"
e5219399 546 "\nAttempts add or remove a IP/Subnet from the banned list.\n"
ed3f13a0 547 "\nArguments:\n"
e5219399
JS
548 "1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n"
549 "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n"
fcc8920f
JS
550 "3. \"bantime\" (numeric, optional) time in seconds how long (or until when if [absolute] is set) the ip is banned (0 or empty means using the default time of 24h which can also be overwritten by the -bantime startup argument)\n"
551 "4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
ed3f13a0
JS
552 "\nExamples:\n"
553 + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
e5219399 554 + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
ed3f13a0
JS
555 + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400")
556 );
557
e5219399
JS
558 CSubNet subNet;
559 CNetAddr netAddr;
560 bool isSubnet = false;
561
562 if (params[0].get_str().find("/") != string::npos)
563 isSubnet = true;
564
565 if (!isSubnet)
566 netAddr = CNetAddr(params[0].get_str());
567 else
568 subNet = CSubNet(params[0].get_str());
569
570 if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
571 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
ed3f13a0
JS
572
573 if (strCommand == "add")
574 {
e5219399
JS
575 if (isSubnet ? CNode::IsBanned(subNet) : CNode::IsBanned(netAddr))
576 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
ed3f13a0
JS
577
578 int64_t banTime = 0; //use standard bantime if not specified
fcc8920f 579 if (params.size() >= 3 && !params[2].isNull())
ed3f13a0
JS
580 banTime = params[2].get_int64();
581
fcc8920f
JS
582 bool absolute = false;
583 if (params.size() == 4 && params[3].isTrue())
584 absolute = true;
585
586 isSubnet ? CNode::Ban(subNet, banTime, absolute) : CNode::Ban(netAddr, banTime, absolute);
ed3f13a0
JS
587
588 //disconnect possible nodes
e5219399 589 while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr)))
cbf3ab51 590 bannedNode->fDisconnect = true;
ed3f13a0
JS
591 }
592 else if(strCommand == "remove")
593 {
e5219399 594 if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) ))
1cad8c9f 595 throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed");
ed3f13a0
JS
596 }
597
fcc8920f 598 return NullUniValue;
ed3f13a0
JS
599}
600
fcc8920f 601UniValue listbanned(const UniValue& params, bool fHelp)
ed3f13a0
JS
602{
603 if (fHelp || params.size() != 0)
604 throw runtime_error(
605 "listbanned\n"
e5219399 606 "\nList all banned IPs/Subnets.\n"
ed3f13a0
JS
607 "\nExamples:\n"
608 + HelpExampleCli("listbanned", "")
609 + HelpExampleRpc("listbanned", "")
610 );
611
e5219399 612 std::map<CSubNet, int64_t> banMap;
ed3f13a0
JS
613 CNode::GetBanned(banMap);
614
fcc8920f 615 UniValue bannedAddresses(UniValue::VARR);
e5219399 616 for (std::map<CSubNet, int64_t>::iterator it = banMap.begin(); it != banMap.end(); it++)
ed3f13a0 617 {
fcc8920f 618 UniValue rec(UniValue::VOBJ);
ed3f13a0 619 rec.push_back(Pair("address", (*it).first.ToString()));
14454a3a 620 rec.push_back(Pair("banned_until", (*it).second));
ed3f13a0
JS
621 bannedAddresses.push_back(rec);
622 }
623
624 return bannedAddresses;
625}
626
fcc8920f 627UniValue clearbanned(const UniValue& params, bool fHelp)
ed3f13a0
JS
628{
629 if (fHelp || params.size() != 0)
630 throw runtime_error(
631 "clearbanned\n"
632 "\nClear all banned IPs.\n"
633 "\nExamples:\n"
634 + HelpExampleCli("clearbanned", "")
635 + HelpExampleRpc("clearbanned", "")
636 );
637
638 CNode::ClearBanned();
639
fcc8920f 640 return NullUniValue;
ed3f13a0 641}
a9496b08
WL
642
643static const CRPCCommand commands[] =
644{ // category name actor (function) okSafeMode
645 // --------------------- ------------------------ ----------------------- ----------
646 { "network", "getconnectioncount", &getconnectioncount, true },
647 { "network", "getdeprecationinfo", &getdeprecationinfo, true },
648 { "network", "ping", &ping, true },
649 { "network", "getpeerinfo", &getpeerinfo, true },
650 { "network", "addnode", &addnode, true },
651 { "network", "disconnectnode", &disconnectnode, true },
652 { "network", "getaddednodeinfo", &getaddednodeinfo, true },
653 { "network", "getnettotals", &getnettotals, true },
654 { "network", "getnetworkinfo", &getnetworkinfo, true },
655 { "network", "setban", &setban, true },
656 { "network", "listbanned", &listbanned, true },
657 { "network", "clearbanned", &clearbanned, true },
658};
659
660void RegisterNetRPCCommands(CRPCTable &tableRPC)
661{
662 for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
663 tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
664}
This page took 0.558389 seconds and 4 git commands to generate.