Skip to content

Commit

Permalink
retrieval: Support DM-paths in ls
Browse files Browse the repository at this point in the history
  • Loading branch information
magik6k committed Nov 17, 2021
1 parent 7fb12e2 commit 8737618
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 13 deletions.
68 changes: 59 additions & 9 deletions cli/client_retr.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/filecoin-project/lotus/markets/utils"
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/traversal"
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
Expand All @@ -24,6 +21,14 @@ import (
"github.com/ipfs/go-merkledag"
carv2 "github.com/ipld/go-car/v2"
"github.com/ipld/go-car/v2/blockstore"
"github.com/ipld/go-ipld-prime"
"github.com/ipld/go-ipld-prime/codec/dagjson"
basicnode "github.com/ipld/go-ipld-prime/node/basic"
"github.com/ipld/go-ipld-prime/traversal"
"github.com/ipld/go-ipld-prime/traversal/selector"
"github.com/ipld/go-ipld-prime/traversal/selector/builder"
selectorparse "github.com/ipld/go-ipld-prime/traversal/selector/parse"
textselector "github.com/ipld/go-ipld-selector-text-lite"
"github.com/multiformats/go-multiaddr"
manet "github.com/multiformats/go-multiaddr/net"
"github.com/urfave/cli/v2"
Expand All @@ -35,6 +40,7 @@ import (

lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/markets/utils"
"github.com/filecoin-project/lotus/node/repo"
)

Expand Down Expand Up @@ -322,8 +328,13 @@ func ClientExportStream(apiAddr string, apiAuth http.Header, eref lapi.ExportRef
}

if resp.StatusCode != http.StatusOK {
em, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, xerrors.Errorf("reading error body: %w", err)
}

resp.Body.Close() // nolint
return nil, xerrors.Errorf("getting root car: http %d", resp.StatusCode)
return nil, xerrors.Errorf("getting root car: http %d: %s", resp.StatusCode, string(em))
}

return resp.Body, nil
Expand Down Expand Up @@ -373,6 +384,20 @@ var clientRetrieveCatCmd = &cli.Command{
},
}

func pathToSel(psel string, sub builder.SelectorSpec) (lapi.Selector, error) {
rs, err := textselector.SelectorSpecFromPath(textselector.Expression(psel), sub)
if err != nil {
return "", xerrors.Errorf("failed to parse path-selector '%s': %w", err)
}

var b bytes.Buffer
if err := dagjson.Encode(rs.Node(), &b); err != nil {
return "", err
}

return lapi.Selector(b.String()), nil
}

var clientRetrieveLsCmd = &cli.Command{
Name: "ls",
Usage: "Show object links",
Expand All @@ -388,7 +413,7 @@ var clientRetrieveLsCmd = &cli.Command{
Value: 1,
},
&cli.StringFlag{
Name: "path-selector",
Name: "datamodel-path",
Usage: "a rudimentary (DM-level-only) text-path selector",
},
}, retrFlagsCommon...),
Expand All @@ -411,13 +436,30 @@ var clientRetrieveLsCmd = &cli.Command{
afmt := NewAppFmt(cctx.App)

rootSelector := lapi.Selector(`{".": {}}`)
dataSelector := lapi.Selector(fmt.Sprintf(`{"a":{">":{"R":{"l":{"depth":%d},":>":{"a":{">":{"|": [{"@":{}}, {".": {}}]}}}}}}}`, cctx.Int("depth")))
dataSelector := lapi.Selector(fmt.Sprintf(`{"a":{">":{"R":{"l":{"depth":%d},":>":{"a":{">":{"|":[{"@":{}},{".":{}}]}}}}}}}`, cctx.Int("depth")))

if cctx.IsSet("datamodel-path") {
rootSelector, err = pathToSel(cctx.String("datamodel-path"), nil)
if err != nil {
return err
}

ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any)
dataSelector, err = pathToSel(cctx.String("datamodel-path"), ssb.ExploreAll(
ssb.ExploreRecursive(selector.RecursionLimitDepth(int64(cctx.Int("depth"))), ssb.ExploreAll(ssb.ExploreUnion(ssb.Matcher(), ssb.ExploreRecursiveEdge()))),
))
if err != nil {
return err
}
}

eref, err := retrieve(ctx, cctx, fapi, &dataSelector, afmt.Printf)
if err != nil {
return err
}

fmt.Println() // separate retrieval events from results

eref.DAGs = append(eref.DAGs, lapi.DagSpec{
RootSelector: &rootSelector,
DataSelector: &dataSelector,
Expand Down Expand Up @@ -453,7 +495,6 @@ var clientRetrieveLsCmd = &cli.Command{
dserv := merkledag.NewDAGService(blockservice.New(cbs, offline.Exchange(cbs)))

if !cctx.Bool("ipld") {

links, err := dserv.GetLinks(ctx, roots[0])
if err != nil {
return xerrors.Errorf("getting links: %w", err)
Expand All @@ -463,7 +504,16 @@ var clientRetrieveLsCmd = &cli.Command{
fmt.Printf("%s %s\t%d\n", link.Cid, link.Name, link.Size)
}
} else {
sel, _ := selectorparse.ParseJSONSelector(fmt.Sprintf(`{"R":{"l":{"depth":%d},":>":{"a":{">":{"|":[{"@":{}},{".":{}}]}}}}}`, cctx.Int("depth")))
jsel := lapi.Selector(fmt.Sprintf(`{"R":{"l":{"depth":%d},":>":{"a":{">":{"|":[{"@":{}},{".":{}}]}}}}}`, cctx.Int("depth")))

if cctx.IsSet("datamodel-path") {
ssb := builder.NewSelectorSpecBuilder(basicnode.Prototype.Any)
jsel, err = pathToSel(cctx.String("datamodel-path"),
ssb.ExploreRecursive(selector.RecursionLimitDepth(int64(cctx.Int("depth"))), ssb.ExploreAll(ssb.ExploreUnion(ssb.Matcher(), ssb.ExploreRecursiveEdge()))),
)
}

sel, _ := selectorparse.ParseJSONSelector(string(jsel))

if err := utils.TraverseDag(
ctx,
Expand Down
4 changes: 0 additions & 4 deletions node/impl/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -1052,10 +1052,6 @@ func parseDagSpec(ctx context.Context, root cid.Cid, dsp []api.DagSpec, ds forma
func(p traversal.Progress, n ipld.Node, r traversal.VisitReason) error {
if r == traversal.VisitReason_SelectionMatch {

if p.LastBlock.Path.String() != p.Path.String() {
return xerrors.Errorf("unsupported selection path '%s' does not correspond to a block boundary (a.k.a. CID link)", p.Path.String())
}

if p.LastBlock.Link == nil {
// this is likely the root node that we've matched here
// todo: is this a correct assumption
Expand Down

0 comments on commit 8737618

Please sign in to comment.