From 9811375d1861250cb5f93598d1be56a2e584cf12 Mon Sep 17 00:00:00 2001
From: Jeromy <jeromyj@gmail.com>
Date: Thu, 14 May 2020 16:11:03 -0700
Subject: [PATCH 1/2] add some commands for interacting with verified registry
 actor to lotus-shed

---
 cmd/lotus-shed/main.go     |   1 +
 cmd/lotus-shed/verifreg.go | 165 +++++++++++++++++++++++++++++++++++++
 2 files changed, 166 insertions(+)
 create mode 100644 cmd/lotus-shed/verifreg.go

diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go
index 34138089f..e7264c92c 100644
--- a/cmd/lotus-shed/main.go
+++ b/cmd/lotus-shed/main.go
@@ -27,6 +27,7 @@ func main() {
 		commpToCidCmd,
 		fetchParamCmd,
 		proofsCmd,
+		verifRegCmd,
 	}
 
 	app := &cli.App{
diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go
new file mode 100644
index 000000000..27cb009ba
--- /dev/null
+++ b/cmd/lotus-shed/verifreg.go
@@ -0,0 +1,165 @@
+package main
+
+import (
+	"fmt"
+
+	"github.com/filecoin-project/go-address"
+	"gopkg.in/urfave/cli.v2"
+
+	"github.com/filecoin-project/lotus/chain/types"
+	lcli "github.com/filecoin-project/lotus/cli"
+
+	"github.com/filecoin-project/lotus/chain/actors"
+	"github.com/filecoin-project/specs-actors/actors/builtin"
+	"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
+)
+
+var verifRegCmd = &cli.Command{
+	Name:  "verifreg",
+	Usage: "Interact with the verified registry actor",
+	Flags: []cli.Flag{},
+	Subcommands: []*cli.Command{
+		verifRegAddVerifierCmd,
+		verifRegVerifyClientCmd,
+	},
+}
+
+var verifRegAddVerifierCmd = &cli.Command{
+	Name:  "add-verifier",
+	Usage: "make a given account a verifier",
+	Action: func(cctx *cli.Context) error {
+		fromk, err := address.NewFromString("t3qfoulel6fy6gn3hjmbhpdpf6fs5aqjb5fkurhtwvgssizq4jey5nw4ptq5up6h7jk7frdvvobv52qzmgjinq")
+		if err != nil {
+			return err
+		}
+
+		if cctx.Args().Len() != 2 {
+			return fmt.Errorf("must specify two arguments: address and allowance")
+		}
+
+		target, err := address.NewFromString(cctx.Args().Get(0))
+		if err != nil {
+			return err
+		}
+
+		allowance, err := types.BigFromString(cctx.Args().Get(1))
+		if err != nil {
+			return err
+		}
+
+		params, err := actors.SerializeParams(&verifreg.AddVerifierParams{Address: target, Allowance: allowance})
+		if err != nil {
+			return err
+		}
+
+		api, closer, err := lcli.GetFullNodeAPI(cctx)
+		if err != nil {
+			return err
+		}
+		defer closer()
+		ctx := lcli.ReqContext(cctx)
+
+		msg := &types.Message{
+			To:       builtin.VerifiedRegistryActorAddr,
+			From:     fromk,
+			Method:   builtin.MethodsVerifiedRegistry.AddVerifier,
+			GasPrice: types.NewInt(1),
+			GasLimit: 300000,
+			Params:   params,
+		}
+
+		smsg, err := api.MpoolPushMessage(ctx, msg)
+		if err != nil {
+			return err
+		}
+
+		fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid())
+
+		mwait, err := api.StateWaitMsg(ctx, smsg.Cid())
+		if err != nil {
+			return err
+		}
+
+		if mwait.Receipt.ExitCode != 0 {
+			return fmt.Errorf("failed to add verifier: %d", mwait.Receipt.ExitCode)
+		}
+
+		return nil
+
+	},
+}
+
+var verifRegVerifyClientCmd = &cli.Command{
+	Name:  "verify-client",
+	Usage: "make a given account a verified client",
+	Flags: []cli.Flag{
+		&cli.StringFlag{
+			Name:  "from",
+			Usage: "specify your verifier address to send the message from",
+		},
+	},
+	Action: func(cctx *cli.Context) error {
+		froms := cctx.String("from")
+		if froms == "" {
+			return fmt.Errorf("must specify from address with --from")
+		}
+
+		fromk, err := address.NewFromString(froms)
+		if err != nil {
+			return err
+		}
+
+		if cctx.Args().Len() != 2 {
+			return fmt.Errorf("must specify two arguments: address and allowance")
+		}
+
+		target, err := address.NewFromString(cctx.Args().Get(0))
+		if err != nil {
+			return err
+		}
+
+		allowance, err := types.BigFromString(cctx.Args().Get(1))
+		if err != nil {
+			return err
+		}
+
+		params, err := actors.SerializeParams(&verifreg.AddVerifiedClientParams{Address: target, Allowance: allowance})
+		if err != nil {
+			return err
+		}
+
+		api, closer, err := lcli.GetFullNodeAPI(cctx)
+		if err != nil {
+			return err
+		}
+		defer closer()
+		ctx := lcli.ReqContext(cctx)
+
+		msg := &types.Message{
+			To:       builtin.VerifiedRegistryActorAddr,
+			From:     fromk,
+			Method:   builtin.MethodsVerifiedRegistry.AddVerifiedClient,
+			GasPrice: types.NewInt(1),
+			GasLimit: 300000,
+			Params:   params,
+		}
+
+		smsg, err := api.MpoolPushMessage(ctx, msg)
+		if err != nil {
+			return err
+		}
+
+		fmt.Printf("message sent, now waiting on cid: %s\n", smsg.Cid())
+
+		mwait, err := api.StateWaitMsg(ctx, smsg.Cid())
+		if err != nil {
+			return err
+		}
+
+		if mwait.Receipt.ExitCode != 0 {
+			return fmt.Errorf("failed to add verified client: %d", mwait.Receipt.ExitCode)
+		}
+
+		return nil
+	},
+}

From 9c020e54b5ab4c09e6524fbeed17ffbb20580483 Mon Sep 17 00:00:00 2001
From: Jeromy <jeromyj@gmail.com>
Date: Thu, 14 May 2020 17:05:57 -0700
Subject: [PATCH 2/2] Add more verifreg commands to list verifiers and clients

---
 cmd/lotus-shed/verifreg.go | 112 +++++++++++++++++++++++++++++++++++++
 1 file changed, 112 insertions(+)

diff --git a/cmd/lotus-shed/verifreg.go b/cmd/lotus-shed/verifreg.go
index 27cb009ba..f1e665078 100644
--- a/cmd/lotus-shed/verifreg.go
+++ b/cmd/lotus-shed/verifreg.go
@@ -1,6 +1,7 @@
 package main
 
 import (
+	"bytes"
 	"fmt"
 
 	"github.com/filecoin-project/go-address"
@@ -9,9 +10,14 @@ import (
 	"github.com/filecoin-project/lotus/chain/types"
 	lcli "github.com/filecoin-project/lotus/cli"
 
+	"github.com/filecoin-project/lotus/api/apibstore"
 	"github.com/filecoin-project/lotus/chain/actors"
 	"github.com/filecoin-project/specs-actors/actors/builtin"
 	"github.com/filecoin-project/specs-actors/actors/builtin/verifreg"
+	"github.com/ipfs/go-hamt-ipld"
+	cbor "github.com/ipfs/go-ipld-cbor"
+
+	cbg "github.com/whyrusleeping/cbor-gen"
 )
 
 var verifRegCmd = &cli.Command{
@@ -21,6 +27,8 @@ var verifRegCmd = &cli.Command{
 	Subcommands: []*cli.Command{
 		verifRegAddVerifierCmd,
 		verifRegVerifyClientCmd,
+		verifRegListVerifiersCmd,
+		verifRegListClientsCmd,
 	},
 }
 
@@ -163,3 +171,107 @@ var verifRegVerifyClientCmd = &cli.Command{
 		return nil
 	},
 }
+
+var verifRegListVerifiersCmd = &cli.Command{
+	Name:  "list-verifiers",
+	Usage: "list all verifiers",
+	Action: func(cctx *cli.Context) error {
+		api, closer, err := lcli.GetFullNodeAPI(cctx)
+		if err != nil {
+			return err
+		}
+		defer closer()
+		ctx := lcli.ReqContext(cctx)
+
+		act, err := api.StateGetActor(ctx, builtin.VerifiedRegistryActorAddr, types.EmptyTSK)
+		if err != nil {
+			return err
+		}
+
+		apibs := apibstore.NewAPIBlockstore(api)
+		cst := cbor.NewCborStore(apibs)
+
+		var st verifreg.State
+		if err := cst.Get(ctx, act.Head, &st); err != nil {
+			return err
+		}
+
+		vh, err := hamt.LoadNode(ctx, cst, st.Verifiers)
+		if err != nil {
+			return err
+		}
+
+		if err := vh.ForEach(ctx, func(k string, val interface{}) error {
+			addr, err := address.NewFromBytes([]byte(k))
+			if err != nil {
+				return err
+			}
+
+			var dcap verifreg.DataCap
+
+			if err := dcap.UnmarshalCBOR(bytes.NewReader(val.(*cbg.Deferred).Raw)); err != nil {
+				return err
+			}
+
+			fmt.Printf("%s: %s\n", addr, dcap)
+
+			return nil
+		}); err != nil {
+			return err
+		}
+
+		return nil
+	},
+}
+
+var verifRegListClientsCmd = &cli.Command{
+	Name:  "list-clients",
+	Usage: "list all verified clients",
+	Action: func(cctx *cli.Context) error {
+		api, closer, err := lcli.GetFullNodeAPI(cctx)
+		if err != nil {
+			return err
+		}
+		defer closer()
+		ctx := lcli.ReqContext(cctx)
+
+		act, err := api.StateGetActor(ctx, builtin.VerifiedRegistryActorAddr, types.EmptyTSK)
+		if err != nil {
+			return err
+		}
+
+		apibs := apibstore.NewAPIBlockstore(api)
+		cst := cbor.NewCborStore(apibs)
+
+		var st verifreg.State
+		if err := cst.Get(ctx, act.Head, &st); err != nil {
+			return err
+		}
+
+		vh, err := hamt.LoadNode(ctx, cst, st.VerifiedClients)
+		if err != nil {
+			return err
+		}
+
+		if err := vh.ForEach(ctx, func(k string, val interface{}) error {
+			addr, err := address.NewFromBytes([]byte(k))
+			if err != nil {
+				return err
+			}
+
+			var dcap verifreg.DataCap
+
+			if err := dcap.UnmarshalCBOR(bytes.NewReader(val.(*cbg.Deferred).Raw)); err != nil {
+				return err
+			}
+
+			fmt.Printf("%s: %s\n", addr, dcap)
+
+			return nil
+		}); err != nil {
+			return err
+		}
+
+		return nil
+	},
+}