Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vsmgr): vsmgr support beneficiary address operation #546

Merged
merged 1 commit into from
Dec 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
},
}