Skip to content
Permalink
Browse files

Feat: Enable DHT-based peer discovery and routing for cluster peers

This uses go-libp2p-kad-dht as routing provider for the Cluster Peers.

This means that:

* A cluster peer can discover other Cluster peers even if they are
not in their peerstore file.
* We remove a bunch of code sending and receiving peers multiaddresses
when a new peer was added to the Cluster.
* PeerAdd now takes an ID and not a multiaddress. We do not need to
ask the new peer which is our external multiaddress nor broadcast
the new multiaddress to everyone. This will fix problems when bootstrapping
a new peer to the Cluster while not all the other peers are online.
* Adding a new peer does not mean to open connections to all peers
anymore. The number of connections will be made according to the DHT
parameters (this is good to have for future work)

The that detecting a peer addition in the watchPeers() function does
no longer mean that we have connected to it or that we know its
multiaddresses. Therefore it's no point to save the peerstore in these
events anymore.

Here a question opens, should we save the peerstore at all, and should we
save multiaddresses only for cluster peers, or for everyone known?
Currently, the peerstore is only updated on clean shutdown,
and it is updated with all the multiaddresses known, and not limited to
peer IDs in the cluster, (because, why not).

License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
  • Loading branch information...
hsanjuan committed Jul 17, 2018
1 parent 99aea7b commit d3d1f960f5d4823b6fbea4d472cf0984488e5bd6
Showing with 144 additions and 204 deletions.
  1. +6 −7 api/rest/client/methods.go
  2. +1 −2 api/rest/client/methods_test.go
  3. +4 −4 api/rest/restapi.go
  4. +4 −4 api/rest/restapi_test.go
  5. +73 −119 cluster.go
  6. +7 −2 package.json
  7. +41 −18 peer_manager_test.go
  8. +4 −2 pnet_test.go
  9. +3 −39 rpc_api.go
  10. +1 −7 test/rpc_api_mock.go
@@ -8,11 +8,10 @@ import (
"net/url"
"time"

"github.com/ipfs/ipfs-cluster/api"

cid "github.com/ipfs/go-cid"
peer "github.com/libp2p/go-libp2p-peer"
ma "github.com/multiformats/go-multiaddr"

"github.com/ipfs/ipfs-cluster/api"
)

// ID returns information about the cluster Peer.
@@ -34,13 +33,13 @@ func (c *Client) Peers() ([]api.ID, error) {
}

type peerAddBody struct {
Addr string `json:"peer_multiaddress"`
PeerID string `json:"peer_id"`
}

// PeerAdd adds a new peer to the cluster.
func (c *Client) PeerAdd(addr ma.Multiaddr) (api.ID, error) {
addrStr := addr.String()
body := peerAddBody{addrStr}
func (c *Client) PeerAdd(pid peer.ID) (api.ID, error) {
pidStr := peer.IDB58Encode(pid)
body := peerAddBody{pidStr}

var buf bytes.Buffer
enc := json.NewEncoder(&buf)
@@ -104,8 +104,7 @@ func TestPeerAdd(t *testing.T) {
defer shutdown(api)

testF := func(t *testing.T, c *Client) {
addr, _ := ma.NewMultiaddr("/ip4/1.2.3.4/tcp/1234/ipfs/" + test.TestPeerID1.Pretty())
id, err := c.PeerAdd(addr)
id, err := c.PeerAdd(test.TestPeerID1)
if err != nil {
t.Fatal(err)
}
@@ -79,7 +79,7 @@ type route struct {
}

type peerAddBody struct {
PeerMultiaddr string `json:"peer_multiaddress"`
PeerID string `json:"peer_id"`
}

// NewAPI creates a new REST API component with the given configuration.
@@ -506,17 +506,17 @@ func (api *API) peerAddHandler(w http.ResponseWriter, r *http.Request) {
return
}

mAddr, err := ma.NewMultiaddr(addInfo.PeerMultiaddr)
_, err = peer.IDB58Decode(addInfo.PeerID)
if err != nil {
sendErrorResponse(w, 400, "error decoding peer_multiaddress")
sendErrorResponse(w, 400, "error decoding peer_id")
return
}

var ids types.IDSerial
err = api.rpcClient.Call("",
"Cluster",
"PeerAdd",
types.MultiaddrToSerial(mAddr),
addInfo.PeerID,
&ids)
sendResponse(w, err, ids)
}
@@ -275,7 +275,7 @@ func TestAPIPeerAddEndpoint(t *testing.T) {
tf := func(t *testing.T, url urlF) {
id := api.IDSerial{}
// post with valid body
body := fmt.Sprintf("{\"peer_multiaddress\":\"/ip4/1.2.3.4/tcp/1234/ipfs/%s\"}", test.TestPeerID1.Pretty())
body := fmt.Sprintf("{\"peer_id\":\"%s\"}", test.TestPeerID1.Pretty())
t.Log(body)
makePost(t, rest, url(rest)+"/peers", []byte(body), &id)

@@ -292,10 +292,10 @@ func TestAPIPeerAddEndpoint(t *testing.T) {
if errResp.Code != 400 {
t.Error("expected error with bad body")
}
// Send invalid multiaddr
makePost(t, rest, url(rest)+"/peers", []byte("{\"peer_multiaddress\": \"ab\"}"), &errResp)
// Send invalid peer id
makePost(t, rest, url(rest)+"/peers", []byte("{\"peer_id\": \"ab\"}"), &errResp)
if errResp.Code != 400 {
t.Error("expected error with bad multiaddress")
t.Error("expected error with bad peer_id")
}
}

0 comments on commit d3d1f96

Please sign in to comment.
You can’t perform that action at this time.