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

options to configure static relays for autorelay #705

Merged
merged 2 commits into from
Jan 17, 2020

Conversation

vyzo
Copy link
Contributor

@vyzo vyzo commented Aug 16, 2019

So that we can avoid hitting the DHT; also changes the desired relays parameter to 1 (from 3).
See #694

@vyzo vyzo requested review from Stebalien and raulk August 16, 2019 10:01
@albrow
Copy link
Contributor

albrow commented Aug 19, 2019

Does the StaticRelays option mean that those are the only relays that can be used? Ideally, for our network we would like to use static relays to reduce the time to first connection but we still want to discover other relays over time. Otherwise our dedicated relay hosts would be overworked.

@vyzo
Copy link
Contributor Author

vyzo commented Aug 19, 2019

With this patch yes, when specified only those will be used.
Perhaps we should have a fallback to the DHT, but the issue is that we are having excessive DHT traffic because of autorelay.

@vyzo
Copy link
Contributor Author

vyzo commented Aug 19, 2019

ping @Stebalien

@vyzo
Copy link
Contributor Author

vyzo commented Aug 19, 2019

Moving forward we also want to use relays discovered by passive discovery (when the option circuit.OptDiscovery is specified).

options.go Outdated
Comment on lines 263 to 265
"/ip4/147.75.80.110/tcp/4001/p2p/QmbFgm5zan8P6eWWmeyfncR5feYEMPbht5b1FW1C37aQ7y",
"/ip4/147.75.195.153/tcp/4001/p2p/QmW9m57aiBDHAkKj9nmFSEn7ZqrcF1fZS4bipsTCHburei",
"/ip4/147.75.70.221/tcp/4001/p2p/Qme8g49gm3q4Acp7xWBKg3nAa9fxZ1YmyDJdyGgoG6LsXh",
Copy link
Member

Choose a reason for hiding this comment

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

Can we have these multiaddrs in a global var? You can initialize them with an IIFE, or in an init function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sure.

p2p/host/relay/autorelay.go Show resolved Hide resolved
@@ -245,6 +248,10 @@ func (ar *AutoRelay) connect(ctx context.Context, pi peer.AddrInfo) bool {
}

func (ar *AutoRelay) discoverRelays(ctx context.Context) ([]peer.AddrInfo, error) {
if len(ar.static) > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think setting static relays should be exclusive from dynamic relay discovery. You probably want static relays for a speedier bootup, but as you dynamically discover relays, you should preferentially switch to those.

Copy link
Member

Choose a reason for hiding this comment

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

I see that @albrow expected the same thing: #705 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This defeats the purpose; the main impetus for the static relay configuration is to avoid hitting the DHT altogether.
We might want to leverage passive discovery with CanHop in the relay module, but I don't think it's a good idea to have both static relays and hit the dht.

Copy link
Member

Choose a reason for hiding this comment

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

At the moment, auto relay discovery is pretty much broken. We have no way to distinguish between good relays and bad relays.

Copy link
Member

Choose a reason for hiding this comment

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

The current "automatically pick a relay" feature is broken. Unfortunately, you're likely to pick a random configured relay with a low connection limit. When that happens, you'll have to keep churning through relays till one sticks.

Really, this is a feature where we either need "blessed" relays or some kind of reputation system.

@vyzo
Copy link
Contributor Author

vyzo commented Oct 8, 2019

Updated to use a global variable in the autorelay module for the default relays; also renamed the DefaultRelays to DefaultStaticRelays and made StaticRelays append instead of overwriting.

and rename DefaultRelays option to DefaultStaticRelays.
Copy link
Member

@Stebalien Stebalien left a comment

Choose a reason for hiding this comment

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

I'd like to include this in a go-ipfs patch release to reduce the stress on the network. @raulk, can we merge this with no changes for now?

Adding support for both static and dynamic relays at the same time is non-trivial.

@@ -245,6 +248,10 @@ func (ar *AutoRelay) connect(ctx context.Context, pi peer.AddrInfo) bool {
}

func (ar *AutoRelay) discoverRelays(ctx context.Context) ([]peer.AddrInfo, error) {
if len(ar.static) > 0 {
Copy link
Member

Choose a reason for hiding this comment

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

The current "automatically pick a relay" feature is broken. Unfortunately, you're likely to pick a random configured relay with a low connection limit. When that happens, you'll have to keep churning through relays till one sticks.

Really, this is a feature where we either need "blessed" relays or some kind of reputation system.

Copy link
Member

@raulk raulk left a comment

Choose a reason for hiding this comment

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

Armed with a much better understanding now, I agree that automatic discovery works less ideally than we’d want, anyway.

If somebody is using autorelay, they’re probably better off using static relays for predictability.

I don’t think we need to go as far as reputational systems to make this functional at first: a BIND/ALLOCATE operation could go a long way.

I’m ok merging this as-is, but I’d really like static relays used while we’re discovering dynamic relays (assuming the discovery works well), and dropping them as soon as we’ve bound to dynamic ones. If those fail, we can fall back to the static ones — making these relays useful for fallback and “fast start”.

@Stebalien
Copy link
Member

Agreed. Static relays are really just an emergency measure until we can implement a better system.

@Stebalien Stebalien merged commit 76944c4 into master Jan 17, 2020
This was referenced Jan 17, 2020
@RubenKelevra
Copy link

RubenKelevra commented Jan 31, 2020

Agreed. Static relays are really just an emergency measure until we can implement a better system.

How about flipping the process, having a node subscribe to pubsub when they need a relay.

All nodes which offer the relay service will send a message on this pubsub on how many connections they can accept.

The number is multiplied with a number x (which is something like 0.01 in the beginning) and is the probably that the node will try to connect to this relay.

On connection to the relay we send a 'request' for relay services. When the relay is already full, it will send a deny message and close the connection.

On each failure to connect to a relay, the number x is cut down in half, to simply estimate the 'load' on all the relays.

After a random period between 30 and 600 minutes the number x is multiplied by 2 again.

@Stebalien
Copy link
Member

We should advertise relays through pubsub (and maybe even just have relays advertise other relays). However, there's still the issue of reputation.

@RubenKelevra
Copy link

@Stebalien I think that's an issue for another time. I think it's best to just replace the DHT method with something that's responding dynamically to the network size, by lowering the connection attempts.

The optimal solution for fixing this would be to add peers in a Web Of Trust fashion and allow 'friends' to use the relay function.

We could also hold those connections all the time and bootstrap with the friend connections first, instead of the static IPs and domains we currently use.

@Stebalien
Copy link
Member

I'm not sure if that's an issue we can punt on. It takes a bit of effort to attack the DHT. It would take very little effort to add enough bad relays to affect the network.

We don't really need a full WoT system, even just something that verifies that a relay is doing the right thing would be enough. For example, some way to ask other peers to dial back through the relay and verify that it's working.

@RubenKelevra
Copy link

@Stebalien if we change the amount of desired relays back to 3, we could check each of those relays by requesting some data:

One relay is asked to provide some random stuff, and we request it thru both other relays.

We cycle this thru all 3 relays to confirm all relays are working fine.


Another possibility is to request everything round robin thru the 3 relays, and if we identify a relay which is sending data which doesn't match the checksums for example, we drop that connwc and create a new one.

ar := &AutoRelay{
host: bhost,
discover: discover,
router: router,
addrsF: bhost.AddrsFactory,
static: static,
Copy link
Collaborator

Choose a reason for hiding this comment

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

@vyzo I know I'm late to the party here, but this felt a bit small for an issue.

Why did we bother changing the constructor and using a []Addr.Info here instead of just creating a Discoverer implementation that returns a the static list?

Sure it can be more efficient to use the slice, but now we have this thing we're going to be stuck removing.

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.

6 participants