Anoncoin  0.9.4
P2P Digital Currency
rpcnet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2014 The Bitcoin developers
2 // Copyright (c) 2013-2014 The Anoncoin Core developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "rpcserver.h"
7 
8 #include "main.h"
9 #include "net.h"
10 #include "netbase.h"
11 #include "protocol.h"
12 #include "sync.h"
13 #include "util.h"
14 #include "version.h"
15 
16 #include <boost/foreach.hpp>
17 #include "json/json_spirit_value.h"
18 /* #include "anoncoinrpc.h" */
19 #include "alert.h"
20 #include "base58.h"
21 
22 using namespace json_spirit;
23 using namespace std;
24 
25 Value getconnectioncount(const Array& params, bool fHelp)
26 {
27  if (fHelp || params.size() != 0)
28  throw runtime_error(
29  "getconnectioncount\n"
30  "\nReturns the number of connections to other nodes.\n"
31  "\nbResult:\n"
32  "n (numeric) The connection count\n"
33  "\nExamples:\n"
34  + HelpExampleCli("getconnectioncount", "")
35  + HelpExampleRpc("getconnectioncount", "")
36  );
37 
38  LOCK(cs_vNodes);
39  return (int)vNodes.size();
40 }
41 
42 Value ping(const Array& params, bool fHelp)
43 {
44  if (fHelp || params.size() != 0)
45  throw runtime_error(
46  "ping\n"
47  "\nRequests that a ping be sent to all other nodes, to measure ping time.\n"
48  "Results provided in getpeerinfo, pingtime and pingwait fields are decimal seconds.\n"
49  "Ping command is handled in queue with all other commands, so it measures processing backlog, not just network ping.\n"
50  "\nExamples:\n"
51  + HelpExampleCli("ping", "")
52  + HelpExampleRpc("ping", "")
53  );
54 
55  // Request that each node send a ping during next message processing pass
56  LOCK(cs_vNodes);
57  BOOST_FOREACH(CNode* pNode, vNodes) {
58  pNode->fPingQueued = true;
59  }
60 
61  return Value::null;
62 }
63 
64 static void CopyNodeStats(std::vector<CNodeStats>& vstats)
65 {
66  vstats.clear();
67 
68  LOCK(cs_vNodes);
69  vstats.reserve(vNodes.size());
70  BOOST_FOREACH(CNode* pnode, vNodes) {
71  CNodeStats stats;
72  pnode->copyStats(stats);
73  vstats.push_back(stats);
74  }
75 }
76 
77 Value getpeerinfo(const Array& params, bool fHelp)
78 {
79  if (fHelp || params.size() != 0)
80  throw runtime_error(
81  "getpeerinfo\n"
82  "\nReturns data about each connected network node as a json array of objects.\n"
83  "\nbResult:\n"
84  "[\n"
85  " {\n"
86  " \"addr\":\"host:port\", (string) The ip address and port of the peer\n"
87  " \"addrlocal\":\"ip:port\", (string) local address\n"
88  " \"services\":\"xxxxxxxxxxxxxxxx\", (string) The services offered\n"
89  " \"lastsend\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last send\n"
90  " \"lastrecv\": ttt, (numeric) The time in seconds since epoch (Jan 1 1970 GMT) of the last receive\n"
91  " \"bytessent\": n, (numeric) The total bytes sent\n"
92  " \"bytesrecv\": n, (numeric) The total bytes received\n"
93  " \"conntime\": ttt, (numeric) The connection time in seconds since epoch (Jan 1 1970 GMT)\n"
94  " \"pingtime\": n, (numeric) ping time\n"
95  " \"pingwait\": n, (numeric) ping wait\n"
96  " \"version\": v, (numeric) The peer version, such as 7001\n"
97  " \"subver\": \"/Satoshi:0.8.5/\", (string) The string version\n"
98  " \"inbound\": true|false, (boolean) Inbound (true) or Outbound (false)\n"
99  " \"startingheight\": n, (numeric) The starting height (block) of the peer\n"
100  " \"banscore\": n, (numeric) The ban score\n"
101  " \"syncnode\": true|false (boolean) if sync node\n"
102  " }\n"
103  " ,...\n"
104  "}\n"
105 
106  "\nExamples:\n"
107  + HelpExampleCli("getpeerinfo", "")
108  + HelpExampleRpc("getpeerinfo", "")
109  );
110 
111  vector<CNodeStats> vstats;
112  CopyNodeStats(vstats);
113 
114  Array ret;
115 
116  BOOST_FOREACH(const CNodeStats& stats, vstats) {
117  Object obj;
118  CNodeStateStats statestats;
119  bool fStateStats = GetNodeStateStats(stats.nodeid, statestats);
120  obj.push_back(Pair("addr", stats.addrName));
121  if (!(stats.addrLocal.empty()))
122  obj.push_back(Pair("addrlocal", stats.addrLocal));
123  obj.push_back(Pair("services", strprintf("%016x", stats.nServices)));
124  obj.push_back(Pair("lastsend", stats.nLastSend));
125  obj.push_back(Pair("lastrecv", stats.nLastRecv));
126  obj.push_back(Pair("bytessent", stats.nSendBytes));
127  obj.push_back(Pair("bytesrecv", stats.nRecvBytes));
128  obj.push_back(Pair("conntime", stats.nTimeConnected));
129  obj.push_back(Pair("pingtime", stats.dPingTime));
130  if (stats.dPingWait > 0.0)
131  obj.push_back(Pair("pingwait", stats.dPingWait));
132  obj.push_back(Pair("version", stats.nVersion));
133  // Use the sanitized form of subver here, to avoid tricksy remote peers from
134  // corrupting or modifiying the JSON output by putting special characters in
135  // their ver message.
136  obj.push_back(Pair("subver", stats.cleanSubVer));
137  obj.push_back(Pair("inbound", stats.fInbound));
138  obj.push_back(Pair("startingheight", stats.nStartingHeight));
139  if (fStateStats) {
140  obj.push_back(Pair("banscore", statestats.nMisbehavior));
141  }
142  obj.push_back(Pair("syncnode", stats.fSyncNode));
143 
144  ret.push_back(obj);
145  }
146 
147  return ret;
148 }
149 
150 Value addnode(const Array& params, bool fHelp)
151 {
152  string strCommand;
153  if (params.size() == 2)
154  strCommand = params[1].get_str();
155  if (fHelp || params.size() != 2 ||
156  (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
157  throw runtime_error(
158  "addnode \"node\" \"add|remove|onetry\"\n"
159  "\nAttempts add or remove a node from the addnode list.\n"
160  "Or try a connection to a node once.\n"
161  "\nArguments:\n"
162  "1. \"node\" (string, required) The node (see getpeerinfo for nodes)\n"
163  "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  "\nExamples:\n"
165  + HelpExampleCli("addnode", "\"192.168.0.6:9333\" \"onetry\"")
166  + HelpExampleRpc("addnode", "\"192.168.0.6:9333\", \"onetry\"")
167  );
168 
169  string strNode = params[0].get_str();
170 
171  if (strCommand == "onetry")
172  {
173  CAddress addr;
174  ConnectNode(addr, strNode.c_str());
175  return Value::null;
176  }
177 
179  vector<string>::iterator it = vAddedNodes.begin();
180  for(; it != vAddedNodes.end(); it++)
181  if (strNode == *it)
182  break;
183 
184  if (strCommand == "add")
185  {
186  if (it != vAddedNodes.end())
187  throw JSONRPCError(RPC_CLIENT_NODE_ALREADY_ADDED, "Error: Node already added");
188  vAddedNodes.push_back(strNode);
189  }
190  else if(strCommand == "remove")
191  {
192  if (it == vAddedNodes.end())
193  throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
194  vAddedNodes.erase(it);
195  }
196 
197  return Value::null;
198 }
199 
200 Value getaddednodeinfo(const Array& params, bool fHelp)
201 {
202  if (fHelp || params.size() < 1 || params.size() > 2)
203  throw runtime_error(
204  "getaddednodeinfo dns ( \"node\" )\n"
205  "\nReturns information about the given added node, or all added nodes\n"
206  "(note that onetry addnodes are not listed here)\n"
207  "If dns is false, only a list of added nodes will be provided,\n"
208  "otherwise connected information will also be available.\n"
209  "\nArguments:\n"
210  "1. dns (boolean, required) If false, only a list of added nodes will be provided, otherwise connected information will also be available.\n"
211  "2. \"node\" (string, optional) If provided, return information about this specific node, otherwise all nodes are returned.\n"
212  "\nResult:\n"
213  "[\n"
214  " {\n"
215  " \"addednode\" : \"192.168.0.201\", (string) The node ip address\n"
216  " \"connected\" : true|false, (boolean) If connected\n"
217  " \"addresses\" : [\n"
218  " {\n"
219  " \"address\" : \"192.168.0.201:9333\", (string) The anoncoin server host and port\n"
220  " \"connected\" : \"outbound\" (string) connection, inbound or outbound\n"
221  " }\n"
222  " ,...\n"
223  " ]\n"
224  " }\n"
225  " ,...\n"
226  "]\n"
227  "\nExamples:\n"
228  + HelpExampleCli("getaddednodeinfo", "true")
229  + HelpExampleCli("getaddednodeinfo", "true \"192.168.0.201\"")
230  + HelpExampleRpc("getaddednodeinfo", "true, \"192.168.0.201\"")
231  );
232 
233  bool fDns = params[0].get_bool();
234 
235  list<string> laddedNodes(0);
236  if (params.size() == 1)
237  {
239  BOOST_FOREACH(string& strAddNode, vAddedNodes)
240  laddedNodes.push_back(strAddNode);
241  }
242  else
243  {
244  string strNode = params[1].get_str();
246  BOOST_FOREACH(string& strAddNode, vAddedNodes)
247  if (strAddNode == strNode)
248  {
249  laddedNodes.push_back(strAddNode);
250  break;
251  }
252  if (laddedNodes.size() == 0)
253  throw JSONRPCError(RPC_CLIENT_NODE_NOT_ADDED, "Error: Node has not been added.");
254  }
255 
256  Array ret;
257  if (!fDns)
258  {
259  BOOST_FOREACH(string& strAddNode, laddedNodes)
260  {
261  Object obj;
262  obj.push_back(Pair("addednode", strAddNode));
263  ret.push_back(obj);
264  }
265  return ret;
266  }
267 
268  list<pair<string, vector<CService> > > laddedAddreses(0);
269  BOOST_FOREACH(string& strAddNode, laddedNodes)
270  {
271  vector<CService> vservNode(0);
272  if(Lookup(strAddNode.c_str(), vservNode, Params().GetDefaultPort(), fNameLookup, 0))
273  laddedAddreses.push_back(make_pair(strAddNode, vservNode));
274  else
275  {
276  Object obj;
277  obj.push_back(Pair("addednode", strAddNode));
278  obj.push_back(Pair("connected", false));
279  Array addresses;
280  obj.push_back(Pair("addresses", addresses));
281  }
282  }
283 
284  LOCK(cs_vNodes);
285  for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
286  {
287  Object obj;
288  obj.push_back(Pair("addednode", it->first));
289 
290  Array addresses;
291  bool fConnected = false;
292  BOOST_FOREACH(CService& addrNode, it->second)
293  {
294  bool fFound = false;
295  Object node;
296  node.push_back(Pair("address", addrNode.ToString()));
297  BOOST_FOREACH(CNode* pnode, vNodes)
298  if (pnode->addr == addrNode)
299  {
300  fFound = true;
301  fConnected = true;
302  node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
303  break;
304  }
305  if (!fFound)
306  node.push_back(Pair("connected", "false"));
307  addresses.push_back(node);
308  }
309  obj.push_back(Pair("connected", fConnected));
310  obj.push_back(Pair("addresses", addresses));
311  ret.push_back(obj);
312  }
313 
314  return ret;
315 }
316 
317 Value getnettotals(const Array& params, bool fHelp)
318 {
319  if (fHelp || params.size() > 0)
320  throw runtime_error(
321  "getnettotals\n"
322  "\nReturns information about network traffic, including bytes in, bytes out,\n"
323  "and current time.\n"
324  "\nResult:\n"
325  "{\n"
326  " \"totalbytesrecv\": n, (numeric) Total bytes received\n"
327  " \"totalbytessent\": n, (numeric) Total bytes sent\n"
328  " \"timemillis\": t (numeric) Total cpu time\n"
329  "}\n"
330  "\nExamples:\n"
331  + HelpExampleCli("getnettotals", "")
332  + HelpExampleRpc("getnettotals", "")
333  );
334 
335  Object obj;
336  obj.push_back(Pair("totalbytesrecv", CNode::GetTotalBytesRecv()));
337  obj.push_back(Pair("totalbytessent", CNode::GetTotalBytesSent()));
338  obj.push_back(Pair("timemillis", GetTimeMillis()));
339  return obj;
340 }
341 
342 static Array GetNetworksInfo()
343 {
344  Array networks;
345  for(int n=0; n<NET_MAX; ++n)
346  {
347  enum Network network = static_cast<enum Network>(n);
348  if(network == NET_UNROUTABLE)
349  continue;
350  proxyType proxy;
351  Object obj;
352  GetProxy(network, proxy);
353  obj.push_back(Pair("name", GetNetworkName(network)));
354  obj.push_back(Pair("limited", IsLimited(network)));
355  obj.push_back(Pair("reachable", IsReachable(network)));
356  obj.push_back(Pair("proxy", proxy.IsValid() ? proxy.ToStringIPPort() : string()));
357  networks.push_back(obj);
358  }
359  return networks;
360 }
361 
362 Value getnetworkinfo(const Array& params, bool fHelp)
363 {
364  if (fHelp || params.size() != 0)
365  throw runtime_error(
366  "getnetworkinfo\n"
367  "Returns an object containing various state info regarding P2P networking.\n"
368  "\nResult:\n"
369  "{\n"
370  " \"version\": xxxxx, (numeric) the server version\n"
371  " \"protocolversion\": xxxxx, (numeric) the protocol version\n"
372  " \"localservices\": \"xxxxxxxxxxxxxxxx\", (string) the services we offer to the network\n"
373  " \"timeoffset\": xxxxx, (numeric) the time offset\n"
374  " \"connections\": xxxxx, (numeric) the number of connections\n"
375  " \"networks\": [ (array) information per network\n"
376  " \"name\": \"xxx\", (string) network (ipv4, ipv6 or onion)\n"
377  " \"limited\": xxx, (boolean) is the network limited using -onlynet?\n"
378  " \"reachable\": xxx, (boolean) is the network reachable?\n"
379  " \"proxy\": \"host:port\" (string) the proxy that is used for this network, or empty if none\n"
380  " },\n"
381  " ],\n"
382  " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n"
383  " \"localaddresses\": [, (array) list of local addresses\n"
384  " \"address\": \"xxxx\", (string) network address\n"
385  " \"port\": xxx, (numeric) network port\n"
386  " \"score\": xxx (numeric) relative score\n"
387  " ]\n"
388  "}\n"
389  "\nExamples:\n"
390  + HelpExampleCli("getnetworkinfo", "")
391  + HelpExampleRpc("getnetworkinfo", "")
392  );
393 
394  Object obj;
395  obj.push_back(Pair("version", (int)CLIENT_VERSION));
396  obj.push_back(Pair("subversion",
397  FormatSubVersion(CLIENT_NAME, CLIENT_VERSION, std::vector<string>())));
398  obj.push_back(Pair("protocolversion",(int)PROTOCOL_VERSION));
399  obj.push_back(Pair("localservices", strprintf("%016x", nLocalServices)));
400  obj.push_back(Pair("timeoffset", GetTimeOffset()));
401  obj.push_back(Pair("connections", (int)vNodes.size()));
402  obj.push_back(Pair("networks", GetNetworksInfo()));
403  obj.push_back(Pair("relayfee", ValueFromAmount(CTransaction::nMinRelayTxFee)));
404  Array localAddresses;
405  {
407  BOOST_FOREACH(const PAIRTYPE(CNetAddr, LocalServiceInfo) &item, mapLocalHost)
408  {
409  Object rec;
410  rec.push_back(Pair("address", item.first.ToString()));
411  rec.push_back(Pair("port", item.second.nPort));
412  rec.push_back(Pair("score", item.second.nScore));
413  localAddresses.push_back(rec);
414  }
415  }
416  obj.push_back(Pair("localaddresses", localAddresses));
417  return obj;
418 }
419 
420 Value makekeypair(const Array& params, bool fHelp)
421 {
422  if (fHelp || params.size() > 1)
423  throw runtime_error(
424  "makekeypair [prefix]\n"
425  "Make a public/private key pair.\n"
426  "[prefix] is optional preferred prefix for the public key.\n");
427 
428  string strPrefix = "";
429  if (params.size() > 0)
430  strPrefix = params[0].get_str();
431 
432  CKey key;
433  CPubKey pubkey;
434  int nCount = 0;
435  do
436  {
437  key.MakeNewKey(false);
438  pubkey = key.GetPubKey();
439  nCount++;
440  } while (nCount < 10000 && strPrefix != HexStr(pubkey.begin(), pubkey.end()).substr(0, strPrefix.size()));
441 
442  if (strPrefix != HexStr(pubkey.begin(), pubkey.end()).substr(0, strPrefix.size()))
443  return Value::null;
444 
445  Object result;
446  result.push_back(Pair("PublicKey", HexStr(pubkey.begin(), pubkey.end())));
447  result.push_back(Pair("PrivateKey", CAnoncoinSecret(key).ToString()));
448  return result;
449 }
static uint64_t GetTotalBytesRecv()
Definition: net.cpp:2157
int nStartingHeight
Definition: net.h:171
Value addnode(const Array &params, bool fHelp)
Definition: rpcnet.cpp:150
int nMisbehavior
Definition: main.h:207
#define PAIRTYPE(t1, t2)
Definition: util.h:49
CAddress addr
Definition: net.h:245
#define strprintf
Definition: tinyformat.h:1011
std::string ToStringIPPort() const
Definition: netbase.cpp:1314
std::string HelpExampleRpc(string methodname, string args)
Definition: rpcserver.cpp:903
std::string cleanSubVer
Definition: net.h:169
int64_t nTimeConnected
Definition: net.h:166
Object JSONRPCError(int code, const string &message)
Value getnetworkinfo(const Array &params, bool fHelp)
Definition: rpcnet.cpp:362
vector< std::string > vAddedNodes
Definition: net.cpp:87
bool fSyncNode
Definition: net.h:174
vector< CNode * > vNodes
Definition: net.cpp:74
int nVersion
Definition: net.h:168
bool fPingQueued
Definition: net.h:307
Value ValueFromAmount(int64_t amount)
Definition: rpcserver.cpp:100
bool fInbound
Definition: net.h:256
int GetDefaultPort() const
Definition: chainparams.h:79
bool IsValid() const
Definition: netbase.cpp:816
CPubKey GetPubKey() const
Definition: key.cpp:397
#define LOCK(cs)
Definition: sync.h:157
A base58-encoded secret key.
Definition: base58.h:122
CCriticalSection cs_mapLocalHost
Definition: net.cpp:53
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netbase.h:109
An encapsulated public key.
Definition: key.h:43
Value getconnectioncount(const Array &params, bool fHelp)
Definition: rpcnet.cpp:25
void MakeNewKey(bool fCompressed)
Definition: key.cpp:362
bool fInbound
Definition: net.h:170
A CService with information about it as peer.
Definition: protocol.h:91
uint64_t nRecvBytes
Definition: net.h:173
double dPingTime
Definition: net.h:175
std::string addrName
Definition: net.h:167
std::string ToString() const
Definition: netbase.cpp:1325
Value makekeypair(const Array &params, bool fHelp)
Definition: rpcnet.cpp:420
int64_t GetTimeMillis()
Definition: util.h:304
uint64_t nSendBytes
Definition: net.h:172
const std::string CLIENT_NAME
static uint64_t GetTotalBytesSent()
Definition: net.cpp:2163
map< CNetAddr, LocalServiceInfo > mapLocalHost
Definition: net.cpp:54
CNode * ConnectNode(CAddress addrConnect, const char *pszDest)
Definition: net.cpp:457
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats)
Get statistics from node state.
Definition: main.cpp:344
Value getnettotals(const Array &params, bool fHelp)
Definition: rpcnet.cpp:317
const unsigned char * begin() const
Definition: key.h:92
CCriticalSection cs_vAddedNodes
Definition: net.cpp:88
Network
Definition: netbase.h:29
Value getpeerinfo(const Array &params, bool fHelp)
Definition: rpcnet.cpp:77
uint64_t nLocalServices
Definition: net.cpp:71
IP address (IPv6, or IPv4 using mapped IPv6 range (::FFFF:0:0/96))
Definition: netbase.h:45
bool IsReachable(enum Network net)
check whether a given network is one we can probably connect to
Definition: net.cpp:304
int nScore
Definition: net.h:152
const CChainParams & Params()
Return the currently selected parameters.
std::string addrLocal
Definition: net.h:177
int64_t GetTimeOffset()
Definition: util.cpp:1235
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:225
std::string FormatSubVersion(const std::string &name, int nClientVersion, const std::vector< std::string > &comments)
Format the subversion field according to BIP 14 spec (https://github.com/bitcoin/bips/blob/master/bip...
uint64_t nServices
Definition: net.h:163
Value getaddednodeinfo(const Array &params, bool fHelp)
Definition: rpcnet.cpp:200
static int64_t nMinRelayTxFee
Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) ...
Definition: core.h:183
bool GetProxy(enum Network net, proxyType &proxyInfoOut)
Definition: netbase.cpp:476
std::string HelpExampleCli(string methodname, string args)
Definition: rpcserver.cpp:899
An encapsulated private key.
Definition: key.h:180
std::string GetNetworkName(enum Network net)
Definition: netbase.cpp:63
Information about a peer.
Definition: net.h:223
Value ping(const Array &params, bool fHelp)
Definition: rpcnet.cpp:42
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
Definition: util.h:256
void copyStats(CNodeStats &stats)
Definition: net.cpp:596
double dPingWait
Definition: net.h:176
CCriticalSection cs_vNodes
Definition: net.cpp:75
bool fNameLookup
Definition: netbase.cpp:48
const unsigned char * end() const
Definition: key.h:93
int64_t nLastSend
Definition: net.h:164
bool IsLimited(enum Network net)
Definition: net.cpp:270
NodeId nodeid
Definition: net.h:162
int64_t nLastRecv
Definition: net.h:165