libp2p / specs

Technical specifications for the libp2p networking stack
https://libp2p.io
1.55k stars 273 forks source link

Proposal: use a list of addresses in priority order for autonat v2 dial requests #539

Open sukunrt opened 1 year ago

sukunrt commented 1 year ago

In discussion with @marten-seemann he suggested:

Maybe the client could send a list of addresses it wants dialed, in descending priority. The receiver would pick exactly one of them and dial it

the proposal is:

Client has a list of addresses it wants to determine reachability for. In a dialRequest they send this list of address in priority order to the autonat server. The autonat server dials the first address it is capable of dialing and reports success or failure for that address.

This will be helpful in cases where we are interested in determining reachability for a newly address transport for which support in the network is low. Many requests for this new transport address will be rejected because the server cannot dial this transport. This proposal allows us to reuse those requests to check reachability for other addresses.

For some history this suggestion is an improvement over the scheme suggested here https://github.com/libp2p/specs/pull/538#discussion_r1162730358 . This scheme aimed to solve the same problem.

sukunrt commented 1 year ago

I'm not entirely convinced of the benefits here. Consider the case where a Node has two addresses, a new transport address NewA and an old transport address OldA.

The node already knows the reachability of OldA. Now it is interested in determining the reachability of NewA. On dial requests for NewA the node is able to obtain confirmation of the reachability status of OldA. But these confirmations aren't very helpful since we will need to confirm the reachability of OldA again after some expiry time. Consider that we are confirming the reachability of all addresses every half an hour. We look at two 30 minute windows 0-30 and 30-60. No matter how many confirmations we get for OldA in the first slot of 0-30 we will need to check reachability once for OldA in the second slot 30-60

This argument gets weaker the more addresses the node gets. Another point in support of the proposal is this protocol will be a superset of the single address request protocol where you send exactly one address in request for reachability testing. Autonat client implementations wishing to simplify can implement a single request per address system within this scheme by sending exactly one address always.

marten-seemann commented 1 year ago

You’d need to be smarter than just sending your entire list of addresses. If you have enough confirmations for OldA, don’t send it.

Where this proposal leads to improvements is in situations where

sukunrt commented 1 year ago

Can you elaborate?

you generate „guesses“ for new addresses (like https://github.com/libp2p/go-libp2p/pull/2251 for example)

Why can't you verify these guesses with a single address request protocol?

marten-seemann commented 1 year ago

I expect us to generate a number of guesses. Not all of them will be super high priority to test them, but rather a „nice to have“. Those addresses can then be added as lower-prio addresses.

sukunrt commented 1 year ago

This will be helpful in cases where we are interested in determining reachability for a newly address transport for which support in the network is low. Many requests for this new transport address will be rejected because the server cannot dial this transport. This proposal allows us to reuse those requests to check reachability for other addresses.

I think my understanding here was wrong.

Should we put this new transport address in to a lower priority bucket that's added on to requests as a "nice to have"? This would reduce the number of dial requests in the network since actively verifying these new transport address might spam the network a lot?

marten-seemann commented 1 year ago

Should we put this new transport address in to a lower priority bucket that's added on to requests as a "nice to have"? This would reduce the number of dial requests in the network since actively verifying these new transport address might spam the network a lot?

Why would they be lower priority? You'd really want to confirm the new transport, if you manage to find a peer that speaks that transport already. Therefore, it would need to have the highest priority, wouldn't it?

sukunrt commented 1 year ago

How would we determine whether the peer supports a particular transport? Based on the advertised addresses in identify?

marten-seemann commented 1 year ago

Here's how I imagine an AutoNAT v2 client would be implemented: The client keeps a list of addresses that it's tracking.

Factors that increase the priority of an address:

Factors that decrease the priority:

I'm sure there's more factors we can come up with to create a ranking.

sukunrt commented 1 year ago

This makes sense. Thanks for elaborating.

This proposal would help in cases when you have many low priority addresses.