Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

p2p, rpc: enable GetAddr, GetAddresses, and getnodeaddresses by network #21843

Merged
merged 7 commits into from
May 20, 2021

Conversation

jonatack
Copy link
Member

@jonatack jonatack commented May 3, 2021

This patch allows passing a network argument to CAddrMan::GetAddr(), CConnman::GetAddresses(), and rpc getnodeaddresses to return only addresses of that network.

It also contains a performance optimisation by promag to no longer call gettime for each vRandom entry inside the CAddrMan::GetAddr_() loop.

@fanquake fanquake added the P2P label May 3, 2021
@jonatack jonatack changed the title net, rpc: enable GetAddr, GetAddresses, and getnodeaddresses by network p2p, rpc: enable GetAddr, GetAddresses, and getnodeaddresses by network May 3, 2021
Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

Approach ACK.

Filtering this "server side" would help reduce network traffic especially if all addresses are requested (matters if the RPC client is not running on the same machine as bitcoind). It does not add any (measurable) computational overhead on the "server side".

@jonatack jonatack force-pushed the getnodeaddresses-by-network branch 2 times, most recently from 209d2a9 to ac01ec0 Compare May 3, 2021 21:40
@jonatack jonatack marked this pull request as ready for review May 3, 2021 22:59
@jonatack
Copy link
Member Author

jonatack commented May 3, 2021

Thanks for the early feedback @vasild! Updated and ready for review.

@DrahtBot
Copy link
Contributor

DrahtBot commented May 4, 2021

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

Conflicts

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.

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK ac01ec0

(would be happy to re-ACK if the default value of the 3rd arg of GetAddr() is removed)

@jonatack jonatack force-pushed the getnodeaddresses-by-network branch from ac01ec0 to 46933d8 Compare May 4, 2021 16:08
@jonatack
Copy link
Member Author

jonatack commented May 4, 2021

Thank you @vasild. Removed the defaults and improved the fuzzing per git diff ac01ec0 09f2c20.

@jonatack
Copy link
Member Author

jonatack commented May 6, 2021

Rebased for CI fix on master.

@vasild
Copy link
Contributor

vasild commented May 11, 2021

The latest push removed the default value for the network argument from CAddrMan::GetAddr() and from CConnMan::GetAddresses() too. The latter deserves a default value because now there are a lot of call sites like connman.GetAddresses(..., std::nullopt), no?

@jonatack
Copy link
Member Author

GetAddresses(..., std::nullopt)`

Only in two places outside of tests, so it seemed better to pass it explicitly.

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.

I think this change could be simplified by setting the default argument of the network filter.

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK bdc57fc

Whether to have a default value for the argument of CAddrMan::GetAddr() and CConnMan::GetAddresses() is not a showstopper for this PR, IMO.

Now there are two non-test callers of GetAddresses() that explicitly pass nullopt:

cache_entry.m_addrs_response_cache = GetAddresses(max_addresses, max_pct, /* network */ std::nullopt);

vAddr = m_connman.GetAddresses(MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND, /* network */ std::nullopt);

@jonatack jonatack force-pushed the getnodeaddresses-by-network branch from bdc57fc to 9d17f30 Compare May 12, 2021 15:26
@jonatack
Copy link
Member Author

Thanks @vasild, agreed. Making them explicit was more work, but I reckon sooner or later someone is going to make them explicit so may as well do it now.

@jonatack
Copy link
Member Author

Only change is @promag's suggestion: git diff bdc57fc 9d17f30

diff --git a/src/addrman.cpp b/src/addrman.cpp
index 473ac21ad0..ceab1689d7 100644
--- a/src/addrman.cpp
+++ b/src/addrman.cpp
@@ -494,6 +494,7 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
+    const int64_t now{GetAdjustedTime()};
     for (unsigned int n = 0; n < vRandom.size(); n++) {
         if (vAddr.size() >= nNodes)
             break;
@@ -503,10 +504,14 @@ void CAddrMan::GetAddr_(std::vector<CAddress>& vAddr, size_t max_addresses, size
         assert(mapInfo.count(vRandom[n]) == 1);
 
         const CAddrInfo& ai = mapInfo[vRandom[n]];
-        // Filter for quality, and if a network is passed, filter also by network.
-        if (!ai.IsTerrible() && (network == std::nullopt || ai.GetNetClass() == network)) {
-            vAddr.push_back(ai);
-        }
+
+        // Filter by network (optional)
+        if (network != std::nullopt && ai.GetNetClass() != network) continue;
+
+        // Filter for quality
+        if (ai.IsTerrible(now)) continue;
+
+        vAddr.push_back(ai);
     }
 }

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.

Code review ACK 9d17f30.

Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK 9d17f30

@jonatack
Copy link
Member Author

jonatack commented May 19, 2021

rebased after merge of #21506, no other change

git range-diff 4da26fb 9d17f30 ce6bca8

     @@ src/net_processing.cpp: void PeerManagerImpl::ProcessMessage(CNode& pfrom, const std::string& msg_type,
              pfrom.vAddrToSend.clear();
              std::vector<CAddress> vAddr;
-         if (pfrom.HasPermission(PF_ADDR)) {
+         if (pfrom.HasPermission(NetPermissionFlags::Addr)) {
              vAddr = m_connman.GetAddresses(MAX_ADDR_TO_SEND, MAX_PCT_ADDR_TO_SEND, /* network */ std::nullopt);

@jonatack jonatack force-pushed the getnodeaddresses-by-network branch from 9d17f30 to ce6bca8 Compare May 19, 2021 11:13
Copy link
Contributor

@vasild vasild left a comment

Choose a reason for hiding this comment

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

ACK ce6bca8

@laanwj
Copy link
Member

laanwj commented May 20, 2021

Code review and lightly tested ACK ce6bca8

@laanwj laanwj merged commit 37e9f07 into bitcoin:master May 20, 2021
@jarolrod
Copy link
Member

post-merge ACK 👍

@jonatack jonatack deleted the getnodeaddresses-by-network branch May 20, 2021 19:01
sidhujag pushed a commit to syscoin/syscoin that referenced this pull request May 21, 2021
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 27, 2021
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 27, 2021
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 27, 2021
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 27, 2021
luke-jr pushed a commit to bitcoinknots/bitcoin that referenced this pull request Jun 27, 2021
random-zebra added a commit to PIVX-Project/PIVX that referenced this pull request Aug 12, 2021
e9d28da [Doc] Document getnodeaddresses in release notes (Fuzzbawls)
ebe2a46 test: improve getnodeaddresses coverage, test by network (Fuzzbawls)
91ac5c7 rpc: enable filtering getnodeaddresses by network (Fuzzbawls)
badfc49 p2p: allow CConnman::GetAddresses() by network, add doxygen (Fuzzbawls)
fa78233 p2p: allow CAddrMan::GetAddr() by network, add doxygen (Fuzzbawls)
a4d2733 p2p: pull time call out of loop in CAddrMan::GetAddr_() (Fuzzbawls)
d5c1250 p2p: enable CAddrMan::GetAddr_() by network, add doxygen (Fuzzbawls)
67e2c2f [RPC] add network field to getnodeaddresses (Fuzzbawls)
b4832b2 [Net] Add addpeeraddress RPC method (Fuzzbawls)
1a31b67 [test] Test that getnodeaddresses() can return all known addresses (Fuzzbawls)
e83fd0e [Addrman] Specify max addresses and pct when calling GetAddresses() (Fuzzbawls)
792655d [RPC] Add getnodeaddresses RPC command (chris-belcher)

Pull request description:

  Implement a new RPC command (`getnodeaddresses`) that provides RPC access to the node's addrman. It may be useful for PIVX wallets to broadcast their transactions over tor for improved privacy without using the centralized DNS seeds.

  I've included upstream improvements to this feature here as well, and this RPC command was used to scrape the Tor v3 hardcoded seed nodes added in #2502

  ---------
  Based on the following upstream PRs:
  * bitcoin#13152
  * bitcoin#19658
  * bitcoin#21594
  * bitcoin#21843

ACKs for top commit:
  furszy:
    all good, tested ACK e9d28da.
  random-zebra:
    utACK e9d28da and merging...

Tree-SHA512: 2e50108504ac8e172c2e31eb64813d6aae6b6819cf197eace2e4e15686906708b2f82262909faad00ce64af0f61945089a36b857064d3ce2398b3acb14e4ad7d
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Mar 3, 2022
Summary:
> p2p: enable CAddrMan::GetAddr_() by network, add doxygen
bitcoin/bitcoin@d35ddca

> p2p: pull time call out of loop in CAddrMan::GetAddr_()
bitcoin/bitcoin@c38981e

> p2p: allow CAddrMan::GetAddr() by network, add doxygen
bitcoin/bitcoin@a49f3dd

> p2p: allow CConnman::GetAddresses() by network, add doxygen
bitcoin/bitcoin@80ba294

This is a partial backport of [[bitcoin/bitcoin#21843 | core#21843]] [1/2]

The fuzzer file does not exist in Bitcoin ABC because of missing backports.

Review hint: this first part of the backport includes all changes of the pull request except for release notes, functional tests and most changes to `src/rpc/net.cpp`

Test Plan:
```

ninja all check-all bench-bitcoin

```

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D11127
Fabcien pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Mar 3, 2022
Summary:
Enable filtering `getnodeaddresses` by network.

Improve `getnodeaddresses` coverage, test by network

This concludes backport of [[bitcoin/bitcoin#21843 | core#21843]]
bitcoin/bitcoin@6c98c09 (feature)
bitcoin/bitcoin@3f89c0e (functional tests)
bitcoin/bitcoin@ce6bca8 (release note)

Depends on D11127

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D11128
gwillen pushed a commit to ElementsProject/elements that referenced this pull request Jun 1, 2022
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Aug 18, 2022
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.

8 participants