This PR:
- adds
CNode::ConnectedThroughNetworkmember function - is based on #19991, and only last two commits belong to it
- is required for https://github.com/bitcoin-core/gui/pull/86 and #20002
This PR:
CNode::ConnectedThroughNetwork member function<!--e57a25ab6845829454e8d69fc972939a-->
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.
<!--174a7506f384e20aa4161008e828411d-->
Reviewers, this pull request conflicts with the following ones:
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.
Concept ACK
Nice! :)
Concept ACK
What about a multiple-choice option that more generally specifies the network that the connection (comes in/goes out) through, instead of specializing it for Tor? Might want to have the same for I2P later, for example.
Also this should be 'onion' to be consistent with our other uses.
What about a multiple-choice option that more generally specifies the network that the connection (comes in/goes out) through, instead of specializing it for Tor? Might want to have the same for I2P later, for example.
Do I understand you correctly that smth following is expected:
$ src/bitcoin-cli help getpeerinfo | grep network_type
"network_type" : clearnet|onion|I2P, Type of the network the peer has connected via
?
Concept ACK. I agree with wladimir's suggestions. @hebasto I think your understanding is correct.
Concept ACK
What about a multiple-choice option that more generally specifies the network that the connection (comes in/goes out) through, instead of specializing it for Tor? Might want to have the same for I2P later, for example.
Also this should be 'onion' to be consistent with our other uses.
This was the goal in #20002, which exposes the GetNetClass() index (allowing for a significant code simplification in -netinfo). Feedback welcome if it should also expose the network class name.
This was the goal in #20002, which exposes the
GetNetClass()index (allowing for a significant code simplification in -netinfo). Feedback welcome if it should also expose the network class name.
What about limiting this PR to introducing CNode::GetNetClass() in addition to CNetAddr::GetNetClass() as the latter does not work for inbound connections via Tor?
Or just drop the last commit in favor of #20002 (if CNode::ConnectedViaTor() logic is sufficient)?
Updated fcd938e80abe634ccd0c0a289a8bdd339c186d24 -> 911a3f9929e2c10493c1ad525ad592dd6859df3f (pr19998.02 -> pr19998.03, diff):
via_tor to getpeerinfo output" in favor of more consistent approach in #20002
@laanwj @naumenkogs RPC part has been moved to #20002 now.513 | @@ -514,6 +514,15 @@ void CNode::SetAddrLocal(const CService& addrLocalIn) { 514 | } 515 | } 516 | 517 | +bool CNode::ConnectedViaTor() const 518 | +{ 519 | + if (m_conn_type == ConnectionType::INBOUND) {
if (IsInboundConn()) {
Haven't reveiewed the code, but conceptually, for future-readyness I'd prefer this to be called ConnectedThroughNetwork and return an enumeration instead of have a Tor-specific call one the API.
Edit: oh, I suggested this before. Apparently I feel strongly about this :smile: .
$ src/bitcoin-cli help getpeerinfo | grep network_type "network_type" : clearnet|onion|I2P, Type of the network the peer has connected via
Yes, exactly! Or maybe even split clearnet into IPv4 and IPv6.
Yes, ATM returning an enum is delegated to the follow-up #20002, where the Network enum is returned using the existing GetNetworkName() function for the enum-to-string conversion. New networks like I2P and CJDNS can be added to that function when they are supported.
Feel free to combine the two steps into one if that is better.
Updated 911a3f9929e2c10493c1ad525ad592dd6859df3f -> cf532ae5d68c2e35e73c793923398e01ee7bca7f (pr19998.03 -> pr19998.06):
Haven't reveiewed the code, but conceptually, for future-readyness I'd prefer this to be called
ConnectedThroughNetworkand return an enumeration instead of have a Tor-specific call one the API.Edit: oh, I suggested this before. Apparently I feel strongly about this smile .
$ src/bitcoin-cli help getpeerinfo | grep network_type "network_type" : clearnet|onion|I2P, Type of the network the peer has connected via
Yes, exactly! Or maybe even split clearnet into IPv4 and IPv6.
Updated cf532ae5d68c2e35e73c793923398e01ee7bca7f -> c972792511f764ff300602bd3c71df1fea90ddcc (pr19998.06 -> pr19998.07) to the recent #19991.
Updated c972792511f764ff300602bd3c71df1fea90ddcc -> ac0f4975fe00f2f72c408cbd6b642b29b0e2f8ce (pr19998.07 -> pr19998.08) due to the conflict with #19991.
Do you plan to add test coverage for the changes here (and in #19991?)
I thought your tests could cover all aspects, right?
Starting to see inbound onions while testing this on #20002 (Edit: WIP update now pushed if anyone wants to use it for testing).
<-> relay net mping ping send recv txn blk uptime asmap id address
in full onion 358 469 0 90 49 35 127.0.0.1:43064
in block onion 450 722 29 104 35 66 127.0.0.1:45118
The updated function here is easy to use, too.
stats.m_network = GetNetworkName(ConnectedThroughNetwork());
586 | @@ -586,6 +587,9 @@ class CConnman 587 | 588 | std::atomic<int64_t> m_next_send_inv_to_incoming{0}; 589 | 590 | + //! -bind=<address>:<port>=onion arguments.
m_onion_binds is/** doxygen formatting like m_try_another_outbound_peer just aboveDeveloper Notes suggest //! style to describe a member.
538 | @@ -538,6 +539,14 @@ void CNode::SetAddrLocal(const CService& addrLocalIn) { 539 | } 540 | } 541 | 542 | +Network CNode::ConnectedThroughNetwork() const 543 | +{ 544 | + if (IsInboundConn() && m_inbound_onion) { 545 | + return NET_ONION; 546 | + } 547 | + return addr.GetNetClass();
optional style nit, could just simplify to a straight ternary
- if (IsInboundConn() && m_inbound_onion) {
- return NET_ONION;
- }
- return addr.GetNetClass();
+ return IsInboundConn() && m_inbound_onion ? NET_ONION : addr.GetNetClass();
or a one-line guard conditional
- if (IsInboundConn() && m_inbound_onion) {
- return NET_ONION;
- }
+ if (IsInboundConn() && m_inbound_onion) return NET_ONION;
return addr.GetNetClass();
957 | @@ -954,6 +958,8 @@ class CNode 958 | assert(false); 959 | } 960 | 961 | + Network ConnectedThroughNetwork() const;
Can you add a doxygen comment here? Maybe provide a quick context on the difference between this and GetNetClass() or why it's needed, for future readers of this code.
Added test coverage.
ACK, I've been testing this with #20002 and also rebased on #19954 (it's thankfully a clean merge) and it seems to be working. A few optional comments below. It may be good to update fuzz/netaddress.cpp (or other fuzzers, I didn't look further) with ConnectedThroughNetwork() and add unit or functional tests for the new -bind functionality. I did add some testing in #20002 for the values returned by ConnectedThroughNetwork(). Edit: reviewing the new push!
191 | @@ -192,14 +192,34 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) 192 | BOOST_CHECK(pnode1->IsFeelerConn() == false); 193 | BOOST_CHECK(pnode1->IsAddrFetchConn() == false); 194 | BOOST_CHECK(pnode1->IsInboundConn() == false); 195 | + BOOST_CHECK_EQUAL(pnode1->ConnectedThroughNetwork(), Network::NET_IPV4); 196 | 197 | - std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, CAddress(), pszDest, ConnectionType::INBOUND); 198 | + std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, CAddress(), pszDest, ConnectionType::INBOUND, false);
here and lines 206 and 215
std::unique_ptr<CNode> pnode2 = MakeUnique<CNode>(id++, NODE_NETWORK, height, hSocket, addr, 1, 1, CAddress(), pszDest, ConnectionType::INBOUND, /* inbound_onion= */ false);
could optionally also add /*nKeyedNetGroupIn=*/ 1 and /*nLocalHostNonceIn=*/ 1
ACK. The new unit tests are green for me locally. Not sure what's up with the travis linter.
Updated 5fc8f155549b1ad39aeef1c3220ebd6026d7f845 -> 3989fcfb6713b074c6c6be143db3aaa33e50525a (pr19998.10 -> pr19998.11):
960 | @@ -954,6 +961,16 @@ class CNode 961 | assert(false); 962 | } 963 | 964 | + /** 965 | + * Get network the peer connected through. 966 | + * 967 | + * CNetAddr::GetNetClass() is used excluding inbound connections that are 968 | + * explicitly tagged as connections from the Tor onion service(s).
It's much better. Perhaps:
Returns Network::NET_ONION for *inbound* onion connections that CNetAddr::GetNetClass() does not currently detect. Otherwise, returns CNetAddr::GetNetClass().
It's for sure that my comment could be improved, but I don't think that it is a correct assumption that it's responsibility of CNetAddr class to detect the network a peer is connected through. I mean "CNetAddr::GetNetClass() does not currently detect" part.
Yes. That seems like a worthwhile clarification. Maybe something ~like:
Returns Network::NET_ONION for *inbound* onion connections, and CNetAddr::GetNetClass() otherwise. The latter cannot be used directly because it doesn't detect the former, and it's not the responsability of the CNetAddr class to know the actual network a peer is connected through.
ACK 3989fcfb6713b074c6c6be143db3aaa33e50525a
Updated 3989fcfb6713b074c6c6be143db3aaa33e50525a -> 3984b78cd7f49e409377f2175a56e8e4bd71d1d8 (pr19998.11 -> pr19998.12, diff):
Thanks for your patience with the suggestions.
re-ACK 3984b78cd7f49e409377f2175a56e8e4bd71d1d8 per git diff 3989fcf 3984b78c
Edit: testing with #20002 (inbound onions detected server-side) vs on master (inbound onions detected client-side), I'm seeing the same ones detected.
Code review ACK 3984b78cd7f49e409377f2175a56e8e4bd71d1d8
Thanks for addressing my suggestion. And making CNode::ConnectedThroughNetwork() return a Network enum directly is a nice touch.