Skip to content

Enhanced Traffic Graph Widget with Multi-timeframe Support and Data Persistence#866

Open
rebroad wants to merge 3 commits into
bitcoin-core:masterfrom
rebroad:trafficgraphwidget-rebased
Open

Enhanced Traffic Graph Widget with Multi-timeframe Support and Data Persistence#866
rebroad wants to merge 3 commits into
bitcoin-core:masterfrom
rebroad:trafficgraphwidget-rebased

Conversation

@rebroad
Copy link
Copy Markdown
Contributor

@rebroad rebroad commented Apr 9, 2025

This PR improves the network traffic graph widget in the Debug window to provide:

  1. Multiple time range options (from 5 minutes to 28 days)
  2. Data persistence between sessions
  3. Interactive visualization features including tooltips and logarithmic scaling

Motivation

The existing network traffic graph has limited utility with its fixed time range and lack of historical data preservation. This enhancement allows users to:

  • Analyze network traffic patterns over different timeframes
  • Preserve historical traffic data between session restarts
  • Interact with the graph to get specific data points
  • Better visualize varying traffic volumes with logarithmic scaling

These improvements are valuable for:

  • Network debugging and troubleshooting
  • Understanding Bitcoin Core's network behaviour
  • Monitoring traffic patterns for optimization
  • Research purposes

Implementation

The implementation preserves all existing functionality while adding new features:

  • Added a pre-configured timeframe selection (13 different timeframes)
  • Implemented traffic data serialization and deserialization
  • Enhanced the visualization with interactive features
  • Improved tooltip information with precise timestamps and traffic rates

Supporting changes:

  • Added formatBytesps function for a prettier display of traffic rates
  • Added FormatISO8601Time for better time display

Testing

Tested on Linux with various network conditions. The new functionality can be exercised by:

  1. Using the slider (or arrow keys) to select different time ranges
  2. Restarting the application to verify data persistence
  3. Clicking on the graph to toggle between linear and logarithmic scales
  4. Hovering over data points to view detailed information

Documentation

The changes are mostly self-documenting through the UI and are constrained to the Qt interface without affecting core functionality.

Compatibility

This PR maintains compatibility with existing functionality. The data persistence file uses proper serialization versioning to allow for future format changes if needed.

@DrahtBot
Copy link
Copy Markdown
Contributor

DrahtBot commented Apr 9, 2025

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Reviews

See the guideline for information on the review process.

Type Reviewers
Concept ACK RandyMcMillan

If your review is incorrectly listed, please copy-paste <!--meta-tag:bot-skip--> into the comment that the bot should ignore.

Conflicts

No conflicts as of last run.

LLM Linter (✨ experimental)

Possible places where named args for integral literals may be used (e.g. func(x, /*named_arg=*/0) in C++, and func(x, named_arg=0) in Python):

  • UpdateNum(m_new_fmax, m_fmax, y_increment, 300) in src/qt/trafficgraphwidget.cpp
  • UpdateNum(m_values[m_new_value], m_range, x_increment, 500) in src/qt/trafficgraphwidget.cpp

2026-05-27 13:08:21

@DrahtBot
Copy link
Copy Markdown
Contributor

DrahtBot commented Apr 9, 2025

🚧 At least one of the CI tasks failed.
Debug: https://github.com/bitcoin-core/gui/runs/40286962281

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch from 530adae to 31b1ffc Compare April 10, 2025 16:33
@rebroad rebroad marked this pull request as ready for review April 10, 2025 21:35
@rebroad rebroad changed the title qt: Improve TrafficGraphWidget functionality qt: Enhanced Traffic Graph Widget with Multi-timeframe Support and Data Persistence Apr 11, 2025
Copy link
Copy Markdown
Member

@luke-jr luke-jr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merging it all together likes this makes review very annoying. It was better as separate PRs.

Comment thread src/qt/trafficgraphwidget.cpp Outdated
Comment on lines +42 to +46
// Restore the saved total bytes counts to the node if they exist
if (m_total_bytes_recv > 0 || m_total_bytes_sent > 0) {
model->node().setTotalBytesRecv(m_total_bytes_recv);
model->node().setTotalBytesSent(m_total_bytes_sent);
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GUI should not be changing low-level internals.

If for some reason the clientModel is changed, its data should be taken as authoritative, even if it contradicts the history so far (if that's an issue, wipe the history).

Alternatively, maybe the history should be stored with the node, and loaded into the GUI (or RPC, in another hypothetical PR).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is that the data is not persistent - but yes, I see your point - it should probably not be something that only happens when the GUI is running, and should perhaps also happen in bitcoind also.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The GUI should not be changing low-level internals.

If for some reason the clientModel is changed, its data should be taken as authoritative, even if it contradicts the history so far (if that's an issue, wipe the history).

Alternatively, maybe the history should be stored with the node, and loaded into the GUI (or RPC, in another hypothetical PR).

@luke-jr I've removed the setTotalBytes functions as I agree with your reasoning. The GUI keeps a local track of the totals from the last session and simply adds them to the totals provided by the node now. I did think about storing the data on the node, but I am not sure it makes much sense given the data is currently stored on the GUI and so it makes more sense to keep the totals local with the traffic history for now. Perhaps someone thinks it's worth storing this on the node in the future, but it doesn't seem like an urgent need for now.

</widget>
</item>
<item>
<widget class="QPushButton" name="btnClearTrafficGraph">
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're deleting this, maybe there should be a way for the user to insert a reference line?

For now, I'd move removal of anything to a separate PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The user can effectively remove the data by deleting the .dat file - is there any basis for being able to do this while the client is running?

Comment thread src/qt/rpcconsole.cpp
// based timer interface
m_node.rpcSetTimerInterfaceIfUnset(rpcTimerInterface);

setTrafficGraphRange(INITIAL_TRAFFIC_GRAPH_MINS);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we losing this default constant?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because it isn't needed - on startup it "defaults" to the first non-full range

Comment thread src/util/time.cpp Outdated
@rebroad
Copy link
Copy Markdown
Contributor Author

rebroad commented Apr 15, 2025

Merging it all together likes this makes review very annoying. It was better as separate PRs.

I vaguely remember people complaining that I was raising several PRs that could be combined when I first raised the PRs years ago.... I guess one cannot please everyone all of the time.

@luke-jr As a middle-ground, I can move the distinct functional changes into different commits.

@rebroad rebroad requested a review from luke-jr April 15, 2025 23:03
@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch from 31b1ffc to ab7bbd0 Compare April 16, 2025 21:37
@laanwj laanwj changed the title qt: Enhanced Traffic Graph Widget with Multi-timeframe Support and Data Persistence Enhanced Traffic Graph Widget with Multi-timeframe Support and Data Persistence Apr 24, 2025
@laanwj laanwj added the Feature label Apr 24, 2025
@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch 6 times, most recently from 280b15c to de2f01a Compare May 1, 2025 14:35
@rebroad
Copy link
Copy Markdown
Contributor Author

rebroad commented May 1, 2025

I've removed the code that changed the totals on the node - the GUI just keeps track now without writing values to the node. Also, added some checks for corrupt save files so that it doesn't load bad data.

@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch 2 times, most recently from cf274a3 to 0982a88 Compare May 1, 2025 23:15
@DrahtBot
Copy link
Copy Markdown
Contributor

DrahtBot commented May 1, 2025

🚧 At least one of the CI tasks failed.
Task lint: https://github.com/bitcoin-core/gui/runs/41512420338
LLM reason (✨ experimental): The CI failure is caused by a lint check failure due to the use of tabs instead of spaces in the codebase.

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch from 0982a88 to 47732ed Compare May 2, 2025 06:34
@rebroad
Copy link
Copy Markdown
Contributor Author

rebroad commented May 2, 2025

I realise this PR is starting to look a bit messy with all the updates. I also realise I ought to separate various functionality changes into separate commits. Is it better to raise a new PR once this is done, force push to this one?

@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch from 47732ed to c308d55 Compare May 2, 2025 06:43
@DrahtBot DrahtBot removed the CI failed label May 2, 2025
@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch from c308d55 to b3155ba Compare May 2, 2025 08:25
@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch 9 times, most recently from 48b175e to b1aa3b8 Compare May 6, 2025 14:58
@DrahtBot DrahtBot removed the CI failed label May 6, 2025
@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch 3 times, most recently from 15fd680 to bc13d01 Compare May 8, 2025 21:54
@DrahtBot
Copy link
Copy Markdown
Contributor

DrahtBot commented Jul 5, 2025

🚧 At least one of the CI tasks failed.
Task tidy: https://github.com/bitcoin-core/gui/runs/41904414250
LLM reason (✨ experimental): The failure is caused by compilation errors due to ignoring the return value of 'fclose()' functions marked as 'nodiscard', leading to build failure.

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

@RandyMcMillan
Copy link
Copy Markdown
Contributor

concept ACK

@rebroad rebroad marked this pull request as ready for review May 26, 2026 12:31
rebroad added 2 commits May 26, 2026 14:43
Add a new GUI utility function to format bytes per second values with appropriate
units (B/s, kB/s, MB/s, GB/s) and precision, ensuring consistent and readable
display of network traffic rates in the traffic graph widget.
Add a new time formatting function that matches the existing date and datetime
ISO8601 formatting functions, providing consistent time display for the
traffic graph widget tooltips and other UI elements that need time-only display.
@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch from bc13d01 to cf8f824 Compare May 26, 2026 12:49
@DrahtBot
Copy link
Copy Markdown
Contributor

🚧 At least one of the CI tasks failed.
Task macOS-cross to arm64: https://github.com/bitcoin-core/gui/actions/runs/26448991497/job/77864217892
LLM reason (✨ experimental): CI failed because the C++ build broke in trafficgraphwidget.cpp with compile errors (LogPrintf undeclared and fclose() return ignored) treated as fatal under -Werror.

Hints

Try to run the tests locally, according to the documentation. However, a CI failure may still
happen due to a number of reasons, for example:

  • Possibly due to a silent merge conflict (the changes in this pull request being
    incompatible with the current code in the target branch). If so, make sure to rebase on the latest
    commit of the target branch.

  • A sanitizer issue, which can only be found by compiling with the sanitizer and running the
    affected test.

  • An intermittent issue.

Leave a comment here, if you need help tracking down a confusing failure.

…persistence

This commit significantly improves the network traffic graph widget with:

1. Multiple timeframe support - View traffic data across different time
   periods (5 minutes to 28 days) using an enhanced slider interface

2. Traffic data persistence - Save and restore traffic information
   between sessions, preserving historical traffic patterns

3. Interactive visualization features:
   - Logarithmic scale toggle (mouse click) for better visualization of
     varying traffic volumes
   - Interactive tooltips showing detailed traffic information at specific points
   - Yellow highlight indicators for selected data points

4. Smooth transitions between different time ranges with animated scaling

These improvements allow users to better monitor and analyze network
traffic patterns over time, which is especially useful for debugging
connectivity issues or understanding network behavior under different
conditions.

The implementation includes proper thread-safety considerations and
handles edge cases like time jumps or missing data appropriately.
@rebroad rebroad force-pushed the trafficgraphwidget-rebased branch from cf8f824 to 601f085 Compare May 27, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants