diff --git a/cli/chain.go b/cli/chain.go index 46933eb1926..3988c7225c6 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -10,6 +10,7 @@ import ( "os" "os/exec" "path" + "reflect" "sort" "strconv" "strings" @@ -58,6 +59,7 @@ var chainCmd = &cli.Command{ chainGasPriceCmd, chainInspectUsage, chainDecodeCmd, + chainEncodeCmd, }, } @@ -1367,3 +1369,86 @@ var chainDecodeParamsCmd = &cli.Command{ return nil }, } + +var chainEncodeCmd = &cli.Command{ + Name: "encode", + Usage: "encode various types", + Subcommands: []*cli.Command{ + chainEncodeParamsCmd, + }, +} + +var chainEncodeParamsCmd = &cli.Command{ + Name: "params", + Usage: "Encodes the given JSON params", + ArgsUsage: "[toAddr method params]", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "tipset", + }, + &cli.StringFlag{ + Name: "encoding", + Value: "base64", + Usage: "specify input encoding to parse", + }, + }, + Action: func(cctx *cli.Context) error { + api, closer, err := GetFullNodeAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := ReqContext(cctx) + + if cctx.Args().Len() != 3 { + return ShowHelp(cctx, fmt.Errorf("incorrect number of arguments")) + } + + to, err := address.NewFromString(cctx.Args().First()) + if err != nil { + return xerrors.Errorf("parsing toAddr: %w", err) + } + + method, err := strconv.ParseInt(cctx.Args().Get(1), 10, 64) + if err != nil { + return xerrors.Errorf("parsing method id: %w", err) + } + + ts, err := LoadTipSet(ctx, cctx, api) + if err != nil { + return err + } + + act, err := api.StateGetActor(ctx, to, ts.Key()) + if err != nil { + return xerrors.Errorf("getting actor: %w", err) + } + + methodMeta, found := stmgr.MethodsMap[act.Code][abi.MethodNum(method)] + if !found { + return fmt.Errorf("method %d not found on actor %s", method, act.Code) + } + + p := reflect.New(methodMeta.Params.Elem()).Interface().(cbg.CBORMarshaler) + + if err := json.Unmarshal([]byte(cctx.Args().Get(2)), p); err != nil { + return fmt.Errorf("unmarshaling input into params type: %w", err) + } + + buf := new(bytes.Buffer) + if err := p.MarshalCBOR(buf); err != nil { + return err + } + + switch cctx.String("encoding") { + case "base64": + fmt.Println(base64.StdEncoding.EncodeToString(buf.Bytes())) + case "hex": + fmt.Println(hex.EncodeToString(buf.Bytes())) + default: + return xerrors.Errorf("unrecognized encoding: %s", cctx.String("encoding")) + } + + return nil + }, +} diff --git a/cli/multisig.go b/cli/multisig.go index 8e6b068d94a..c3d3b980280 100644 --- a/cli/multisig.go +++ b/cli/multisig.go @@ -473,12 +473,12 @@ var msigApproveCmd = &cli.Command{ return ShowHelp(cctx, fmt.Errorf("must pass at least multisig address and message ID")) } - if cctx.Args().Len() > 5 && cctx.Args().Len() != 7 { - return ShowHelp(cctx, fmt.Errorf("usage: msig approve [ ]")) + if cctx.Args().Len() > 2 && cctx.Args().Len() < 5 { + return ShowHelp(cctx, fmt.Errorf("usage: msig approve ")) } - if cctx.Args().Len() > 2 && cctx.Args().Len() != 5 { - return ShowHelp(cctx, fmt.Errorf("usage: msig approve ")) + if cctx.Args().Len() > 5 && cctx.Args().Len() != 7 { + return ShowHelp(cctx, fmt.Errorf("usage: msig approve [ ]")) } api, closer, err := GetFullNodeAPI(cctx) diff --git a/cmd/epik-storage-miner/actor.go b/cmd/epik-storage-miner/actor.go index cfd7e5a4963..5fd95f4a1df 100644 --- a/cmd/epik-storage-miner/actor.go +++ b/cmd/epik-storage-miner/actor.go @@ -789,8 +789,8 @@ var actorControlSet = &cli.Command{ var actorSetOwnerCmd = &cli.Command{ Name: "set-owner", - Usage: "Set owner address", - ArgsUsage: "[address]", + Usage: "Set owner address (this command should be invoked twice, first with the old owner as the senderAddress, and then with the new owner)", + ArgsUsage: "[newOwnerAddress senderAddress]", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "really-do-it", @@ -804,8 +804,8 @@ var actorSetOwnerCmd = &cli.Command{ return nil } - if !cctx.Args().Present() { - return fmt.Errorf("must pass address of new owner address") + if cctx.NArg() != 2 { + return fmt.Errorf("must pass new owner address and sender address") } nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) @@ -827,53 +827,42 @@ var actorSetOwnerCmd = &cli.Command{ return err } - newAddr, err := api.StateLookupID(ctx, na, types.EmptyTSK) + newAddrId, err := api.StateLookupID(ctx, na, types.EmptyTSK) if err != nil { return err } - maddr, err := nodeApi.ActorAddress(ctx) + fa, err := address.NewFromString(cctx.Args().Get(1)) if err != nil { return err } - mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) + fromAddrId, err := api.StateLookupID(ctx, fa, types.EmptyTSK) if err != nil { return err } - sp, err := actors.SerializeParams(&newAddr) + maddr, err := nodeApi.ActorAddress(ctx) if err != nil { - return xerrors.Errorf("serializing params: %w", err) + return err } - smsg, err := api.MpoolPushMessage(ctx, &types.Message{ - From: mi.Owner, - To: maddr, - Method: miner.Methods.ChangeOwnerAddress, - Value: big.Zero(), - Params: sp, - }, nil) + mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) if err != nil { - return xerrors.Errorf("mpool push: %w", err) + return err } - fmt.Println("Propose Message CID:", smsg.Cid()) - - // wait for it to get mined into a block - wait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) - if err != nil { - return err + if fromAddrId != mi.Owner && fromAddrId != newAddrId { + return xerrors.New("from address must either be the old owner or the new owner") } - // check it executed successfully - if wait.Receipt.ExitCode != 0 { - fmt.Println("Propose owner change failed!") - return err + sp, err := actors.SerializeParams(&newAddrId) + if err != nil { + return xerrors.Errorf("serializing params: %w", err) } - smsg, err = api.MpoolPushMessage(ctx, &types.Message{ - From: newAddr, + smsg, err := api.MpoolPushMessage(ctx, &types.Message{ + From: fromAddrId, To: maddr, Method: miner.Methods.ChangeOwnerAddress, Value: big.Zero(), @@ -883,20 +872,22 @@ var actorSetOwnerCmd = &cli.Command{ return xerrors.Errorf("mpool push: %w", err) } - fmt.Println("Approve Message CID:", smsg.Cid()) + fmt.Println("Message CID:", smsg.Cid()) // wait for it to get mined into a block - wait, err = api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) + wait, err := api.StateWaitMsg(ctx, smsg.Cid(), build.MessageConfidence) if err != nil { return err } // check it executed successfully if wait.Receipt.ExitCode != 0 { - fmt.Println("Approve owner change failed!") + fmt.Println("owner change failed!") return err } + fmt.Println("message succeeded!") + return nil }, }