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

feat: address management #612

Merged
merged 4 commits into from
Apr 29, 2020
Merged

feat: address management #612

merged 4 commits into from
Apr 29, 2020

Conversation

vasco-santos
Copy link
Member

@vasco-santos vasco-santos commented Apr 20, 2020

This PR adds an Address Management component. This component aims to allow users to add to the libp2p configuration { listen, announce, noAnnounce } addresses.

These addresses will be used by each subsystem according to their needs. The details for the reasoning for these addresses are detailed on /src/address-manager/README.md, which should be read in this branch (last commit)

Needs:

  • Address Manager tests
  • Remove multiaddrs from discovery
  • Consider Listen addresses update on noAnnounce addresses filtering
  • Improve configuration doc

Closes #202

Depends on:

@vasco-santos
Copy link
Member Author

cc @jacobheun

Once you have time, please check this out and let me know your thoughs. Go to the feat: address manager commit and look into:

  • Address Manager Readme
  • API Readme
  • src/address-manager/index.js: there is one TODO comment

Copy link
Contributor

@jacobheun jacobheun left a comment

Choose a reason for hiding this comment

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

Added some thoughts on how advertised addresses could be handled.

* @param {Array<Multiaddr>} newMultiaddrs
* @return {Array<Multiaddr>}
*/
_replaceListen (newMultiaddrs) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should do this, it makes tracking things more difficult and since we're not tracking everything in PeerInfo this is a bit easier to manage. We should keep the listen, announce, and noAnnounce untouched. They could be added to, but we shouldn't internally replace them, these should be user controlled.

We should have a method that computes everything for advertised addresses, this could live on libp2p itself. libp2p.getAddrs() or similar. This method would do something like:

  • Get the TransportManager addresses, libp2p.transportManager.getAddrs()
  • Add in the announce addresses, [...libp2p.transportManager.getAddrs(), ...libp2p.addressManager.announce]
  • And then filter out matching noAnnounce and any duplicate addresses

The big advantage of this is that we are able to update addresses over time and will always be able to reference our original addresses. Things like Identify will just be able to call this method when they need the latest addresses.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also with this, I think we can simplify this class; get rid of the getters and just expose the properties.

Copy link
Member Author

Choose a reason for hiding this comment

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

This solution seems good to me and I will try it out. My main concern here is the same issue that I still have to solve: noAnnounce addresses using random ports for filtering. Unless the match criteria does not consider the port, we would need to make a comparison between the provided listenAddr and what is in libp2p.transportManager.getAddrs()

Copy link
Member Author

Choose a reason for hiding this comment

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

changed accordingly

Copy link
Contributor

@jacobheun jacobheun Apr 27, 2020

Choose a reason for hiding this comment

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

This solution seems good to me and I will try it out. My main concern here is the same issue that I still have to solve: noAnnounce addresses using random ports for filtering

Not sure I follow. Are you concerned that a listening address of /ip4/0.0.0.0/tcp/0 can't be filtered with a noAnnounce of /ip4/0.0.0.0/tcp/0? If so, I don't think this matters and users shouldn't be trying to do this. While this is helpful for testing, listening on random ports is not recommended for production usage. The only noAnnounce "wildcard" I think would be nice to have is filtering loopback IP addresses, but that could be checked by the app before configuring libp2p.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes. I already added support for that now, but it is a bit messy 😅

The only noAnnounce "wildcard" I think would be nice to have is filtering loopback IP addresses, but that could be checked by the app before configuring libp2p.

👍

@vasco-santos vasco-santos force-pushed the feat/address-management branch 2 times, most recently from 1095875 to 8a86437 Compare April 27, 2020 07:48
@vasco-santos vasco-santos force-pushed the feat/address-management branch 2 times, most recently from ef59d4a to 7d9a8d1 Compare April 27, 2020 16:33
Copy link
Contributor

@jacobheun jacobheun left a comment

Choose a reason for hiding this comment

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

Mostly minor things and some language clarifications


### Examples

#### Basic setup

TODO: should we add to the basic setup the configuration of listen addresses? we should probably make it a required option?
Copy link
Contributor

Choose a reason for hiding this comment

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

It shouldn't be required. Creating a dial only node is a valid use case.

doc/API.md Outdated

`libp2p.peerRouting.findPeer(peerId, options)`
`libp2p.getAdvertisingMultiaddrs()`
Copy link
Contributor

Choose a reason for hiding this comment

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

We discussed offline making this a computed getter, libp2p.multiaddrs, to be similar to libp2p.peerInfo.multiaddrs.

doc/API.md Outdated
```

### addressManager.getAnnounceMultiaddrs
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe truncate these methods to addressManager.get...Addrs?

@@ -136,6 +136,8 @@ If you want to know more about libp2p stream multiplexing, you should read the f

Now that you have configured a [**Transport**][transport], [**Crypto**][crypto] and [**Stream Multiplexer**](streamMuxer) module, you can start your libp2p node. We can start and stop libp2p using the [`libp2p.start()`](./API.md#start) and [`libp2p.stop()`](./API.md#stop) methods.

TODO: add listen addresses here?
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, I would configure a websocket listen address (on a specific port).


#### Modify Listen Addresses

While adding new addresses to listen on runtime is a feasible operation, removing one listen address might have bad implications for the node, since all the connections using that listen address will be closed. With this in mind and taking also into consideration the lack of good use cases for removing listen addresses, the Address Manager API only allows libp2p users to add new Listen Addresses on runtime.
Copy link
Contributor

Choose a reason for hiding this comment

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

A future use case for removing listening addresses would be Relay and Rendezvous. If we asked used Rendezvous to find relays to listen on, we could add them to our list. If the relay we found was at its maximum listener capacity, it could potentially tell us to go away, at which point we would likely remove it from our listen addresses.

I don't think we need to speculate on the operations here though. Mentioning the potential of them changing in runtime and that it should provide a mechanism for listening to those changes would be sufficient here.

* @param {Map<string, handler>} options.protocols A reference to the protocols we support
* @param {PeerId} options.peerId The peer running the identify service
* @param {{ listen: Array<Multiaddr>}} options.addresses The peer addresses
*/
constructor (options) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Not that there are fewer params this could help simplify the options accessor calls in the constructor

Suggested change
constructor (options) {
constructor ({ libp2p, protocols }) {

src/index.js Outdated
return false
}

// Filter out if in the special filter
Copy link
Contributor

Choose a reason for hiding this comment

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

I would remove support for this right now and we can look at doing a followup PR for this with verbose testing. I think this logic isn't quite right and non TCP addresses might behave unexpectedly here.

@vasco-santos vasco-santos force-pushed the feat/address-management branch from a7c4dcd to 0b439fe Compare April 28, 2020 14:45
@vasco-santos vasco-santos force-pushed the feat/address-management branch from 0b439fe to 21b39eb Compare April 28, 2020 14:49
@vasco-santos
Copy link
Member Author

vasco-santos commented Apr 28, 2020

@jacobheun everything should be addressed now, and the dependent PR, as well as the pubsub discovery module were updated according to these changes

@@ -122,7 +122,7 @@ class Circuit {
type: CircuitPB.Type.HOP,
srcPeer: {
id: this.peerId.toBytes(),
addrs: this.addresses.listen.map(addr => addr.buffer)
addrs: this.addressManager.getListenAddrs().map(addr => addr.buffer)
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be libp2p.multiaddrs not the listen addrs.

src/index.js Outdated
@@ -189,6 +188,8 @@ class Libp2p extends EventEmitter {
*/
async start () {
log('libp2p is starting')
// TODO: consider validate listen addresses on start?
// depend on transports?
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you mean? When the TransportManager listens it results in each Transport filtering out all addresses that don't match it. We're not logging any information around "hey, you gave us an address and there is no transport that's valid for it", unless non of the addresses match any transport.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is not valid anymore. Old thought

@vasco-santos vasco-santos force-pushed the feat/address-management branch from c5764cf to 7b8e5be Compare April 29, 2020 14:24
Copy link
Contributor

@jacobheun jacobheun left a comment

Choose a reason for hiding this comment

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

This LGTM. CI is having issues, this should be good to merge.

@vasco-santos vasco-santos merged commit e5592b0 into 0.28.x Apr 29, 2020
@achingbrain achingbrain deleted the feat/address-management branch May 18, 2023 13:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants