Add bytessent, bytesrecv and syncnode to getpeerinfo
[novacoin.git] / src / rpcnet.cpp
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.
4
5 #include "net.h"
6 #include "bitcoinrpc.h"
7 #include "alert.h"
8 #include "wallet.h"
9 #include "db.h"
10 #include "walletdb.h"
11
12 using namespace json_spirit;
13 using namespace std;
14
15 Value getconnectioncount(const Array& params, bool fHelp)
16 {
17     if (fHelp || params.size() != 0)
18         throw runtime_error(
19             "getconnectioncount\n"
20             "Returns the number of connections to other nodes.");
21
22     LOCK(cs_vNodes);
23     return (int)vNodes.size();
24 }
25
26 static void CopyNodeStats(std::vector<CNodeStats>& vstats)
27 {
28     vstats.clear();
29
30     LOCK(cs_vNodes);
31     vstats.reserve(vNodes.size());
32     BOOST_FOREACH(CNode* pnode, vNodes) {
33         CNodeStats stats;
34         pnode->copyStats(stats);
35         vstats.push_back(stats);
36     }
37 }
38
39 Value getpeerinfo(const Array& params, bool fHelp)
40 {
41     if (fHelp || params.size() != 0)
42         throw runtime_error(
43             "getpeerinfo\n"
44             "Returns data about each connected network node.");
45
46     vector<CNodeStats> vstats;
47     CopyNodeStats(vstats);
48
49     Array ret;
50
51     BOOST_FOREACH(const CNodeStats& stats, vstats) {
52         Object obj;
53
54         obj.push_back(Pair("addr", stats.addrName));
55         obj.push_back(Pair("services", strprintf("%08"PRI64x, stats.nServices)));
56         obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend));
57         obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv));
58         obj.push_back(Pair("bytessent", (boost::int64_t)stats.nSendBytes));
59         obj.push_back(Pair("bytesrecv", (boost::int64_t)stats.nRecvBytes));
60         obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected));
61         obj.push_back(Pair("version", stats.nVersion));
62         obj.push_back(Pair("subver", stats.strSubVer));
63         obj.push_back(Pair("inbound", stats.fInbound));
64         obj.push_back(Pair("releasetime", (boost::int64_t)stats.nReleaseTime));
65         obj.push_back(Pair("startingheight", stats.nStartingHeight));
66         obj.push_back(Pair("banscore", stats.nMisbehavior));
67         if (stats.fSyncNode)
68             obj.push_back(Pair("syncnode", true));
69         ret.push_back(obj);
70     }
71
72     return ret;
73 }
74
75 extern CCriticalSection cs_mapAlerts;
76 extern map<uint256, CAlert> mapAlerts;
77  
78 // ppcoin: send alert.  
79 // There is a known deadlock situation with ThreadMessageHandler
80 // ThreadMessageHandler: holds cs_vSend and acquiring cs_main in SendMessages()
81 // ThreadRPCServer: holds cs_main and acquiring cs_vSend in alert.RelayTo()/PushMessage()/BeginMessage()
82 Value sendalert(const Array& params, bool fHelp)
83 {
84     if (fHelp || params.size() < 6)
85         throw runtime_error(
86             "sendalert <message> <privatekey> <minver> <maxver> <priority> <id> [cancelupto]\n"
87             "<message> is the alert text message\n"
88             "<privatekey> is hex string of alert master private key\n"
89             "<minver> is the minimum applicable internal client version\n"
90             "<maxver> is the maximum applicable internal client version\n"
91             "<priority> is integer priority number\n"
92             "<id> is the alert id\n"
93             "[cancelupto] cancels all alert id's up to this number\n"
94             "Returns true or false.");
95
96     CAlert alert;
97     CKey key;
98
99     alert.strStatusBar = params[0].get_str();
100     alert.nMinVer = params[2].get_int();
101     alert.nMaxVer = params[3].get_int();
102     alert.nPriority = params[4].get_int();
103     alert.nID = params[5].get_int();
104     if (params.size() > 6)
105         alert.nCancel = params[6].get_int();
106     alert.nVersion = PROTOCOL_VERSION;
107     alert.nRelayUntil = GetAdjustedTime() + 365*24*60*60;
108     alert.nExpiration = GetAdjustedTime() + 365*24*60*60;
109
110     CDataStream sMsg(SER_NETWORK, PROTOCOL_VERSION);
111     sMsg << (CUnsignedAlert)alert;
112     alert.vchMsg = vector<unsigned char>(sMsg.begin(), sMsg.end());
113
114     vector<unsigned char> vchPrivKey = ParseHex(params[1].get_str());
115     key.SetPrivKey(CPrivKey(vchPrivKey.begin(), vchPrivKey.end())); // if key is not correct openssl may crash
116     if (!key.Sign(Hash(alert.vchMsg.begin(), alert.vchMsg.end()), alert.vchSig))
117         throw runtime_error(
118             "Unable to sign alert, check private key?\n");  
119     if(!alert.ProcessAlert()) 
120         throw runtime_error(
121             "Failed to process alert.\n");
122     // Relay alert
123     {
124         LOCK(cs_vNodes);
125         BOOST_FOREACH(CNode* pnode, vNodes)
126             alert.RelayTo(pnode);
127     }
128
129     Object result;
130     result.push_back(Pair("strStatusBar", alert.strStatusBar));
131     result.push_back(Pair("nVersion", alert.nVersion));
132     result.push_back(Pair("nMinVer", alert.nMinVer));
133     result.push_back(Pair("nMaxVer", alert.nMaxVer));
134     result.push_back(Pair("nPriority", alert.nPriority));
135     result.push_back(Pair("nID", alert.nID));
136     if (alert.nCancel > 0)
137         result.push_back(Pair("nCancel", alert.nCancel));
138     return result;
139 }