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 vector<CAddress> vAddr = addrman.GetAddr();
50 BOOST_FOREACH(const CAddress &addr, vAddr) {
51 // Don't return addresses older than nCutOff timestamp
52 int64_t nCutOff = GetTime() - (nNodeLifespan * 24 * 60 * 60);
54 if (!addr.IsRoutable() || addr.IsLocal() || addr.nTime > nCutOff)
58 addrManItem.push_back(Pair("address", addr.ToString()));
61 switch(addr.GetNetwork())
76 addrManItem.push_back(Pair("type", strNetType));
77 addrManItem.push_back(Pair("time", (int64_t)addr.nTime));
79 ret.push_back(addrManItem);
85 Value getpeerinfo(const Array& params, bool fHelp)
87 if (fHelp || params.size() != 0)
90 "Returns data about each connected network node.");
92 vector<CNodeStats> vstats;
93 CopyNodeStats(vstats);
97 BOOST_FOREACH(const CNodeStats& stats, vstats) {
100 obj.push_back(Pair("addr", stats.addrName));
101 obj.push_back(Pair("services", strprintf("%08" PRIx64, stats.nServices)));
102 obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend));
103 obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv));
104 obj.push_back(Pair("bytessent", (boost::int64_t)stats.nSendBytes));
105 obj.push_back(Pair("bytesrecv", (boost::int64_t)stats.nRecvBytes));
106 obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected));
107 obj.push_back(Pair("version", stats.nVersion));
108 obj.push_back(Pair("subver", stats.strSubVer));
109 obj.push_back(Pair("inbound", stats.fInbound));
110 obj.push_back(Pair("releasetime", (boost::int64_t)stats.nReleaseTime));
111 obj.push_back(Pair("startingheight", stats.nStartingHeight));
112 obj.push_back(Pair("banscore", stats.nMisbehavior));
114 obj.push_back(Pair("syncnode", true));
121 Value addnode(const Array& params, bool fHelp)
124 if (params.size() == 2)
125 strCommand = params[1].get_str();
126 if (fHelp || params.size() != 2 ||
127 (strCommand != "onetry" && strCommand != "add" && strCommand != "remove"))
129 "addnode <node> <add|remove|onetry>\n"
130 "Attempts add or remove <node> from the addnode list or try a connection to <node> once.");
132 string strNode = params[0].get_str();
134 if (strCommand == "onetry")
137 OpenNetworkConnection(addr, NULL, strNode.c_str());
141 LOCK(cs_vAddedNodes);
142 vector<string>::iterator it = vAddedNodes.begin();
143 for(; it != vAddedNodes.end(); it++)
147 if (strCommand == "add")
149 if (it != vAddedNodes.end())
150 throw JSONRPCError(-23, "Error: Node already added");
151 vAddedNodes.push_back(strNode);
153 else if(strCommand == "remove")
155 if (it == vAddedNodes.end())
156 throw JSONRPCError(-24, "Error: Node has not been added.");
157 vAddedNodes.erase(it);
163 Value getaddednodeinfo(const Array& params, bool fHelp)
165 if (fHelp || params.size() < 1 || params.size() > 2)
167 "getaddednodeinfo <dns> [node]\n"
168 "Returns information about the given added node, or all added nodes\n"
169 "(note that onetry addnodes are not listed here)\n"
170 "If dns is false, only a list of added nodes will be provided,\n"
171 "otherwise connected information will also be available.");
173 bool fDns = params[0].get_bool();
175 list<string> laddedNodes(0);
176 if (params.size() == 1)
178 LOCK(cs_vAddedNodes);
179 BOOST_FOREACH(string& strAddNode, vAddedNodes)
180 laddedNodes.push_back(strAddNode);
184 string strNode = params[1].get_str();
185 LOCK(cs_vAddedNodes);
186 BOOST_FOREACH(string& strAddNode, vAddedNodes)
187 if (strAddNode == strNode)
189 laddedNodes.push_back(strAddNode);
192 if (laddedNodes.size() == 0)
193 throw JSONRPCError(-24, "Error: Node has not been added.");
199 BOOST_FOREACH(string& strAddNode, laddedNodes)
200 ret.push_back(Pair("addednode", strAddNode));
206 list<pair<string, vector<CService> > > laddedAddreses(0);
207 BOOST_FOREACH(string& strAddNode, laddedNodes)
209 vector<CService> vservNode(0);
210 if(Lookup(strAddNode.c_str(), vservNode, GetDefaultPort(), fNameLookup, 0))
211 laddedAddreses.push_back(make_pair(strAddNode, vservNode));
215 obj.push_back(Pair("addednode", strAddNode));
216 obj.push_back(Pair("connected", false));
218 obj.push_back(Pair("addresses", addresses));
223 for (list<pair<string, vector<CService> > >::iterator it = laddedAddreses.begin(); it != laddedAddreses.end(); it++)
226 obj.push_back(Pair("addednode", it->first));
229 bool fConnected = false;
230 BOOST_FOREACH(CService& addrNode, it->second)
234 node.push_back(Pair("address", addrNode.ToString()));
235 BOOST_FOREACH(CNode* pnode, vNodes)
236 if (pnode->addr == addrNode)
240 node.push_back(Pair("connected", pnode->fInbound ? "inbound" : "outbound"));
244 node.push_back(Pair("connected", "false"));
245 addresses.push_back(node);
247 obj.push_back(Pair("connected", fConnected));
248 obj.push_back(Pair("addresses", addresses));
255 extern CCriticalSection cs_mapAlerts;
256 extern map<uint256, CAlert> mapAlerts;
258 // ppcoin: send alert.
259 // There is a known deadlock situation with ThreadMessageHandler
260 // ThreadMessageHandler: holds cs_vSend and acquiring cs_main in SendMessages()
261 // ThreadRPCServer: holds cs_main and acquiring cs_vSend in alert.RelayTo()/PushMessage()/BeginMessage()
262 Value sendalert(const Array& params, bool fHelp)
264 if (fHelp || params.size() < 6)
266 "sendalert <message> <privatekey> <minver> <maxver> <priority> <id> [cancelupto]\n"
267 "<message> is the alert text message\n"
268 "<privatekey> is hex string of alert master private key\n"
269 "<minver> is the minimum applicable internal client version\n"
270 "<maxver> is the maximum applicable internal client version\n"
271 "<priority> is integer priority number\n"
272 "<id> is the alert id\n"
273 "[cancelupto] cancels all alert id's up to this number\n"
274 "Returns true or false.");
279 alert.strStatusBar = params[0].get_str();
280 alert.nMinVer = params[2].get_int();
281 alert.nMaxVer = params[3].get_int();
282 alert.nPriority = params[4].get_int();
283 alert.nID = params[5].get_int();
284 if (params.size() > 6)
285 alert.nCancel = params[6].get_int();
286 alert.nVersion = PROTOCOL_VERSION;
287 alert.nRelayUntil = GetAdjustedTime() + 365*24*60*60;
288 alert.nExpiration = GetAdjustedTime() + 365*24*60*60;
290 CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION);
291 sMsg << (CUnsignedAlert)alert;
292 alert.vchMsg = vector<unsigned char>(sMsg.begin(), sMsg.end());
294 vector<unsigned char> vchPrivKey = ParseHex(params[1].get_str());
295 key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash
296 if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig))
298 "Unable to sign alert, check private key?\n");
299 if(!alert.ProcessAlert())
301 "Failed to process alert.\n");
305 BOOST_FOREACH(CNode* pnode, vNodes)
306 alert.RelayTo(pnode);
310 result.push_back(Pair("strStatusBar", alert.strStatusBar));
311 result.push_back(Pair("nVersion", alert.nVersion));
312 result.push_back(Pair("nMinVer", alert.nMinVer));
313 result.push_back(Pair("nMaxVer", alert.nMaxVer));
314 result.push_back(Pair("nPriority", alert.nPriority));
315 result.push_back(Pair("nID", alert.nID));
316 if (alert.nCancel > 0)
317 result.push_back(Pair("nCancel", alert.nCancel));
321 Value getnettotals(const Array& params, bool fHelp)
323 if (fHelp || params.size() > 0)
326 "Returns information about network traffic, including bytes in, bytes out,\n"
327 "and current time.");
330 obj.push_back(Pair("totalbytesrecv", static_cast< boost::uint64_t>(CNode::GetTotalBytesRecv())));
331 obj.push_back(Pair("totalbytessent", static_cast<boost::uint64_t>(CNode::GetTotalBytesSent())));
332 obj.push_back(Pair("timemillis", static_cast<boost::int64_t>(GetTimeMillis())));