Merge pull request #5342 from filecoin-project/asr/change-owner
Allow multisigs to be set as miner owner address
This commit is contained in:
commit
23ce0645ed
85
cli/chain.go
85
cli/chain.go
@ -10,6 +10,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
"reflect"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -56,6 +57,7 @@ var chainCmd = &cli.Command{
|
|||||||
chainGasPriceCmd,
|
chainGasPriceCmd,
|
||||||
chainInspectUsage,
|
chainInspectUsage,
|
||||||
chainDecodeCmd,
|
chainDecodeCmd,
|
||||||
|
chainEncodeCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1327,3 +1329,86 @@ var chainDecodeParamsCmd = &cli.Command{
|
|||||||
return nil
|
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
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -473,12 +473,12 @@ var msigApproveCmd = &cli.Command{
|
|||||||
return ShowHelp(cctx, fmt.Errorf("must pass at least multisig address and message ID"))
|
return ShowHelp(cctx, fmt.Errorf("must pass at least multisig address and message ID"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if cctx.Args().Len() > 5 && cctx.Args().Len() != 7 {
|
if cctx.Args().Len() > 2 && cctx.Args().Len() < 5 {
|
||||||
return ShowHelp(cctx, fmt.Errorf("usage: msig approve <msig addr> <message ID> <proposer address> <desination> <value> [ <method> <params> ]"))
|
return ShowHelp(cctx, fmt.Errorf("usage: msig approve <msig addr> <message ID> <proposer address> <desination> <value>"))
|
||||||
}
|
}
|
||||||
|
|
||||||
if cctx.Args().Len() > 2 && cctx.Args().Len() != 5 {
|
if cctx.Args().Len() > 5 && cctx.Args().Len() != 7 {
|
||||||
return ShowHelp(cctx, fmt.Errorf("usage: msig approve <msig addr> <message ID> <proposer address> <desination> <value>"))
|
return ShowHelp(cctx, fmt.Errorf("usage: msig approve <msig addr> <message ID> <proposer address> <desination> <value> [ <method> <params> ]"))
|
||||||
}
|
}
|
||||||
|
|
||||||
api, closer, err := GetFullNodeAPI(cctx)
|
api, closer, err := GetFullNodeAPI(cctx)
|
||||||
|
@ -622,8 +622,8 @@ var actorControlSet = &cli.Command{
|
|||||||
|
|
||||||
var actorSetOwnerCmd = &cli.Command{
|
var actorSetOwnerCmd = &cli.Command{
|
||||||
Name: "set-owner",
|
Name: "set-owner",
|
||||||
Usage: "Set owner 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: "[address]",
|
ArgsUsage: "[newOwnerAddress senderAddress]",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.BoolFlag{
|
&cli.BoolFlag{
|
||||||
Name: "really-do-it",
|
Name: "really-do-it",
|
||||||
@ -637,8 +637,8 @@ var actorSetOwnerCmd = &cli.Command{
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if !cctx.Args().Present() {
|
if cctx.NArg() != 2 {
|
||||||
return fmt.Errorf("must pass address of new owner address")
|
return fmt.Errorf("must pass new owner address and sender address")
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||||
@ -660,7 +660,17 @@ var actorSetOwnerCmd = &cli.Command{
|
|||||||
return err
|
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -675,13 +685,17 @@ var actorSetOwnerCmd = &cli.Command{
|
|||||||
return err
|
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 {
|
if err != nil {
|
||||||
return xerrors.Errorf("serializing params: %w", err)
|
return xerrors.Errorf("serializing params: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := api.MpoolPushMessage(ctx, &types.Message{
|
smsg, err := api.MpoolPushMessage(ctx, &types.Message{
|
||||||
From: mi.Owner,
|
From: fromAddrId,
|
||||||
To: maddr,
|
To: maddr,
|
||||||
Method: miner.Methods.ChangeOwnerAddress,
|
Method: miner.Methods.ChangeOwnerAddress,
|
||||||
Value: big.Zero(),
|
Value: big.Zero(),
|
||||||
@ -691,7 +705,7 @@ var actorSetOwnerCmd = &cli.Command{
|
|||||||
return xerrors.Errorf("mpool push: %w", err)
|
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 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)
|
||||||
@ -701,34 +715,11 @@ var actorSetOwnerCmd = &cli.Command{
|
|||||||
|
|
||||||
// check it executed successfully
|
// check it executed successfully
|
||||||
if wait.Receipt.ExitCode != 0 {
|
if wait.Receipt.ExitCode != 0 {
|
||||||
fmt.Println("Propose owner change failed!")
|
fmt.Println("owner change failed!")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err = api.MpoolPushMessage(ctx, &types.Message{
|
fmt.Println("message succeeded!")
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user