mirror of
https://github.com/ipfs/kubo.git
synced 2025-07-03 13:00:37 +08:00
change ipns resolve/publish to store raw keys, not b58 encoded
This commit is contained in:
@ -6,6 +6,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"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.
|
||||
Arguments: []cmds.Argument{
|
||||
cmds.StringArg("peerid", false, false, "peer.ID of node to look up").EnableStdin(),
|
||||
},
|
||||
Options: []cmds.Option{
|
||||
cmds.StringOption("f", "format", "optional output format"),
|
||||
},
|
||||
Run: func(req cmds.Request, res cmds.Response) {
|
||||
node, err := req.Context().GetNode()
|
||||
if err != nil {
|
||||
@ -101,11 +105,25 @@ if no peer is specified, prints out local peers info.
|
||||
return nil, u.ErrCast()
|
||||
}
|
||||
|
||||
marshaled, err := json.MarshalIndent(val, "", "\t")
|
||||
format, found, err := res.Request().Option("format").String()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(marshaled), nil
|
||||
if found {
|
||||
output := format
|
||||
output = strings.Replace(output, "<id>", val.ID, -1)
|
||||
output = strings.Replace(output, "<aver>", val.AgentVersion, -1)
|
||||
output = strings.Replace(output, "<pver>", val.ProtocolVersion, -1)
|
||||
output = strings.Replace(output, "<pubkey>", val.PublicKey, -1)
|
||||
return strings.NewReader(output), nil
|
||||
} else {
|
||||
|
||||
marshaled, err := json.MarshalIndent(val, "", "\t")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bytes.NewReader(marshaled), nil
|
||||
}
|
||||
},
|
||||
},
|
||||
Type: IdOutput{},
|
||||
|
@ -6,6 +6,8 @@ import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
|
||||
|
||||
cmds "github.com/jbenet/go-ipfs/commands"
|
||||
core "github.com/jbenet/go-ipfs/core"
|
||||
nsys "github.com/jbenet/go-ipfs/namesys"
|
||||
@ -54,12 +56,16 @@ Publish a <ref> to another public key:
|
||||
return
|
||||
}
|
||||
|
||||
args := req.Arguments()
|
||||
|
||||
if n.PeerHost == nil {
|
||||
res.SetError(errNotOnline, cmds.ErrClient)
|
||||
if !n.OnlineMode() {
|
||||
err := n.SetupOfflineRouting()
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
args := req.Arguments()
|
||||
|
||||
if n.Identity == "" {
|
||||
res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
|
||||
return
|
||||
@ -98,7 +104,8 @@ Publish a <ref> to another public key:
|
||||
|
||||
func publish(n *core.IpfsNode, k crypto.PrivKey, ref string) (*IpnsEntry, error) {
|
||||
pub := nsys.NewRoutingPublisher(n.Routing)
|
||||
err := pub.Publish(k, ref)
|
||||
val := b58.Decode(ref)
|
||||
err := pub.Publish(n.Context(), k, u.Key(val))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
"strings"
|
||||
|
||||
cmds "github.com/jbenet/go-ipfs/commands"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
var resolveCmd = &cmds.Command{
|
||||
@ -48,13 +49,16 @@ Resolve te value of another name:
|
||||
return
|
||||
}
|
||||
|
||||
var name string
|
||||
|
||||
if n.PeerHost == nil {
|
||||
res.SetError(errNotOnline, cmds.ErrClient)
|
||||
return
|
||||
if !n.OnlineMode() {
|
||||
err := n.SetupOfflineRouting()
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var name string
|
||||
|
||||
if len(req.Arguments()) == 0 {
|
||||
if n.Identity == "" {
|
||||
res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
|
||||
@ -66,7 +70,7 @@ Resolve te value of another name:
|
||||
name = req.Arguments()[0]
|
||||
}
|
||||
|
||||
output, err := n.Namesys.Resolve(name)
|
||||
output, err := n.Namesys.Resolve(n.Context(), name)
|
||||
if err != nil {
|
||||
res.SetError(err, cmds.ErrNormal)
|
||||
return
|
||||
@ -78,8 +82,8 @@ Resolve te value of another name:
|
||||
},
|
||||
Marshalers: cmds.MarshalerMap{
|
||||
cmds.Text: func(res cmds.Response) (io.Reader, error) {
|
||||
output := res.Output().(string)
|
||||
return strings.NewReader(output), nil
|
||||
output := res.Output().(u.Key)
|
||||
return strings.NewReader(output.B58String()), nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -367,6 +367,9 @@ func (n *IpfsNode) SetupOfflineRouting() error {
|
||||
}
|
||||
|
||||
n.Routing = offroute.NewOfflineRouter(n.Repo.Datastore(), n.PrivateKey)
|
||||
|
||||
n.Namesys = namesys.NewNameSystem(n.Routing)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package ipns
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
@ -252,7 +253,7 @@ func TestFastRepublish(t *testing.T) {
|
||||
writeFileData(t, dataA, fname) // random
|
||||
<-time.After(shortRepublishTimeout * 2)
|
||||
log.Debug("resolving first hash")
|
||||
resolvedHash, err := node.Namesys.Resolve(pubkeyHash)
|
||||
resolvedHash, err := node.Namesys.Resolve(context.Background(), pubkeyHash)
|
||||
if err != nil {
|
||||
t.Fatal("resolve err:", pubkeyHash, err)
|
||||
}
|
||||
@ -271,7 +272,7 @@ func TestFastRepublish(t *testing.T) {
|
||||
}(shortRepublishTimeout)
|
||||
|
||||
hasPublished := func() bool {
|
||||
res, err := node.Namesys.Resolve(pubkeyHash)
|
||||
res, err := node.Namesys.Resolve(context.Background(), pubkeyHash)
|
||||
if err != nil {
|
||||
t.Fatalf("resolve err: %v", err)
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ var (
|
||||
// point to an empty directory.
|
||||
func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
|
||||
emptyDir := &mdag.Node{Data: ft.FolderPBData()}
|
||||
k, err := n.DAG.Add(emptyDir)
|
||||
nodek, err := n.DAG.Add(emptyDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -54,7 +54,7 @@ func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
|
||||
}
|
||||
|
||||
pub := nsys.NewRoutingPublisher(n.Routing)
|
||||
err = pub.Publish(key, k.B58String())
|
||||
err = pub.Publish(n.Context(), key, nodek)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -116,7 +116,7 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er
|
||||
|
||||
go nd.repub.Run()
|
||||
|
||||
pointsTo, err := n.Namesys.Resolve(name)
|
||||
pointsTo, err := n.Namesys.Resolve(n.Context(), name)
|
||||
if err != nil {
|
||||
log.Warning("Could not resolve value for local ipns entry, providing empty dir")
|
||||
nd.Nd = &mdag.Node{Data: ft.FolderPBData()}
|
||||
@ -124,12 +124,12 @@ func CreateRoot(n *core.IpfsNode, keys []ci.PrivKey, ipfsroot string) (*Root, er
|
||||
continue
|
||||
}
|
||||
|
||||
if !u.IsValidHash(pointsTo) {
|
||||
if !u.IsValidHash(pointsTo.B58String()) {
|
||||
log.Criticalf("Got back bad data from namesys resolve! [%s]", pointsTo)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
node, err := n.Resolver.ResolvePath(pointsTo)
|
||||
node, err := n.Resolver.ResolvePath(pointsTo.B58String())
|
||||
if err != nil {
|
||||
log.Warning("Failed to resolve value from ipns entry in ipfs")
|
||||
continue
|
||||
@ -186,13 +186,13 @@ func (s *Root) Lookup(name string, intr fs.Intr) (fs.Node, fuse.Error) {
|
||||
}
|
||||
|
||||
log.Debugf("ipns: Falling back to resolution for [%s].", name)
|
||||
resolved, err := s.Ipfs.Namesys.Resolve(name)
|
||||
resolved, err := s.Ipfs.Namesys.Resolve(s.Ipfs.Context(), name)
|
||||
if err != nil {
|
||||
log.Warningf("ipns: namesys resolve error: %s", err)
|
||||
return nil, fuse.ENOENT
|
||||
}
|
||||
|
||||
return &Link{s.IpfsRoot + "/" + resolved}, nil
|
||||
return &Link{s.IpfsRoot + "/" + resolved.B58String()}, nil
|
||||
}
|
||||
|
||||
// ReadDir reads a particular directory. Disallowed for root.
|
||||
@ -461,7 +461,7 @@ func (n *Node) republishRoot() error {
|
||||
}
|
||||
log.Debug("Publishing changes!")
|
||||
|
||||
err = n.Ipfs.Namesys.Publish(root.key, ndkey.Pretty())
|
||||
err = n.Ipfs.Namesys.Publish(n.Ipfs.Context(), root.key, ndkey)
|
||||
if err != nil {
|
||||
log.Errorf("ipns: Publish Failed: %s", err)
|
||||
return err
|
||||
|
@ -3,9 +3,12 @@ package namesys
|
||||
import (
|
||||
"net"
|
||||
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
b58 "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-base58"
|
||||
isd "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-is-domain"
|
||||
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
||||
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// DNSResolver implements a Resolver on DNS domains
|
||||
@ -22,7 +25,7 @@ func (r *DNSResolver) CanResolve(name string) bool {
|
||||
// Resolve implements Resolver
|
||||
// TXT records for a given domain name should contain a b58
|
||||
// encoded multihash.
|
||||
func (r *DNSResolver) Resolve(name string) (string, error) {
|
||||
func (r *DNSResolver) Resolve(ctx context.Context, name string) (u.Key, error) {
|
||||
log.Info("DNSResolver resolving %v", name)
|
||||
txt, err := net.LookupTXT(name)
|
||||
if err != nil {
|
||||
@ -39,7 +42,7 @@ func (r *DNSResolver) Resolve(name string) (string, error) {
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
return t, nil
|
||||
return u.Key(chk), nil
|
||||
}
|
||||
|
||||
return "", ErrResolveFailed
|
||||
|
@ -3,7 +3,9 @@ package namesys
|
||||
import (
|
||||
"errors"
|
||||
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
ci "github.com/jbenet/go-ipfs/p2p/crypto"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// ErrResolveFailed signals an error when attempting to resolve.
|
||||
@ -28,7 +30,7 @@ type NameSystem interface {
|
||||
type Resolver interface {
|
||||
|
||||
// Resolve looks up a name, and returns the value previously published.
|
||||
Resolve(name string) (value string, err error)
|
||||
Resolve(ctx context.Context, name string) (value u.Key, err error)
|
||||
|
||||
// CanResolve checks whether this Resolver can resolve a name
|
||||
CanResolve(name string) bool
|
||||
@ -39,5 +41,5 @@ type Publisher interface {
|
||||
|
||||
// Publish establishes a name-value mapping.
|
||||
// TODO make this not PrivKey specific.
|
||||
Publish(name ci.PrivKey, value string) error
|
||||
Publish(ctx context.Context, name ci.PrivKey, value u.Key) error
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
package namesys
|
||||
|
||||
import (
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
ci "github.com/jbenet/go-ipfs/p2p/crypto"
|
||||
routing "github.com/jbenet/go-ipfs/routing"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// ipnsNameSystem implements IPNS naming.
|
||||
@ -32,10 +34,10 @@ func NewNameSystem(r routing.IpfsRouting) NameSystem {
|
||||
}
|
||||
|
||||
// Resolve implements Resolver
|
||||
func (ns *ipns) Resolve(name string) (string, error) {
|
||||
func (ns *ipns) Resolve(ctx context.Context, name string) (u.Key, error) {
|
||||
for _, r := range ns.resolvers {
|
||||
if r.CanResolve(name) {
|
||||
return r.Resolve(name)
|
||||
return r.Resolve(ctx, name)
|
||||
}
|
||||
}
|
||||
return "", ErrResolveFailed
|
||||
@ -52,6 +54,6 @@ func (ns *ipns) CanResolve(name string) bool {
|
||||
}
|
||||
|
||||
// Publish implements Publisher
|
||||
func (ns *ipns) Publish(name ci.PrivKey, value string) error {
|
||||
return ns.publisher.Publish(name, value)
|
||||
func (ns *ipns) Publish(ctx context.Context, name ci.PrivKey, value u.Key) error {
|
||||
return ns.publisher.Publish(ctx, name, value)
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ package namesys
|
||||
import (
|
||||
"errors"
|
||||
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
proquint "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/bren2010/proquint"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
type ProquintResolver struct{}
|
||||
@ -15,10 +17,10 @@ func (r *ProquintResolver) CanResolve(name string) bool {
|
||||
}
|
||||
|
||||
// Resolve implements Resolver. Decodes the proquint string.
|
||||
func (r *ProquintResolver) Resolve(name string) (string, error) {
|
||||
func (r *ProquintResolver) Resolve(ctx context.Context, name string) (u.Key, error) {
|
||||
ok := r.CanResolve(name)
|
||||
if !ok {
|
||||
return "", errors.New("not a valid proquint string")
|
||||
}
|
||||
return string(proquint.Decode(name)), nil
|
||||
return u.Key(proquint.Decode(name)), nil
|
||||
}
|
||||
|
@ -37,17 +37,16 @@ func NewRoutingPublisher(route routing.IpfsRouting) Publisher {
|
||||
|
||||
// Publish implements Publisher. Accepts a keypair and a value,
|
||||
// and publishes it out to the routing system
|
||||
func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
||||
func (p *ipnsPublisher) Publish(ctx context.Context, k ci.PrivKey, value u.Key) error {
|
||||
log.Debugf("namesys: Publish %s", value)
|
||||
|
||||
// validate `value` is a ref (multihash)
|
||||
_, err := mh.FromB58String(value)
|
||||
_, err := mh.FromB58String(value.Pretty())
|
||||
if err != nil {
|
||||
log.Errorf("hash cast failed: %s", value)
|
||||
return fmt.Errorf("publish value must be str multihash. %v", err)
|
||||
}
|
||||
|
||||
ctx := context.TODO()
|
||||
data, err := createRoutingEntryData(k, value)
|
||||
if err != nil {
|
||||
log.Error("entry creation failed.")
|
||||
@ -65,7 +64,7 @@ func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
||||
|
||||
log.Debugf("Storing pubkey at: %s", namekey)
|
||||
// Store associated public key
|
||||
timectx, _ := context.WithDeadline(ctx, time.Now().Add(time.Second*4))
|
||||
timectx, _ := context.WithDeadline(ctx, time.Now().Add(time.Second*10))
|
||||
err = p.routing.PutValue(timectx, namekey, pkbytes)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -75,7 +74,7 @@ func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
||||
|
||||
log.Debugf("Storing ipns entry at: %s", ipnskey)
|
||||
// Store ipns entry at "/ipns/"+b58(h(pubkey))
|
||||
timectx, _ = context.WithDeadline(ctx, time.Now().Add(time.Second*4))
|
||||
timectx, _ = context.WithDeadline(ctx, time.Now().Add(time.Second*10))
|
||||
err = p.routing.PutValue(timectx, ipnskey, data)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -84,7 +83,7 @@ func (p *ipnsPublisher) Publish(k ci.PrivKey, value string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func createRoutingEntryData(pk ci.PrivKey, val string) ([]byte, error) {
|
||||
func createRoutingEntryData(pk ci.PrivKey, val u.Key) ([]byte, error) {
|
||||
entry := new(pb.IpnsEntry)
|
||||
|
||||
entry.Value = []byte(val)
|
||||
|
@ -1,6 +1,7 @@
|
||||
package namesys
|
||||
|
||||
import (
|
||||
context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
"testing"
|
||||
|
||||
mockrouting "github.com/jbenet/go-ipfs/routing/mock"
|
||||
@ -19,13 +20,13 @@ func TestRoutingResolve(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
err = publisher.Publish(privk, "Hello")
|
||||
err = publisher.Publish(context.Background(), privk, "Hello")
|
||||
if err == nil {
|
||||
t.Fatal("should have errored out when publishing a non-multihash val")
|
||||
}
|
||||
|
||||
h := u.Key(u.Hash([]byte("Hello"))).Pretty()
|
||||
err = publisher.Publish(privk, h)
|
||||
h := u.Key(u.Hash([]byte("Hello")))
|
||||
err = publisher.Publish(context.Background(), privk, h)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -36,7 +37,7 @@ func TestRoutingResolve(t *testing.T) {
|
||||
}
|
||||
|
||||
pkhash := u.Hash(pubkb)
|
||||
res, err := resolver.Resolve(u.Key(pkhash).Pretty())
|
||||
res, err := resolver.Resolve(context.Background(), u.Key(pkhash).Pretty())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -38,9 +38,8 @@ func (r *routingResolver) CanResolve(name string) bool {
|
||||
|
||||
// Resolve implements Resolver. Uses the IPFS routing system to resolve SFS-like
|
||||
// names.
|
||||
func (r *routingResolver) Resolve(name string) (string, error) {
|
||||
func (r *routingResolver) Resolve(ctx context.Context, name string) (u.Key, error) {
|
||||
log.Debugf("RoutingResolve: '%s'", name)
|
||||
ctx := context.TODO()
|
||||
hash, err := mh.FromB58String(name)
|
||||
if err != nil {
|
||||
log.Warning("RoutingResolve: bad input hash: [%s]\n", name)
|
||||
@ -88,5 +87,5 @@ func (r *routingResolver) Resolve(name string) (string, error) {
|
||||
}
|
||||
|
||||
// ok sig checks out. this is a valid name.
|
||||
return string(entry.GetValue()), nil
|
||||
return u.Key(entry.GetValue()), nil
|
||||
}
|
||||
|
28
test/sharness/t0100-name.sh
Executable file
28
test/sharness/t0100-name.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 2014 Jeromy Johnson
|
||||
# MIT Licensed; see the LICENSE file in this repository.
|
||||
#
|
||||
|
||||
test_description="Test ipfs repo operations"
|
||||
|
||||
. lib/test-lib.sh
|
||||
|
||||
test_init_ipfs
|
||||
|
||||
test_expect_success "'ipfs name publish' succeeds" '
|
||||
PEERID=`ipfs id -format="<id>"` &&
|
||||
HASH=QmYpv2VEsxzTTXRYX3PjDg961cnJE3kY1YDXLycHGQ3zZB &&
|
||||
ipfs name publish $HASH > publish_out &&
|
||||
echo Published name $PEERID to $HASH > expected1 &&
|
||||
test_cmp publish_out expected1
|
||||
|
||||
'
|
||||
|
||||
test_expect_success "'ipfs name resolve' succeeds" '
|
||||
ipfs name resolve $PEERID > output &&
|
||||
printf "%s" $HASH > expected2 &&
|
||||
test_cmp output expected2
|
||||
'
|
||||
|
||||
test_done
|
Reference in New Issue
Block a user