Skip to content

Commit

Permalink
feat(ResolveDatasetRef): new action for resolving dataset references
Browse files Browse the repository at this point in the history
feeling pretty pumped about this method rn. Our code has needed a clearly-defined
name resolution system for a while now, and I think this method gets such a system
in place. Not _finished_, just, in place.
  • Loading branch information
b5 committed Sep 11, 2018
1 parent 38d34c8 commit 00aefc2
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 4 deletions.
20 changes: 20 additions & 0 deletions actions/dataset_ref.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package actions

import (
"github.com/qri-io/qri/p2p"
"github.com/qri-io/qri/repo"
)

// ResolveDatasetRef uses a node to complete the missing pieces of a dataset
// reference. The most typical example is completing a human ref like
// peername/dataset_name with content-addressed identifiers
// It will first attempt to use the local repo to Canonicalize the reference,
// falling back to a network call if one isn't found
// TODO - consider reinforcing p2p network with registry lookups
func ResolveDatasetRef(n *p2p.QriNode, ref *repo.DatasetRef) error {
if err := repo.CanonicalizeDatasetRef(n.Repo, ref); err == nil && ref.Path != "" {
return nil
}

return n.ResolveDatasetRef(ref)
}
53 changes: 53 additions & 0 deletions actions/dataset_ref_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package actions

import (
"context"
"testing"

"github.com/qri-io/qri/p2p"
"github.com/qri-io/qri/p2p/test"
"github.com/qri-io/qri/repo"
)

func TestResolveDatasetRef(t *testing.T) {
ctx := context.Background()
factory := p2ptest.NewTestNodeFactory(p2p.NewTestableQriNode)
testPeers, err := p2ptest.NewTestNetwork(ctx, factory, 3)
if err != nil {
t.Fatalf("error creating network: %s", err.Error())
}
if err := p2ptest.ConnectNodes(ctx, testPeers); err != nil {
t.Fatalf("error connecting peers: %s", err.Error())
}

// Convert from test nodes to non-test nodes.
peers := make([]*p2p.QriNode, len(testPeers))
for i, node := range testPeers {
peers[i] = node.(*p2p.QriNode)
}

// give peer 1 a ref that others don't have
p, err := peers[1].Repo.Profile()
if err != nil {
t.Fatal(err)
}
ref := repo.DatasetRef{Peername: p.Peername, Name: "bar", ProfileID: p.ID, Path: "/ipfs/QmXSGsgt8Bn8jepw7beXibYUfWSJVU2SzP3TpkioQVUrmM"}
if err = peers[1].Repo.PutRef(ref); err != nil {
t.Fatalf("error putting ref in repo: %s", err.Error())
}
expect := "test-repo-1/bar@QmWYgD49r9HnuXEppQEq1a7SUUryja4QNs9E6XCH2PayCD/ipfs/QmXSGsgt8Bn8jepw7beXibYUfWSJVU2SzP3TpkioQVUrmM"
in := &repo.DatasetRef{Peername: "test-repo-1", Name: "bar"}

// TODO - fix this lie
peers[2].Online = false
if err := ResolveDatasetRef(peers[2], in); err == nil {
t.Error("expected offline node to not be able to resolve non-local ref")
}

if err := ResolveDatasetRef(peers[0], in); err != nil {
t.Error(err.Error())
}
if in.String() != expect {
t.Errorf("returned ref mismatch. expected: %s, got: %s", expect, in.String())
}
}
7 changes: 5 additions & 2 deletions p2p/p2p.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
package p2p

import (
"fmt"

golog "github.com/ipfs/go-log"

// gologging "gx/ipfs/QmQvJiADDe7JR4m968MwXobTCCzUqQkP87aRHe29MEBGHV/go-logging"
// golog "gx/ipfs/QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52/go-log"
identify "gx/ipfs/QmY51bqSM5XgxQZqsBrQcRkKTnCb8EKpJpR9K6Qax7Njco/go-libp2p/p2p/protocol/identify"
protocol "gx/ipfs/QmZNkThpqfVXs9GNbexPrfBbXSLNYeKrE7jwFM2oqHbyqN/go-libp2p-protocol"
)
Expand All @@ -30,3 +30,6 @@ func init() {
// TODO - understand where & how client versions are used
identify.ClientVersion = QriServiceTag
}

// ErrNotConnected is for a missing required network connection
var ErrNotConnected = fmt.Errorf("no p2p connection")
4 changes: 4 additions & 0 deletions p2p/resolve_ref.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ const MtResolveDatasetRef = MsgType("resolve_dataset_ref")
func (n *QriNode) ResolveDatasetRef(ref *repo.DatasetRef) (err error) {
log.Debugf("%s ResolveDatasetRef %s", n.ID, ref)

if !n.Online {
return ErrNotConnected
}

pids := n.ClosestConnectedPeers(ref.ProfileID, 15)
if len(pids) == 0 {
return fmt.Errorf("no connected peers")
Expand Down
3 changes: 1 addition & 2 deletions p2p/resolve_ref_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import (
"sync"
"testing"

"github.com/qri-io/qri/p2p"
"github.com/qri-io/qri/p2p/test"
"github.com/qri-io/qri/repo"
)

func TestResolveDatasetRef(t *testing.T) {
ctx := context.Background()
factory := p2ptest.NewTestNodeFactory(p2p.NewTestableQriNode)
factory := p2ptest.NewTestNodeFactory(NewTestableQriNode)
testPeers, err := p2ptest.NewTestDirNetwork(ctx, factory)
if err != nil {
t.Fatalf("error creating network: %s", err.Error())
Expand Down

0 comments on commit 00aefc2

Please sign in to comment.