Skip to content

Commit

Permalink
coreapi name: switch publish/resolve to coreapi
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Łukasz Magiera <magik6k@gmail.com>
  • Loading branch information
magik6k committed Oct 4, 2018
1 parent e8b137f commit 54fe163
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 150 deletions.
53 changes: 16 additions & 37 deletions core/commands/name/ipns.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import (

cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
e "github.com/ipfs/go-ipfs/core/commands/e"
namesys "github.com/ipfs/go-ipfs/namesys"
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
nsopts "github.com/ipfs/go-ipfs/namesys/opts"

"gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit"
offline "gx/ipfs/QmScZySgru9jaoDa12sSfvh21sWbqF5eXkieTmJzAHJXkQ/go-ipfs-routing/offline"
cmds "gx/ipfs/QmXTmUCBtDUrzDYVzASogLiNph7EBuYqEgPL7QoHNMzUnz/go-ipfs-cmds"
logging "gx/ipfs/QmZChCsSt8DctjceaL56Eibc29CVQq4dGKRXC5JRZ6Ppae/go-log"
path "gx/ipfs/QmcjwUb36Z16NJkvDX6ccXPqsFswo6AsRXynyXcLLCphV2/go-path"
Expand Down Expand Up @@ -80,44 +79,21 @@ Resolve the value of a dnslink:
cmdkit.StringOption(dhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := cmdenv.GetNode(env)
api, err := cmdenv.GetApi(env)
if err != nil {
return err
}

if !n.OnlineMode() {
err := n.SetupOfflineRouting()
if err != nil {
return err
}
}

nocache, _ := req.Options["nocache"].(bool)
local, _ := req.Options["local"].(bool)

// default to nodes namesys resolver
var resolver namesys.Resolver = n.Namesys

if local && nocache {
return errors.New("cannot specify both local and nocache")
}

if local {
offroute := offline.NewOfflineRouter(n.Repo.Datastore(), n.RecordValidator)
resolver = namesys.NewIpnsResolver(offroute)
}

if nocache {
resolver = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), 0)
}

var name string
if len(req.Arguments) == 0 {
if n.Identity == "" {
return errors.New("identity not loaded")
self, err := api.Key().Self(req.Context)
if err != nil {
return err
}
name = n.Identity.Pretty()

name = self.ID().Pretty()
} else {
name = req.Arguments[0]
}
Expand All @@ -126,12 +102,16 @@ Resolve the value of a dnslink:
rc, rcok := req.Options[dhtRecordCountOptionName].(int)
dhtt, dhttok := req.Options[dhtTimeoutOptionName].(string)

var ropts []nsopts.ResolveOpt
opts := []options.NameResolveOption{
options.Name.Local(local),
options.Name.Cache(!nocache),
}

if !recursive {
ropts = append(ropts, nsopts.Depth(1))
opts = append(opts, options.Name.ResolveOption(nsopts.Depth(1)))
}
if rcok {
ropts = append(ropts, nsopts.DhtRecordCount(uint(rc)))
opts = append(opts, options.Name.ResolveOption(nsopts.DhtRecordCount(uint(rc))))
}
if dhttok {
d, err := time.ParseDuration(dhtt)
Expand All @@ -141,20 +121,19 @@ Resolve the value of a dnslink:
if d < 0 {
return errors.New("DHT timeout value must be >= 0")
}
ropts = append(ropts, nsopts.DhtTimeout(d))
opts = append(opts, options.Name.ResolveOption(nsopts.DhtTimeout(d)))
}

if !strings.HasPrefix(name, "/ipns/") {
name = "/ipns/" + name
}

output, err := resolver.Resolve(req.Context, name, ropts...)
output, err := api.Name().Resolve(req.Context, name, opts...)
if err != nil {
return err
}

// TODO: better errors (in the case of not finding the name, we get "failed to find any peer in table")
return cmds.EmitOnce(res, &ResolvedPath{output})
return cmds.EmitOnce(res, &ResolvedPath{path.FromString(output.String())})
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
Expand Down
140 changes: 27 additions & 113 deletions core/commands/name/publish.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,22 @@
package name

import (
"context"
"errors"
"fmt"
"io"
"time"

core "github.com/ipfs/go-ipfs/core"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
e "github.com/ipfs/go-ipfs/core/commands/e"
keystore "github.com/ipfs/go-ipfs/keystore"
iface "github.com/ipfs/go-ipfs/core/coreapi/interface"
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"

crypto "gx/ipfs/QmPvyPwuCgJ7pDmrKDxRtsScJgBaM5h4EpRL2qQJsmXf4n/go-libp2p-crypto"
"gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit"
cmds "gx/ipfs/QmXTmUCBtDUrzDYVzASogLiNph7EBuYqEgPL7QoHNMzUnz/go-ipfs-cmds"
peer "gx/ipfs/QmbNepETomvmXfz1X5pHNFD2QuPqnqi47dTd94QJWSorQ3/go-libp2p-peer"
path "gx/ipfs/QmcjwUb36Z16NJkvDX6ccXPqsFswo6AsRXynyXcLLCphV2/go-path"
)

var (
errAllowOffline = errors.New("can't publish while offline: pass `--allow-offline` to override")
errIpnsMount = errors.New("cannot manually publish while IPNS is mounted")
errIdentityLoad = errors.New("identity not loaded")
)

const (
Expand Down Expand Up @@ -90,71 +84,60 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
cmdkit.BoolOption(quieterOptionName, "Q", "Write only final hash."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
n, err := cmdenv.GetNode(env)
api, err := cmdenv.GetApi(env)
if err != nil {
return err
}

allowOffline, _ := req.Options[allowOfflineOptionName].(bool)
if !n.OnlineMode() {
if !allowOffline {
return errAllowOffline
}
err := n.SetupOfflineRouting()
if err != nil {
return err
}
}

if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
return errIpnsMount
}

pstr := req.Arguments[0]

if n.Identity == "" {
return errIdentityLoad
}

popts := new(publishOpts)

popts.verifyExists, _ = req.Options[resolveOptionName].(bool)
allowOffline, _ := req.Options[allowOfflineOptionName].(bool)
kname, _ := req.Options[keyOptionName].(string)

validtime, _ := req.Options[lifeTimeOptionName].(string)
d, err := time.ParseDuration(validtime)
validTimeOpt, _ := req.Options[lifeTimeOptionName].(string)
validTime, err := time.ParseDuration(validTimeOpt)
if err != nil {
return fmt.Errorf("error parsing lifetime option: %s", err)
}

popts.pubValidTime = d
opts := []options.NamePublishOption{
options.Name.AllowOffline(allowOffline),
options.Name.Key(kname),
options.Name.ValidTime(validTime),
}

ctx := req.Context
if ttl, found := req.Options[ttlOptionName].(string); found {
d, err := time.ParseDuration(ttl)
if err != nil {
return err
}

ctx = context.WithValue(ctx, "ipns-publish-ttl", d)
opts = append(opts, options.Name.TTL(d))
}

kname, _ := req.Options[keyOptionName].(string)
k, err := keylookup(n, kname)
p, err := iface.ParsePath(req.Arguments[0])
if err != nil {
return err
}

pth, err := path.ParsePath(pstr)
if err != nil {
return err
if verifyExists, _ := req.Options[resolveOptionName].(bool); verifyExists {
_, err := api.ResolveNode(req.Context, p)
if err != nil {
return err
}
}

output, err := publish(ctx, n, k, pth, popts)
out, err := api.Name().Publish(req.Context, p, opts...)
if err != nil {
if err == iface.ErrOffline {
err = errAllowOffline
}
return err
}

return cmds.EmitOnce(res, output)
return cmds.EmitOnce(res, &IpnsEntry{
Name: out.Name(),
Value: out.Value().String(),
})
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
Expand All @@ -175,72 +158,3 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
},
Type: IpnsEntry{},
}

type publishOpts struct {
verifyExists bool
pubValidTime time.Duration
}

func publish(ctx context.Context, n *core.IpfsNode, k crypto.PrivKey, ref path.Path, opts *publishOpts) (*IpnsEntry, error) {

if opts.verifyExists {
// verify the path exists
_, err := core.Resolve(ctx, n.Namesys, n.Resolver, ref)
if err != nil {
return nil, err
}
}

eol := time.Now().Add(opts.pubValidTime)
err := n.Namesys.PublishWithEOL(ctx, k, ref, eol)
if err != nil {
return nil, err
}

pid, err := peer.IDFromPrivateKey(k)
if err != nil {
return nil, err
}

return &IpnsEntry{
Name: pid.Pretty(),
Value: ref.String(),
}, nil
}

func keylookup(n *core.IpfsNode, k string) (crypto.PrivKey, error) {

res, err := n.GetKey(k)
if res != nil {
return res, nil
}

if err != nil && err != keystore.ErrNoSuchKey {
return nil, err
}

keys, err := n.Repo.Keystore().List()
if err != nil {
return nil, err
}

for _, key := range keys {
privKey, err := n.Repo.Keystore().Get(key)
if err != nil {
return nil, err
}

pubKey := privKey.GetPublic()

pid, err := peer.IDFromPublicKey(pubKey)
if err != nil {
return nil, err
}

if pid.Pretty() == k {
return privKey, nil
}
}

return nil, fmt.Errorf("no key by the given name or PeerID was found")
}

0 comments on commit 54fe163

Please sign in to comment.