Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added /name/upload command definition #3547

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ os:
- osx

language: go
go_import_path: github.com/ipfs/go-ipfs

go:
- 1.7
Expand Down
4 changes: 3 additions & 1 deletion core/commands/dht_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import (

"github.com/ipfs/go-ipfs/namesys"
tu "github.com/ipfs/go-ipfs/thirdparty/testutil"
routing "gx/ipfs/QmbkGVaN9W6RYJK4Ws5FvMKXKDqdRQ5snhtaa92qP6L8eU/go-libp2p-routing"
)

func TestKeyTranslation(t *testing.T) {
pid := tu.RandPeerIDFatal(t)
a, b := namesys.IpnsKeysForID(pid)
a := routing.KeyForPublicKey(pid)
b := namesys.IpnsKeyForID(pid)

pkk, err := escapeDhtKey("/pk/" + pid.Pretty())
if err != nil {
Expand Down
6 changes: 1 addition & 5 deletions core/commands/name.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,6 @@ Publish an <ipfs-path> to your identity name:
> ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

Publish an <ipfs-path> to another public key:

> ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

Resolve the value of your identity:

> ipfs name resolve
Expand All @@ -53,6 +48,7 @@ Resolve the value of a reference:

Subcommands: map[string]*cmds.Command{
"publish": PublishCmd,
"upload": UploadNameCmd,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upload probably isnt the best name for this feature... maybe something like publish-record could be used, since its not intented as a common thing?

cc @Kubuxu @diasdavid @lgierth

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that record stores will be simple stores with get/put interfaces, something like /record/put sounds like a good name to me

"resolve": IpnsCmd,
},
}
134 changes: 109 additions & 25 deletions core/commands/publish.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,91 @@ import (
core "github.com/ipfs/go-ipfs/core"
path "github.com/ipfs/go-ipfs/path"

multibase "gx/ipfs/QmShp7G5GEsLVZ52imm6VP4nukpc5ipdHbscrxJMNasmSd/go-multibase"
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
crypto "gx/ipfs/QmfWDLQjGjVe4fr5CoztYW2DYYjRysMJrFe1RCsXLPTf46/go-libp2p-crypto"
)

var errNotOnline = errors.New("This command must be run in online mode. Try running 'ipfs daemon' first.")

type UploadResult struct {
Peer string
OldSeq uint64
NewSeq uint64
NewPath path.Path
}

var UploadNameCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Upload a signed IPNS record to an IPFS node",
},

Arguments: []cmds.Argument{
cmds.StringArg("ipns-rec", true, false, "binary IPNS record").EnableStdin(),
},
Options: []cmds.Option{
cmds.StringOption("key", "Public key of the author who signed the IPNS record"),
},

Run: func(req cmds.Request, res cmds.Response) {
log.Debug("begin name upload")
n, err := getNodeWithNamesys(req, res)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

if len(req.Arguments()) != 1 {
res.SetError(errors.New("Must provide the IPNS record as the single argument"), cmds.ErrNormal)
return
}

_, record, err := multibase.Decode(req.Arguments()[0])
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

ctx := req.Context()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this closer to where its used

pubkeyString, found, err := req.Option("key").String()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
if !found {
res.SetError(errors.New("Must provide a public key as the --key option"), cmds.ErrNormal)
return
}

_, pubkeyBytes, err := multibase.Decode(pubkeyString)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

pubkey, err := crypto.UnmarshalPublicKey(pubkeyBytes)
crypto.MarshalPublicKey(pubkey)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this line is unnecessary

if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

id, oldSeq, newSeq, newPath, err := n.Namesys.Upload(ctx, pubkey, record)
res.SetOutput(&UploadResult{Peer: id.Pretty(), OldSeq: oldSeq, NewSeq: newSeq, NewPath: newPath})
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
o := res.Output().(*UploadResult)
return strings.NewReader(fmt.Sprintf("/ipns/%s was set to %s (old seq=%d, new seq=%d)\n", o.Peer, o.NewPath, o.OldSeq, o.NewSeq)), nil
},
},
Type: UploadResult{},
}

var PublishCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Publish an object to IPNS.",
Expand All @@ -38,11 +117,6 @@ Publish an <ipfs-path> to your identity name:
> ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

Publish an <ipfs-path> to another public key (not implemented):

> ipfs name publish /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
Published to QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n: /ipfs/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy

`,
},

Expand All @@ -60,32 +134,13 @@ Publish an <ipfs-path> to another public key (not implemented):
},
Run: func(req cmds.Request, res cmds.Response) {
log.Debug("begin publish")
n, err := req.InvocContext().GetNode()
n, err := getNodeWithNamesys(req, res)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

if !n.OnlineMode() {
err := n.SetupOfflineRouting()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
}

if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
res.SetError(errors.New("You cannot manually publish while IPNS is mounted."), cmds.ErrNormal)
return
}

pstr := req.Arguments()[0]

if n.Identity == "" {
res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal)
return
}

popts := new(publishOpts)

popts.verifyExists, _, _ = req.Option("resolve").Bool()
Expand Down Expand Up @@ -134,6 +189,35 @@ Publish an <ipfs-path> to another public key (not implemented):
Type: IpnsEntry{},
}

func getNodeWithNamesys(req cmds.Request, res cmds.Response) (n *core.IpfsNode, err error) {
n, err = req.InvocContext().GetNode()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

if !n.OnlineMode() {
err = n.SetupOfflineRouting()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
}

if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
err = errors.New("You cannot manually publish while IPNS is mounted.")
res.SetError(err, cmds.ErrNormal)
return
}

if n.Identity == "" {
err = errors.New("Identity not loaded!")
res.SetError(err, cmds.ErrNormal)
}

return
}

type publishOpts struct {
verifyExists bool
pubValidTime time.Duration
Expand Down
2 changes: 1 addition & 1 deletion core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,7 @@ func (n *IpfsNode) setupIpnsRepublisher() error {
return err
}

n.IpnsRepub = ipnsrp.NewRepublisher(n.Routing, n.Repo.Datastore(), n.Peerstore)
n.IpnsRepub = ipnsrp.NewRepublisher(n.Namesys, n.Peerstore)
n.IpnsRepub.AddName(n.Identity)

if cfg.Ipns.RepublishPeriod != "" {
Expand Down
29 changes: 20 additions & 9 deletions core/corehttp/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,22 @@ import (
"testing"
"time"

core "github.com/ipfs/go-ipfs/core"
coreunix "github.com/ipfs/go-ipfs/core/coreunix"
"github.com/ipfs/go-ipfs/core"
"github.com/ipfs/go-ipfs/core/coreunix"
dag "github.com/ipfs/go-ipfs/merkledag"
namesys "github.com/ipfs/go-ipfs/namesys"
path "github.com/ipfs/go-ipfs/path"
repo "github.com/ipfs/go-ipfs/repo"
config "github.com/ipfs/go-ipfs/repo/config"
testutil "github.com/ipfs/go-ipfs/thirdparty/testutil"
"github.com/ipfs/go-ipfs/namesys"
"github.com/ipfs/go-ipfs/path"
"github.com/ipfs/go-ipfs/repo"
"github.com/ipfs/go-ipfs/repo/config"
"github.com/ipfs/go-ipfs/thirdparty/testutil"

id "gx/ipfs/QmbzCT1CwxVZ2ednptC9RavuJe7Bv8DDi2Ne89qUrA37XM/go-libp2p/p2p/protocol/identify"
ci "gx/ipfs/QmfWDLQjGjVe4fr5CoztYW2DYYjRysMJrFe1RCsXLPTf46/go-libp2p-crypto"
peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
)

var errNotImplemented = errors.New("not implemented for mockNamesys")

type mockNamesys map[string]path.Path

func (m mockNamesys) Resolve(ctx context.Context, name string) (value path.Path, err error) {
Expand All @@ -38,11 +41,19 @@ func (m mockNamesys) ResolveN(ctx context.Context, name string, depth int) (valu
}

func (m mockNamesys) Publish(ctx context.Context, name ci.PrivKey, value path.Path) error {
return errors.New("not implemented for mockNamesys")
return errNotImplemented
}

func (m mockNamesys) PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.Path, _ time.Time) error {
return errors.New("not implemented for mockNamesys")
return errNotImplemented
}

func (m mockNamesys) RePublish(ctx context.Context, name ci.PrivKey, _ time.Time) error {
return errNotImplemented
}

func (m mockNamesys) Upload(ctx context.Context, pk ci.PubKey, record []byte) (peer.ID, uint64, uint64, path.Path, error) {
return "", 0, 0, "", errNotImplemented
}

func newNodeWithMockNamesys(ns mockNamesys) (*core.IpfsNode, error) {
Expand Down
1 change: 1 addition & 0 deletions fuse/ipns/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

// InitializeKeyspace sets the ipns record for the given key to
// point to an empty directory.
// TODO: compare to github.com/ipfs/go-ipfs/namesys/publisher.go
func InitializeKeyspace(n *core.IpfsNode, key ci.PrivKey) error {
emptyDir := ft.EmptyDirNode()
nodek, err := n.DAG.Add(emptyDir)
Expand Down
14 changes: 11 additions & 3 deletions namesys/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ For command-line bindings to this functionality, see:
package namesys

import (
"context"
"errors"
"time"

context "context"
path "github.com/ipfs/go-ipfs/path"
"github.com/ipfs/go-ipfs/path"

peer "gx/ipfs/QmfMmLGoKzCHDN7cGgk64PJr4iipzidDRME8HABSJqvmhC/go-libp2p-peer"
ci "gx/ipfs/QmfWDLQjGjVe4fr5CoztYW2DYYjRysMJrFe1RCsXLPTf46/go-libp2p-crypto"
)

Expand Down Expand Up @@ -68,7 +70,7 @@ var ErrPublishFailed = errors.New("Could not publish name.")
// key (name).
type NameSystem interface {
Resolver
Publisher
RePublisher
}

// Resolver is an object capable of resolving names.
Expand Down Expand Up @@ -111,3 +113,9 @@ type Publisher interface {
// call once the records spec is implemented
PublishWithEOL(ctx context.Context, name ci.PrivKey, value path.Path, eol time.Time) error
}

type RePublisher interface {
Publisher
RePublish(ctx context.Context, sk ci.PrivKey, eol time.Time) error
Upload(ctx context.Context, pk ci.PubKey, record []byte) (id peer.ID, oldSeq uint64, newSeq uint64, newPath path.Path, err error)
}
Loading