Skip to content

Commit

Permalink
Add Network Traffic Graph
Browse files Browse the repository at this point in the history
  • Loading branch information
Tranz5 committed Sep 20, 2014
1 parent be63e54 commit 3446a75
Show file tree
Hide file tree
Showing 18 changed files with 379 additions and 15 deletions.
2 changes: 2 additions & 0 deletions HoboNickels-qt.pro
Expand Up @@ -205,6 +205,7 @@ HEADERS += src/qt/bitcoingui.h \
src/qt/guiconstants.h \
src/qt/optionsmodel.h \
src/qt/monitoreddatamapper.h \
src/qt/trafficgraphwidget.h \
src/qt/transactiondesc.h \
src/qt/transactiondescdialog.h \
src/qt/bitcoinamountfield.h \
Expand Down Expand Up @@ -271,6 +272,7 @@ SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
src/qt/transactionrecord.cpp \
src/qt/optionsmodel.cpp \
src/qt/monitoreddatamapper.cpp \
src/qt/trafficgraphwidget.cpp \
src/qt/transactiondesc.cpp \
src/qt/transactiondescdialog.cpp \
src/qt/bitcoinstrings.cpp \
Expand Down
1 change: 1 addition & 0 deletions src/bitcoinrpc.cpp
Expand Up @@ -199,6 +199,7 @@ static const CRPCCommand vRPCCommands[] =
{ "getconnectioncount", &getconnectioncount, true, false, false },
{ "getpeerinfo", &getpeerinfo, true, false, false },
{ "ping", &ping, true, false, false },
{ "getnettotals", &getnettotals, true, true, false },
{ "addnode", &addnode, true, true, false },
{ "getaddednodeinfo", &getaddednodeinfo, true, true, false },
{ "getdifficulty", &getdifficulty, true, false, false },
Expand Down
1 change: 1 addition & 0 deletions src/bitcoinrpc.h
Expand Up @@ -138,6 +138,7 @@ extern void EnsureWalletIsUnlocked(CWallet* pWallet = NULL);
extern json_spirit::Value getconnectioncount(CWallet* pWallet, const json_spirit::Array& params, bool fHelp); // in rpcnet.cpp
extern json_spirit::Value getpeerinfo(CWallet* pWallet, const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value ping(CWallet* pWallet, const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getnettotals(CWallet* pWallet, const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value addnode(CWallet* pWallet, const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value getaddednodeinfo(CWallet* pWallet, const json_spirit::Array& params, bool fHelp);
extern json_spirit::Value dumpwallet(CWallet* pWallet, const json_spirit::Array& params, bool fHelp);
Expand Down
38 changes: 32 additions & 6 deletions src/net.cpp
Expand Up @@ -431,9 +431,10 @@ void AddressCurrentlyConnected(const CService& addr)
}





uint64 CNode::nTotalBytesRecv = 0;
uint64 CNode::nTotalBytesSent = 0;
CCriticalSection CNode::cs_totalBytesRecv;
CCriticalSection CNode::cs_totalBytesSent;


CNode* FindNode(const CNetAddr& ip)
Expand Down Expand Up @@ -743,6 +744,7 @@ void SocketSendData(CNode *pnode)
pnode->nLastSend = GetTime();
pnode->nSendOffset += nBytes;
pnode->nSendBytes += nBytes;
pnode->RecordBytesSent(nBytes);
if (pnode->nSendOffset == data.size()) {
pnode->nSendOffset = 0;
pnode->nSendSize -= data.size();
Expand Down Expand Up @@ -863,10 +865,9 @@ void ThreadSocketHandler2(void* parg)
}
}
}
if (vNodes.size() != nPrevNodeCount)
{
if (vNodes.size() != nPrevNodeCount) {
nPrevNodeCount = vNodes.size();
uiInterface.NotifyNumConnectionsChanged(vNodes.size());
uiInterface.NotifyNumConnectionsChanged(nPrevNodeCount);
}


Expand Down Expand Up @@ -1025,6 +1026,7 @@ void ThreadSocketHandler2(void* parg)
pnode->CloseSocketDisconnect();
pnode->nLastRecv = GetTime();
pnode->nRecvBytes += nBytes;
pnode->RecordBytesRecv(nBytes);

}
else if (nBytes == 0)
Expand Down Expand Up @@ -2105,3 +2107,27 @@ void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataSt
RelayInventory(inv);
}

void CNode::RecordBytesRecv(uint64 bytes)
{
LOCK(cs_totalBytesRecv);
nTotalBytesRecv += bytes;
}

void CNode::RecordBytesSent(uint64 bytes)
{
LOCK(cs_totalBytesSent);
nTotalBytesSent += bytes;
}

uint64 CNode::GetTotalBytesRecv()
{
LOCK(cs_totalBytesRecv);
return nTotalBytesRecv;
}

uint64 CNode::GetTotalBytesSent()
{
LOCK(cs_totalBytesSent);
return nTotalBytesSent;
}

13 changes: 13 additions & 0 deletions src/net.h
Expand Up @@ -331,6 +331,12 @@ class CNode
}

private:
// Network usage totals
static CCriticalSection cs_totalBytesRecv;
static CCriticalSection cs_totalBytesSent;
static uint64 nTotalBytesRecv;
static uint64 nTotalBytesSent;

CNode(const CNode&);
void operator=(const CNode&);
public:
Expand Down Expand Up @@ -721,6 +727,13 @@ class CNode
static bool IsBanned(CNetAddr ip);
bool Misbehaving(int howmuch); // 1 == a little, 100 == a lot
void copyStats(CNodeStats &stats);

// Network stats
static void RecordBytesRecv(uint64 bytes);
static void RecordBytesSent(uint64 bytes);

static uint64 GetTotalBytesRecv();
static uint64 GetTotalBytesSent();
};


Expand Down
1 change: 1 addition & 0 deletions src/qt/bitcoin.qrc
Expand Up @@ -51,6 +51,7 @@
<file alias="transaction_conflicted">res/icons/transaction_conflicted.png</file>
<file alias="blexp">res/icons/blexp.png</file>
<file alias="info">res/icons/info.png</file>
<file alias="traffic">res/icons/traffic.png</file>
</qresource>
<qresource prefix="/images">
<file alias="about">res/images/about.png</file>
Expand Down
16 changes: 10 additions & 6 deletions src/qt/bitcoingui.cpp
Expand Up @@ -195,6 +195,7 @@ BitcoinGUI::BitcoinGUI(QWidget *parent):

rpcConsole = new RPCConsole(this);

connect(openTrafficAction, SIGNAL(triggered()), rpcConsole, SLOT(showTab_Stats()));
connect(openRPCConsoleAction, SIGNAL(triggered()), rpcConsole, SLOT(show()));

// Install event filter to be able to catch status tip events (QEvent::StatusTip)
Expand Down Expand Up @@ -375,6 +376,10 @@ void BitcoinGUI::createActions()
openRPCConsoleAction->setStatusTip(tr("Open debugging and diagnostic console"));
openRPCConsoleAction->setToolTip(openRPCConsoleAction->statusTip());

openTrafficAction = new QAction(QIcon(":/icons/traffic"), tr("&Traffic window"), this);
openTrafficAction->setStatusTip(tr("Open Network Traffic Graph"));
openTrafficAction->setToolTip(openTrafficAction->statusTip());

connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
Expand Down Expand Up @@ -441,6 +446,7 @@ void BitcoinGUI::createMenuBar()

QMenu *network = appMenuBar->addMenu(tr("&Network"));
network->addAction(blockAction);
network->addAction(openTrafficAction);
network->addSeparator();
network->addAction(blocksIconAction);
network->addAction(stakingIconAction);
Expand Down Expand Up @@ -657,14 +663,12 @@ void BitcoinGUI::connectionIconClicked()
{
QString strAllPeer;
QVector<CNodeStats> qvNodeStats = clientModel->getPeerStats();
uint64 nTotSendBytes = 0, nTotRecvBytes = 0 ,nTotBlocksRequested = 0;
uint64 nTotBlocksRequested = 0;
int nTotPeers = clientModel->getNumConnections();
double dTotPingTime = 0.0;

BOOST_FOREACH(const CNodeStats& stats, qvNodeStats) {
QString strPeer;
nTotSendBytes+=stats.nSendBytes;
nTotRecvBytes+=stats.nRecvBytes;
nTotBlocksRequested+=stats.nBlocksRequested;
dTotPingTime+=stats.dPingTime;

Expand Down Expand Up @@ -696,8 +700,8 @@ void BitcoinGUI::connectionIconClicked()
"\tPlease click \"Show Details\" for more information.\n")
.arg(nTotPeers)
.arg(dTotPingTime/nTotPeers)
.arg(nTotRecvBytes)
.arg(nTotSendBytes)
.arg(clientModel->getTotalBytesRecv())
.arg(clientModel->getTotalBytesSent())
.arg(nTotBlocksRequested),
CClientUIInterface::MODAL,
tr("%1")
Expand Down Expand Up @@ -803,7 +807,7 @@ void BitcoinGUI::gotoSignMessageTab(QString addr)

void BitcoinGUI::gotoVerifyMessageTab(QString addr)
{
if (walletStack) walletStack->gotoSignMessageTab(addr);
if (walletStack) walletStack->gotoVerifyMessageTab(addr);
}

void BitcoinGUI::setNumConnections(int count)
Expand Down
1 change: 1 addition & 0 deletions src/qt/bitcoingui.h
Expand Up @@ -115,6 +115,7 @@ class BitcoinGUI : public QMainWindow
QAction *changePassphraseAction;
QAction *aboutQtAction;
QAction *openRPCConsoleAction;
QAction *openTrafficAction;
QAction *loadWalletAction;
QAction *unloadWalletAction;
QAction *newWalletAction;
Expand Down
13 changes: 13 additions & 0 deletions src/qt/clientmodel.cpp
Expand Up @@ -113,6 +113,17 @@ int ClientModel::getStakeTargetSpacing()
return nStakeTargetSpacing;
}

quint64 ClientModel::getTotalBytesRecv() const
{
return CNode::GetTotalBytesRecv();
}

quint64 ClientModel::getTotalBytesSent() const
{
return CNode::GetTotalBytesSent();
}


QDateTime ClientModel::getLastBlockDate(bool fProofofStake) const
{
LOCK(cs_main);
Expand Down Expand Up @@ -146,6 +157,8 @@ void ClientModel::updateTimer()
// ensure we return the maximum of newNumBlocksOfPeers and newNumBlocks to not create weird displays in the GUI
emit numBlocksChanged(newNumBlocks, std::max(newNumBlocksOfPeers, newNumBlocks));
}

emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
}

void ClientModel::updateNumConnections(int numConnections)
Expand Down
4 changes: 4 additions & 0 deletions src/qt/clientmodel.h
Expand Up @@ -48,6 +48,9 @@ class ClientModel : public QObject
double getPosKernalPS();
int getStakeTargetSpacing();

quint64 getTotalBytesRecv() const;
quint64 getTotalBytesSent() const;


QDateTime getLastBlockDate(bool fProofofStake=false) const;

Expand Down Expand Up @@ -83,6 +86,7 @@ class ClientModel : public QObject
signals:
void numConnectionsChanged(int count);
void numBlocksChanged(int count, int countOfPeers);
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
void alertsChanged(const QString &warnings);
void walletAdded(const QString &name);
void walletRemoved(const QString &name);
Expand Down
Binary file added src/qt/res/icons/traffic.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
62 changes: 61 additions & 1 deletion src/qt/rpcconsole.cpp
Expand Up @@ -25,6 +25,8 @@ const int CONSOLE_HISTORY = 50;

const QSize ICON_SIZE(24, 24);

const int INITIAL_TRAFFIC_GRAPH_MINS = 30;

const struct {
const char *url;
const char *source;
Expand Down Expand Up @@ -209,6 +211,7 @@ RPCConsole::RPCConsole(QWidget *parent) :
ui->openSSLVersion->setText(SSLeay_version(SSLEAY_VERSION));

startExecutor();
setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS);

clear();
}
Expand Down Expand Up @@ -257,13 +260,17 @@ bool RPCConsole::eventFilter(QObject* obj, QEvent *event)

void RPCConsole::setClientModel(ClientModel *model)
{
this->clientModel = model;
clientModel = model;
ui->trafficGraph->setClientModel(model);
if(model)
{
// Subscribe to information, replies, messages, errors
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
connect(model, SIGNAL(numBlocksChanged(int,int)), this, SLOT(setNumBlocks(int,int)));

updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));

// Provide initial values
ui->clientVersion->setText(model->formatFullVersion());
ui->clientName->setText(model->clientName());
Expand Down Expand Up @@ -439,3 +446,56 @@ void RPCConsole::on_showCLOptionsButton_clicked()
GUIUtil::HelpMessageBox help;
help.exec();
}

void RPCConsole::on_sldGraphRange_valueChanged(int value)
{
const int multiplier = 5; // each position on the slider represents 5 min
int mins = value * multiplier;
setTrafficGraphRange(mins);
}

QString RPCConsole::FormatBytes(quint64 bytes)
{
if(bytes < 1024)
return QString(tr("%1 B")).arg(bytes);
if(bytes < 1024 * 1024)
return QString(tr("%1 KB")).arg(bytes / 1024);
if(bytes < 1024 * 1024 * 1024)
return QString(tr("%1 MB")).arg(bytes / 1024 / 1024);

return QString(tr("%1 GB")).arg(bytes / 1024 / 1024 / 1024);
}

void RPCConsole::setTrafficGraphRange(int mins)
{
ui->trafficGraph->setGraphRangeMins(mins);
if(mins < 60) {
ui->lblGraphRange->setText(QString(tr("%1 m")).arg(mins));
} else {
int hours = mins / 60;
int minsLeft = mins % 60;
if(minsLeft == 0) {
ui->lblGraphRange->setText(QString(tr("%1 h")).arg(hours));
} else {
ui->lblGraphRange->setText(QString(tr("%1 h %2 m")).arg(hours).arg(minsLeft));
}
}
}

void RPCConsole::updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut)
{
ui->lblBytesIn->setText(FormatBytes(totalBytesIn));
ui->lblBytesOut->setText(FormatBytes(totalBytesOut));
}

void RPCConsole::on_btnClearTrafficGraph_clicked()
{
ui->trafficGraph->clear();
}

void RPCConsole::showTab_Stats()
{
ui->tabWidget->setCurrentIndex(2);
this->show();
}

12 changes: 12 additions & 0 deletions src/qt/rpcconsole.h
Expand Up @@ -27,6 +27,7 @@ class RPCConsole: public QDialog
CMD_ERROR
};


protected:
virtual bool eventFilter(QObject* obj, QEvent *event);

Expand All @@ -37,6 +38,12 @@ private slots:
void on_openDebugLogfileButton_clicked();
/** display messagebox with program parameters (same as hobonickels-qt --help) */
void on_showCLOptionsButton_clicked();
/** change the time range of the network traffic graph */
void on_sldGraphRange_valueChanged(int value);
/** update traffic statistics */
void updateTrafficStats(quint64 totalBytesIn, quint64 totalBytesOut);
/** clear traffic graph */
void on_btnClearTrafficGraph_clicked();

public slots:
void clear();
Expand All @@ -49,12 +56,17 @@ public slots:
void browseHistory(int offset);
/** Scroll console view to end */
void scrollToEnd();
/** Show Traffic Stats Tab */
void showTab_Stats();
signals:
// For RPC command executor
void stopExecutor();
void cmdRequest(const QString &command);

private:
static QString FormatBytes(quint64 bytes);
void setTrafficGraphRange(int mins);

Ui::RPCConsole *ui;
ClientModel *clientModel;
QStringList history;
Expand Down
1 change: 0 additions & 1 deletion src/qt/signverifymessagedialog.cpp
Expand Up @@ -70,7 +70,6 @@ void SignVerifyMessageDialog::setAddress_VM(const QString &address)
void SignVerifyMessageDialog::showTab_SM(bool fShow)
{
ui->tabWidget->setCurrentIndex(0);

if (fShow)
this->show();
}
Expand Down

0 comments on commit 3446a75

Please sign in to comment.