Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1// Copyright (c) 2011-present The Bitcoin Core developers2// Distributed under the MIT software license, see the accompanying3// file COPYING or http://www.opensource.org/licenses/mit-license.php.5#include <interfaces/node.h>6#include <qt/trafficgraphwidget.h>7#include <qt/clientmodel.h>9#include <QPainter>10#include <QPainterPath>11#include <QColor>12#include <QTimer>14#include <chrono>15#include <cmath>17#define DESIRED_SAMPLES 80019#define XMARGIN 1020#define YMARGIN 1022TrafficGraphWidget::TrafficGraphWidget(QWidget* parent)23: QWidget(parent),24vSamplesIn(),25vSamplesOut()26{27timer = new QTimer(this);28connect(timer, &QTimer::timeout, this, &TrafficGraphWidget::updateRates);29}31void TrafficGraphWidget::setClientModel(ClientModel *model)32{33clientModel = model;34if(model) {35nLastBytesIn = model->node().getTotalBytesRecv();36nLastBytesOut = model->node().getTotalBytesSent();37}38}40std::chrono::minutes TrafficGraphWidget::getGraphRange() const { return m_range; }42void TrafficGraphWidget::paintPath(QPainterPath &path, QQueue<float> &samples)43{44int sampleCount = samples.size();45if(sampleCount > 0) {46int h = height() - YMARGIN * 2, w = width() - XMARGIN * 2;47int x = XMARGIN + w;48path.moveTo(x, YMARGIN + h);49for(int i = 0; i < sampleCount; ++i) {50x = XMARGIN + w - w * i / DESIRED_SAMPLES;51int y = YMARGIN + h - (int)(h * samples.at(i) / fMax);52path.lineTo(x, y);53}54path.lineTo(x, YMARGIN + h);55}56}58void TrafficGraphWidget::paintEvent(QPaintEvent *)59{60QPainter painter(this);61painter.fillRect(rect(), Qt::black);63if(fMax <= 0.0f) return;65QColor axisCol(Qt::gray);66int h = height() - YMARGIN * 2;67painter.setPen(axisCol);68painter.drawLine(XMARGIN, YMARGIN + h, width() - XMARGIN, YMARGIN + h);70// decide what order of magnitude we are71int base = std::floor(std::log10(fMax));72float val = std::pow(10.0f, base);74const QString units = tr("kB/s");75const float yMarginText = 2.0;77// draw lines78painter.setPen(axisCol);79painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));80for(float y = val; y < fMax; y += val) {81int yy = YMARGIN + h - h * y / fMax;82painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);83}84// if we drew 3 or fewer lines, break them up at the next lower order of magnitude85if(fMax / val <= 3.0f) {86axisCol = axisCol.darker();87val = pow(10.0f, base - 1);88painter.setPen(axisCol);89painter.drawText(XMARGIN, YMARGIN + h - h * val / fMax-yMarginText, QString("%1 %2").arg(val).arg(units));90int count = 1;91for(float y = val; y < fMax; y += val, count++) {92// don't overwrite lines drawn above93if(count % 10 == 0)94continue;95int yy = YMARGIN + h - h * y / fMax;96painter.drawLine(XMARGIN, yy, width() - XMARGIN, yy);97}98}100painter.setRenderHint(QPainter::Antialiasing);101if(!vSamplesIn.empty()) {102QPainterPath p;103paintPath(p, vSamplesIn);104painter.fillPath(p, QColor(0, 255, 0, 128));105painter.setPen(Qt::green);106painter.drawPath(p);107}108if(!vSamplesOut.empty()) {109QPainterPath p;110paintPath(p, vSamplesOut);111painter.fillPath(p, QColor(255, 0, 0, 128));112painter.setPen(Qt::red);113painter.drawPath(p);114}115}117void TrafficGraphWidget::updateRates()118{119if(!clientModel) return;121quint64 bytesIn = clientModel->node().getTotalBytesRecv(),122bytesOut = clientModel->node().getTotalBytesSent();123float in_rate_kilobytes_per_sec = static_cast<float>(bytesIn - nLastBytesIn) / timer->interval();124float out_rate_kilobytes_per_sec = static_cast<float>(bytesOut - nLastBytesOut) / timer->interval();125vSamplesIn.push_front(in_rate_kilobytes_per_sec);126vSamplesOut.push_front(out_rate_kilobytes_per_sec);127nLastBytesIn = bytesIn;128nLastBytesOut = bytesOut;130while(vSamplesIn.size() > DESIRED_SAMPLES) {131vSamplesIn.pop_back();132}133while(vSamplesOut.size() > DESIRED_SAMPLES) {134vSamplesOut.pop_back();135}137float tmax = 0.0f;138for (const float f : vSamplesIn) {139if(f > tmax) tmax = f;140}141for (const float f : vSamplesOut) {142if(f > tmax) tmax = f;143}144fMax = tmax;145update();146}148void TrafficGraphWidget::setGraphRange(std::chrono::minutes new_range)149{150m_range = new_range;151const auto msecs_per_sample{std::chrono::duration_cast<std::chrono::milliseconds>(m_range) / DESIRED_SAMPLES};152timer->stop();153timer->setInterval(msecs_per_sample);155clear();156}158void TrafficGraphWidget::clear()159{160timer->stop();162vSamplesOut.clear();163vSamplesIn.clear();164fMax = 0.0f;166if(clientModel) {167nLastBytesIn = clientModel->node().getTotalBytesRecv();168nLastBytesOut = clientModel->node().getTotalBytesSent();169}170timer->start();171}
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.