package main import ( "context" "encoding/hex" "fmt" "io" "os" "github.com/ipfs/go-cid" block "github.com/ipfs/go-libipfs/blocks" "github.com/ipld/go-car" "github.com/urfave/cli/v2" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/node/repo" ) var importCarCmd = &cli.Command{ Name: "import-car", Description: "Import a car file into node chain blockstore", Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", Value: "~/.lotus", EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { r, err := repo.NewFS(cctx.String("repo")) if err != nil { return xerrors.Errorf("opening fs repo: %w", err) } ctx := context.TODO() exists, err := r.Exists() if err != nil { return err } if !exists { return xerrors.Errorf("lotus repo doesn't exist") } lr, err := r.Lock(repo.FullNode) if err != nil { return err } defer lr.Close() //nolint:errcheck cf := cctx.Args().Get(0) f, err := os.OpenFile(cf, os.O_RDONLY, 0664) if err != nil { return xerrors.Errorf("opening the car file: %w", err) } bs, err := lr.Blockstore(ctx, repo.UniversalBlockstore) if err != nil { return err } defer func() { if c, ok := bs.(io.Closer); ok { if err := c.Close(); err != nil { log.Warnf("failed to close blockstore: %s", err) } } }() cr, err := car.NewCarReader(f) if err != nil { return err } for { blk, err := cr.Next() switch err { case io.EOF: if err := f.Close(); err != nil { return err } fmt.Println() return nil default: if err := f.Close(); err != nil { return err } fmt.Println() return err case nil: fmt.Printf("\r%s", blk.Cid()) if err := bs.Put(context.Background(), blk); err != nil { if err := f.Close(); err != nil { return err } return xerrors.Errorf("put %s: %w", blk.Cid(), err) } } } }, } var importObjectCmd = &cli.Command{ Name: "import-obj", Usage: "import a raw ipld object into your datastore", Flags: []cli.Flag{ &cli.StringFlag{ Name: "repo", Value: "~/.lotus", EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { r, err := repo.NewFS(cctx.String("repo")) if err != nil { return xerrors.Errorf("opening fs repo: %w", err) } ctx := context.TODO() exists, err := r.Exists() if err != nil { return err } if !exists { return xerrors.Errorf("lotus repo doesn't exist") } lr, err := r.Lock(repo.FullNode) if err != nil { return err } defer lr.Close() //nolint:errcheck bs, err := lr.Blockstore(ctx, repo.UniversalBlockstore) if err != nil { return fmt.Errorf("failed to open blockstore: %w", err) } defer func() { if c, ok := bs.(io.Closer); ok { if err := c.Close(); err != nil { log.Warnf("failed to close blockstore: %s", err) } } }() c, err := cid.Decode(cctx.Args().Get(0)) if err != nil { return err } data, err := hex.DecodeString(cctx.Args().Get(1)) if err != nil { return err } blk, err := block.NewBlockWithCid(data, c) if err != nil { return err } if err := bs.Put(context.Background(), blk); err != nil { return err } return nil }, }