-
Notifications
You must be signed in to change notification settings - Fork 233
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
dht mode toggling (modulo dynamic switching) #350
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks good for the most part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shaping up well.
dht.go
Outdated
@@ -41,6 +41,11 @@ var logger = logging.Logger("dht") | |||
// collect members of the routing table. | |||
const NumBootstrapQueries = 5 | |||
|
|||
const ( | |||
ModeServer = 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can use a custom type definition and iota here.
|
||
// hacky... also closes both inbound and outbound streams | ||
for _, c := range dht.host.Network().Conns() { | ||
for _, s := range c.GetStreams() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re: backwards-compatibility. This is where the tricky part comes in. This drops streams for peers in our routing table. It will not invite the peer to drop us from theirs. So they’ll keep querying us, and we’ll “na” all their negotiations. We’ll basically become an unhelpful peer taking up a slot in their table, unless we disconnect to trigger the removal.
On a related note, there seems to be a race between identify and the DHT notifee. Even if we disconnect and reconnect, if the DHT notifee runs before identify finishes, we might be deciding on stale protocols: https://github.com/libp2p/go-libp2p-kad-dht/blob/master/notif.go#L27
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah... the backwards compatibility bit kinda sucks. I don't know that a nice backwards compatible solution exists aside from hard disconnecting from those peers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd much rather track streams manually.
Alright, I'm only closing inbound dht streams now, and i'm resetting them instead of just closing. Anyone have ideas for good tests to write to test this out? |
@whyrusleeping maybe just use mocknet to make two hosts and check the behavior of |
@bigs feel like taking a stab at writing those tests?
With the relay infrastructure, the network is, in theory, very well connected. We need to implement the logic that's going to dynamically switch from one to another. Without it, this PR is equivalent to the existing |
@raulk exactly. The point of this is just giving some other code the ability to switch between the two. The next step is to start all ipfs nodes in client mode, and only switch to server mode if autonat detects a publicly dialable peer |
@whyrusleeping do you want to implement the controller in IPFS (since I believe it has access to autonat), or should we do it in the DHT via one of the options here: #349 (comment), and then switch to the event bus when it’s ready? |
I think doing it in ipfs will likely be the simplest solution. Unless you
disagree, let's go with that.
…On Mon, Jun 17, 2019, 2:34 PM Raúl Kripalani ***@***.***> wrote:
@whyrusleeping <https://github.com/whyrusleeping> do you want to
implement the controller in IPFS (since I believe it has access to
autonat), or should we do it in the DHT via one of the options here: #349
(comment)
<#349 (comment)>,
and then switch to the event bus when it’s ready?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#350?email_source=notifications&email_token=AAJPQHDGY2XACBOZ7R3XOOTP27RNHA5CNFSM4HX36MEKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODX4G6ZA#issuecomment-502820708>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAJPQHCW2T7PV56RDZBE5VDP27RNHANCNFSM4HX36MEA>
.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We still need to wire this through to identify:
- We need to know when the peer starts speaking the DHT protocol.
- We need to know when the peer stops speaking the DHT protocol.
(mostly 1).
|
||
// hacky... also closes both inbound and outbound streams | ||
for _, c := range dht.host.Network().Conns() { | ||
for _, s := range c.GetStreams() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd much rather track streams manually.
return nil | ||
} | ||
|
||
func (dht *IpfsDHT) moveToClientMode() error { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be fine but I'd feel safer if we checked if we were in client mode in the stream handler, just in case.
Alright, current plan of attack:
Old peers will be slow to add new peers to their routing tables, as we currently rely on the protocol probe up front for detecting if peers are in client mode. If older peers are informed about new peers in server mode who they previously rejected as a client, they will attempt to open a new stream to that peer, so eventually this will propagate around. New peers will include old peers in their routing table if they start in server mode. We thought about adding an extra DHT message to signal whether or not we are in server mode or client mode, but the problem there is that it requires you to keep the listeners on. I'm not actually sure this is that bad of a problem. |
added an extremely basic test demonstrating the change in behavior from client -> server -> client |
Thanks @bigs ! I pushed changes that add handling for identify push protocol changes from other peers. The next (And hopefully final) step is to decide if we want to version bump the dht. it will be pretty painful, but should make the resulting DHT muuuuch better. |
How this could pan out:
I think this is a good idea, and can implement it very easily. thoughts? @raulk @vyzo @Stebalien @Kubuxu |
dht.go
Outdated
|
||
if !cfg.Client { | ||
dht.mode = ModeServer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just call modeToServer?
Do it. Peer routing should still work as long as the old node is connected to at least one new node. Note: We don't want to add support for the new protocol and use both. If we do that, the dht's will "join" and turning off the old protocol won't break them (until everyone upgrades). |
dht.go
Outdated
ch := make(chan event.EvtPeerProtocolsUpdated, 8) | ||
cancel, err := dht.host.EventBus().Subscribe(ch) | ||
if err != nil { | ||
return nil, err |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this compile?
dht.go
Outdated
|
||
if add && drop { | ||
// TODO: discuss how to handle this case | ||
log.Warning("peer adding and dropping dht protocols? odd") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the way this is implemented, in practice it's very, very, very unlikely that the event will contain (a) multiple protocols, and/or (b) multiple operations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
right, but its possible, so what do we do when it does?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is tricky. the data model allows it to happen, but the implementation doesn't allow it to happen. maybe we should revisit these event structs to eliminate the * cardinality.
This is WIP and there are still items being discussed. Removing this review to avoid confusion.
@whyrusleeping that sounds fair, and I arrive to the same conclusion re: the tradeoff. But I'd like us to evaluate these alternate scenarios:
|
Co-Authored-By: Raúl Kripalani <raul.kripalani@gmail.com>
210d9f1
to
5f434a8
Compare
|
||
if add && drop { | ||
// TODO: discuss how to handle this case | ||
logger.Warning("peer adding and dropping dht protocols? odd") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proposal: "Peer is bad, we don't want them in our routing table"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can either noop (since both operations cancel each other out), or discard the peer altogether.
closes #349
First stab at this, trying to make it as minimally invasive as possible.
Please suggest tests to write (or please help me test).
I think we can avoid the extra message type i mentioned in the issue, and rely on protocol negotiation to handle getting peers to drop us from their routing tables. Old peers will be a little messed up by this, but they already have such a hard time dialing and connecting anyways, i don't think anyone will notice a difference