diff --git a/api/api.go b/api/api.go index 0db8285ad..d292f3ef8 100644 --- a/api/api.go +++ b/api/api.go @@ -2,6 +2,7 @@ package api import ( "context" + "github.com/ipfs/go-ipfs/filestore" "github.com/filecoin-project/go-lotus/chain" "github.com/filecoin-project/go-lotus/chain/address" @@ -17,6 +18,13 @@ type Version struct { // TODO: git commit / os / genesis cid? } +type Import struct { + Status filestore.Status + Key cid.Cid + FilePath string + Size uint64 +} + // API is a low-level interface to the Filecoin network type API interface { // chain @@ -89,7 +97,7 @@ type API interface { //ClientUnimport(path string) // ClientListImports lists imported files and their root CIDs - //ClientListImports() []Import + ClientListImports(ctx context.Context) ([]Import, error) //ClientListAsks() []Ask diff --git a/api/struct.go b/api/struct.go index 67b22e37e..483831fe4 100644 --- a/api/struct.go +++ b/api/struct.go @@ -28,7 +28,8 @@ type Struct struct { WalletNew func(context.Context, string) (address.Address, error) WalletList func(context.Context) ([]address.Address, error) - ClientImport func(ctx context.Context, path string) (cid.Cid, error) + ClientImport func(ctx context.Context, path string) (cid.Cid, error) + ClientListImports func(ctx context.Context) ([]Import, error) NetPeers func(context.Context) ([]peer.AddrInfo, error) NetConnect func(context.Context, peer.AddrInfo) error @@ -36,6 +37,10 @@ type Struct struct { } } +func (c *Struct) ClientListImports(ctx context.Context) ([]Import, error) { + return c.Internal.ClientListImports(ctx) +} + func (c *Struct) ClientImport(ctx context.Context, path string) (cid.Cid, error) { return c.Internal.ClientImport(ctx, path) } diff --git a/cli/client.go b/cli/client.go index b7706242c..f6bd3e9b0 100644 --- a/cli/client.go +++ b/cli/client.go @@ -10,12 +10,13 @@ var clientCmd = &cli.Command{ Usage: "Make deals, store data, retrieve data", Subcommands: []*cli.Command{ clientImportCmd, + clientLocalCmd, }, } var clientImportCmd = &cli.Command{ - Name: "import", - Usage: "import data", + Name: "import", + Usage: "Import data", Action: func(cctx *cli.Context) error { api, err := getAPI(cctx) if err != nil { @@ -30,4 +31,25 @@ var clientImportCmd = &cli.Command{ fmt.Println(c.String()) return nil }, -} \ No newline at end of file +} + +var clientLocalCmd = &cli.Command{ + Name: "local", + Usage: "List locally imported data", + Action: func(cctx *cli.Context) error { + api, err := getAPI(cctx) + if err != nil { + return err + } + ctx := reqContext(cctx) + + list, err := api.ClientListImports(ctx) + if err != nil { + return err + } + for _, v := range list { + fmt.Printf("%s %s %d %s\n", v.Key, v.FilePath, v.Size, v.Status) + } + return nil + }, +} diff --git a/node/api.go b/node/api.go index 9c58d3041..27b779ba2 100644 --- a/node/api.go +++ b/node/api.go @@ -2,6 +2,7 @@ package node import ( "context" + "github.com/ipfs/go-ipfs/filestore" "github.com/filecoin-project/go-lotus/api" "github.com/filecoin-project/go-lotus/build" @@ -22,6 +23,7 @@ type API struct { Host host.Host Chain *chain.ChainStore PubSub *pubsub.PubSub + Filestore *filestore.Filestore Mpool *chain.MessagePool Wallet *chain.Wallet } diff --git a/node/builder.go b/node/builder.go index 483eb155a..34528d22e 100644 --- a/node/builder.go +++ b/node/builder.go @@ -3,12 +3,14 @@ package node import ( "context" "errors" + "github.com/ipfs/go-ipfs/filestore" "reflect" "time" "github.com/ipfs/go-datastore" blockstore "github.com/ipfs/go-ipfs-blockstore" exchange "github.com/ipfs/go-ipfs-exchange-interface" + ipld "github.com/ipfs/go-ipld-format" ci "github.com/libp2p/go-libp2p-core/crypto" "github.com/libp2p/go-libp2p-core/host" "github.com/libp2p/go-libp2p-core/peer" @@ -18,7 +20,6 @@ import ( pubsub "github.com/libp2p/go-libp2p-pubsub" record "github.com/libp2p/go-libp2p-record" "go.uber.org/fx" - ipld "github.com/ipfs/go-ipld-format" "github.com/filecoin-project/go-lotus/api" "github.com/filecoin-project/go-lotus/chain" @@ -167,6 +168,7 @@ func Online() Option { Override(new(blockstore.GCLocker), blockstore.NewGCLocker), Override(new(blockstore.GCBlockstore), blockstore.NewGCBlockstore), Override(new(exchange.Interface), modules.Bitswap), + Override(new(*filestore.Filestore), modules.ClientFstore), Override(new(ipld.DAGService), modules.ClientDAG), // Filecoin services diff --git a/node/client/import.go b/node/client/import.go index fa96cc2d2..26f2a78d9 100644 --- a/node/client/import.go +++ b/node/client/import.go @@ -2,6 +2,8 @@ package client import ( "context" + "github.com/filecoin-project/go-lotus/api" + "github.com/ipfs/go-ipfs/filestore" "go.uber.org/fx" "os" @@ -17,9 +19,10 @@ type LocalStorage struct { fx.In LocalDAG ipld.DAGService + Filestore *filestore.Filestore } -func (s *LocalStorage) ClientImport(ctx context.Context, path string) (cid.Cid, error) { +func (s *LocalStorage) ClientImport(ctx context.Context, path string) (cid.Cid, error) { f, err := os.Open(path) if err != nil { return cid.Undef, err @@ -55,3 +58,30 @@ func (s *LocalStorage) ClientImport(ctx context.Context, path string) (cid.Cid, return nd.Cid(), bufferedDS.Commit() } + + +func (s *LocalStorage) ClientListImports(ctx context.Context) ([]api.Import, error) { + next, err := filestore.ListAll(s.Filestore, false) + if err != nil { + return nil, err + } + + // TODO: make this less very bad by tracking root cids instead of using ListAll + + out := make([]api.Import, 0) + for { + r := next() + if r == nil { + return out, nil + } + if r.Offset != 0 { + continue + } + out = append(out, api.Import{ + Status: r.Status, + Key: r.Key, + FilePath: r.FilePath, + Size: r.Size, + }) + } +} \ No newline at end of file diff --git a/node/modules/core.go b/node/modules/core.go index 62795277c..02e4d18da 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -79,7 +79,7 @@ func Blockstore(r repo.LockedRepo) (blockstore.Blockstore, error) { return blockstore.NewIdStore(bs), nil } -func ClientDAG(lc fx.Lifecycle, r repo.LockedRepo) (ipld.DAGService, error) { +func ClientFstore(r repo.LockedRepo) (*filestore.Filestore, error) { clientds, err := r.Datastore("/client") if err != nil { return nil, err @@ -91,7 +91,10 @@ func ClientDAG(lc fx.Lifecycle, r repo.LockedRepo) (ipld.DAGService, error) { // TODO: fm.AllowUrls (needs more code in client import) bs := blockstore.NewBlockstore(blocks) - fstore := filestore.NewFilestore(bs, fm) + return filestore.NewFilestore(bs, fm), nil +} + +func ClientDAG(lc fx.Lifecycle, fstore *filestore.Filestore) ipld.DAGService { ibs := blockstore.NewIdStore(fstore) bsvc := blockservice.New(ibs, offline.Exchange(ibs)) dag := merkledag.NewDAGService(bsvc) @@ -102,5 +105,5 @@ func ClientDAG(lc fx.Lifecycle, r repo.LockedRepo) (ipld.DAGService, error) { }, }) - return dag, nil + return dag }