1 // Copyright (c) 2009-2012 Bitcoin Developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 #include "bitcoinrpc.h"
12 using namespace json_spirit;
15 Value getconnectioncount(const Array& params, bool fHelp)
17 if (fHelp || params.size() != 0)
19 "getconnectioncount\n"
20 "Returns the number of connections to other nodes.");
23 return (int)vNodes.size();
26 static void CopyNodeStats(std::vector<CNodeStats>& vstats)
31 vstats.reserve(vNodes.size());
32 BOOST_FOREACH(CNode* pnode, vNodes) {
34 pnode->copyStats(stats);
35 vstats.push_back(stats);
39 Value getaddrmaninfo(const Array& params, bool fHelp)
41 if (fHelp || params.size() != 0)
44 "Returns a dump of addrman data.");
46 // Return a full list of "online" address items
47 vector<CAddress> vAddr = addrman.GetOnlineAddr();
51 BOOST_FOREACH(const CAddress &addr, vAddr) {
52 if (!addr.IsRoutable() || addr.IsLocal())
56 addrManItem.push_back(Pair("address", addr.ToString()));
59 switch(addr.GetNetwork())
62 // strNetType = "tor";
65 // strNetType = "i2p";
75 addrManItem.push_back(Pair("type", strNetType));
76 addrManItem.push_back(Pair("time", (int64_t)addr.nTime));
78 ret.push_back(addrManItem);
84 Value getpeerinfo(const Array& params, bool fHelp)
86 if (fHelp || params.size() != 0)
89 "Returns data about each connected network node.");
91 vector<CNodeStats> vstats;
92 CopyNodeStats(vstats);
96 BOOST_FOREACH(const CNodeStats& stats, vstats) {
99 obj.push_back(Pair("addr", stats.addrName));
100 obj.push_back(Pair("services", strprintf("%08" PRIx64, stats.nServices)));
101 obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend));
102 obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv));
103 obj.push_back(Pair("bytessent", (boost::int64_t)stats.nSendBytes));
104 obj.push_back(Pair("bytesrecv", (boost::int64_t)stats.nRecvBytes));
105 obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected));
106 obj.push_back(Pair("version", stats.nVersion));
107 obj.push_back(Pair("subver", stats.strSubVer));
108 obj.push_back(Pair("inbound", stats.fInbound));
109 obj.push_back(Pair("releasetime", (boost::int64_t)stats.nReleaseTime));
110 obj.push_back(Pair("startingheight", stats.nStartingHeight));
111 obj.push_back(Pair("banscore", stats.nMisbehavior));
113 obj.push_back(Pair("syncnode", true));
120 Value addnode(const Array& params, bool fHelp)
123 if (params.size() == 2)
124 strCommand = params[1].get_str();
125 if (fHelp || params.size() != 2 ||
126 (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
128 "addnode <node> <add|remove|onetry>\n"
129 "Attempts add or remove <node> from the addnode list or try a connection to <node> once.");
131 string strNode = params[0].get_str();
133 if (strCommand == "onetry")
136 OpenNetworkConnection(addr, NULL, strNode.c_str());
140 LOCK(cs_vAddedNodes);
141 vector<string>::iterator it = vAddedNodes.begin();
142 for(; it != vAddedNodes.end(); it++)
146 if (strCommand == "add")
148 if (it != vAddedNodes.end())
149 throw JSONRPCError(-23, "Error: Node already added");
150 vAddedNodes.push_back(strNode);
152 else if(strCommand == "remove")
154 if (it == vAddedNodes.end())
155 throw JSONRPCError(-24, "Error: Node has not been added.");
156 vAddedNodes.erase(it);
162 Value getaddednodeinfo(const Array& params, bool fHelp)
164 if (fHelp || params.size() < 1 || params.size() > 2)
166 "getaddednodeinfo <dns> [node]\n"
167 "Returns information about the given added node, or all added nodes\n"
168 "(note that onetry addnodes are not listed here)\n"
169 "If dns is false, only a list of added nodes will be provided,\n"
170 "otherwise connected information will also be available.");
172 bool fDns = params[0].get_bool();
174 list<string> laddedNodes(0);
175 if (params.size() == 1)
177 LOCK(cs_vAddedNodes);
178 BOOST_FOREACH(string& strAddNode, vAddedNodes)
179 laddedNodes.push_back(strAddNode);
183 string strNode = params[1].get_str();
184 LOCK(cs_vAddedNodes);
185 BOOST_FOREACH(string& strAddNode, vAddedNodes)
186 if (strAddNode == strNode)
188 laddedNodes.push_back(strAddNode);
191 if (laddedNodes.size() == 0)
192 throw JSONRPCError(-24, "Error: Node has not been added.");
198 BOOST_FOREACH(string& strAddNode, laddedNodes)
199 ret.push_back(Pair("addednode", strAddNode));
205 list<pair<string, vector<CService> > > laddedAddreses(0);
206 BOOST_FOREACH(string& strAddNode, laddedNodes)
208 vector<CService> vservNode(0);
209 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
210 laddedAddreses.push_back(make_pair(strAddNode, vservNode));
214 obj.push_back(Pair("addednode", strAddNode));
215 obj.push_back(Pair("connected", false));
217 obj.push_back(Pair("addresses", addresses));
222 for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
225 obj.push_back(Pair("addednode", it->first));
228 bool fConnected = false;
229 BOOST_FOREACH(CService& addrNode, it->second)
233 node.push_back(Pair("address", addrNode.ToString()));
234 BOOST_FOREACH(CNode* pnode, vNodes)
235 if (pnode->addr == addrNode)
239 node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
243 node.push_back(Pair("connected", "false"));
244 addresses.push_back(node);
246 obj.push_back(Pair("connected", fConnected));
247 obj.push_back(Pair("addresses", addresses));
254 extern CCriticalSection cs_mapAlerts;
255 extern map<uint256, CAlert> mapAlerts;
257 // ppcoin: send alert.
258 // There is a known deadlock situation with ThreadMessageHandler
259 // ThreadMessageHandler: holds cs_vSend and acquiring cs_main in SendMessages()
260 // ThreadRPCServer: holds cs_main and acquiring cs_vSend in alert.RelayTo()/PushMessage()/BeginMessage()
261 Value sendalert(const Array& params, bool fHelp)
263 if (fHelp || params.size() < 6)
265 "sendalert <message> <privatekey> <minver> <maxver> <priority> <id> [cancelupto]\n"
266 "<message> is the alert text message\n"
267 "<privatekey> is hex string of alert master private key\n"
268 "<minver> is the minimum applicable internal client version\n"
269 "<maxver> is the maximum applicable internal client version\n"
270 "<priority> is integer priority number\n"
271 "<id> is the alert id\n"
272 "[cancelupto] cancels all alert id's up to this number\n"
273 "Returns true or false.");
278 alert.strStatusBar = params[0].get_str();
279 alert.nMinVer = params[2].get_int();
280 alert.nMaxVer = params[3].get_int();
281 alert.nPriority = params[4].get_int();
282 alert.nID = params[5].get_int();
283 if (params.size() > 6)
284 alert.nCancel = params[6].get_int();
285 alert.nVersion = PROTOCOL_VERSION;
286 alert.nRelayUntil = GetAdjustedTime() + 365*24*60*60;
287 alert.nExpiration = GetAdjustedTime() + 365*24*60*60;
289 CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION);
290 sMsg << (CUnsignedAlert)alert;
291 alert.vchMsg = vector<unsigned char>(sMsg.begin(), sMsg.end());
293 vector<unsigned char> vchPrivKey = ParseHex(params[1].get_str());
294 key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash
295 if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig))
297 "Unable to sign alert, check private key?\n");
298 if(!alert.ProcessAlert())
300 "Failed to process alert.\n");
304 BOOST_FOREACH(CNode* pnode, vNodes)
305 alert.RelayTo(pnode);
309 result.push_back(Pair("strStatusBar", alert.strStatusBar));
310 result.push_back(Pair("nVersion", alert.nVersion));
311 result.push_back(Pair("nMinVer", alert.nMinVer));
312 result.push_back(Pair("nMaxVer", alert.nMaxVer));
313 result.push_back(Pair("nPriority", alert.nPriority));
314 result.push_back(Pair("nID", alert.nID));
315 if (alert.nCancel > 0)
316 result.push_back(Pair("nCancel", alert.nCancel));
320 Value getnettotals(const Array& params, bool fHelp)
322 if (fHelp || params.size() > 0)
325 "Returns information about network traffic, including bytes in, bytes out,\n"
326 "and current time.");
329 obj.push_back(Pair("totalbytesrecv", static_cast< boost::uint64_t>(CNode::GetTotalBytesRecv())));
330 obj.push_back(Pair("totalbytessent", static_cast<boost::uint64_t>(CNode::GetTotalBytesSent())));
331 obj.push_back(Pair("timemillis", static_cast<boost::int64_t>(GetTimeMillis())));