package main import ( "encoding/json" "fmt" "io" "os" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" "github.com/ipld/go-car" "github.com/urfave/cli/v2" cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" adt13 "github.com/filecoin-project/go-state-types/builtin/v13/util/adt" "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/chain/actors/adt" ) var adlCmd = &cli.Command{ Name: "adl", Usage: "adl manipulation commands", Subcommands: []*cli.Command{ adlAmtCmd, }, } var adlAmtCmd = &cli.Command{ Name: "amt", Usage: "AMT manipulation commands", Subcommands: []*cli.Command{ adlAmtGetCmd, }, } var adlAmtGetCmd = &cli.Command{ Name: "get", Usage: "Get an element from an AMT", Flags: []cli.Flag{ &cli.StringFlag{ Name: "car-file", Usage: "write a car file with two hamts (use lotus-shed export-car)", }, &cli.IntFlag{ Name: "bitwidth", Usage: "bitwidth of the HAMT", Value: 5, }, &cli.StringFlag{ Name: "root", Usage: "root cid of the HAMT", }, &cli.Int64Flag{ Name: "key", Usage: "key to get", }, }, Action: func(cctx *cli.Context) error { bs := blockstore.NewMemorySync() f, err := os.Open(cctx.String("car-file")) if err != nil { return err } defer func(f *os.File) { _ = f.Close() }(f) cr, err := car.NewCarReader(f) if err != nil { return err } for { blk, err := cr.Next() if err != nil { if err == io.EOF { break } return err } if err := bs.Put(cctx.Context, blk); err != nil { return err } } root, err := cid.Parse(cctx.String("root")) if err != nil { return err } m, err := adt13.AsArray(adt.WrapStore(cctx.Context, cbor.NewCborStore(bs)), root, cctx.Int("bitwidth")) if err != nil { return err } var out cbg.Deferred ok, err := m.Get(cctx.Uint64("key"), &out) if err != nil { return err } if !ok { return xerrors.Errorf("no such element") } fmt.Printf("RAW: %x\n", out.Raw) fmt.Println("----") var i interface{} if err := cbor.DecodeInto(out.Raw, &i); err == nil { ij, err := json.MarshalIndent(i, "", " ") if err != nil { return err } fmt.Println(string(ij)) } return nil }, }