[doc][trivial] Remove source forge from Debian watch.
[bitcoinplatinum.git] / src / rpcnet.cpp
blob89150106494ac99ae372ef2e877122e38b397ae4
1 // Copyright (c) 2009-2014 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "rpcserver.h"
7 #include "chainparams.h"
8 #include "clientversion.h"
9 #include "main.h"
10 #include "net.h"
11 #include "netbase.h"
12 #include "protocol.h"
13 #include "sync.h"
14 #include "timedata.h"
15 #include "ui_interface.h"
16 #include "util.h"
17 #include "utilstrencodings.h"
18 #include "version.h"
20 #include <boost/foreach.hpp>
22 #include <univalue.h>
24 using namespace std;
26 UniValue getconnectioncount(const UniValue& params, bool fHelp)
28 if (fHelp || params.size() != 0)
29 throw runtime_error(
30 "getconnectioncount\n"
31 "\nReturns the number of connections to other nodes.\n"
32 "\nResult:\n"
33 "n (numeric) The connection count\n"
34 "\nExamples:\n"
35 + HelpExampleCli("getconnectioncount", "")
36 + HelpExampleRpc("getconnectioncount", "")
39 LOCK2(cs_main, cs_vNodes);
41 return (int)vNodes.size();
44 UniValue ping(const UniValue& params, bool fHelp)
46 if (fHelp || params.size() != 0)
47 throw runtime_error(
48 "ping\n"
49 "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
50 "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
51 "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
52 "\nExamples:\n"
53 + HelpExampleCli("ping", "")
54 + HelpExampleRpc("ping", "")
57 // Request that each node send a ping during next message processing pass
58 LOCK2(cs_main, cs_vNodes);
60 BOOST_FOREACH(CNode* pNode, vNodes) {
61 pNode->fPingQueued = true;
64 return NullUniValue;
67 static void CopyNodeStats(std::vector<CNodeStats>& vstats)
69 vstats.clear();
71 LOCK(cs_vNodes);
72 vstats.reserve(vNodes.size());
73 BOOST_FOREACH(CNode* pnode, vNodes) {
74 CNodeStats stats;
75 pnode->copyStats(stats);
76 vstats.push_back(stats);
80 UniValue getpeerinfo(const UniValue& params, bool fHelp)
82 if (fHelp || params.size() != 0)
83 throw runtime_error(
84 "getpeerinfo\n"
85 "\nReturns data about each connected network node as a json array of objects.\n"
86 "\nResult:\n"
87 "[\n"
88 " {\n"
89 " \"id\": n, (numeric) Peer index\n"
90 " \"addr\":\"host:port\", (string) The ip address and port of the peer\n"
91 " \"addrlocal\":\"ip:port\", (string) local address\n"
92 " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n"
93 " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
94 " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
95 " \"bytessent\": n, (numeric) The total bytes sent\n"
96 " \"bytesrecv\": n, (numeric) The total bytes received\n"
97 " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
98 " \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
99 " \"pingtime\": n, (numeric) ping time\n"
100 " \"minping\": n, (numeric) minimum observed ping time\n"
101 " \"pingwait\": n, (numeric) ping wait\n"
102 " \"version\": v, (numeric) The peer version, such as 7001\n"
103 " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
104 " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
105 " \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
106 " \"banscore\": n, (numeric) The ban score\n"
107 " \"synced_headers\": n, (numeric) The last header we have in common with this peer\n"
108 " \"synced_blocks\": n, (numeric) The last block we have in common with this peer\n"
109 " \"inflight\": [\n"
110 " n, (numeric) The heights of blocks we're currently asking from this peer\n"
111 " ...\n"
112 " ]\n"
113 " }\n"
114 " ,...\n"
115 "]\n"
116 "\nExamples:\n"
117 + HelpExampleCli("getpeerinfo", "")
118 + HelpExampleRpc("getpeerinfo", "")
121 LOCK(cs_main);
123 vector<CNodeStats> vstats;
124 CopyNodeStats(vstats);
126 UniValue ret(UniValue::VARR);
128 BOOST_FOREACH(const CNodeStats& stats, vstats) {
129 UniValue obj(UniValue::VOBJ);
130 CNodeStateStats statestats;
131 bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
132 obj.push_back(Pair("id", stats.nodeid));
133 obj.push_back(Pair("addr", stats.addrName));
134 if (!(stats.addrLocal.empty()))
135 obj.push_back(Pair("addrlocal", stats.addrLocal));
136 obj.push_back(Pair("services", strprintf("%016x", stats.nServices)));
137 obj.push_back(Pair("lastsend", stats.nLastSend));
138 obj.push_back(Pair("lastrecv", stats.nLastRecv));
139 obj.push_back(Pair("bytessent", stats.nSendBytes));
140 obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
141 obj.push_back(Pair("conntime", stats.nTimeConnected));
142 obj.push_back(Pair("timeoffset", stats.nTimeOffset));
143 obj.push_back(Pair("pingtime", stats.dPingTime));
144 obj.push_back(Pair("minping", stats.dPingMin));
145 if (stats.dPingWait > 0.0)
146 obj.push_back(Pair("pingwait", stats.dPingWait));
147 obj.push_back(Pair("version", stats.nVersion));
148 // Use the sanitized form of subver here, to avoid tricksy remote peers from
149 // corrupting or modifiying the JSON output by putting special characters in
150 // their ver message.
151 obj.push_back(Pair("subver", stats.cleanSubVer));
152 obj.push_back(Pair("inbound", stats.fInbound));
153 obj.push_back(Pair("startingheight", stats.nStartingHeight));
154 if (fStateStats) {
155 obj.push_back(Pair("banscore", statestats.nMisbehavior));
156 obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
157 obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
158 UniValue heights(UniValue::VARR);
159 BOOST_FOREACH(int height, statestats.vHeightInFlight) {
160 heights.push_back(height);
162 obj.push_back(Pair("inflight", heights));
164 obj.push_back(Pair("whitelisted", stats.fWhitelisted));
166 ret.push_back(obj);
169 return ret;
172 UniValue addnode(const UniValue& params, bool fHelp)
174 string strCommand;
175 if (params.size() == 2)
176 strCommand = params[1].get_str();
177 if (fHelp || params.size() != 2 ||
178 (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
179 throw runtime_error(
180 "addnode \"node\" \"add|remove|onetry\"\n"
181 "\nAttempts add or remove a node from the addnode list.\n"
182 "Or try a connection to a node once.\n"
183 "\nArguments:\n"
184 "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
185 "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"
186 "\nExamples:\n"
187 + HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
188 + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
191 string strNode = params[0].get_str();
193 if (strCommand == "onetry")
195 CAddress addr;
196 OpenNetworkConnection(addr, NULL, strNode.c_str());
197 return NullUniValue;
200 LOCK(cs_vAddedNodes);
201 vector<string>::iterator it = vAddedNodes.begin();
202 for(; it != vAddedNodes.end(); it++)
203 if (strNode == *it)
204 break;
206 if (strCommand == "add")
208 if (it != vAddedNodes.end())
209 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
210 vAddedNodes.push_back(strNode);
212 else if(strCommand == "remove")
214 if (it == vAddedNodes.end())
215 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
216 vAddedNodes.erase(it);
219 return NullUniValue;
222 UniValue disconnectnode(const UniValue& params, bool fHelp)
224 if (fHelp || params.size() != 1)
225 throw runtime_error(
226 "disconnectnode \"node\" \n"
227 "\nImmediately disconnects from the specified node.\n"
228 "\nArguments:\n"
229 "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
230 "\nExamples:\n"
231 + HelpExampleCli("disconnectnode", "\"192.168.0.6:8333\"")
232 + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8333\"")
235 CNode* pNode = FindNode(params[0].get_str());
236 if (pNode == NULL)
237 throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
239 pNode->fDisconnect = true;
241 return NullUniValue;
244 UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
246 if (fHelp || params.size() < 1 || params.size() > 2)
247 throw runtime_error(
248 "getaddednodeinfo dns ( \"node\" )\n"
249 "\nReturns information about the given added node, or all added nodes\n"
250 "(note that onetry addnodes are not listed here)\n"
251 "If dns is false, only a list of added nodes will be provided,\n"
252 "otherwise connected information will also be available.\n"
253 "\nArguments:\n"
254 "1. dns (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
255 "2. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
256 "\nResult:\n"
257 "[\n"
258 " {\n"
259 " \"addednode\" : \"192.168.0.201\", (string) The node ip address\n"
260 " \"connected\" : true|false, (boolean) If connected\n"
261 " \"addresses\" : [\n"
262 " {\n"
263 " \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server host and port\n"
264 " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
265 " }\n"
266 " ,...\n"
267 " ]\n"
268 " }\n"
269 " ,...\n"
270 "]\n"
271 "\nExamples:\n"
272 + HelpExampleCli("getaddednodeinfo", "true")
273 + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
274 + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
277 bool fDns = params[0].get_bool();
279 list<string> laddedNodes(0);
280 if (params.size() == 1)
282 LOCK(cs_vAddedNodes);
283 BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
284 laddedNodes.push_back(strAddNode);
286 else
288 string strNode = params[1].get_str();
289 LOCK(cs_vAddedNodes);
290 BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) {
291 if (strAddNode == strNode)
293 laddedNodes.push_back(strAddNode);
294 break;
297 if (laddedNodes.size() == 0)
298 throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
301 UniValue ret(UniValue::VARR);
302 if (!fDns)
304 BOOST_FOREACH (const std::string& strAddNode, laddedNodes) {
305 UniValue obj(UniValue::VOBJ);
306 obj.push_back(Pair("addednode", strAddNode));
307 ret.push_back(obj);
309 return ret;
312 list<pair<string, vector<CService> > > laddedAddreses(0);
313 BOOST_FOREACH(const std::string& strAddNode, laddedNodes) {
314 vector<CService> vservNode(0);
315 if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
316 laddedAddreses.push_back(make_pair(strAddNode, vservNode));
317 else
319 UniValue obj(UniValue::VOBJ);
320 obj.push_back(Pair("addednode", strAddNode));
321 obj.push_back(Pair("connected", false));
322 UniValue addresses(UniValue::VARR);
323 obj.push_back(Pair("addresses", addresses));
327 LOCK(cs_vNodes);
328 for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
330 UniValue obj(UniValue::VOBJ);
331 obj.push_back(Pair("addednode", it->first));
333 UniValue addresses(UniValue::VARR);
334 bool fConnected = false;
335 BOOST_FOREACH(const CService& addrNode, it->second) {
336 bool fFound = false;
337 UniValue node(UniValue::VOBJ);
338 node.push_back(Pair("address", addrNode.ToString()));
339 BOOST_FOREACH(CNode* pnode, vNodes) {
340 if (pnode->addr == addrNode)
342 fFound = true;
343 fConnected = true;
344 node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
345 break;
348 if (!fFound)
349 node.push_back(Pair("connected", "false"));
350 addresses.push_back(node);
352 obj.push_back(Pair("connected", fConnected));
353 obj.push_back(Pair("addresses", addresses));
354 ret.push_back(obj);
357 return ret;
360 UniValue getnettotals(const UniValue& params, bool fHelp)
362 if (fHelp || params.size() > 0)
363 throw runtime_error(
364 "getnettotals\n"
365 "\nReturns information about network traffic, including bytes in, bytes out,\n"
366 "and current time.\n"
367 "\nResult:\n"
368 "{\n"
369 " \"totalbytesrecv\": n, (numeric) Total bytes received\n"
370 " \"totalbytessent\": n, (numeric) Total bytes sent\n"
371 " \"timemillis\": t, (numeric) Total cpu time\n"
372 " \"uploadtarget\":\n"
373 " {\n"
374 " \"timeframe\": n, (numeric) Length of the measuring timeframe in seconds\n"
375 " \"target\": n, (numeric) Target in bytes\n"
376 " \"target_reached\": true|false, (boolean) True if target is reached\n"
377 " \"serve_historical_blocks\": true|false, (boolean) True if serving historical blocks\n"
378 " \"bytes_left_in_cycle\": t, (numeric) Bytes left in current time cycle\n"
379 " \"time_left_in_cycle\": t (numeric) Seconds left in current time cycle\n"
380 " }\n"
381 "}\n"
382 "\nExamples:\n"
383 + HelpExampleCli("getnettotals", "")
384 + HelpExampleRpc("getnettotals", "")
387 UniValue obj(UniValue::VOBJ);
388 obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
389 obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
390 obj.push_back(Pair("timemillis", GetTimeMillis()));
392 UniValue outboundLimit(UniValue::VOBJ);
393 outboundLimit.push_back(Pair("timeframe", CNode::GetMaxOutboundTimeframe()));
394 outboundLimit.push_back(Pair("target", CNode::GetMaxOutboundTarget()));
395 outboundLimit.push_back(Pair("target_reached", CNode::OutboundTargetReached(false)));
396 outboundLimit.push_back(Pair("serve_historical_blocks", !CNode::OutboundTargetReached(true)));
397 outboundLimit.push_back(Pair("bytes_left_in_cycle", CNode::GetOutboundTargetBytesLeft()));
398 outboundLimit.push_back(Pair("time_left_in_cycle", CNode::GetMaxOutboundTimeLeftInCycle()));
399 obj.push_back(Pair("uploadtarget", outboundLimit));
400 return obj;
403 static UniValue GetNetworksInfo()
405 UniValue networks(UniValue::VARR);
406 for(int n=0; n<NET_MAX; ++n)
408 enum Network network = static_cast<enum Network>(n);
409 if(network == NET_UNROUTABLE)
410 continue;
411 proxyType proxy;
412 UniValue obj(UniValue::VOBJ);
413 GetProxy(network, proxy);
414 obj.push_back(Pair("name", GetNetworkName(network)));
415 obj.push_back(Pair("limited", IsLimited(network)));
416 obj.push_back(Pair("reachable", IsReachable(network)));
417 obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()));
418 obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials));
419 networks.push_back(obj);
421 return networks;
424 UniValue getnetworkinfo(const UniValue& params, bool fHelp)
426 if (fHelp || params.size() != 0)
427 throw runtime_error(
428 "getnetworkinfo\n"
429 "Returns an object containing various state info regarding P2P networking.\n"
430 "\nResult:\n"
431 "{\n"
432 " \"version\": xxxxx, (numeric) the server version\n"
433 " \"subversion\": \"/Satoshi:x.x.x/\", (string) the server subversion string\n"
434 " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
435 " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
436 " \"timeoffset\": xxxxx, (numeric) the time offset\n"
437 " \"connections\": xxxxx, (numeric) the number of connections\n"
438 " \"networks\": [ (array) information per network\n"
439 " {\n"
440 " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n"
441 " \"limited\": true|false, (boolean) is the network limited using -onlynet?\n"
442 " \"reachable\": true|false, (boolean) is the network reachable?\n"
443 " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n"
444 " }\n"
445 " ,...\n"
446 " ],\n"
447 " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
448 " \"localaddresses\": [ (array) list of local addresses\n"
449 " {\n"
450 " \"address\": \"xxxx\", (string) network address\n"
451 " \"port\": xxx, (numeric) network port\n"
452 " \"score\": xxx (numeric) relative score\n"
453 " }\n"
454 " ,...\n"
455 " ]\n"
456 " \"warnings\": \"...\" (string) any network warnings (such as alert messages) \n"
457 "}\n"
458 "\nExamples:\n"
459 + HelpExampleCli("getnetworkinfo", "")
460 + HelpExampleRpc("getnetworkinfo", "")
463 LOCK(cs_main);
465 UniValue obj(UniValue::VOBJ);
466 obj.push_back(Pair("version", CLIENT_VERSION));
467 obj.push_back(Pair("subversion", strSubVersion));
468 obj.push_back(Pair("protocolversion",PROTOCOL_VERSION));
469 obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
470 obj.push_back(Pair("timeoffset", GetTimeOffset()));
471 obj.push_back(Pair("connections", (int)vNodes.size()));
472 obj.push_back(Pair("networks", GetNetworksInfo()));
473 obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
474 UniValue localAddresses(UniValue::VARR);
476 LOCK(cs_mapLocalHost);
477 BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
479 UniValue rec(UniValue::VOBJ);
480 rec.push_back(Pair("address", item.first.ToString()));
481 rec.push_back(Pair("port", item.second.nPort));
482 rec.push_back(Pair("score", item.second.nScore));
483 localAddresses.push_back(rec);
486 obj.push_back(Pair("localaddresses", localAddresses));
487 obj.push_back(Pair("warnings", GetWarnings("statusbar")));
488 return obj;
491 UniValue setban(const UniValue& params, bool fHelp)
493 string strCommand;
494 if (params.size() >= 2)
495 strCommand = params[1].get_str();
496 if (fHelp || params.size() < 2 ||
497 (strCommand != "add" && strCommand != "remove"))
498 throw runtime_error(
499 "setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n"
500 "\nAttempts add or remove a IP/Subnet from the banned list.\n"
501 "\nArguments:\n"
502 "1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n"
503 "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n"
504 "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"
505 "4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
506 "\nExamples:\n"
507 + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
508 + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
509 + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400")
512 CSubNet subNet;
513 CNetAddr netAddr;
514 bool isSubnet = false;
516 if (params[0].get_str().find("/") != string::npos)
517 isSubnet = true;
519 if (!isSubnet)
520 netAddr = CNetAddr(params[0].get_str());
521 else
522 subNet = CSubNet(params[0].get_str());
524 if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
525 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
527 if (strCommand == "add")
529 if (isSubnet ? CNode::IsBanned(subNet) : CNode::IsBanned(netAddr))
530 throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
532 int64_t banTime = 0; //use standard bantime if not specified
533 if (params.size() >= 3 && !params[2].isNull())
534 banTime = params[2].get_int64();
536 bool absolute = false;
537 if (params.size() == 4 && params[3].isTrue())
538 absolute = true;
540 isSubnet ? CNode::Ban(subNet, BanReasonManuallyAdded, banTime, absolute) : CNode::Ban(netAddr, BanReasonManuallyAdded, banTime, absolute);
542 //disconnect possible nodes
543 while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr)))
544 bannedNode->fDisconnect = true;
546 else if(strCommand == "remove")
548 if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) ))
549 throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed");
552 DumpBanlist(); //store banlist to disk
553 uiInterface.BannedListChanged();
555 return NullUniValue;
558 UniValue listbanned(const UniValue& params, bool fHelp)
560 if (fHelp || params.size() != 0)
561 throw runtime_error(
562 "listbanned\n"
563 "\nList all banned IPs/Subnets.\n"
564 "\nExamples:\n"
565 + HelpExampleCli("listbanned", "")
566 + HelpExampleRpc("listbanned", "")
569 banmap_t banMap;
570 CNode::GetBanned(banMap);
572 UniValue bannedAddresses(UniValue::VARR);
573 for (banmap_t::iterator it = banMap.begin(); it != banMap.end(); it++)
575 CBanEntry banEntry = (*it).second;
576 UniValue rec(UniValue::VOBJ);
577 rec.push_back(Pair("address", (*it).first.ToString()));
578 rec.push_back(Pair("banned_until", banEntry.nBanUntil));
579 rec.push_back(Pair("ban_created", banEntry.nCreateTime));
580 rec.push_back(Pair("ban_reason", banEntry.banReasonToString()));
582 bannedAddresses.push_back(rec);
585 return bannedAddresses;
588 UniValue clearbanned(const UniValue& params, bool fHelp)
590 if (fHelp || params.size() != 0)
591 throw runtime_error(
592 "clearbanned\n"
593 "\nClear all banned IPs.\n"
594 "\nExamples:\n"
595 + HelpExampleCli("clearbanned", "")
596 + HelpExampleRpc("clearbanned", "")
599 CNode::ClearBanned();
600 DumpBanlist(); //store banlist to disk
601 uiInterface.BannedListChanged();
603 return NullUniValue;