Feathercoin  0.5.0
P2P Digital Currency
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
rpcnet.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2012 Bitcoin Developers
2 // Copyright (c) 2012-2013 PPCoin developers
3 // Copyright (c) 2013 Primecoin developers
4 // Copyright (c) 2013 Feathercoin developers
5 // Distributed under the MIT/X11 software license, see the accompanying
6 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
7 
8 #include "net.h"
9 #include "bitcoinrpc.h"
10 #include "alert.h"
11 #include "base58.h"
12 
13 using namespace json_spirit;
14 using namespace std;
15 
16 Value getconnectioncount(const Array& params, bool fHelp)
17 {
18  if (fHelp || params.size() != 0)
19  throw runtime_error(
20  "getconnectioncount\n"
21  "Returns the number of connections to other nodes.");
22 
23  LOCK(cs_vNodes);
24  return (int)vNodes.size();
25 }
26 
27 static void CopyNodeStats(std::vector<CNodeStats>& vstats)
28 {
29  vstats.clear();
30 
31  LOCK(cs_vNodes);
32  vstats.reserve(vNodes.size());
33  BOOST_FOREACH(CNode* pnode, vNodes) {
35  pnode->copyStats(stats);
36  vstats.push_back(stats);
37  }
38 }
39 
40 Value getpeerinfo(const Array& params, bool fHelp)
41 {
42  if (fHelp || params.size() != 0)
43  throw runtime_error(
44  "getpeerinfo\n"
45  "Returns data about each connected network node.");
46 
47  vector<CNodeStats> vstats;
48  CopyNodeStats(vstats);
49 
50  Array ret;
51 
52  BOOST_FOREACH(const CNodeStats& stats, vstats) {
53  Object obj;
54 
55  obj.push_back(Pair("addr", stats.addrName));
56  obj.push_back(Pair("services", strprintf("%08"PRI64x, stats.nServices)));
57  obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend));
58  obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv));
59  obj.push_back(Pair("bytessent", (boost::int64_t)stats.nSendBytes));
60  obj.push_back(Pair("bytesrecv", (boost::int64_t)stats.nRecvBytes));
61  obj.push_back(Pair("blocksrequested", (boost::int64_t)stats.nBlocksRequested));
62  obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected));
63  obj.push_back(Pair("version", stats.nVersion));
64  // Use the sanitized form of subver here, to avoid tricksy remote peers from
65  // corrupting or modifiying the JSON output by putting special characters in
66  // their ver message.
67  obj.push_back(Pair("subver", stats.cleanSubVer));
68  obj.push_back(Pair("inbound", stats.fInbound));
69  obj.push_back(Pair("startingheight", stats.nStartingHeight));
70  obj.push_back(Pair("banscore", stats.nMisbehavior));
71  if (stats.fSyncNode)
72  obj.push_back(Pair("syncnode", true));
73 
74  ret.push_back(obj);
75  }
76 
77  return ret;
78 }
79 
80 Value addnode(const Array& params, bool fHelp)
81 {
82  string strCommand;
83  if (params.size() == 2)
84  strCommand = params[1].get_str();
85  if (fHelp || params.size() != 2 ||
86  (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
87  throw runtime_error(
88  "addnode <node> <add|remove|onetry>\n"
89  "Attempts add or remove <node> from the addnode list or try a connection to <node> once.");
90 
91  string strNode = params[0].get_str();
92 
93  if (strCommand == "onetry")
94  {
95  CAddress addr;
96  ConnectNode(addr, strNode.c_str());
97  return Value::null;
98  }
99 
101  vector<string>::iterator it = vAddedNodes.begin();
102  for(; it != vAddedNodes.end(); it++)
103  if (strNode == *it)
104  break;
105 
106  if (strCommand == "add")
107  {
108  if (it != vAddedNodes.end())
109  throw JSONRPCError(-23, "Error: Node already added");
110  vAddedNodes.push_back(strNode);
111  }
112  else if(strCommand == "remove")
113  {
114  if (it == vAddedNodes.end())
115  throw JSONRPCError(-24, "Error: Node has not been added.");
116  vAddedNodes.erase(it);
117  }
118 
119  return Value::null;
120 }
121 
122 Value getaddednodeinfo(const Array& params, bool fHelp)
123 {
124  if (fHelp || params.size() < 1 || params.size() > 2)
125  throw runtime_error(
126  "getaddednodeinfo <dns> [node]\n"
127  "Returns information about the given added node, or all added nodes\n"
128  "(note that onetry addnodes are not listed here)\n"
129  "If dns is false, only a list of added nodes will be provided,\n"
130  "otherwise connected information will also be available.");
131 
132  bool fDns = params[0].get_bool();
133 
134  list<string> laddedNodes(0);
135  if (params.size() == 1)
136  {
138  BOOST_FOREACH(string& strAddNode, vAddedNodes)
139  laddedNodes.push_back(strAddNode);
140  }
141  else
142  {
143  string strNode = params[1].get_str();
145  BOOST_FOREACH(string& strAddNode, vAddedNodes)
146  if (strAddNode == strNode)
147  {
148  laddedNodes.push_back(strAddNode);
149  break;
150  }
151  if (laddedNodes.size() == 0)
152  throw JSONRPCError(-24, "Error: Node has not been added.");
153  }
154 
155  if (!fDns)
156  {
157  Object ret;
158  BOOST_FOREACH(string& strAddNode, laddedNodes)
159  ret.push_back(Pair("addednode", strAddNode));
160  return ret;
161  }
162 
163  Array ret;
164 
165  list<pair<string, vector<CService> > > laddedAddreses(0);
166  BOOST_FOREACH(string& strAddNode, laddedNodes)
167  {
168  vector<CService> vservNode(0);
169  if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
170  laddedAddreses.push_back(make_pair(strAddNode, vservNode));
171  else
172  {
173  Object obj;
174  obj.push_back(Pair("addednode", strAddNode));
175  obj.push_back(Pair("connected", false));
176  Array addresses;
177  obj.push_back(Pair("addresses", addresses));
178  }
179  }
180 
181  LOCK(cs_vNodes);
182  for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
183  {
184  Object obj;
185  obj.push_back(Pair("addednode", it->first));
186 
187  Array addresses;
188  bool fConnected = false;
189  BOOST_FOREACH(CService& addrNode, it->second)
190  {
191  bool fFound = false;
192  Object node;
193  node.push_back(Pair("address", addrNode.ToString()));
194  BOOST_FOREACH(CNode* pnode, vNodes)
195  if (pnode->addr == addrNode)
196  {
197  fFound = true;
198  fConnected = true;
199  node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
200  break;
201  }
202  if (!fFound)
203  node.push_back(Pair("connected", "false"));
204  addresses.push_back(node);
205  }
206  obj.push_back(Pair("connected", fConnected));
207  obj.push_back(Pair("addresses", addresses));
208  ret.push_back(obj);
209  }
210 
211  return ret;
212 }
213 
214 // make a public-private key pair (first introduced in ppcoin)
215 Value makekeypair(const Array& params, bool fHelp)
216 {
217  if (fHelp || params.size() > 1)
218  throw runtime_error(
219  "makekeypair [prefix]\n"
220  "Make a public/private key pair.\n"
221  "[prefix] is optional preferred prefix for the public key.\n");
222 
223  string strPrefix = "";
224  if (params.size() > 0)
225  strPrefix = params[0].get_str();
226 
227  CKey key;
228  CPubKey pubkey;
229  int nCount = 0;
230  do
231  {
232  key.MakeNewKey(false);
233  pubkey = key.GetPubKey();
234  nCount++;
235  } while (nCount < 10000 && strPrefix != HexStr(pubkey.begin(), pubkey.end()).substr(0, strPrefix.size()));
236 
237  if (strPrefix != HexStr(pubkey.begin(), pubkey.end()).substr(0, strPrefix.size()))
238  return Value::null;
239 
240  Object result;
241  result.push_back(Pair("PublicKey", HexStr(pubkey.begin(), pubkey.end())));
242  result.push_back(Pair("PrivateKey", CBitcoinSecret(key).ToString()));
243  return result;
244 }
245 
246 
247 // Send alert (first introduced in ppcoin)
248 // There is a known deadlock situation with ThreadMessageHandler
249 // ThreadMessageHandler: holds cs_vSend and acquiring cs_main in SendMessages()
250 // ThreadRPCServer: holds cs_main and acquiring cs_vSend in alert.RelayTo()/PushMessage()/BeginMessage()
251 Value sendalert(const Array& params, bool fHelp)
252 {
253  if (fHelp || params.size() < 6)
254  throw runtime_error(
255  "sendalert <message> <privatekey> <minver> <maxver> <priority> <id> [cancelupto]\n"
256  "<message> is the alert text message\n"
257  "<privatekey> is base58 hex string of alert master private key\n"
258  "<minver> is the minimum applicable internal client version\n"
259  "<maxver> is the maximum applicable internal client version\n"
260  "<priority> is integer priority number\n"
261  "<id> is the alert id\n"
262  "[cancelupto] cancels all alert id's up to this number\n"
263  "Returns true or false.");
264 
265  // Prepare the alert message
266  CAlert alert;
267  alert.strStatusBar = params[0].get_str();
268  alert.nMinVer = params[2].get_int();
269  alert.nMaxVer = params[3].get_int();
270  alert.nPriority = params[4].get_int();
271  alert.nID = params[5].get_int();
272  if (params.size() > 6)
273  alert.nCancel = params[6].get_int();
274  alert.nVersion = PROTOCOL_VERSION;
275  alert.nRelayUntil = GetAdjustedTime() + 365*24*60*60;
276  alert.nExpiration = GetAdjustedTime() + 365*24*60*60;
277 
278  CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION);
279  sMsg << (CUnsignedAlert)alert;
280  alert.vchMsg = vector<unsigned char>(sMsg.begin(), sMsg.end());
281 
282  // Prepare master key and sign alert message
283  CBitcoinSecret vchSecret;
284  if (!vchSecret.SetString(params[1].get_str()))
285  throw runtime_error("Invalid alert master key");
286  CKey key = vchSecret.GetKey(); // if key is not correct openssl may crash
287  if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig))
288  throw runtime_error(
289  "Unable to sign alert, check alert master key?\n");
290 
291  // Process alert
292  if(!alert.ProcessAlert())
293  throw runtime_error(
294  "Failed to process alert.\n");
295 
296  // Relay alert
297  {
298  LOCK(cs_vNodes);
299  BOOST_FOREACH(CNode* pnode, vNodes)
300  alert.RelayTo(pnode);
301  }
302 
303  Object result;
304  result.push_back(Pair("strStatusBar", alert.strStatusBar));
305  result.push_back(Pair("nVersion", alert.nVersion));
306  result.push_back(Pair("nMinVer", alert.nMinVer));
307  result.push_back(Pair("nMaxVer", alert.nMaxVer));
308  result.push_back(Pair("nPriority", alert.nPriority));
309  result.push_back(Pair("nID", alert.nID));
310  if (alert.nCancel > 0)
311  result.push_back(Pair("nCancel", alert.nCancel));
312  return result;
313 }
int nStartingHeight
Definition: net.h:103
#define strprintf(format,...)
Definition: util.h:169
int64 nLastSend
Definition: net.h:96
#define PRI64x
Definition: util.h:53
Value sendalert(const Array &params, bool fHelp)
Definition: rpcnet.cpp:251
const_iterator begin() const
Definition: serialize.h:884
Value addnode(const Array &params, bool fHelp)
Definition: rpcnet.cpp:80
int64 nExpiration
Definition: alert.h:28
CAddress addr
Definition: net.h:178
std::vector< unsigned char > vchMsg
Definition: alert.h:71
uint64 nRecvBytes
Definition: net.h:106
std::string cleanSubVer
Definition: net.h:101
bool Sign(const uint256 &hash, std::vector< unsigned char > &vchSig) const
Definition: key.cpp:321
bool ProcessAlert(bool fThread=true)
Definition: alert.cpp:169
int nVersion
Definition: alert.h:26
Double ended buffer combining vector and stream-like interfaces.
Definition: serialize.h:799
uint64 nSendBytes
Definition: net.h:105
std::string strStatusBar
Definition: alert.h:39
Object JSONRPCError(int code, const string &message)
Definition: bitcoinrpc.cpp:46
vector< std::string > vAddedNodes
Definition: net.cpp:69
int64 nRelayUntil
Definition: alert.h:27
Config::Object_type Object
bool fSyncNode
Definition: net.h:108
vector< CNode * > vNodes
Definition: net.cpp:56
int nVersion
Definition: net.h:100
Definition: net.h:92
int nMisbehavior
Definition: net.h:104
int64 nLastRecv
Definition: net.h:97
bool fInbound
Definition: net.h:189
An alert is a combination of a serialized CUnsignedAlert and a signature.
Definition: alert.h:68
CPubKey GetPubKey() const
Definition: key.cpp:312
#define LOCK(cs)
Definition: sync.h:108
A base58-encoded secret key.
Definition: base58.h:398
A combination of a network address (CNetAddr) and a (TCP) port.
Definition: netbase.h:90
Alerts are for notifying old versions if they become too obsolete and need to upgrade.
Definition: alert.h:23
An encapsulated public key.
Definition: key.h:40
static const Value_impl null
int64 GetAdjustedTime()
Definition: util.cpp:1317
Value getconnectioncount(const Array &params, bool fHelp)
Definition: rpcnet.cpp:16
void MakeNewKey(bool fCompressed)
Definition: key.cpp:285
bool fInbound
Definition: net.h:102
A CService with information about it as peer.
Definition: protocol.h:76
int nMaxVer
Definition: alert.h:33
std::string addrName
Definition: net.h:99
std::string ToString() const
Definition: netbase.cpp:1126
Config::Array_type Array
uint256 Hash(const T1 pbegin, const T1 pend)
Definition: hash.h:16
int64 nTimeConnected
Definition: net.h:98
Value makekeypair(const Array &params, bool fHelp)
Definition: rpcnet.cpp:215
std::vector< unsigned char > vchSig
Definition: alert.h:72
CNode * ConnectNode(CAddress addrConnect, const char *pszDest)
Definition: net.cpp:457
const unsigned char * begin() const
Definition: key.h:89
CCriticalSection cs_vAddedNodes
Definition: net.cpp:70
Value getpeerinfo(const Array &params, bool fHelp)
Definition: rpcnet.cpp:40
bool RelayTo(CNode *pnode) const
Definition: alert.cpp:127
uint64 nBlocksRequested
Definition: net.h:107
int nMinVer
Definition: alert.h:32
bool Lookup(const char *pszName, std::vector< CService > &vAddr, int portDefault, bool fAllowLookup, unsigned int nMaxSolutions)
Definition: netbase.cpp:133
Stats stats
Definition: db_bench.cc:291
Value getaddednodeinfo(const Array &params, bool fHelp)
Definition: rpcnet.cpp:122
signed long long int64_t
Definition: stdint.h:18
int nCancel
Definition: alert.h:30
An encapsulated private key.
Definition: key.h:172
Information about a peer.
Definition: net.h:154
std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
Definition: util.h:292
std::string get_str(std::string::const_iterator begin, std::string::const_iterator end)
void copyStats(CNodeStats &stats)
Definition: net.cpp:607
Config::Pair_type Pair
CCriticalSection cs_vNodes
Definition: net.cpp:57
bool fNameLookup
Definition: netbase.cpp:25
const unsigned char * end() const
Definition: key.h:90
const_iterator end() const
Definition: serialize.h:886
uint64 nServices
Definition: net.h:95
int nPriority
Definition: alert.h:35