Skip to content

Conversation

@RandyMcMillan
Copy link
Contributor

@RandyMcMillan RandyMcMillan commented Feb 3, 2022

This change adds an "Age" column to the peers table view,
which displays the duration of each peer's connection.

@RandyMcMillan
Copy link
Contributor Author

Screen Shot 2022-02-02 at 9 00 10 PM

@RandyMcMillan
Copy link
Contributor Author

RandyMcMillan commented Feb 3, 2022

commit 363f181 - the column is resizing to accommodate 1 h 1 m 20 s time format.

Screen Shot 2022-02-03 at 7 52 49 AM

@RandyMcMillan
Copy link
Contributor Author

commit 281b65b

we make adjustments so that the peers tab collapses down to a useful "desktop widget".

Screen Shot 2022-02-03 at 8 32 21 AM

@RandyMcMillan
Copy link
Contributor Author

This PR and #540 will work well together. Both the network graph and peers tab will be useful in a minimized window size and present information in a well formatted way.
Screen Shot 2022-02-03 at 8 40 42 AM

Copy link
Contributor

@jarolrod jarolrod left a comment

Choose a reason for hiding this comment

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

What is the reason to add this column to the peers table? Why is it a useful metric for a user of the GUI?

/*: Title of Peers Table column which describes the type of
peer connection. The "type" describes why the connection exists. */
tr("Duration"),
/*: Title of Peers Table column which describes the duration of
Copy link
Contributor

Choose a reason for hiding this comment

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

You added this translator comment in reverse, the comment on lines 95 and 96 should be above line 94 in this diff.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for your attention on this.

@RandyMcMillan
Copy link
Contributor Author

RandyMcMillan commented Feb 4, 2022

What is the reason to add this column to the peers table? Why is it a useful metric for a user of the GUI?

I guess one could ask - why peer id address direction type network ping sent received or user agent are useful.

And the fact that there is so much visual real estate NOT BEING USED FOR ANYTHING AT ALL - I am not even sure what the concern or hesitation to adding more columns to the table view would be. On wider screens more than half of the available real-estate is LITERALLY EMPTY SPACE.

Screen Shot 2022-02-04 at 6 09 10 AM

@RandyMcMillan
Copy link
Contributor Author

RandyMcMillan commented Feb 4, 2022

If - by your assertion - the connection duration is NOT USEFUL - why track it? Why not rip it out of the Client Model - a system could use that memory and resources for something else.

@RandyMcMillan
Copy link
Contributor Author

RandyMcMillan commented Feb 4, 2022

The command line equivalent bitcoin-cli -netinfo 5 we report age to the user. So adding "Duration" to the gui tableview is a parallel to the command line report. Changing the column name to age seems more appropriate than debating whether or not it should be added. I follow the naming convention in the code using Duration GUIUtil::formatDurationStr().
Screen Shot 2022-02-04 at 7 22 57 AM

NOTE: I agree with using a 3 char column title in the command line equivalent - but in the gui - Duration is more appropriate IMO.

@RandyMcMillan
Copy link
Contributor Author

Note: I like the idea of verbosity in the command line version.
bitcoin-cli -netinfo
bitcoin-cli -netinfo 1
bitcoin-cli -netinfo 2
etc...

If defending the nuance and minutia of gui design changes wasn't so ridiculous (in this repo) - we could consider adding similar functionality to the gui (levels of verbosity to the table) - but I literally don't get paid enough (approaching nothing) to deal with that type of design process unless every one else was already on board.

@ghost
Copy link

ghost commented Feb 4, 2022

Concept ACK

The connection duration is a useful metric to see when viewing the peer table - sorting the tableview with the connection duration is made possible.

Duration is also useful combined with other things because users can see how much data was sent and received in that duration.

@jonatack
Copy link
Member

jonatack commented Feb 4, 2022

Concept ACK. I do look frequently at age in -netinfo. The direction and type columns should remain together, as combined they form the connection type, like <-> and type in -netinfo, see enum class ConnectionType in src/net.h. I see age/duration as being next to the id column, like in -netinfo, or the data sent/recv ones as @prayank23 mentioned. It may be good to make the output less verbose somehow (seconds seems unneeded). If you use signet, you won't need to black out sensitive parts of your screenshots.

Edit: the commits seem overly fine-grained, maybe combine the first three or four into one.

tr("Direction"),
/*: Title of Peers Table column which indicates the duration (length of time)
since the peer connection started. */
tr("Duration"),
Copy link
Member

Choose a reason for hiding this comment

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

I like Age, but if you don't, maybe consider Uptime.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

used Age as column name

ui->banlistWidget->setColumnWidth(BanTableModel::Address, BANSUBNET_COLUMN_WIDTH);
ui->banlistWidget->setColumnWidth(BanTableModel::Bantime, BANTIME_COLUMN_WIDTH);
}
ui->banlistWidget->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::ResizeToContents);
Copy link
Member

Choose a reason for hiding this comment

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

Here and line 694 as well

Suggested change
ui->banlistWidget->horizontalHeader()->setSectionResizeMode( 0, QHeaderView::ResizeToContents);
ui->banlistWidget->horizontalHeader()->setSectionResizeMode(0, QHeaderView::ResizeToContents);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed white space

@RandyMcMillan
Copy link
Contributor Author

@jonatack - thanks for the constructive feedback - I appreciate your reasoning. I will re-implement accordingly.

@RandyMcMillan RandyMcMillan force-pushed the 1643853831-peers-tab-add-duration-column branch from 16c9ebf to 22b1a40 Compare February 5, 2022 02:54
@RandyMcMillan
Copy link
Contributor Author

commit 22b1a40 implements suggested changes.
Squashed commits per feedback

@RandyMcMillan
Copy link
Contributor Author

RandyMcMillan commented Feb 5, 2022

Screenshots of 22b1a40

Screen Shot 2022-02-04 at 10 09 00 PM

If anybody wants to send a patch truncating the time format - I will gladly add it with attribution.
Note: We could also wait - There are a couple things we could still add to the table view.
For example we could add a version field - that lends itself to sorting...and we aren't really short on column space...

Screen Shot 2022-02-04 at 10 31 44 PM

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

utACK 22b1a40

@luke-jr
Copy link
Member

luke-jr commented Feb 5, 2022

Concept ACK

I do note the sort will be the same as sorting by ID...

@RandyMcMillan
Copy link
Contributor Author

@luke-jr - good observation - thanks again for your great feed back - (my apologize for the other thing - I will make the mempool-tab repo more "normal" 😄 )

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

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

Debug build is clean and seems to be working. Can you update, squash and fix the commit names, descriptions, and code organization? i.e. make this ready for more final review.

It would be nice to remove the seconds display--seems noisy, distracting and unneeded. Nodes can be up for weeks, months or longer.

sorting the tableview with the connection duration is made possible.

Suggest removing the above from the pull description, as it is the same as the existing sort by peer id. Albeit with the current version, the sort orders of Peer and Age are inversed.

@hebasto hebasto changed the title gui: peers-tab: add connection duration column to tableview peers-tab: add connection duration column to tableview Feb 9, 2022
@hebasto hebasto added the Feature label Feb 9, 2022
@RandyMcMillan RandyMcMillan force-pushed the 1643853831-peers-tab-add-duration-column branch 3 times, most recently from e4d1d6c to d01c0b3 Compare February 11, 2022 04:21
@RandyMcMillan
Copy link
Contributor Author

Commit: d01c0b3

Cleaned up commit structure and messages.
The Age column now displays the connection duration in seconds for the first minute - then switches to hour/minute format when connection age is greater than 60 seconds.

Screen Shot 2022-02-10 at 11 34 03 PM

Copy link
Member

@jonatack jonatack left a comment

Choose a reason for hiding this comment

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

Tested approach ACK, this seems much improved.

return GUIUtil::formatDurationStr(std::chrono::duration_cast<std::chrono::seconds>(time_now-rec->nodeStats.m_connected));
}else{
return GUIUtil::formatDurationStr(std::chrono::duration_cast<std::chrono::minutes>(time_now-rec->nodeStats.m_connected));
}
Copy link
Member

Choose a reason for hiding this comment

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

d01c0b3 suggestions

  • clang-format
  • use chrono literals, e.g. 60s instead of std::chrono::seconds{60}
  • drop unneeded casts and comment that echoes the code (and shouldn't be in doxygen format here)
suggested diff

+using namespace std::chrono_literals;
+
 PeerTableModel::PeerTableModel(interfaces::Node& node, QObject* parent) :
     QAbstractTableModel(parent),
     m_node(node),
@@ -72,11 +75,11 @@ QVariant PeerTableModel::data(const QModelIndex& index, int role) const
         case NetNodeId:
             return (qint64)rec->nodeStats.nodeid;
         case Age:
-            if(std::chrono::duration_cast<std::chrono::minutes>(time_now-rec->nodeStats.m_connected) < std::chrono::seconds{60}){
-                /* display connection "Age" in seconds for first minute */
-                return GUIUtil::formatDurationStr(std::chrono::duration_cast<std::chrono::seconds>(time_now-rec->nodeStats.m_connected));
-            }else{
-                return GUIUtil::formatDurationStr(std::chrono::duration_cast<std::chrono::minutes>(time_now-rec->nodeStats.m_connected));
+            if (time_now - rec->nodeStats.m_connected < 60s) {
+                return GUIUtil::formatDurationStr(time_now - rec->nodeStats.m_connected);
+            } else {
+                return GUIUtil::formatDurationStr(
+                    std::chrono::duration_cast<std::chrono::minutes>(time_now - rec->nodeStats.m_connected));
             }

If this becomes larger, say, to display in DD:HH format after 24 hours it may make sense to extract it to a helper function.

Copy link
Contributor Author

@RandyMcMillan RandyMcMillan Feb 11, 2022

Choose a reason for hiding this comment

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

The ResizeToContents settings should accommodate the duration string as the connection persists longer than 24 hours.

NOTE: The fact that <chrono> is formatting the string for # s, # m then # h # m suggests that it will
format for # d # h # m. I guess we could spoof the time to prove/test this.

I applied your suggested diff with attribution.

Copy link
Member

Choose a reason for hiding this comment

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

The fact that <chrono> is formatting the string for # s, # m then # h # m suggests that it will format for # d # h # m. I guess we could spoof the time to prove/test this.

Tested with a few different values and you're right: 23 h 59 s, 1 d, 1 d 1 h 59 m, 1 d 2 h, 1 d 2 h 1 m, etc. The spacing makes the column wider and a bit noisier than necessary. Could be improved here or as a follow-up.

-    const auto time_now{GetTime<std::chrono::seconds>()};
+    const auto time_now{GetTime<std::chrono::seconds>() + 86380s};

@RandyMcMillan RandyMcMillan force-pushed the 1643853831-peers-tab-add-duration-column branch 2 times, most recently from 139f2ed to 795a03d Compare February 11, 2022 19:29
Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

tACK a2e44c1

image

if (hours >= 24) return QObject::tr("%1 d").arg(hours / 24);
if (hours) return QObject::tr("%1 h").arg(hours);
const auto minutes{std::chrono::duration_cast<std::chrono::minutes>(age).count()};
return QObject::tr("%1 m").arg(minutes);
Copy link
Member

Choose a reason for hiding this comment

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

@RandyMcMillan, looking at this further, I think the function in 349c597 can be simplified and improved as follows:

@@ -736,12 +736,10 @@ QString FormatPeerAge(std::chrono::seconds time_connected)
 {
     const auto time_now{GetTime<std::chrono::seconds>()};
     const auto age{time_now - time_connected};
-    if (age < 60s) return QObject::tr("%1 s").arg(age.count());
-    const auto hours{std::chrono::duration_cast<std::chrono::hours>(age).count()};
-    if (hours >= 24) return QObject::tr("%1 d").arg(hours / 24);
-    if (hours) return QObject::tr("%1 h").arg(hours);
-    const auto minutes{std::chrono::duration_cast<std::chrono::minutes>(age).count()};
-    return QObject::tr("%1 m").arg(minutes);
+    if (age >= 24h) return QObject::tr("%1 d").arg(age / 24h);
+    if (age >= 1h) return QObject::tr("%1 h").arg(age / 1h);
+    if (age >= 1min) return QObject::tr("%1 m").arg(age / 1min);
+    return QObject::tr("%1 s").arg(age / 1s);
 } 

Copy link
Member

Choose a reason for hiding this comment

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

I repushed an update to https://github.com/jonatack/gui/commits/gui-peers-tab-age-column with the changes in #543 (comment) and #543 (comment) if you want to cherry-pick them.

Copy link
Member

Choose a reason for hiding this comment

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

Should probably add translator notes too

Copy link
Member

Choose a reason for hiding this comment

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

Should probably add translator notes too

Agree, am doing this for several of these (FormatPeerAge, formatDurationStr, TimeDurationField, etc.) as a follow-up.

@RandyMcMillan RandyMcMillan force-pushed the 1643853831-peers-tab-add-duration-column branch from a2e44c1 to 35d685a Compare February 14, 2022 18:39
@RandyMcMillan
Copy link
Contributor Author

Rebased to 25a91a5
commit abf93dd includes a more compact implementation of the
QString FormatPeerAge(std::chrono::seconds time_connected)
helper function.

@jonatack
Copy link
Member

jonatack commented Feb 14, 2022

ACK 35d685a

I like that the Peer and Age columns have the opposite default sort direction, displaying both the newest and oldest peers by default.

Note that there is a Connection Time in the peer details that displays the Age in a more verbose format. I think it's ok as-is, as the formats are different, or maybe might propose renaming the former to Age (Connection Time).

Copy link

@ghost ghost left a comment

Choose a reason for hiding this comment

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

reACK 35d685a

@RandyMcMillan
Copy link
Contributor Author

This has been a fun collaborative effort. 😄

I enjoyed watching a rough idea get polished into an "ACK-able" state.

Copy link
Contributor

@shaavan shaavan left a comment

Choose a reason for hiding this comment

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

ACK 35d685a

I agree with the concept of adding an Age column in the Node window table because I agree with all the reasons for its approval discussed above. To briefly reiterate them:

  1. We have unused screen real estate which could be used more productively.
  2. The Age column is displayed in the -netinfo command for bitcoin-cli. It makes logical sense to keep our GUI consistent with the cli.
  3. Age column is frequently used by users through -netinfo command. So it would be a good idea to add the GUI.

Regarding the code:

  • I like the structuring of the FormatPeerPage function. The code is clean and easy to understand.
  • I like the idea of displaying only the highest degree of time, instead of precise time. This gives users a general idea of how a node has been contacted to them, while also not taking too much screen real estate, and user’s attention.
  • I think naming the column “Age” seems appropriate to me. This keeps it consistent with bitcoin-cli's naming.

Here are some screenshots I have added showing the correct working of this PR, on Ubuntu 20.04

Master PR
Screenshot from 2022-02-15 17-05-17 PR

Copy link
Contributor

@w0xlt w0xlt left a comment

Choose a reason for hiding this comment

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

tACK 35d685a on Ubuntu 21.10 Qt 5.15.2

Copy link
Contributor

@promag promag left a comment

Choose a reason for hiding this comment

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

Concept ACK.

return strList.join(" ");
}

QString FormatPeerAge(std::chrono::seconds time_connected)
Copy link
Contributor

Choose a reason for hiding this comment

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

abf93dd

I think this could be idempotent QString FormatAge(std::chrono::seconds age), to avoid GetTime.

Note that PeerTableModel has a timer to refresh the data, just call GetTime once there.

Copy link
Member

@jonatack jonatack Mar 6, 2022

Choose a reason for hiding this comment

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

@promag I agree this would be an improvement and am looking into it, but am not sure how to integrate GetTime into the peertablemodel.cpp QTimer code. Pointers welcome.

case NetNodeId:
return (qint64)rec->nodeStats.nodeid;
case Age:
return GUIUtil::FormatPeerAge(rec->nodeStats.m_connected);
Copy link
Contributor

Choose a reason for hiding this comment

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

852b036

Following my previous comment, this could be

return GUIUtil::FormatAge(m_now - rec->nodeStats.m_connected);

@jonatack
Copy link
Member

This pull has 4 ACKs and could perhaps be merged now that v23 has been branched off, which would enable moving forward on planned follow-ups like #543 (comment), while still allowing a possible improvement per #543 (comment).

@RandyMcMillan RandyMcMillan requested a review from hebasto March 12, 2022 19:28
@RandyMcMillan
Copy link
Contributor Author

7ddff98 merged requested changes.
Will squash after re-review.

@jonatack
Copy link
Member

jonatack commented Mar 13, 2022

ACK. Squashing the changes into the relevant commit (in this case, the last commit 35d685a) when re-pushing an update can save time for reviewers and speed up the merge. See the "Squashing Commits" section of CONTRIBUTING.md.

jonatack and others added 3 commits March 16, 2022 04:54
Co-authored-by: randymcmillan <randy.lee.mcmillan@gmail.com>
Co-authored-by: Jon Atack <jon@atack.com>
Co-authored-by: Hennadii Stepanov <32963518+hebasto@users.noreply.github.com>
@RandyMcMillan RandyMcMillan force-pushed the 1643853831-peers-tab-add-duration-column branch from 7ddff98 to 51708c4 Compare March 16, 2022 08:56
@RandyMcMillan
Copy link
Contributor Author

51708c4 squashed merged requested changes.
rebased on top of 310ba92

@jonatack
Copy link
Member

re-ACK 51708c4

@Jamewood
Copy link

(PR #543)

@Jamewood
Copy link

Jamewood commented Mar 17, 2022 via email

@RandyMcMillan
Copy link
Contributor Author

@Jamewood - thank you for the ACK if this was your intention - please ACK in the appropriate format - and remove the other comments. 😀

Copy link
Contributor

@shaavan shaavan left a comment

Choose a reason for hiding this comment

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

reACK 51708c4

Changes since my last review:

  • Dropped “Magic numbers”. i.e.,
    1PeerTableModel::Age
    0BanTableModel::Address
  • Rebased over master.

I agree with the idea of dropping “magic” numbers because:

  1. It makes code easier to understand and reason with.
  2. It makes code robust to change in enum ordering under the class’s definition.

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

ACK 51708c4, I have reviewed the code and it looks OK, I agree it can be merged.

@hebasto hebasto merged commit 0f46e73 into bitcoin-core:master Apr 12, 2022
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Apr 13, 2022
… to tableview

51708c4 gui: peersWidget - ResizeToContents Age and IP/Netmask columns (randymcmillan)
209301a gui: add Age column to peers tab (randymcmillan)
127de22 gui: add FormatPeerAge() utility helper (Jon Atack)

Pull request description:

  This change adds an "Age" column to the peers table view,
  which displays the duration of each peer's connection.

ACKs for top commit:
  jonatack:
    re-ACK  51708c4
  Jamewood:
    > re-ACK 51708c4
  shaavan:
    reACK 51708c4
  hebasto:
    ACK 51708c4, I have reviewed the code and it looks OK, I agree it can be merged.

Tree-SHA512: 27323f7080ec0d3fcdbf1b190fba1cd2d7406840ab6607c221cf8af950db9134e22721cc5a88f4fc4f390d8b05e98bc4b7521661a31fadad9e2c6c6390e71788
@bitcoin-core bitcoin-core locked and limited conversation to collaborators Apr 12, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants