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