Skip to content

Commit 370bd22

Browse files
authored
Merge pull request #5484 from ipfs/fix/resolve-hamt
resolve: use unixfs ResolveOnce
2 parents 23b44ba + 0fd87de commit 370bd22

File tree

7 files changed

+80
-80
lines changed

7 files changed

+80
-80
lines changed

core/commands/resolve.go

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,21 @@ package commands
22

33
import (
44
"errors"
5+
"fmt"
56
"io"
67
"strings"
78
"time"
89

9-
cmds "github.com/ipfs/go-ipfs/commands"
10-
"github.com/ipfs/go-ipfs/core"
10+
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
1111
e "github.com/ipfs/go-ipfs/core/commands/e"
1212
ncmd "github.com/ipfs/go-ipfs/core/commands/name"
13+
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
14+
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
1315
ns "github.com/ipfs/go-ipfs/namesys"
1416
nsopts "github.com/ipfs/go-ipfs/namesys/opts"
1517
path "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
1618

19+
"gx/ipfs/QmPTfgFTo9PFr1PvPKyKoeMgBvYPh6cX3aDP7DHKVbnCbi/go-ipfs-cmds"
1720
"gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit"
1821
)
1922

@@ -62,12 +65,17 @@ Resolve the value of an IPFS DAG path:
6265
},
6366
Options: []cmdkit.Option{
6467
cmdkit.BoolOption("recursive", "r", "Resolve until the result is an IPFS name."),
65-
cmdkit.UintOption("dht-record-count", "dhtrc", "Number of records to request for DHT resolution."),
68+
cmdkit.IntOption("dht-record-count", "dhtrc", "Number of records to request for DHT resolution."),
6669
cmdkit.StringOption("dht-timeout", "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."),
6770
},
68-
Run: func(req cmds.Request, res cmds.Response) {
71+
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
72+
api, err := cmdenv.GetApi(env)
73+
if err != nil {
74+
res.SetError(err, cmdkit.ErrNormal)
75+
return
76+
}
6977

70-
n, err := req.InvocContext().GetNode()
78+
n, err := cmdenv.GetNode(env)
7179
if err != nil {
7280
res.SetError(err, cmdkit.ErrNormal)
7381
return
@@ -81,16 +89,19 @@ Resolve the value of an IPFS DAG path:
8189
}
8290
}
8391

84-
name := req.Arguments()[0]
85-
recursive, _, _ := req.Option("recursive").Bool()
92+
name := req.Arguments[0]
93+
recursive, _ := req.Options["recursive"].(bool)
8694

8795
// the case when ipns is resolved step by step
8896
if strings.HasPrefix(name, "/ipns/") && !recursive {
89-
rc, rcok, _ := req.Option("dht-record-count").Int()
90-
dhtt, dhttok, _ := req.Option("dht-timeout").String()
91-
ropts := []nsopts.ResolveOpt{nsopts.Depth(1)}
97+
rc, rcok := req.Options["dht-record-count"].(uint)
98+
dhtt, dhttok := req.Options["dht-timeout"].(string)
99+
ropts := []options.NameResolveOption{
100+
options.Name.ResolveOption(nsopts.Depth(1)),
101+
}
102+
92103
if rcok {
93-
ropts = append(ropts, nsopts.DhtRecordCount(uint(rc)))
104+
ropts = append(ropts, options.Name.ResolveOption(nsopts.DhtRecordCount(rc)))
94105
}
95106
if dhttok {
96107
d, err := time.ParseDuration(dhtt)
@@ -102,48 +113,45 @@ Resolve the value of an IPFS DAG path:
102113
res.SetError(errors.New("DHT timeout value must be >= 0"), cmdkit.ErrNormal)
103114
return
104115
}
105-
ropts = append(ropts, nsopts.DhtTimeout(d))
116+
ropts = append(ropts, options.Name.ResolveOption(nsopts.DhtTimeout(d)))
106117
}
107-
p, err := n.Namesys.Resolve(req.Context(), name, ropts...)
118+
p, err := api.Name().Resolve(req.Context, name, ropts...)
108119
// ErrResolveRecursion is fine
109120
if err != nil && err != ns.ErrResolveRecursion {
110121
res.SetError(err, cmdkit.ErrNormal)
111122
return
112123
}
113-
res.SetOutput(&ncmd.ResolvedPath{Path: p})
124+
cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: path.Path(p.String())})
114125
return
115126
}
116127

117128
// else, ipfs path or ipns with recursive flag
118-
p, err := path.ParsePath(name)
129+
p, err := coreiface.ParsePath(name)
119130
if err != nil {
120131
res.SetError(err, cmdkit.ErrNormal)
121132
return
122133
}
123134

124-
node, err := core.Resolve(req.Context(), n.Namesys, n.Resolver, p)
135+
rp, err := api.ResolvePath(req.Context, p)
125136
if err != nil {
126137
res.SetError(err, cmdkit.ErrNormal)
127138
return
128139
}
129140

130-
c := node.Cid()
141+
c := rp.Cid()
131142

132-
res.SetOutput(&ncmd.ResolvedPath{Path: path.FromCid(c)})
143+
cmds.EmitOnce(res, &ncmd.ResolvedPath{Path: path.FromCid(c)})
133144
},
134-
Marshalers: cmds.MarshalerMap{
135-
cmds.Text: func(res cmds.Response) (io.Reader, error) {
136-
v, err := unwrapOutput(res.Output())
137-
if err != nil {
138-
return nil, err
139-
}
140-
145+
Encoders: cmds.EncoderMap{
146+
cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
141147
output, ok := v.(*ncmd.ResolvedPath)
142148
if !ok {
143-
return nil, e.TypeErr(output, v)
149+
return e.TypeErr(output, v)
144150
}
145-
return strings.NewReader(output.Path.String() + "\n"), nil
146-
},
151+
152+
fmt.Fprintln(w, output.Path.String())
153+
return nil
154+
}),
147155
},
148156
Type: ncmd.ResolvedPath{},
149157
}

core/commands/root.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ var rootSubcommands = map[string]*cmds.Command{
135135
"ping": lgc.NewCommand(PingCmd),
136136
"p2p": lgc.NewCommand(P2PCmd),
137137
"refs": lgc.NewCommand(RefsCmd),
138-
"resolve": lgc.NewCommand(ResolveCmd),
138+
"resolve": ResolveCmd,
139139
"swarm": lgc.NewCommand(SwarmCmd),
140140
"tar": lgc.NewCommand(TarCmd),
141141
"file": lgc.NewCommand(unixfs.UnixFSCmd),
@@ -183,7 +183,7 @@ var rootROSubcommands = map[string]*cmds.Command{
183183
"resolve": dag.DagResolveCmd,
184184
},
185185
}),
186-
"resolve": lgc.NewCommand(ResolveCmd),
186+
"resolve": ResolveCmd,
187187
"version": lgc.NewCommand(VersionCmd),
188188
}
189189

core/coreapi/interface/options/name.go

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package options
22

33
import (
44
"time"
5+
6+
ropts "github.com/ipfs/go-ipfs/namesys/opts"
57
)
68

79
const (
@@ -14,9 +16,10 @@ type NamePublishSettings struct {
1416
}
1517

1618
type NameResolveSettings struct {
17-
Recursive bool
18-
Local bool
19-
Cache bool
19+
Local bool
20+
Cache bool
21+
22+
ResolveOpts []ropts.ResolveOpt
2023
}
2124

2225
type NamePublishOption func(*NamePublishSettings) error
@@ -40,9 +43,8 @@ func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error)
4043

4144
func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) {
4245
options := &NameResolveSettings{
43-
Recursive: false,
44-
Local: false,
45-
Cache: true,
46+
Local: false,
47+
Cache: true,
4648
}
4749

4850
for _, opt := range opts {
@@ -80,15 +82,6 @@ func (nameOpts) Key(key string) NamePublishOption {
8082
}
8183
}
8284

83-
// Recursive is an option for Name.Resolve which specifies whether to perform a
84-
// recursive lookup. Default value is false
85-
func (nameOpts) Recursive(recursive bool) NameResolveOption {
86-
return func(settings *NameResolveSettings) error {
87-
settings.Recursive = recursive
88-
return nil
89-
}
90-
}
91-
9285
// Local is an option for Name.Resolve which specifies if the lookup should be
9386
// offline. Default value is false
9487
func (nameOpts) Local(local bool) NameResolveOption {
@@ -106,3 +99,11 @@ func (nameOpts) Cache(cache bool) NameResolveOption {
10699
return nil
107100
}
108101
}
102+
103+
//
104+
func (nameOpts) ResolveOption(opt ropts.ResolveOpt) NameResolveOption {
105+
return func(settings *NameResolveSettings) error {
106+
settings.ResolveOpts = append(settings.ResolveOpts, opt)
107+
return nil
108+
}
109+
}

core/coreapi/name.go

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,16 @@ import (
77
"strings"
88
"time"
99

10-
core "github.com/ipfs/go-ipfs/core"
10+
"github.com/ipfs/go-ipfs/core"
1111
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
1212
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
13-
keystore "github.com/ipfs/go-ipfs/keystore"
14-
namesys "github.com/ipfs/go-ipfs/namesys"
15-
nsopts "github.com/ipfs/go-ipfs/namesys/opts"
13+
"github.com/ipfs/go-ipfs/keystore"
14+
"github.com/ipfs/go-ipfs/namesys"
1615
ipath "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
1716

18-
crypto "gx/ipfs/QmPvyPwuCgJ7pDmrKDxRtsScJgBaM5h4EpRL2qQJsmXf4n/go-libp2p-crypto"
19-
peer "gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer"
20-
offline "gx/ipfs/QmSNe4MWVxZWk6UxxW2z2EKofFo4GdFzud1vfn1iVby3mj/go-ipfs-routing/offline"
17+
"gx/ipfs/QmPvyPwuCgJ7pDmrKDxRtsScJgBaM5h4EpRL2qQJsmXf4n/go-libp2p-crypto"
18+
"gx/ipfs/QmQsErDt8Qgw1XrsXf2BpEzDgGWtB1YLsTAARBup5b6B9W/go-libp2p-peer"
19+
"gx/ipfs/QmSNe4MWVxZWk6UxxW2z2EKofFo4GdFzud1vfn1iVby3mj/go-ipfs-routing/offline"
2120
)
2221

2322
type NameAPI CoreAPI
@@ -119,12 +118,7 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam
119118
name = "/ipns/" + name
120119
}
121120

122-
var ropts []nsopts.ResolveOpt
123-
if !options.Recursive {
124-
ropts = append(ropts, nsopts.Depth(1))
125-
}
126-
127-
output, err := resolver.Resolve(ctx, name, ropts...)
121+
output, err := resolver.Resolve(ctx, name, options.ResolveOpts...)
128122
if err != nil {
129123
return nil, err
130124
}

core/coreapi/path.go

Lines changed: 12 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,44 @@
11
package coreapi
22

33
import (
4-
context "context"
5-
fmt "fmt"
4+
"context"
5+
"fmt"
66
gopath "path"
77

8-
core "github.com/ipfs/go-ipfs/core"
8+
"github.com/ipfs/go-ipfs/core"
99
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
10-
namesys "github.com/ipfs/go-ipfs/namesys"
1110
uio "gx/ipfs/QmPL8bYtbACcSFFiSr4s2du7Na382NxRADR8hC7D9FkEA2/go-unixfs/io"
1211
ipfspath "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path"
13-
resolver "gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path/resolver"
12+
"gx/ipfs/QmX7uSbkNz76yNwBhuwYwRbhihLnJqM73VTCjS3UMJud9A/go-path/resolver"
1413

15-
cid "gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid"
14+
"gx/ipfs/QmPSQnBKM9g7BaUcZCvswUJVscQ1ipjmwxN5PXCjkp9EQ7/go-cid"
1615
ipld "gx/ipfs/QmdDXJs4axxefSPgK6Y1QhpJWKuDPnGJiqgq4uncb4rFHL/go-ipld-format"
1716
)
1817

1918
// ResolveNode resolves the path `p` using Unixfs resolver, gets and returns the
2019
// resolved Node.
2120
func (api *CoreAPI) ResolveNode(ctx context.Context, p coreiface.Path) (ipld.Node, error) {
22-
return resolveNode(ctx, api.node.DAG, api.node.Namesys, p)
23-
}
24-
25-
// ResolvePath resolves the path `p` using Unixfs resolver, returns the
26-
// resolved path.
27-
func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreiface.ResolvedPath, error) {
28-
return resolvePath(ctx, api.node.DAG, api.node.Namesys, p)
29-
}
30-
31-
func resolveNode(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSystem, p coreiface.Path) (ipld.Node, error) {
32-
rp, err := resolvePath(ctx, ng, nsys, p)
21+
rp, err := api.ResolvePath(ctx, p)
3322
if err != nil {
3423
return nil, err
3524
}
3625

37-
node, err := ng.Get(ctx, rp.Cid())
26+
node, err := api.node.DAG.Get(ctx, rp.Cid())
3827
if err != nil {
3928
return nil, err
4029
}
4130
return node, nil
4231
}
4332

44-
func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSystem, p coreiface.Path) (coreiface.ResolvedPath, error) {
33+
// ResolvePath resolves the path `p` using Unixfs resolver, returns the
34+
// resolved path.
35+
func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreiface.ResolvedPath, error) {
4536
if _, ok := p.(coreiface.ResolvedPath); ok {
4637
return p.(coreiface.ResolvedPath), nil
4738
}
4839

4940
ipath := ipfspath.Path(p.String())
50-
ipath, err := core.ResolveIPNS(ctx, nsys, ipath)
41+
ipath, err := core.ResolveIPNS(ctx, api.node.Namesys, ipath)
5142
if err == core.ErrNoNamesys {
5243
return nil, coreiface.ErrOffline
5344
} else if err != nil {
@@ -66,7 +57,7 @@ func resolvePath(ctx context.Context, ng ipld.NodeGetter, nsys namesys.NameSyste
6657
}
6758

6859
r := &resolver.Resolver{
69-
DAG: ng,
60+
DAG: api.node.DAG,
7061
ResolveOnce: resolveOnce,
7162
}
7263

core/coreapi/unixfs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, r io.Reader) (coreiface.ResolvedP
3232
func (api *UnixfsAPI) Cat(ctx context.Context, p coreiface.Path) (coreiface.Reader, error) {
3333
dget := api.node.DAG // TODO: use a session here once routing perf issues are resolved
3434

35-
dagnode, err := resolveNode(ctx, dget, api.node.Namesys, p)
35+
dagnode, err := api.core().ResolveNode(ctx, p)
3636
if err != nil {
3737
return nil, err
3838
}

test/sharness/t0260-sharding.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ test_expect_success "gateway can resolve sharded dirs" '
8484
test_cmp expected actual
8585
'
8686

87+
test_expect_success "'ipfs resolve' can resolve sharded dirs" '
88+
echo /ipfs/QmZ3RfWk1u5LEGYLHA633B5TNJy3Du27K6Fny9wcxpowGS > expected &&
89+
ipfs resolve "/ipfs/$SHARDED/file100" > actual &&
90+
test_cmp expected actual
91+
'
92+
8793
test_kill_ipfs_daemon
8894

8995
test_add_large_dir_v1() {

0 commit comments

Comments
 (0)