Skip to content

Commit

Permalink
Msig commands for change beneficiary propose and approve.
Browse files Browse the repository at this point in the history
  • Loading branch information
geoff-vball committed Sep 14, 2022
1 parent 8e78234 commit 0945e94
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 1 deletion.
11 changes: 10 additions & 1 deletion cmd/lotus-miner/actor.go
Original file line number Diff line number Diff line change
Expand Up @@ -1251,7 +1251,16 @@ var actorConfirmChangeBeneficiary = &cli.Command{
return fmt.Errorf("confirm beneficiary change failed")
}

fmt.Printf("Beneficiary key change to %s successfully sent\n", mi.PendingBeneficiaryTerm.NewBeneficiary)
updatedMinerInfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}

if updatedMinerInfo.PendingBeneficiaryTerm == nil {
fmt.Println("Beneficiary address successfully changed")
} else {
fmt.Println("Beneficiary address change awaiting additional confirmations")
}

return nil
},
Expand Down
197 changes: 197 additions & 0 deletions cmd/lotus-shed/miner-multisig.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ var minerMultisigsCmd = &cli.Command{
mmProposeChangeWorker,
mmConfirmChangeWorker,
mmProposeControlSet,
mmProposeChangeBeneficiary,
mmConfirmChangeBeneficiary,
},
Flags: []cli.Flag{
&cli.StringFlag{
Expand Down Expand Up @@ -468,6 +470,109 @@ var mmProposeChangeWorker = &cli.Command{
},
}

var mmProposeChangeBeneficiary = &cli.Command{
Name: "propose-change-beneficiary",
Usage: "Propose a beneficiary address change",
ArgsUsage: "[beneficiaryAddress quota expiration]",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "really-do-it",
Usage: "Actually send transaction performing the action",
Value: false,
},
&cli.StringFlag{
Name: "actor",
Usage: "specify the address of miner actor",
},
},
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() != 3 {
return fmt.Errorf("must specify three arguments")
}

api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return xerrors.Errorf("getting fullnode api: %w", err)
}
defer acloser()

ctx := lcli.ReqContext(cctx)

na, err := address.NewFromString(cctx.Args().Get(0))
if err != nil {
return xerrors.Errorf("parsing beneficiary address: %w", err)
}

newAddr, err := api.StateLookupID(ctx, na, types.EmptyTSK)
if err != nil {
return xerrors.Errorf("looking up new beneficiary address: %w", err)
}

quota, err := types.ParseFIL(cctx.Args().Get(1))
if err != nil {
return xerrors.Errorf("parsing quota: %w", err)
}

expiration, err := types.BigFromString(cctx.Args().Get(2))
if err != nil {
return xerrors.Errorf("parsing expiration: %w", err)
}

multisigAddr, sender, minerAddr, err := getInputs(cctx)
if err != nil {
return err
}

mi, err := api.StateMinerInfo(ctx, minerAddr, types.EmptyTSK)
if err != nil {
return err
}

if mi.PendingBeneficiaryTerm != nil {
fmt.Println("WARNING: replacing Pending Beneficiary Term of:")
fmt.Println("Beneficiary: ", mi.PendingBeneficiaryTerm.NewBeneficiary)
fmt.Println("Quota:", mi.PendingBeneficiaryTerm.NewQuota)
fmt.Println("Expiration Epoch:", mi.PendingBeneficiaryTerm.NewExpiration)
}

if !cctx.Bool("really-do-it") {
fmt.Println("Pass --really-do-it to actually execute this action")
return nil
}

params := &miner.ChangeBeneficiaryParams{
NewBeneficiary: newAddr,
NewQuota: abi.TokenAmount(quota),
NewExpiration: abi.ChainEpoch(expiration.Int64()),
}

sp, err := actors.SerializeParams(params)
if err != nil {
return xerrors.Errorf("serializing params: %w", err)
}

pcid, err := api.MsigPropose(ctx, multisigAddr, minerAddr, big.Zero(), sender, uint64(builtin.MethodsMiner.ChangeBeneficiary), sp)
if err != nil {
return xerrors.Errorf("proposing message: %w", err)
}

fmt.Println("Propose Message CID: ", pcid)

// wait for it to get mined into a block
wait, err := api.StateWaitMsg(ctx, pcid, build.MessageConfidence)
if err != nil {
return xerrors.Errorf("waiting for message to be included in block: %w", err)
}

// check it executed successfully
if wait.Receipt.ExitCode != 0 {
return fmt.Errorf("propose beneficiary change failed")
}

return nil
},
}

var mmConfirmChangeWorker = &cli.Command{
Name: "confirm-change-worker",
Usage: "Confirm an worker address change",
Expand Down Expand Up @@ -551,6 +656,98 @@ var mmConfirmChangeWorker = &cli.Command{
},
}

var mmConfirmChangeBeneficiary = &cli.Command{
Name: "confirm-change-beneficiary",
Usage: "Confirm a beneficiary address change",
ArgsUsage: "[minerAddress]",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "really-do-it",
Usage: "Actually send transaction performing the action",
Value: false,
},
},
Action: func(cctx *cli.Context) error {
if !cctx.Args().Present() {
return fmt.Errorf("must specify one argument")
}

api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return xerrors.Errorf("getting fullnode api: %w", err)
}
defer acloser()

ctx := lcli.ReqContext(cctx)

multisigAddr, sender, minerAddr, err := getInputs(cctx)
if err != nil {
return err
}

mi, err := api.StateMinerInfo(ctx, minerAddr, types.EmptyTSK)
if err != nil {
return err
}

if mi.PendingBeneficiaryTerm == nil {
return fmt.Errorf("no pending beneficiary term found for miner %s", minerAddr)
}

fmt.Println("Confirming Pending Beneficiary Term of:")
fmt.Println("Beneficiary: ", mi.PendingBeneficiaryTerm.NewBeneficiary)
fmt.Println("Quota:", mi.PendingBeneficiaryTerm.NewQuota)
fmt.Println("Expiration Epoch:", mi.PendingBeneficiaryTerm.NewExpiration)

if !cctx.Bool("really-do-it") {
fmt.Println("Pass --really-do-it to actually execute this action")
return nil
}

params := &miner.ChangeBeneficiaryParams{
NewBeneficiary: mi.PendingBeneficiaryTerm.NewBeneficiary,
NewQuota: mi.PendingBeneficiaryTerm.NewQuota,
NewExpiration: mi.PendingBeneficiaryTerm.NewExpiration,
}

sp, err := actors.SerializeParams(params)
if err != nil {
return xerrors.Errorf("serializing params: %w", err)
}

pcid, err := api.MsigPropose(ctx, multisigAddr, minerAddr, big.Zero(), sender, uint64(builtin.MethodsMiner.ChangeBeneficiary), sp)
if err != nil {
return xerrors.Errorf("proposing message: %w", err)
}

fmt.Println("Confirm Message CID:", pcid)

// wait for it to get mined into a block
wait, err := api.StateWaitMsg(ctx, pcid, build.MessageConfidence)
if err != nil {
return xerrors.Errorf("waiting for message to be included in block: %w", err)
}

// check it executed successfully
if wait.Receipt.ExitCode != 0 {
return fmt.Errorf("confirm beneficiary change failed")
}

updatedMinerInfo, err := api.StateMinerInfo(ctx, minerAddr, types.EmptyTSK)
if err != nil {
return err
}

if updatedMinerInfo.PendingBeneficiaryTerm == nil {
fmt.Println("Beneficiary address successfully changed")
} else {
fmt.Println("Beneficiary address change awaiting additional confirmations")
}

return nil
},
}

var mmProposeControlSet = &cli.Command{
Name: "propose-control-set",
Usage: "Set control address(-es)",
Expand Down

0 comments on commit 0945e94

Please sign in to comment.