Skip to content

Conversation

@LarryRuane
Copy link
Contributor

@LarryRuane LarryRuane commented Feb 6, 2023

This PR adds last_block_announcement to the per-peer getpeerinfo RPC result. This is the most recent time that this peer was the first to notify our node of a new block (one that we didn't already know about), or zero if this peer has never been the first to notify us of a new block. This timestamp already exists internally and is used for stale-tip eviction logic; this PR exposes it at the RPC layer.

This PR started out as a suggestion for additional test coverage, see #26172 (comment). It turned out that the easiest way to test (already-merged) #26172 is to add this field to getpeerinfo and have a functional test verify its value. But it may also be useful to have this result in its own right, similar to that RPC's existing last_block field -- it indicates something about the quality of our peers. It allows one to predict which peer will be evicted when the stale tip logic activates. (I'm not sure if that would be useful, but it may be.)

The functional test added here fails without #26172, which is the main goal.

This PR does not test the actual stale-tip eviction logic; that's difficult to do with a functional test. But it does test the correctness of the timestamp that the eviction logic depends on. #23352 is an attempt to test the eviction logic using a unit test, it's not ready to be merged yet. I think having both kinds of tests would be beneficial.

@DrahtBot
Copy link
Contributor

DrahtBot commented Feb 6, 2023

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

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/27052.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK naiyoma
Concept ACK satsie, kristapsk
Stale ACK rkrux

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #34181 (refactor: [p2p] Make ProcessMessage private again, Use references when non-null by maflcko)
  • #19461 (multiprocess: Add bitcoin-gui -ipcconnect option by ryanofsky)
  • #19460 (multiprocess: Add bitcoin-wallet -ipcconnect option by ryanofsky)
  • #10102 (Multiprocess bitcoin by ryanofsky)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@LarryRuane
Copy link
Contributor Author

Force pushed to fix CI failure

@satsie
Copy link
Contributor

satsie commented Feb 7, 2023

Concept ACK. I spent quite a bit of time trying to test #26172 (my findings are documented here) and can confirm the difficulty of testing it with the current state of the test framework.

I also support the suggestion to add last_block_announcement to getpeerinfo not only because it seems to be the easiest way to test 26172, but I agree it can be useful information to have when trying to learn more about one's peers, especially when this timestamp is already available internally.

src/net.h Outdated
Copy link
Member

Choose a reason for hiding this comment

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

If you change the type, why not use NodeSeconds (a time point)? While std::chrono::seconds (a duration) is used widely in the codebase, because all durations that denote a time point are since epoch, using a dedicated type such as NodeSeconds might be clearer.

src/net.h Outdated
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this belongs in CNode. It is used in our outbound eviction logic which is part of net processing and it isn't used in net at all (imo, the eviction logic should be encapsulated in its own module entirely #25268 😉).

Also afaict, there is no need to move m_last_block_announcement, because you can just return it in PeerManager::GetNodeStateStats.

@LarryRuane
Copy link
Contributor Author

Force pushed from becf38061b2625bcc629293fec0dce7c27292e14 to

  • efc2e70f1763c6bf3f6b246202adb9d5f1f798ee diff -- needed rebase
  • 16d2903b8a9e6e980e24e04ab2d86c7e778f5764 diff -- make the suggested review changes
  • 2e80e3bdcd9cac7878c0d14956ba9c57626da855 diff -- fix CI failure
  • 6c564aafb3d5f61fffa0d6311ad688c47b14014a diff -- add release notes, and small improvement to functional test

I'll take this out of draft now since I think it's ready for review.

@LarryRuane LarryRuane force-pushed the 2023-02-getpeerinfo branch from 5bcf849 to f7788f6 Compare April 30, 2025 20:34
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jun 6, 2025
Copy its value from CNodeState. Unused until the next commit.

Github-Pull: bitcoin#27052
Rebased-From: ff699907ed9418fc522e56f54595e957193853dc
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jun 6, 2025
Github-Pull: bitcoin#27052
Rebased-From: e9a0e210418accf8336984d143c5f7c62efabfa3
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jun 6, 2025
Github-Pull: bitcoin#27052
Rebased-From: b15ecabff363de98899531911db6c4abe3f783e7
luke-jr pushed a commit to luke-jr/bitcoin that referenced this pull request Jun 6, 2025
Github-Pull: bitcoin#27052
Rebased-From: 5bcf8491d15ac148507a4d172469e1fd9d12078e
Copy link
Contributor

Choose a reason for hiding this comment

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

first to announced a new block → first to announce a new block

// to their network, counting both outbound-full-relay and manual peers.
NodeId worst_peer = -1;
int64_t oldest_block_announcement = std::numeric_limits<int64_t>::max();
std::optional<NodeSeconds> oldest_block_announcement;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I understand why this is optional. Originally, it was set to a sentinel value.
I don't see a situation where it wouldn't have a value.
My suggestion → NodeSeconds oldest_block_announcement = NodeSeconds::max();
That way .has_value() checks and *oldest_block_announcement can be avoided.

Copy link
Member

@theuni theuni Aug 19, 2025

Choose a reason for hiding this comment

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

optional + has_value() communicates intent much more clearly than the sentinel imo. Though admittedly it's awkward as long as worst_peer uses a sentinel as well.

I'd expect to see std::optional<std::pair<NodeId, NodeSeconds>> worst_peer, personally.

Copy link
Contributor

@naiyoma naiyoma left a comment

Choose a reason for hiding this comment

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

Tested ACK cbe4603

Changes since last review: rebased and addressed nit fixes.

Also tested with msg_cmpctblock - test passed as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants