Open lzl124631x opened 5 years ago
So sometimes I can see the multiaddr but sometimes not. Why?
not sure about that.
Why was there a host with port 59919 created for 5000?
that's an ephemeral port, it is created by the kernel when you make an outbound connection.
@lzl124631x What OS?
@anacrolix
Richards-MacBook-Pro:~ ricl$ sw_vers
ProductName: Mac OS X
ProductVersion: 10.14.1
BuildVersion: 18B75
I've forgotten why I asked that, but it was relevant at the time.
Hey @lzl124631x. With reference to your first question:
Task:
Note: Locally known (cached) providers are stored in something called a providerSet
. A call to FindProviders
, FindProvidersAsync
or Provide
will be responsible for updating any new peer to the providerSet
. (there might be other functions which can update providerSet
)
The situation you are facing arises when your node, say X
tries to connect to some other node, say Y
which is already connected to the bootstrap node, B
(or any node common to X
and Y
).
Y
wants to connect to B
. After successfully connecting, B
stores Y
in its closest peers list and vice versa. Y
also called Y.dht.Provide("key")
to be a provider for "key".X
connects to B
, they connect successfully. X.dht.Provide()
is called:
3.1 X
adds itself to the providerSet
but with empty address i.e. []. (This is important)
3.2 It then calls X.dht.GetClosestPeers
which fetches second degree peers from the NearestPeers
i.e. B
for now.
3.3 B
will return Y
along with its addresses. Now, X
will connect to Y
. [I think this step was added to improve your connections automatically. A node will automatically connect to its second degree nodes if you have insufficient number of connections.]
3.4 At this point node X
and Y
are connected to each other. Although Y
is not added in the providerSet
of X
and vice versa.X.dht.FindProvider("key")
is called:
4.1 X
will run a query to find if NearestPeers
can be a provider for "key".
4.2 NearestPeers
to X
at this time are B
and Y
and both will return a list of peers they know can be a provider for "key".
4.3 Y
will return itself as it can be a provider for "key" but it will return empty list of address for itself. B
also returns Y
as B
knows that Y
can be a provider but because B
knows Y's
addresses, B
returns a full list of addresses of Y
.
4.4 Now the problem is which query returns first. If the answer from Y
is returned first it will be an empty list of address and if B
returns you will get a full list of addresses. Although you can overwrite the empty list but PeerSet.TryAdd
used here does not add the peer to the provider set if its already in the set even if the addresses are empty. When FindProvider
returns an empty list, under above circumstances, you are already connected to that peer so host.Connect
will be successful. Hence, Connected to: {<peer.ID Qm*UB48gJ> []} chat.go:183
.
I think this can be reported as a bug. Ideally, a node should replace an empty list of addresses with addresses known from some other peer but findProvidersAsyncRoutine
uses a chan pstore.PeerInfo
for output and a result is immediately written to this chan. This means whichever query returns the result first will be written to the chan and subsequent results will be ignored.
Background
I started 4
chat-with-rendezvous
locally with port 3000, 4000, 5000, 6000 respectively.My forked example repo: https://github.com/lzl124631x/go-libp2p-examples/commit/adb0eb38bef472749742ada537c431490c019005
Question 1
Sometimes I saw log like this:
while other times I saw:
So sometimes I can see the multiaddr but sometimes not. Why?
Question 2
I saw message like this:
Why was there a host with port
59919
created for5000
?@Stebalien @upperwal @vyzo