diff --git a/cli/chain.go b/cli/chain.go index 4230e4838..2dc0801b4 100644 --- a/cli/chain.go +++ b/cli/chain.go @@ -10,6 +10,7 @@ import ( "os" "os/exec" "path" + "reflect" "sort" "strconv" "strings" @@ -56,6 +57,7 @@ var chainCmd = &cli.Command{ chainGasPriceCmd, chainInspectUsage, chainDecodeCmd, + chainEncodeCmd, }, } @@ -1327,3 +1329,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 e18c48b8f..c3a062ed4 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/lotus-storage-miner/actor.go b/cmd/lotus-storage-miner/actor.go index d1fc96972..bcd29ea60 100644 --- a/cmd/lotus-storage-miner/actor.go +++ b/cmd/lotus-storage-miner/actor.go @@ -622,8 +622,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", @@ -637,8 +637,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) @@ -660,7 +660,17 @@ 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 + } + + fa, err := address.NewFromString(cctx.Args().Get(1)) + if err != nil { + return err + } + + fromAddrId, err := api.StateLookupID(ctx, fa, types.EmptyTSK) if err != nil { return err } @@ -675,13 +685,17 @@ var actorSetOwnerCmd = &cli.Command{ return err } - sp, err := actors.SerializeParams(&newAddr) + if fromAddrId != mi.Owner && fromAddrId != newAddrId { + return xerrors.New("from address must either be the old owner or the new owner") + } + + sp, err := actors.SerializeParams(&newAddrId) if err != nil { return xerrors.Errorf("serializing params: %w", err) } smsg, err := api.MpoolPushMessage(ctx, &types.Message{ - From: mi.Owner, + From: fromAddrId, To: maddr, Method: miner.Methods.ChangeOwnerAddress, Value: big.Zero(), @@ -691,7 +705,7 @@ var actorSetOwnerCmd = &cli.Command{ return xerrors.Errorf("mpool push: %w", err) } - fmt.Println("Propose 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) @@ -701,34 +715,11 @@ var actorSetOwnerCmd = &cli.Command{ // check it executed successfully if wait.Receipt.ExitCode != 0 { - fmt.Println("Propose owner change failed!") + fmt.Println("owner change failed!") return err } - smsg, err = api.MpoolPushMessage(ctx, &types.Message{ - From: newAddr, - To: maddr, - Method: miner.Methods.ChangeOwnerAddress, - Value: big.Zero(), - Params: sp, - }, nil) - if err != nil { - return xerrors.Errorf("mpool push: %w", err) - } - - fmt.Println("Approve 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 - } - - // check it executed successfully - if wait.Receipt.ExitCode != 0 { - fmt.Println("Approve owner change failed!") - return err - } + fmt.Println("message succeeded!") return nil },