From 70ab73a0087cbb0d6b26c9ad58146ae542b1b9be Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 28 Jun 2012 23:18:38 -0400 Subject: [PATCH 1/2] Create new rpcnet module, and move 'getconnectioncount' RPC to it --- bitcoin-qt.pro | 1 + src/bitcoinrpc.cpp | 12 +----------- src/makefile.linux-mingw | 1 + src/makefile.mingw | 1 + src/makefile.osx | 1 + src/makefile.unix | 1 + src/rpcnet.cpp | 21 +++++++++++++++++++++ 7 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 src/rpcnet.cpp diff --git a/bitcoin-qt.pro b/bitcoin-qt.pro index b293bad94..6bfeeff07 100644 --- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -206,6 +206,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/walletmodel.cpp \ src/bitcoinrpc.cpp \ src/rpcdump.cpp \ + src/rpcnet.cpp \ src/qt/overviewpage.cpp \ src/qt/csvmodelwriter.cpp \ src/crypter.cpp \ diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index de6db5398..3c61121da 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -46,6 +46,7 @@ static std::string strRPCUserColonPass; static int64 nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; +extern Value getconnectioncount(const Array& params, bool fHelp); extern Value dumpprivkey(const Array& params, bool fHelp); extern Value importprivkey(const Array& params, bool fHelp); @@ -456,17 +457,6 @@ Value getblockcount(const Array& params, bool fHelp) } -Value getconnectioncount(const Array& params, bool fHelp) -{ - if (fHelp || params.size() != 0) - throw runtime_error( - "getconnectioncount\n" - "Returns the number of connections to other nodes."); - - return (int)vNodes.size(); -} - - Value getdifficulty(const Array& params, bool fHelp) { if (fHelp || params.size() != 0) diff --git a/src/makefile.linux-mingw b/src/makefile.linux-mingw index cd8e97080..5afb5c78a 100644 --- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -60,6 +60,7 @@ OBJS= \ obj/protocol.o \ obj/bitcoinrpc.o \ obj/rpcdump.o \ + obj/rpcnet.o \ obj/script.o \ obj/sync.o \ obj/util.o \ diff --git a/src/makefile.mingw b/src/makefile.mingw index 919be007b..907a15a3f 100644 --- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -57,6 +57,7 @@ OBJS= \ obj/protocol.o \ obj/bitcoinrpc.o \ obj/rpcdump.o \ + obj/rpcnet.o \ obj/script.o \ obj/sync.o \ obj/util.o \ diff --git a/src/makefile.osx b/src/makefile.osx index 972873312..cbb269cef 100644 --- a/src/makefile.osx +++ b/src/makefile.osx @@ -84,6 +84,7 @@ OBJS= \ obj/protocol.o \ obj/bitcoinrpc.o \ obj/rpcdump.o \ + obj/rpcnet.o \ obj/script.o \ obj/sync.o \ obj/util.o \ diff --git a/src/makefile.unix b/src/makefile.unix index 9052891b4..420c7ac3f 100644 --- a/src/makefile.unix +++ b/src/makefile.unix @@ -104,6 +104,7 @@ OBJS= \ obj/protocol.o \ obj/bitcoinrpc.o \ obj/rpcdump.o \ + obj/rpcnet.o \ obj/script.o \ obj/sync.o \ obj/util.o \ diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp new file mode 100644 index 000000000..1c27d0ef8 --- /dev/null +++ b/src/rpcnet.cpp @@ -0,0 +1,21 @@ +// Copyright (c) 2009-2012 Bitcoin Developers +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "net.h" +#include "bitcoinrpc.h" + +using namespace json_spirit; +using namespace std; + +Value getconnectioncount(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getconnectioncount\n" + "Returns the number of connections to other nodes."); + + return (int)vNodes.size(); +} + + From 1006f0707e34f8903f247195dabd86243ae61f05 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 29 Jun 2012 17:24:53 -0400 Subject: [PATCH 2/2] RPC: add 'getpeerinfo', returning easy-to-retrieve per-CNode data --- src/bitcoinrpc.cpp | 2 ++ src/net.cpp | 18 +++++++++++++++++- src/net.h | 19 +++++++++++++++++++ src/rpcnet.cpp | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/bitcoinrpc.cpp b/src/bitcoinrpc.cpp index 3c61121da..51690243b 100644 --- a/src/bitcoinrpc.cpp +++ b/src/bitcoinrpc.cpp @@ -47,6 +47,7 @@ static int64 nWalletUnlockTime; static CCriticalSection cs_nWalletUnlockTime; extern Value getconnectioncount(const Array& params, bool fHelp); +extern Value getpeerinfo(const Array& params, bool fHelp); extern Value dumpprivkey(const Array& params, bool fHelp); extern Value importprivkey(const Array& params, bool fHelp); @@ -2300,6 +2301,7 @@ static const CRPCCommand vRPCCommands[] = { "stop", &stop, true }, { "getblockcount", &getblockcount, true }, { "getconnectioncount", &getconnectioncount, true }, + { "getpeerinfo", &getpeerinfo, true }, { "getdifficulty", &getdifficulty, true }, { "getgenerate", &getgenerate, true }, { "setgenerate", &setgenerate, true }, diff --git a/src/net.cpp b/src/net.cpp index f1073e0a3..2a09d20de 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -606,7 +606,23 @@ bool CNode::Misbehaving(int howmuch) return false; } - +#undef X +#define X(name) stats.name = name +void CNode::copyStats(CNodeStats &stats) +{ + X(nServices); + X(nLastSend); + X(nLastRecv); + X(nTimeConnected); + X(addrName); + X(nVersion); + X(strSubVer); + X(fInbound); + X(nReleaseTime); + X(nStartingHeight); + X(nMisbehavior); +} +#undef X diff --git a/src/net.h b/src/net.h index fa6f70086..21ecaef84 100644 --- a/src/net.h +++ b/src/net.h @@ -128,6 +128,24 @@ extern std::map mapAlreadyAskedFor; +class CNodeStats +{ +public: + uint64 nServices; + int64 nLastSend; + int64 nLastRecv; + int64 nTimeConnected; + std::string addrName; + int nVersion; + std::string strSubVer; + bool fInbound; + int64 nReleaseTime; + int nStartingHeight; + int nMisbehavior; +}; + + + /** Information about a peer */ @@ -617,6 +635,7 @@ public: static void ClearBanned(); // needed for unit testing static bool IsBanned(CNetAddr ip); bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot + void copyStats(CNodeStats &stats); }; diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 1c27d0ef8..c5746651c 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -15,7 +15,53 @@ Value getconnectioncount(const Array& params, bool fHelp) "getconnectioncount\n" "Returns the number of connections to other nodes."); + LOCK(cs_vNodes); return (int)vNodes.size(); } +static void CopyNodeStats(std::vector& vstats) +{ + vstats.clear(); + + LOCK(cs_vNodes); + vstats.reserve(vNodes.size()); + BOOST_FOREACH(CNode* pnode, vNodes) { + CNodeStats stats; + pnode->copyStats(stats); + vstats.push_back(stats); + } +} + +Value getpeerinfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getpeerinfo\n" + "Returns data about each connected network node."); + + vector vstats; + CopyNodeStats(vstats); + + Array ret; + + BOOST_FOREACH(const CNodeStats& stats, vstats) { + Object obj; + + obj.push_back(Pair("addr", stats.addrName)); + obj.push_back(Pair("services", strprintf("%08"PRI64x, stats.nServices))); + obj.push_back(Pair("lastsend", (boost::int64_t)stats.nLastSend)); + obj.push_back(Pair("lastrecv", (boost::int64_t)stats.nLastRecv)); + obj.push_back(Pair("conntime", (boost::int64_t)stats.nTimeConnected)); + obj.push_back(Pair("version", stats.nVersion)); + obj.push_back(Pair("subver", stats.strSubVer)); + obj.push_back(Pair("inbound", stats.fInbound)); + obj.push_back(Pair("releasetime", (boost::int64_t)stats.nReleaseTime)); + obj.push_back(Pair("height", stats.nStartingHeight)); + obj.push_back(Pair("banscore", stats.nMisbehavior)); + + ret.push_back(obj); + } + + return ret; +}