Skip to content

Commit

Permalink
feat(vsmgr): vsmgr support beneficiary address operation
Browse files Browse the repository at this point in the history
  • Loading branch information
remakeZK committed Dec 15, 2022
1 parent a306adb commit c3fd3f2
Show file tree
Hide file tree
Showing 2 changed files with 280 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"

"github.com/docker/go-units"
"github.com/filecoin-project/go-address"
"github.com/libp2p/go-libp2p/core/peer"
ma "github.com/multiformats/go-multiaddr"
"github.com/urfave/cli/v2"
Expand Down Expand Up @@ -65,6 +66,25 @@ var utilMinerInfoCmd = &cli.Command{
fmt.Printf("\t%s\n", addr)
}

if minfo.Beneficiary != address.Undef {
fmt.Println()
fmt.Printf("Beneficiary:\t%s\n", minfo.Beneficiary)
if minfo.Beneficiary != minfo.Owner {
fmt.Printf("Beneficiary Quota:\t%s\n", minfo.BeneficiaryTerm.Quota)
fmt.Printf("Beneficiary Used Quota:\t%s\n", minfo.BeneficiaryTerm.UsedQuota)
fmt.Printf("Beneficiary Expiration:\t%s\n", minfo.BeneficiaryTerm.Expiration)
}
}

if minfo.PendingBeneficiaryTerm != nil {
fmt.Printf("Pending Beneficiary Term:\n")
fmt.Printf("New Beneficiary:\t%s\n", minfo.PendingBeneficiaryTerm.NewBeneficiary)
fmt.Printf("New Quota:\t%s\n", minfo.PendingBeneficiaryTerm.NewQuota)
fmt.Printf("New Expiration:\t%s\n", minfo.PendingBeneficiaryTerm.NewExpiration)
fmt.Printf("Approved By Beneficiary:\t%t\n", minfo.PendingBeneficiaryTerm.ApprovedByBeneficiary)
fmt.Printf("Approved By Nominee:\t%t\n", minfo.PendingBeneficiaryTerm.ApprovedByNominee)
}
fmt.Println()
fmt.Printf("WokerChangeEpoch: %d\n", minfo.WorkerChangeEpoch)
if minfo.PeerId != nil {
fmt.Printf("PeerID: %s\n", *minfo.PeerId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ import (
"bytes"
"fmt"
"os"

cbor "github.com/ipfs/go-ipld-cbor"
"github.com/urfave/cli/v2"
"strconv"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
Expand All @@ -15,11 +13,12 @@ import (
"github.com/filecoin-project/go-state-types/big"
stbuiltin "github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/network"

"github.com/filecoin-project/venus/venus-shared/actors"
"github.com/filecoin-project/venus/venus-shared/actors/adt"
"github.com/filecoin-project/venus/venus-shared/actors/builtin/miner"
"github.com/filecoin-project/venus/venus-shared/types"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/urfave/cli/v2"

"github.com/ipfs-force-community/venus-cluster/venus-sector-manager/core"
"github.com/ipfs-force-community/venus-cluster/venus-sector-manager/modules"
Expand Down Expand Up @@ -47,6 +46,8 @@ var utilSealerActorCmd = &cli.Command{
utilSealerActorProposeChangeWorker,
utilSealerActorConfirmChangeWorker,
utilSealerActorCompactAllocatedCmd,
utilSealerActorProposeChangeBeneficiary,
utilSealerActorConfirmChangeBeneficiary,
},
}

Expand Down Expand Up @@ -156,6 +157,10 @@ var utilSealerActorWithdrawCmd = &cli.Command{
Usage: "number of block confirmations to wait for",
Value: int(policy.InteractivePoRepConfidence),
},
&cli.BoolFlag{
Name: "beneficiary",
Usage: "send withdraw message from the beneficiary address",
},
},
Action: func(cctx *cli.Context) error {
api, ctx, stop, err := extractAPI(cctx)
Expand Down Expand Up @@ -200,9 +205,16 @@ var utilSealerActorWithdrawCmd = &cli.Command{
return err
}

var sender address.Address
if cctx.IsSet("beneficiary") {
sender = mi.Beneficiary
} else {
sender = mi.Owner
}

mid, err := api.Messager.PushMessage(ctx, &types.Message{
To: maddr,
From: mi.Owner,
From: sender,
Value: types.NewInt(0),
Method: stbuiltin.MethodsMiner.WithdrawBalance,
Params: params,
Expand Down Expand Up @@ -937,3 +949,246 @@ var utilSealerActorCompactAllocatedCmd = &cli.Command{
return nil
},
}

var utilSealerActorProposeChangeBeneficiary = &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.BoolFlag{
Name: "overwrite-pending-change",
Usage: "Overwrite the current beneficiary change proposal",
Value: false,
},
&cli.StringFlag{
Name: "miner",
Usage: "specify the address of miner actor",
},
},
Action: func(cctx *cli.Context) error {
if cctx.NArg() != 3 {
return fmt.Errorf("must past 3 args")
}
api, ctx, stop, err := extractAPI(cctx)
if err != nil {
return err
}
defer stop()

maddr, err := ShouldAddress(cctx.String("miner"), true, true)
if err != nil {
return err
}

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

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

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

expiration, err := strconv.ParseInt(cctx.Args().Get(2), 10, 64)
if err != nil {
return fmt.Errorf("parsing expiration: %w", err)
}

mi, err := api.Chain.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return fmt.Errorf("getting miner info: %w", err)
}

if mi.Beneficiary == mi.Owner && newAddr == mi.Owner {
return fmt.Errorf("beneficiary %s already set to owner address", mi.Beneficiary)
}

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("overwrite-pending-change") {
return fmt.Errorf("must pass --overwrite-pending-change to replace current pending beneficiary change. Please review CAREFULLY")
}
}

if !cctx.Bool("really-do-it") {
fmt.Println("Pass --really-do-it to actually execute this action. Review what you're about to approve CAREFULLY please")
return nil
}

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

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

mid, err := api.Messager.PushMessage(ctx, &types.Message{
From: mi.Owner,
To: maddr,
Method: stbuiltin.MethodsMiner.ChangeBeneficiary,
Value: big.Zero(),
Params: sp,
}, nil)

if err != nil {
return fmt.Errorf("push message: %w", err)
}
fmt.Println("Propose Message ID:", mid)
// wait for it to get mined into a block
wait, err := api.Messager.WaitMessage(ctx, mid, policy.InteractivePoRepConfidence)
if err != nil {
return fmt.Errorf("waiting for message to be included in block: %w", err)
}

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

updatedMinerInfo, err := api.Chain.StateMinerInfo(ctx, maddr, wait.TipSetKey)
if err != nil {
return fmt.Errorf("getting miner info: %w", err)
}

if updatedMinerInfo.PendingBeneficiaryTerm == nil && updatedMinerInfo.Beneficiary == newAddr {
fmt.Println("Beneficiary address successfully changed")
} else {
fmt.Println("Beneficiary address change awaiting additional confirmations")
}
return nil
},
}
var utilSealerActorConfirmChangeBeneficiary = &cli.Command{
Name: "confirm-change-beneficiary",
Usage: "Confirm a beneficiary address change",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "really-do-it",
Usage: "Actually send transaction performing the action",
Value: false,
},
&cli.BoolFlag{
Name: "existing-beneficiary",
Usage: "send confirmation from the existing beneficiary address",
},
&cli.BoolFlag{
Name: "new-beneficiary",
Usage: "send confirmation from the new beneficiary address",
},
&cli.StringFlag{
Name: "miner",
Usage: "specify the address of miner actor",
},
},
Action: func(cctx *cli.Context) error {
api, ctx, stop, err := extractAPI(cctx)
if err != nil {
return err
}
defer stop()

maddr, err := ShouldAddress(cctx.String("miner"), true, true)
if err != nil {
return err
}

mi, err := api.Chain.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
if mi.PendingBeneficiaryTerm == nil {
return fmt.Errorf("no pending beneficiary term found for miner %s", maddr)
}

if (cctx.IsSet("existing-beneficiary") && cctx.IsSet("new-beneficiary")) || (!cctx.IsSet("existing-beneficiary") && !cctx.IsSet("new-beneficiary")) {
return fmt.Errorf("must pass exactly one of --existing-beneficiary or --new-beneficiary")
}

var fromAddr address.Address
if cctx.IsSet("existing-beneficiary") {
if mi.PendingBeneficiaryTerm.ApprovedByBeneficiary {
return fmt.Errorf("beneficiary change already approved by current beneficiary")
}
fromAddr = mi.Beneficiary
} else {
if mi.PendingBeneficiaryTerm.ApprovedByNominee {
return fmt.Errorf("beneficiary change already approved by new beneficiary")
}
fromAddr = mi.PendingBeneficiaryTerm.NewBeneficiary
}

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. Review what you're about to approve CAREFULLY please")
return nil
}

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

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

mid, err := api.Messager.PushMessage(ctx, &types.Message{
From: fromAddr,
To: maddr,
Method: stbuiltin.MethodsMiner.ChangeBeneficiary,
Value: big.Zero(),
Params: sp,
}, nil)
if err != nil {
return fmt.Errorf("push message: %w", err)
}
fmt.Println("Propose Message ID:", mid)

// wait for it to get mined into a block
wait, err := api.Messager.WaitMessage(ctx, mid, policy.InteractivePoRepConfidence)
if err != nil {
return fmt.Errorf("waiting for message to be included in block: %w", err)
}

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

updatedMinerInfo, err := api.Chain.StateMinerInfo(ctx, maddr, wait.TipSetKey)
if err != nil {
return fmt.Errorf("getting miner info: %w", err)
}

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

0 comments on commit c3fd3f2

Please sign in to comment.