#include <boost/foreach.hpp>
-#include "json/json_spirit_value.h"
+#include <univalue.h>
-using namespace json_spirit;
using namespace std;
-Value getconnectioncount(const Array& params, bool fHelp)
+UniValue getconnectioncount(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
+ HelpExampleRpc("getconnectioncount", "")
);
- LOCK(cs_vNodes);
+ LOCK2(cs_main, cs_vNodes);
+
return (int)vNodes.size();
}
-Value ping(const Array& params, bool fHelp)
+UniValue ping(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
);
// Request that each node send a ping during next message processing pass
- LOCK(cs_vNodes);
+ LOCK2(cs_main, cs_vNodes);
+
BOOST_FOREACH(CNode* pNode, vNodes) {
pNode->fPingQueued = true;
}
- return Value::null;
+ return NullUniValue;
}
static void CopyNodeStats(std::vector<CNodeStats>& vstats)
}
}
-Value getpeerinfo(const Array& params, bool fHelp)
+UniValue getpeerinfo(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
" \"timeoffset\": ttt, (numeric) The time offset in seconds\n"
" \"pingtime\": n, (numeric) ping time\n"
" \"pingwait\": n, (numeric) ping wait\n"
- " \"version\": v, (numeric) The peer version, such as 7001\n"
- " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
+ " \"version\": v, (numeric) The peer version, such as 170002\n"
+ " \"subver\": \"/MagicBean:x.y.z[-v]/\", (string) The string version\n"
" \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
" \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
" \"banscore\": n, (numeric) The ban score\n"
+ HelpExampleRpc("getpeerinfo", "")
);
+ LOCK(cs_main);
+
vector<CNodeStats> vstats;
CopyNodeStats(vstats);
- Array ret;
+ UniValue ret(UniValue::VARR);
BOOST_FOREACH(const CNodeStats& stats, vstats) {
- Object obj;
+ UniValue obj(UniValue::VOBJ);
CNodeStateStats statestats;
bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
obj.push_back(Pair("id", stats.nodeid));
obj.push_back(Pair("banscore", statestats.nMisbehavior));
obj.push_back(Pair("synced_headers", statestats.nSyncHeight));
obj.push_back(Pair("synced_blocks", statestats.nCommonHeight));
- Array heights;
+ UniValue heights(UniValue::VARR);
BOOST_FOREACH(int height, statestats.vHeightInFlight) {
heights.push_back(height);
}
return ret;
}
-Value addnode(const Array& params, bool fHelp)
+UniValue addnode(const UniValue& params, bool fHelp)
{
string strCommand;
if (params.size() == 2)
"1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
"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"
"\nExamples:\n"
- + HelpExampleCli("addnode", "\"192.168.0.6:8333\" \"onetry\"")
- + HelpExampleRpc("addnode", "\"192.168.0.6:8333\", \"onetry\"")
+ + HelpExampleCli("addnode", "\"192.168.0.6:8233\" \"onetry\"")
+ + HelpExampleRpc("addnode", "\"192.168.0.6:8233\", \"onetry\"")
);
string strNode = params[0].get_str();
{
CAddress addr;
OpenNetworkConnection(addr, NULL, strNode.c_str());
- return Value::null;
+ return NullUniValue;
}
LOCK(cs_vAddedNodes);
vAddedNodes.erase(it);
}
- return Value::null;
+ return NullUniValue;
}
-Value getaddednodeinfo(const Array& params, bool fHelp)
+UniValue disconnectnode(const UniValue& params, bool fHelp)
+{
+ if (fHelp || params.size() != 1)
+ throw runtime_error(
+ "disconnectnode \"node\" \n"
+ "\nImmediately disconnects from the specified node.\n"
+ "\nArguments:\n"
+ "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
+ "\nExamples:\n"
+ + HelpExampleCli("disconnectnode", "\"192.168.0.6:8233\"")
+ + HelpExampleRpc("disconnectnode", "\"192.168.0.6:8233\"")
+ );
+
+ CNode* pNode = FindNode(params[0].get_str());
+ if (pNode == NULL)
+ throw JSONRPCError(RPC_CLIENT_NODE_NOT_CONNECTED, "Node not found in connected nodes");
+
+ pNode->fDisconnect = true;
+
+ return NullUniValue;
+}
+
+UniValue getaddednodeinfo(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
" \"connected\" : true|false, (boolean) If connected\n"
" \"addresses\" : [\n"
" {\n"
- " \"address\" : \"192.168.0.201:8333\", (string) The bitcoin server host and port\n"
+ " \"address\" : \"192.168.0.201:8233\", (string) The bitcoin server host and port\n"
" \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
" }\n"
" ,...\n"
if (params.size() == 1)
{
LOCK(cs_vAddedNodes);
- BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ BOOST_FOREACH(const std::string& strAddNode, vAddedNodes)
laddedNodes.push_back(strAddNode);
}
else
{
string strNode = params[1].get_str();
LOCK(cs_vAddedNodes);
- BOOST_FOREACH(string& strAddNode, vAddedNodes)
+ BOOST_FOREACH(const std::string& strAddNode, vAddedNodes) {
if (strAddNode == strNode)
{
laddedNodes.push_back(strAddNode);
break;
}
+ }
if (laddedNodes.size() == 0)
throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
}
- Array ret;
+ UniValue ret(UniValue::VARR);
if (!fDns)
{
- BOOST_FOREACH(string& strAddNode, laddedNodes)
- {
- Object obj;
+ BOOST_FOREACH (const std::string& strAddNode, laddedNodes) {
+ UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("addednode", strAddNode));
ret.push_back(obj);
}
}
list<pair<string, vector<CService> > > laddedAddreses(0);
- BOOST_FOREACH(string& strAddNode, laddedNodes)
- {
+ BOOST_FOREACH(const std::string& strAddNode, laddedNodes) {
vector<CService> vservNode(0);
if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
laddedAddreses.push_back(make_pair(strAddNode, vservNode));
else
{
- Object obj;
+ UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("addednode", strAddNode));
obj.push_back(Pair("connected", false));
- Array addresses;
+ UniValue addresses(UniValue::VARR);
obj.push_back(Pair("addresses", addresses));
}
}
LOCK(cs_vNodes);
for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
{
- Object obj;
+ UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("addednode", it->first));
- Array addresses;
+ UniValue addresses(UniValue::VARR);
bool fConnected = false;
- BOOST_FOREACH(CService& addrNode, it->second)
- {
+ BOOST_FOREACH(const CService& addrNode, it->second) {
bool fFound = false;
- Object node;
+ UniValue node(UniValue::VOBJ);
node.push_back(Pair("address", addrNode.ToString()));
- BOOST_FOREACH(CNode* pnode, vNodes)
+ BOOST_FOREACH(CNode* pnode, vNodes) {
if (pnode->addr == addrNode)
{
fFound = true;
node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
break;
}
+ }
if (!fFound)
node.push_back(Pair("connected", "false"));
addresses.push_back(node);
return ret;
}
-Value getnettotals(const Array& params, bool fHelp)
+UniValue getnettotals(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() > 0)
throw runtime_error(
+ HelpExampleRpc("getnettotals", "")
);
- Object obj;
+ UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
obj.push_back(Pair("timemillis", GetTimeMillis()));
return obj;
}
-static Array GetNetworksInfo()
+static UniValue GetNetworksInfo()
{
- Array networks;
+ UniValue networks(UniValue::VARR);
for(int n=0; n<NET_MAX; ++n)
{
enum Network network = static_cast<enum Network>(n);
if(network == NET_UNROUTABLE)
continue;
proxyType proxy;
- Object obj;
+ UniValue obj(UniValue::VOBJ);
GetProxy(network, proxy);
obj.push_back(Pair("name", GetNetworkName(network)));
obj.push_back(Pair("limited", IsLimited(network)));
obj.push_back(Pair("reachable", IsReachable(network)));
- obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.ToStringIPPort() : string()));
+ obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.proxy.ToStringIPPort() : string()));
+ obj.push_back(Pair("proxy_randomize_credentials", proxy.randomize_credentials));
networks.push_back(obj);
}
return networks;
}
-Value getnetworkinfo(const Array& params, bool fHelp)
+UniValue getnetworkinfo(const UniValue& params, bool fHelp)
{
if (fHelp || params.size() != 0)
throw runtime_error(
"\nResult:\n"
"{\n"
" \"version\": xxxxx, (numeric) the server version\n"
- " \"subversion\": \"/Satoshi:x.x.x/\", (string) the server subversion string\n"
+ " \"subversion\": \"/MagicBean:x.y.z[-v]/\", (string) the server subversion string\n"
" \"protocolversion\": xxxxx, (numeric) the protocol version\n"
" \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
" \"timeoffset\": xxxxx, (numeric) the time offset\n"
" }\n"
" ,...\n"
" ],\n"
- " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
+ " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n"
" \"localaddresses\": [ (array) list of local addresses\n"
" {\n"
" \"address\": \"xxxx\", (string) network address\n"
" }\n"
" ,...\n"
" ]\n"
+ " \"warnings\": \"...\" (string) any network warnings (such as alert messages) \n"
"}\n"
"\nExamples:\n"
+ HelpExampleCli("getnetworkinfo", "")
+ HelpExampleRpc("getnetworkinfo", "")
);
- Object obj;
+ LOCK(cs_main);
+
+ UniValue obj(UniValue::VOBJ);
obj.push_back(Pair("version", CLIENT_VERSION));
obj.push_back(Pair("subversion",
FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>())));
obj.push_back(Pair("connections", (int)vNodes.size()));
obj.push_back(Pair("networks", GetNetworksInfo()));
obj.push_back(Pair("relayfee", ValueFromAmount(::minRelayTxFee.GetFeePerK())));
- Array localAddresses;
+ UniValue localAddresses(UniValue::VARR);
{
LOCK(cs_mapLocalHost);
BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
{
- Object rec;
+ UniValue rec(UniValue::VOBJ);
rec.push_back(Pair("address", item.first.ToString()));
rec.push_back(Pair("port", item.second.nPort));
rec.push_back(Pair("score", item.second.nScore));
}
}
obj.push_back(Pair("localaddresses", localAddresses));
+ obj.push_back(Pair("warnings", GetWarnings("statusbar")));
return obj;
}
+
+UniValue setban(const UniValue& params, bool fHelp)
+{
+ string strCommand;
+ if (params.size() >= 2)
+ strCommand = params[1].get_str();
+ if (fHelp || params.size() < 2 ||
+ (strCommand != "add" && strCommand != "remove"))
+ throw runtime_error(
+ "setban \"ip(/netmask)\" \"add|remove\" (bantime) (absolute)\n"
+ "\nAttempts add or remove a IP/Subnet from the banned list.\n"
+ "\nArguments:\n"
+ "1. \"ip(/netmask)\" (string, required) The IP/Subnet (see getpeerinfo for nodes ip) with a optional netmask (default is /32 = single ip)\n"
+ "2. \"command\" (string, required) 'add' to add a IP/Subnet to the list, 'remove' to remove a IP/Subnet from the list\n"
+ "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"
+ "4. \"absolute\" (boolean, optional) If set, the bantime must be a absolute timestamp in seconds since epoch (Jan 1 1970 GMT)\n"
+ "\nExamples:\n"
+ + HelpExampleCli("setban", "\"192.168.0.6\" \"add\" 86400")
+ + HelpExampleCli("setban", "\"192.168.0.0/24\" \"add\"")
+ + HelpExampleRpc("setban", "\"192.168.0.6\", \"add\" 86400")
+ );
+
+ CSubNet subNet;
+ CNetAddr netAddr;
+ bool isSubnet = false;
+
+ if (params[0].get_str().find("/") != string::npos)
+ isSubnet = true;
+
+ if (!isSubnet)
+ netAddr = CNetAddr(params[0].get_str());
+ else
+ subNet = CSubNet(params[0].get_str());
+
+ if (! (isSubnet ? subNet.IsValid() : netAddr.IsValid()) )
+ throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Invalid IP/Subnet");
+
+ if (strCommand == "add")
+ {
+ if (isSubnet ? CNode::IsBanned(subNet) : CNode::IsBanned(netAddr))
+ throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: IP/Subnet already banned");
+
+ int64_t banTime = 0; //use standard bantime if not specified
+ if (params.size() >= 3 && !params[2].isNull())
+ banTime = params[2].get_int64();
+
+ bool absolute = false;
+ if (params.size() == 4 && params[3].isTrue())
+ absolute = true;
+
+ isSubnet ? CNode::Ban(subNet, banTime, absolute) : CNode::Ban(netAddr, banTime, absolute);
+
+ //disconnect possible nodes
+ while(CNode *bannedNode = (isSubnet ? FindNode(subNet) : FindNode(netAddr)))
+ bannedNode->fDisconnect = true;
+ }
+ else if(strCommand == "remove")
+ {
+ if (!( isSubnet ? CNode::Unban(subNet) : CNode::Unban(netAddr) ))
+ throw JSONRPCError(RPC_MISC_ERROR, "Error: Unban failed");
+ }
+
+ return NullUniValue;
+}
+
+UniValue listbanned(const UniValue& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "listbanned\n"
+ "\nList all banned IPs/Subnets.\n"
+ "\nExamples:\n"
+ + HelpExampleCli("listbanned", "")
+ + HelpExampleRpc("listbanned", "")
+ );
+
+ std::map<CSubNet, int64_t> banMap;
+ CNode::GetBanned(banMap);
+
+ UniValue bannedAddresses(UniValue::VARR);
+ for (std::map<CSubNet, int64_t>::iterator it = banMap.begin(); it != banMap.end(); it++)
+ {
+ UniValue rec(UniValue::VOBJ);
+ rec.push_back(Pair("address", (*it).first.ToString()));
+ rec.push_back(Pair("banned_until", (*it).second));
+ bannedAddresses.push_back(rec);
+ }
+
+ return bannedAddresses;
+}
+
+UniValue clearbanned(const UniValue& params, bool fHelp)
+{
+ if (fHelp || params.size() != 0)
+ throw runtime_error(
+ "clearbanned\n"
+ "\nClear all banned IPs.\n"
+ "\nExamples:\n"
+ + HelpExampleCli("clearbanned", "")
+ + HelpExampleRpc("clearbanned", "")
+ );
+
+ CNode::ClearBanned();
+
+ return NullUniValue;
+}