Skip to content

Commit

Permalink
sptool: Port lotus-miner actor withdraw
Browse files Browse the repository at this point in the history
  • Loading branch information
magik6k committed Mar 18, 2024
1 parent 404c496 commit fcfb88e
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 103 deletions.
98 changes: 98 additions & 0 deletions cli/spcli/actor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package spcli

import (
"bytes"
"fmt"

"github.com/urfave/cli/v2"
"golang.org/x/xerrors"

"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/network"

lapi "github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/node/impl"
)

func ActorWithdrawCmd(getActor ActorAddressGetter) *cli.Command {
return &cli.Command{
Name: "withdraw",
Usage: "withdraw available balance to beneficiary",
ArgsUsage: "[amount (FIL)]",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "confidence",
Usage: "number of block confirmations to wait for",
Value: int(build.MessageConfidence),
},
&cli.BoolFlag{
Name: "beneficiary",
Usage: "send withdraw message from the beneficiary address",
},
},
Action: func(cctx *cli.Context) error {
amount := abi.NewTokenAmount(0)

if cctx.Args().Present() {
f, err := types.ParseFIL(cctx.Args().First())
if err != nil {
return xerrors.Errorf("parsing 'amount' argument: %w", err)
}

amount = abi.TokenAmount(f)
}

api, acloser, err := lcli.GetFullNodeAPIV1(cctx)
if err != nil {
return err
}
defer acloser()

ctx := lcli.ReqContext(cctx)

maddr, err := getActor(cctx)
if err != nil {
return err
}

res, err := impl.WithdrawBalance(ctx, api, maddr, amount, !cctx.IsSet("beneficiary"))
if err != nil {
return err
}

fmt.Printf("Requested withdrawal in message %s\nwaiting for it to be included in a block..\n", res)

// wait for it to get mined into a block
wait, err := api.StateWaitMsg(ctx, res, uint64(cctx.Int("confidence")), lapi.LookbackNoLimit, true)
if err != nil {
return xerrors.Errorf("Timeout waiting for withdrawal message %s", res)
}

if wait.Receipt.ExitCode.IsError() {
return xerrors.Errorf("Failed to execute withdrawal message %s: %w", wait.Message, wait.Receipt.ExitCode.Error())
}

nv, err := api.StateNetworkVersion(ctx, wait.TipSet)
if err != nil {
return err
}

if nv >= network.Version14 {
var withdrawn abi.TokenAmount
if err := withdrawn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
return err
}

fmt.Printf("Successfully withdrew %s \n", types.FIL(withdrawn))
if withdrawn.LessThan(amount) {
fmt.Printf("Note that this is less than the requested amount of %s\n", types.FIL(amount))
}
}

return nil
},
}
}
9 changes: 9 additions & 0 deletions cli/spcli/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package spcli

import (
"github.com/urfave/cli/v2"

"github.com/filecoin-project/go-address"
)

type ActorAddressGetter func(cctx *cli.Context) (address address.Address, err error)
90 changes: 2 additions & 88 deletions cmd/lotus-miner/actor.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package main

import (
"bytes"
"fmt"
"os"
"strconv"
"strings"

"github.com/fatih/color"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
"github.com/libp2p/go-libp2p/core/peer"
ma "github.com/multiformats/go-multiaddr"
Expand All @@ -22,7 +20,6 @@ import (
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/builtin/v9/miner"
"github.com/filecoin-project/go-state-types/network"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/blockstore"
Expand All @@ -33,6 +30,7 @@ import (
lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/cli/spcli"
"github.com/filecoin-project/lotus/lib/tablewriter"
)

Expand All @@ -41,7 +39,7 @@ var actorCmd = &cli.Command{
Usage: "manipulate the miner actor",
Subcommands: []*cli.Command{
actorSetAddrsCmd,
actorWithdrawCmd,
spcli.ActorWithdrawCmd(LMActorGetter),
actorRepayDebtCmd,
actorSetPeeridCmd,
actorSetOwnerCmd,
Expand Down Expand Up @@ -240,90 +238,6 @@ var actorSetPeeridCmd = &cli.Command{
},
}

var actorWithdrawCmd = &cli.Command{
Name: "withdraw",
Usage: "withdraw available balance to beneficiary",
ArgsUsage: "[amount (FIL)]",
Flags: []cli.Flag{
&cli.IntFlag{
Name: "confidence",
Usage: "number of block confirmations to wait for",
Value: int(build.MessageConfidence),
},
&cli.BoolFlag{
Name: "beneficiary",
Usage: "send withdraw message from the beneficiary address",
},
},
Action: func(cctx *cli.Context) error {
amount := abi.NewTokenAmount(0)

if cctx.Args().Present() {
f, err := types.ParseFIL(cctx.Args().First())
if err != nil {
return xerrors.Errorf("parsing 'amount' argument: %w", err)
}

amount = abi.TokenAmount(f)
}

minerApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()

api, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer acloser()

ctx := lcli.ReqContext(cctx)

var res cid.Cid
if cctx.IsSet("beneficiary") {
res, err = minerApi.BeneficiaryWithdrawBalance(ctx, amount)
} else {
res, err = minerApi.ActorWithdrawBalance(ctx, amount)
}
if err != nil {
return err
}

fmt.Printf("Requested withdrawal in message %s\nwaiting for it to be included in a block..\n", res)

// wait for it to get mined into a block
wait, err := api.StateWaitMsg(ctx, res, uint64(cctx.Int("confidence")))
if err != nil {
return xerrors.Errorf("Timeout waiting for withdrawal message %s", res)
}

if wait.Receipt.ExitCode.IsError() {
return xerrors.Errorf("Failed to execute withdrawal message %s: %w", wait.Message, wait.Receipt.ExitCode.Error())
}

nv, err := api.StateNetworkVersion(ctx, wait.TipSet)
if err != nil {
return err
}

if nv >= network.Version14 {
var withdrawn abi.TokenAmount
if err := withdrawn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
return err
}

fmt.Printf("Successfully withdrew %s \n", types.FIL(withdrawn))
if withdrawn.LessThan(amount) {
fmt.Printf("Note that this is less than the requested amount of %s\n", types.FIL(amount))
}
}

return nil
},
}

var actorRepayDebtCmd = &cli.Command{
Name: "repay-debt",
Usage: "pay down a miner's debt",
Expand Down
10 changes: 10 additions & 0 deletions cmd/lotus-miner/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -197,3 +197,13 @@ func setHidden(cmd *cli.Command) *cli.Command {
cmd.Hidden = true
return cmd
}

func LMActorGetter(cctx *cli.Context) (address.Address, error) {
minerApi, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return address.Undef, err
}
defer closer()

return minerApi.ActorAddress(cctx.Context)
}
14 changes: 10 additions & 4 deletions cmd/sptool/actor.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
package main

import "github.com/urfave/cli/v2"
import (
"github.com/urfave/cli/v2"

"github.com/filecoin-project/lotus/cli/spcli"
)

var actorCmd = &cli.Command{
Name: "actor",
Usage: "Manage Filecoin Miner Actor Metadata",
Subcommands: []*cli.Command{},
Name: "actor",
Usage: "Manage Filecoin Miner Actor Metadata",
Subcommands: []*cli.Command{
spcli.ActorWithdrawCmd(SPTActorGetter),
},
}
30 changes: 26 additions & 4 deletions cmd/sptool/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@ package main
import (
"context"
"fmt"
"github.com/filecoin-project/lotus/build"
logging "github.com/ipfs/go-log/v2"
"github.com/urfave/cli/v2"
"os"
"os/signal"

logging "github.com/ipfs/go-log/v2"
"github.com/urfave/cli/v2"

"github.com/filecoin-project/go-address"

"github.com/filecoin-project/lotus/build"
)

var log = logging.Logger("sptool")

func main() {
local := []*cli.Command{}
local := []*cli.Command{
actorCmd,
//sectorsCmd,
//provingCmd,
//proposalsCmd,
}

app := &cli.App{
Name: "sptool",
Expand All @@ -31,6 +40,11 @@ func main() {
Name: "log-level",
Value: "info",
},
&cli.StringFlag{
Name: "actor",
Required: true,
Usage: "miner actor to manage",
},
},
Before: func(cctx *cli.Context) error {
return logging.SetLogLevel("sptool", cctx.String("sptool"))
Expand All @@ -57,3 +71,11 @@ func main() {
}

}

func SPTActorGetter(cctx *cli.Context) (address.Address, error) {
addr, err := address.NewFromString(cctx.String("actor"))
if err != nil {
return address.Undef, fmt.Errorf("parsing address: %w", err)
}
return addr, nil
}
14 changes: 7 additions & 7 deletions node/impl/storminer.go
Original file line number Diff line number Diff line change
Expand Up @@ -1377,15 +1377,15 @@ func (sm *StorageMinerAPI) RuntimeSubsystems(context.Context) (res api.MinerSubs
}

func (sm *StorageMinerAPI) ActorWithdrawBalance(ctx context.Context, amount abi.TokenAmount) (cid.Cid, error) {
return sm.withdrawBalance(ctx, amount, true)
return WithdrawBalance(ctx, sm.Full, sm.Miner.Address(), amount, true)
}

func (sm *StorageMinerAPI) BeneficiaryWithdrawBalance(ctx context.Context, amount abi.TokenAmount) (cid.Cid, error) {
return sm.withdrawBalance(ctx, amount, false)
return WithdrawBalance(ctx, sm.Full, sm.Miner.Address(), amount, false)
}

func (sm *StorageMinerAPI) withdrawBalance(ctx context.Context, amount abi.TokenAmount, fromOwner bool) (cid.Cid, error) {
available, err := sm.Full.StateMinerAvailableBalance(ctx, sm.Miner.Address(), types.EmptyTSK)
func WithdrawBalance(ctx context.Context, full api.FullNode, maddr address.Address, amount abi.TokenAmount, fromOwner bool) (cid.Cid, error) {
available, err := full.StateMinerAvailableBalance(ctx, maddr, types.EmptyTSK)
if err != nil {
return cid.Undef, xerrors.Errorf("Error getting miner balance: %w", err)
}
Expand All @@ -1405,7 +1405,7 @@ func (sm *StorageMinerAPI) withdrawBalance(ctx context.Context, amount abi.Token
return cid.Undef, err
}

mi, err := sm.Full.StateMinerInfo(ctx, sm.Miner.Address(), types.EmptyTSK)
mi, err := full.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return cid.Undef, xerrors.Errorf("Error getting miner's owner address: %w", err)
}
Expand All @@ -1417,8 +1417,8 @@ func (sm *StorageMinerAPI) withdrawBalance(ctx context.Context, amount abi.Token
sender = mi.Beneficiary
}

smsg, err := sm.Full.MpoolPushMessage(ctx, &types.Message{
To: sm.Miner.Address(),
smsg, err := full.MpoolPushMessage(ctx, &types.Message{
To: maddr,
From: sender,
Value: types.NewInt(0),
Method: builtintypes.MethodsMiner.WithdrawBalance,
Expand Down

0 comments on commit fcfb88e

Please sign in to comment.