@cryptotaxi247 / kubo / commits / f1267d062

change ipns resolve/publish to store raw keys, not b58 encoded

Jeromy committed Jan 26, 2015 at 20:13 UTC f1267d0624fbb0493221ac33f4c0e43b64c58851
14 files changed +117 -48
core/commands/id.go
+20 -2
@@ -6,6 +6,7 @@ import (
6 "encoding/json"
7 "errors"
8 "io"
9 + "strings"
10 "time"
11
12 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
@@ -45,6 +46,9 @@ if no peer is specified, prints out local peers info.
46 Arguments: []cmds.Argument{
47 cmds.StringArg("peerid", false, false, "peer.ID of node to look up").EnableStdin(),
48 },
49 + Options: []cmds.Option{
50 + cmds.StringOption("f", "format", "optional output format"),
51 + },
52 Run: func(req cmds.Request, res cmds.Response) {
53 node, err := req.Context().GetNode()
54 if err != nil {
@@ -101,11 +105,25 @@ if no peer is specified, prints out local peers info.
105 return nil, u.ErrCast()
106 }
107
104 - marshaled, err := json.MarshalIndent(val, "", "\t")
108 + format, found, err := res.Request().Option("format").String()
109 if err != nil {
110 return nil, err
111 }
108 - return bytes.NewReader(marshaled), nil
112 + if found {
113 + output := format
114 + output = strings.Replace(output, "<id>", val.ID, -1)
115 + output = strings.Replace(output, "<aver>", val.AgentVersion, -1)
116 + output = strings.Replace(output, "<pver>", val.ProtocolVersion, -1)
117 + output = strings.Replace(output, "<pubkey>", val.PublicKey, -1)
118 + return strings.NewReader(output), nil
119 + } else {
120 +
121 + marshaled, err := json.MarshalIndent(val, "", "\t")
122 + if err != nil {
123 + return nil, err
124 + }
125 + return bytes.NewReader(marshaled), nil
126 + }
127 },
128 },
129 Type: IdOutput{},
core/commands/publish.go
+12 -5
@@ -6,6 +6,8 @@ import (
6 "io"
7 "strings"
8
9 + b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
10 +
11 cmds "github.com/jbenet/go-ipfs/commands"
12 core "github.com/jbenet/go-ipfs/core"
13 nsys "github.com/jbenet/go-ipfs/namesys"
@@ -54,12 +56,16 @@ Publish a <ref> to another public key:
56 return
57 }
58
57 - args := req.Arguments()
58 -
59 - if n.PeerHost == nil {
60 - res.SetError(errNotOnline, cmds.ErrClient)
59 + if !n.OnlineMode() {
60 + err := n.SetupOfflineRouting()
61 + if err != nil {
62 + res.SetError(err, cmds.ErrNormal)
63 + return
64 + }
65 }
66
67 + args := req.Arguments()
68 +
69 if n.Identity == "" {
70 res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
71 return
@@ -98,7 +104,8 @@ Publish a <ref> to another public key:
104
105 func publish(n *core.IpfsNode, k crypto.PrivKey, ref string) (*IpnsEntry, error) {
106 pub := nsys.NewRoutingPublisher(n.Routing)
101 - err := pub.Publish(k, ref)
107 + val := b58.Decode(ref)
108 + err := pub.Publish(n.Context(), k, u.Key(val))
109 if err != nil {
110 return nil, err
111 }
core/commands/resolve.go
+12 -8
@@ -6,6 +6,7 @@ import (
6 "strings"
7
8 cmds "github.com/jbenet/go-ipfs/commands"
9 + u "github.com/jbenet/go-ipfs/util"
10 )
11
12 var resolveCmd = &cmds.Command{
@@ -48,13 +49,16 @@ Resolve te value of another name:
49 return
50 }
51
51 - var name string
52 -
53 - if n.PeerHost == nil {
54 - res.SetError(errNotOnline, cmds.ErrClient)
55 - return
52 + if !n.OnlineMode() {
53 + err := n.SetupOfflineRouting()
54 + if err != nil {
55 + res.SetError(err, cmds.ErrNormal)
56 + return
57 + }
58 }
59
60 + var name string
61 +
62 if len(req.Arguments()) == 0 {
63 if n.Identity == "" {
64 res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
@@ -66,7 +70,7 @@ Resolve te value of another name:
70 name = req.Arguments()[0]
71 }
72
69 - output, err := n.Namesys.Resolve(name)
73 + output, err := n.Namesys.Resolve(n.Context(), name)
74 if err != nil {
75 res.SetError(err, cmds.ErrNormal)
76 return
@@ -78,8 +82,8 @@ Resolve te value of another name:
82 },
83 Marshalers: cmds.MarshalerMap{
84 cmds.Text: func(res cmds.Response) (io.Reader, error) {
81 - output := res.Output().(string)
82 - return strings.NewReader(output), nil
85 + output := res.Output().(u.Key)
86 + return strings.NewReader(output.B58String()), nil
87 },
88 },
89 }
core/core.go
+3
@@ -367,6 +367,9 @@ func (n *IpfsNode) SetupOfflineRouting() error {
367 }
368
369 n.Routing = offroute.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey)
370 +
371 + n.Namesys = namesys.NewNameSystem(n.Routing)
372 +
373 return nil
374 }
375
fuse/ipns/ipns_test.go
+3 -2
@@ -3,6 +3,7 @@ package ipns
3 import (
4 "bytes"
5 "crypto/rand"
6 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
7 "io/ioutil"
8 "os"
9 "testing"
@@ -252,7 +253,7 @@ func TestFastRepublish(t *testing.T) {
253 writeFileData(t, dataA, fname) // random
254 <-time.After(shortRepublishTimeout * 2)
255 log.Debug("resolving first hash")
255 - resolvedHash, err := node.Namesys.Resolve(pubkeyHash)
256 + resolvedHash, err := node.Namesys.Resolve(context.Background(), pubkeyHash)
257 if err != nil {
258 t.Fatal("resolve err:", pubkeyHash, err)
259 }
@@ -271,7 +272,7 @@ func TestFastRepublish(t *testing.T) {
272 }(shortRepublishTimeout)
273
274 hasPublished := func() bool {
274 - res, err := node.Namesys.Resolve(pubkeyHash)
275 + res, err := node.Namesys.Resolve(context.Background(), pubkeyHash)
276 if err != nil {
277 t.Fatalf("resolve err: %v", err)
278 }
fuse/ipns/ipns_unix.go
+8 -8
@@ -38,7 +38,7 @@ var (
38 // point to an empty directory.
39 func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
40 emptyDir := &mdag.Node{Data: ft.FolderPBData()}
41 - k, err := n.DAG.Add(emptyDir)
41 + nodek, err := n.DAG.Add(emptyDir)
42 if err != nil {
43 return err
44 }
@@ -54,7 +54,7 @@ func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
54 }
55
56 pub := nsys.NewRoutingPublisher(n.Routing)
57 - err = pub.Publish(key, k.B58String())
57 + err = pub.Publish(n.Context(), key, nodek)
58 if err != nil {
59 return err
60 }
@@ -116,7 +116,7 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er
116
117 go nd.repub.Run()
118
119 - pointsTo, err := n.Namesys.Resolve(name)
119 + pointsTo, err := n.Namesys.Resolve(n.Context(), name)
120 if err != nil {
121 log.Warning("Could not resolve value for local ipns entry, providing empty dir")
122 nd.Nd = &mdag.Node{Data: ft.FolderPBData()}
@@ -124,12 +124,12 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er
124 continue
125 }
126
127 - if !u.IsValidHash(pointsTo) {
127 + if !u.IsValidHash(pointsTo.B58String()) {
128 log.Criticalf("Got back bad data from namesys resolve! [%s]", pointsTo)
129 return nil, nil
130 }
131
132 - node, err := n.Resolver.ResolvePath(pointsTo)
132 + node, err := n.Resolver.ResolvePath(pointsTo.B58String())
133 if err != nil {
134 log.Warning("Failed to resolve value from ipns entry in ipfs")
135 continue
@@ -186,13 +186,13 @@ func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
186 }
187
188 log.Debugf("ipns: Falling back to resolution for [%s].", name)
189 - resolved, err := s.Ipfs.Namesys.Resolve(name)
189 + resolved, err := s.Ipfs.Namesys.Resolve(s.Ipfs.Context(), name)
190 if err != nil {
191 log.Warningf("ipns: namesys resolve error: %s", err)
192 return nil, fuse.ENOENT
193 }
194
195 - return &Link{s.IpfsRoot + "/" + resolved}, nil
195 + return &Link{s.IpfsRoot + "/" + resolved.B58String()}, nil
196 }
197
198 // ReadDir reads a particular directory. Disallowed for root.
@@ -461,7 +461,7 @@ func (n *Node) republishRoot() error {
461 }
462 log.Debug("Publishing changes!")
463
464 - err = n.Ipfs.Namesys.Publish(root.key, ndkey.Pretty())
464 + err = n.Ipfs.Namesys.Publish(n.Ipfs.Context(), root.key, ndkey)
465 if err != nil {
466 log.Errorf("ipns: Publish Failed: %s", err)
467 return err
namesys/dns.go
+5 -2
@@ -3,9 +3,12 @@ package namesys
3 import (
4 "net"
5
6 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
7 b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
8 isd "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-is-domain"
9 mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
10 +
11 + u "github.com/jbenet/go-ipfs/util"
12 )
13
14 // DNSResolver implements a Resolver on DNS domains
@@ -22,7 +25,7 @@ func (r *DNSResolver) CanResolve(name string) bool {
25 // Resolve implements Resolver
26 // TXT records for a given domain name should contain a b58
27 // encoded multihash.
25 -func (r *DNSResolver) Resolve(name string) (string, error) {
28 +func (r *DNSResolver) Resolve(ctx context.Context, name string) (u.Key, error) {
29 log.Info("DNSResolver resolving %v", name)
30 txt, err := net.LookupTXT(name)
31 if err != nil {
@@ -39,7 +42,7 @@ func (r *DNSResolver) Resolve(name string) (string, error) {
42 if err != nil {
43 continue
44 }
42 - return t, nil
45 + return u.Key(chk), nil
46 }
47
48 return "", ErrResolveFailed
namesys/interface.go
+4 -2
@@ -3,7 +3,9 @@ package namesys
3 import (
4 "errors"
5
6 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
7 ci "github.com/jbenet/go-ipfs/p2p/crypto"
8 + u "github.com/jbenet/go-ipfs/util"
9 )
10
11 // ErrResolveFailed signals an error when attempting to resolve.
@@ -28,7 +30,7 @@ type NameSystem interface {
30 type Resolver interface {
31
32 // Resolve looks up a name, and returns the value previously published.
31 - Resolve(name string) (value string, err error)
33 + Resolve(ctx context.Context, name string) (value u.Key, err error)
34
35 // CanResolve checks whether this Resolver can resolve a name
36 CanResolve(name string) bool
@@ -39,5 +41,5 @@ type Publisher interface {
41
42 // Publish establishes a name-value mapping.
43 // TODO make this not PrivKey specific.
42 - Publish(name ci.PrivKey, value string) error
44 + Publish(ctx context.Context, name ci.PrivKey, value u.Key) error
45 }
namesys/namesys.go
+6 -4
@@ -1,8 +1,10 @@
1 package namesys
2
3 import (
4 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5 ci "github.com/jbenet/go-ipfs/p2p/crypto"
6 routing "github.com/jbenet/go-ipfs/routing"
7 + u "github.com/jbenet/go-ipfs/util"
8 )
9
10 // ipnsNameSystem implements IPNS naming.
@@ -32,10 +34,10 @@ func NewNameSystem(r routing.IpfsRouting) NameSystem {
34 }
35
36 // Resolve implements Resolver
35 -func (ns *ipns) Resolve(name string) (string, error) {
37 +func (ns *ipns) Resolve(ctx context.Context, name string) (u.Key, error) {
38 for _, r := range ns.resolvers {
39 if r.CanResolve(name) {
38 - return r.Resolve(name)
40 + return r.Resolve(ctx, name)
41 }
42 }
43 return "", ErrResolveFailed
@@ -52,6 +54,6 @@ func (ns *ipns) CanResolve(name string) bool {
54 }
55
56 // Publish implements Publisher
55 -func (ns *ipns) Publish(name ci.PrivKey, value string) error {
56 - return ns.publisher.Publish(name, value)
57 +func (ns *ipns) Publish(ctx context.Context, name ci.PrivKey, value u.Key) error {
58 + return ns.publisher.Publish(ctx, name, value)
59 }
namesys/proquint.go
+4 -2
@@ -3,7 +3,9 @@ package namesys
3 import (
4 "errors"
5
6 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
7 proquint "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/bren2010/proquint"
8 + u "github.com/jbenet/go-ipfs/util"
9 )
10
11 type ProquintResolver struct{}
@@ -15,10 +17,10 @@ func (r *ProquintResolver) CanResolve(name string) bool {
17 }
18
19 // Resolve implements Resolver. Decodes the proquint string.
18 -func (r *ProquintResolver) Resolve(name string) (string, error) {
20 +func (r *ProquintResolver) Resolve(ctx context.Context, name string) (u.Key, error) {
21 ok := r.CanResolve(name)
22 if !ok {
23 return "", errors.New("not a valid proquint string")
24 }
23 - return string(proquint.Decode(name)), nil
25 + return u.Key(proquint.Decode(name)), nil
26 }
namesys/publisher.go
+5 -6
@@ -37,17 +37,16 @@ func NewRoutingPublisher(route routing.IpfsRouting) Publisher {
37
38 // Publish implements Publisher. Accepts a keypair and a value,
39 // and publishes it out to the routing system
40 -func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
40 +func (p *ipnsPublisher) Publish(ctx context.Context, k ci.PrivKey, value u.Key) error {
41 log.Debugf("namesys: Publish %s", value)
42
43 // validate `value` is a ref (multihash)
44 - _, err := mh.FromB58String(value)
44 + _, err := mh.FromB58String(value.Pretty())
45 if err != nil {
46 log.Errorf("hash cast failed: %s", value)
47 return fmt.Errorf("publish value must be str multihash. %v", err)
48 }
49
50 - ctx := context.TODO()
50 data, err := createRoutingEntryData(k, value)
51 if err != nil {
52 log.Error("entry creation failed.")
@@ -65,7 +64,7 @@ func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
64
65 log.Debugf("Storing pubkey at: %s", namekey)
66 // Store associated public key
68 - timectx, _ := context.WithDeadline(ctx, time.Now().Add(time.Second*4))
67 + timectx, _ := context.WithDeadline(ctx, time.Now().Add(time.Second*10))
68 err = p.routing.PutValue(timectx, namekey, pkbytes)
69 if err != nil {
70 return err
@@ -75,7 +74,7 @@ func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
74
75 log.Debugf("Storing ipns entry at: %s", ipnskey)
76 // Store ipns entry at "/ipns/"+b58(h(pubkey))
78 - timectx, _ = context.WithDeadline(ctx, time.Now().Add(time.Second*4))
77 + timectx, _ = context.WithDeadline(ctx, time.Now().Add(time.Second*10))
78 err = p.routing.PutValue(timectx, ipnskey, data)
79 if err != nil {
80 return err
@@ -84,7 +83,7 @@ func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
83 return nil
84 }
85
87 -func createRoutingEntryData(pk ci.PrivKey, val string) ([]byte, error) {
86 +func createRoutingEntryData(pk ci.PrivKey, val u.Key) ([]byte, error) {
87 entry := new(pb.IpnsEntry)
88
89 entry.Value = []byte(val)
namesys/resolve_test.go
+5 -4
@@ -1,6 +1,7 @@
1 package namesys
2
3 import (
4 + context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
5 "testing"
6
7 mockrouting "github.com/jbenet/go-ipfs/routing/mock"
@@ -19,13 +20,13 @@ func TestRoutingResolve(t *testing.T) {
20 t.Fatal(err)
21 }
22
22 - err = publisher.Publish(privk, "Hello")
23 + err = publisher.Publish(context.Background(), privk, "Hello")
24 if err == nil {
25 t.Fatal("should have errored out when publishing a non-multihash val")
26 }
27
27 - h := u.Key(u.Hash([]byte("Hello"))).Pretty()
28 - err = publisher.Publish(privk, h)
28 + h := u.Key(u.Hash([]byte("Hello")))
29 + err = publisher.Publish(context.Background(), privk, h)
30 if err != nil {
31 t.Fatal(err)
32 }
@@ -36,7 +37,7 @@ func TestRoutingResolve(t *testing.T) {
37 }
38
39 pkhash := u.Hash(pubkb)
39 - res, err := resolver.Resolve(u.Key(pkhash).Pretty())
40 + res, err := resolver.Resolve(context.Background(), u.Key(pkhash).Pretty())
41 if err != nil {
42 t.Fatal(err)
43 }
namesys/routing.go
+2 -3
@@ -38,9 +38,8 @@ func (r *routingResolver) CanResolve(name string) bool {
38
39 // Resolve implements Resolver. Uses the IPFS routing system to resolve SFS-like
40 // names.
41 -func (r *routingResolver) Resolve(name string) (string, error) {
41 +func (r *routingResolver) Resolve(ctx context.Context, name string) (u.Key, error) {
42 log.Debugf("RoutingResolve: '%s'", name)
43 - ctx := context.TODO()
43 hash, err := mh.FromB58String(name)
44 if err != nil {
45 log.Warning("RoutingResolve: bad input hash: [%s]\n", name)
@@ -88,5 +87,5 @@ func (r *routingResolver) Resolve(name string) (string, error) {
87 }
88
89 // ok sig checks out. this is a valid name.
91 - return string(entry.GetValue()), nil
90 + return u.Key(entry.GetValue()), nil
91 }
test/sharness/t0100-name.sh new
+28
@@ -0,0 +1,28 @@
1 +#!/bin/sh
2 +#
3 +# Copyright (c) 2014 Jeromy Johnson
4 +# MIT Licensed; see the LICENSE file in this repository.
5 +#
6 +
7 +test_description="Test ipfs repo operations"
8 +
9 +. lib/test-lib.sh
10 +
11 +test_init_ipfs
12 +
13 +test_expect_success "'ipfs name publish' succeeds" '
14 + PEERID=`ipfs id -format="<id>"` &&
15 + HASH=QmYpv2VEsxzTTXRYX3PjDg961cnJE3kY1YDXLycHGQ3zZB &&
16 + ipfs name publish $HASH > publish_out &&
17 + echo Published name $PEERID to $HASH > expected1 &&
18 + test_cmp publish_out expected1
19 +
20 +'
21 +
22 +test_expect_success "'ipfs name resolve' succeeds" '
23 + ipfs name resolve $PEERID > output &&
24 + printf "%s" $HASH > expected2 &&
25 + test_cmp output expected2
26 +'
27 +
28 +test_done