Skip to content

tracing: network connection tracepoints#25832

Merged
fanquake merged 7 commits into
bitcoin:masterfrom
0xB10C:2022-05-connection-tracepoints
Feb 5, 2025
Merged

tracing: network connection tracepoints#25832
fanquake merged 7 commits into
bitcoin:masterfrom
0xB10C:2022-05-connection-tracepoints

Conversation

@0xB10C

@0xB10C 0xB10C commented Aug 12, 2022

Copy link
Copy Markdown
Contributor

This adds five new tracepoints with documentation and tests for network connections:

  • established connections with net:inbound_connection and net:outbound_connection
  • closed connections (both closed by us or by the peer) with net:closed_connnection
  • inbound connections that we choose to evict with net:evicted_inbound_connection
  • connections that are misbehaving and punished with net:misbehaving_connection

I've been using these tracepoints for a few months now to monitor connection lifetimes, re-connection frequency by IP and netgroup, misbehavior, peer discouragement, and eviction and more. Together with the two existing P2P message tracepoints they allow for a good overview of local P2P network activity. Also sort-of addresses #22006 (comment).

I've been back and forth on which arguments to include. For example, net:evicted_connection could also include some of the eviction metrics like e.g. last_block_time, min_ping_time, ... but I've left them out for now. If wanted, this can be added here or in a follow-up. I've tried to minimize a potential performance impact by measuring executed instructions with gdb where possible (method described here). I don't think a few hundred extra instructions are too crucial, as connection opens/closes aren't too frequent (compared to e.g. P2P messages). Note: e.g. CreateNodeFromAcceptedSocket() usually executes between 80k and 90k instructions for each new inbound connection.

tracepoint instructions
net:inbound_connection 390 ins
net:outbound_connection between 700 and 1000 ins
net:closed_connnection 473 ins
net:evicted_inbound_connection not measured; likely similar to net:closed_connnection
net:misbehaving_connection not measured

Also added a bpftrace (tested with v0.14.1) log_p2p_connections.bt example script that produces output similar to:

Attaching 6 probes...
Logging opened, closed, misbehaving, and evicted P2P connections
OUTBOUND conn to 127.0.0.1:15287: id=0, type=block-relay-only, network=0, total_out=1
INBOUND conn from 127.0.0.1:45324: id=1, type=inbound, network=0, total_in=1
MISBEHAVING conn id=1, message='getdata message size = 50001'
CLOSED conn to 127.0.0.1:15287: id=0, type=block-relay-only, network=0, established=1231006505
EVICTED conn to 127.0.0.1:45324: id=1, type=inbound, network=0, established=1612312312

@jb55

jb55 commented Aug 12, 2022 via email

Copy link
Copy Markdown
Contributor

kouloumos added a commit to kouloumos/bitcoin that referenced this pull request Aug 17, 2022
@portlandhodl

portlandhodl commented Aug 18, 2022

Copy link
Copy Markdown

Just reporting in that everything is functional. Console log looks correct.

Tests Passed
image

0xB10C added a commit to peer-observer/peer-observer that referenced this pull request Sep 12, 2022
0xB10C added a commit to peer-observer/peer-observer that referenced this pull request Sep 12, 2022
0xB10C added a commit to peer-observer/peer-observer that referenced this pull request Sep 12, 2022
0xB10C added a commit to peer-observer/peer-observer that referenced this pull request Sep 12, 2022
@DrahtBot

DrahtBot commented Sep 13, 2022

Copy link
Copy Markdown
Contributor

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/25832.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK laanwj, vasild, sipa
Concept ACK dergoegge, i-am-yuvi
Stale ACK jb55, virtu, maflcko

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:

  • #30988 (Split CConnman by vasild)
  • #30381 ([WIP] net: return result from addnode RPC by willcl-ark)

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.

@0xB10C

0xB10C commented Nov 16, 2022

Copy link
Copy Markdown
Contributor Author

Note to self: might be worth checking if we can also pass AS information and not only the net_group.

@0xB10C

0xB10C commented Jan 20, 2023

Copy link
Copy Markdown
Contributor Author

Note to self: might be worth checking if we can also pass AS information and not only the net_group.

This is possible by accessing the CNodeStats, but don't think we should do that in the tracepoint. We have the IP and can lookup the AS in a tracing scirpt, if necessary.


Fixed up the linter complains and rebased. This is ready for further review.

@dergoegge

Copy link
Copy Markdown
Member

Concept ACK

@0xB10C
0xB10C force-pushed the 2022-05-connection-tracepoints branch from 8528781 to ac438b1 Compare March 21, 2023 09:16
@0xB10C
0xB10C force-pushed the 2022-05-connection-tracepoints branch from ac438b1 to 6de4fc7 Compare March 21, 2023 11:36
@0xB10C

0xB10C commented Mar 21, 2023

Copy link
Copy Markdown
Contributor Author

The linter started complaining about "E275 missing whitespace after keyword". Fixed this up in the individual commits.

ac438b1 -> 6de4fc7 (2022-05-connection-tracepoints.pr.1 -> 2022-05-connection-tracepoints.pr.2; compare)

Comment thread src/net.cpp Outdated
Comment thread src/net.cpp Outdated
@virtu

virtu commented Mar 24, 2023

Copy link
Copy Markdown
Contributor

ACK 6de4fc7

Code reviewed tracepoints, tests, and demo script. Tracepoint placement looks good, so do tests. Successfully ran functional tests and the demo script.

Some points:

  • Any reason why only inbound_connection and outbound_connection explicitly cast all arguments in the demo script?
  • I think some of the format specifiers in the demo script are lightly off, leading to outputs with negative netgroup values on my system. I believe it should be %lld for int64 and %llu for uint64.
  • As brought up previously, it would be nice to switch from nKeyedNetGroup to netgroup ids that are consistent over time

@DrahtBot
DrahtBot requested a review from jb55 March 24, 2023 13:44
@laanwj

laanwj commented Jan 21, 2025

Copy link
Copy Markdown
Member

Both CI errors are related to mempool synchronization. It seems very unlikely to be caused by the changes in this PR.

@laanwj laanwj left a comment

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.

Code review ACK 6eb94b3082e6ff6882e27ee98abb3c79f34abbe0

@DrahtBot
DrahtBot requested a review from vasild January 21, 2025 13:49
@fanquake fanquake added this to the 29.0 milestone Jan 21, 2025
Comment thread test/functional/interface_usdt_net.py Outdated
0xB10C and others added 7 commits February 4, 2025 10:24
A bpftrace script that logs information from the
net:*_connection tracepoints.

I've tested this script with bpftrace version 0.14.1 and v0.20.2.
A v3 onion address with a `:` and a five digit port has a length of
68 chars. As noted in
bitcoin#25832 (comment)
peers e.g. added via hostname might have a longer CNode::m_addr_name.
These might be cut off in tracing tools.
@0xB10C

0xB10C commented Feb 4, 2025

Copy link
Copy Markdown
Contributor Author

Rebased and addressed #25832 (comment)

@laanwj laanwj left a comment

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.

re-ACK e3622a9

@vasild vasild left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

ACK e3622a9

@sipa sipa left a comment

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.

utACK e3622a9

Comment thread doc/tracing.md Outdated

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.

It's not very nice to expose this internal value in the interface, if we want it to be stable. What about using the BIP155 network ID instead?

@0xB10C

0xB10C commented Feb 5, 2025

Copy link
Copy Markdown
Contributor Author

Using BIP155 network IDs is a good idea! Planning to address #25832 (comment) in a followup.

@vasild

vasild commented Feb 6, 2025

Copy link
Copy Markdown
Contributor

CNetAddr::GetBIP155Network() might be useful.

@0xB10C

0xB10C commented Feb 7, 2025

Copy link
Copy Markdown
Contributor Author

I implemented both the BIP155 NetworkID approach (0xB10C@72133f3) and the Network as string approach from #25832 (comment) (0xB10C@39102d4).

The BIP155 approach is a bit more involved with making GetBIP155Network() public, introducing a ConnectedThroughBIP155Network() helper, and passing 0 (or something else?) for NET_INTERNAL as there is no BIP155 equivalent. With this approach, NET_UNROUTABLE isn't exposed - e.g. 127.0.0.1 will get the BIP155 NetworkID for IPv4.

The network name as string approach exposes NET_UNROUTABLE as not_publicly_routable and NET_INTERNAL as internal. We have these in -netinfo too.

I have a slight preference on BIP155 NetworkIDs over keeping-as-is or network name as string.

@laanwj

laanwj commented Feb 9, 2025

Copy link
Copy Markdown
Member

I have a slight preference on BIP155 NetworkIDs over keeping-as-is or network name as string.

Agree. Strings are sensitive to typos, and require extra effort for matching when doing statistics. i think even the current enumeration is better than that. BIP155 is a good suggestion, but as you have to make up non-standard values, and handle NET_UNROUTABLE differently i'm not entirely sure.

The purpose of tracing is to gain insight into internal state so logging the actual values makes more sense than thinking up a new convention. The internal enumeration is likely stable enough to warrant being a (semi-)stable interface.

@sipa

sipa commented Feb 9, 2025

Copy link
Copy Markdown
Member

The BIP155 approach is a bit more involved with making GetBIP155Network() public, introducing a ConnectedThroughBIP155Network() helper, and passing 0 (or something else?) for NET_INTERNAL as there is no BIP155 equivalent.

Given that BIP155 network IDs are uint8_t's, I think it suffices to pick a value outside of that range for unreachable. For example, 0x100, or 0xffffffff for a uint32_t, or -1 for a signed integer type.

Using 0 works too of course, and I guess it won't get assigned in future extensions, but using something outside of the range might be even more future-proof.

@0xB10C

0xB10C commented Feb 12, 2025

Copy link
Copy Markdown
Contributor Author

Agree. Strings are sensitive to typos, and require extra effort for matching when doing statistics. i think even the current enumeration is better than that. BIP155 is a good suggestion, but as you have to make up non-standard values, and handle NET_UNROUTABLE differently i'm not entirely sure.
The purpose of tracing is to gain insight into internal state so logging the actual values makes more sense than thinking up a new convention. The internal enumeration is likely stable enough to warrant being a (semi-)stable interface.

I tend to agree. A few toughs:

Unless there are strong opinions on needing a follow up, I'll plan to leave this as is.

for closed_connection in closed_connections:
assert closed_connection.conn.id > 0
assert_equal("inbound", closed_connection.conn.conn_type.decode('utf-8'))
assert_equal(0, closed_connection.conn.network)

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.

This should have been

- assert_equal(0, closed_connection.conn.network)
+ assert_equal(NETWORK_TYPE_UNROUTABLE, closed_connection.conn.network)

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.