miner withdrawbalance API
This commit is contained in:
parent
a843c52e38
commit
4f03486011
@ -48,6 +48,13 @@ type StorageMiner interface {
|
|||||||
ActorSectorSize(context.Context, address.Address) (abi.SectorSize, error) //perm:read
|
ActorSectorSize(context.Context, address.Address) (abi.SectorSize, error) //perm:read
|
||||||
ActorAddressConfig(ctx context.Context) (AddressConfig, error) //perm:read
|
ActorAddressConfig(ctx context.Context) (AddressConfig, error) //perm:read
|
||||||
|
|
||||||
|
// WithdrawBalance allows to withdraw balance from miner actor to owner address
|
||||||
|
// Specify amount as "0" to withdraw full balance. This method returns a message CID
|
||||||
|
// even when StateWaitMessage() fails and reciept exit code is non-zero
|
||||||
|
// User should check for message execution manually if this method returns a
|
||||||
|
// "Timeout waiting for withdrawl message" error.
|
||||||
|
WithdrawBalance(ctx context.Context, amount abi.TokenAmount, confidence uint64) (cid.Cid, error) //perm:admin
|
||||||
|
|
||||||
MiningBase(context.Context) (*types.TipSet, error) //perm:read
|
MiningBase(context.Context) (*types.TipSet, error) //perm:read
|
||||||
|
|
||||||
ComputeWindowPoSt(ctx context.Context, dlIdx uint64, tsk types.TipSetKey) ([]miner.SubmitWindowedPoStParams, error) //perm:admin
|
ComputeWindowPoSt(ctx context.Context, dlIdx uint64, tsk types.TipSetKey) ([]miner.SubmitWindowedPoStParams, error) //perm:admin
|
||||||
|
@ -880,6 +880,8 @@ type StorageMinerStruct struct {
|
|||||||
|
|
||||||
StorageTryLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) `perm:"admin"`
|
StorageTryLock func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 storiface.SectorFileType) (bool, error) `perm:"admin"`
|
||||||
|
|
||||||
|
WithdrawBalance func(p0 context.Context, p1 abi.TokenAmount, p2 uint64) (cid.Cid, error) `perm:"admin"`
|
||||||
|
|
||||||
WorkerConnect func(p0 context.Context, p1 string) error `perm:"admin"`
|
WorkerConnect func(p0 context.Context, p1 string) error `perm:"admin"`
|
||||||
|
|
||||||
WorkerJobs func(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) `perm:"admin"`
|
WorkerJobs func(p0 context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) `perm:"admin"`
|
||||||
@ -5186,6 +5188,17 @@ func (s *StorageMinerStub) StorageTryLock(p0 context.Context, p1 abi.SectorID, p
|
|||||||
return false, ErrNotSupported
|
return false, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStruct) WithdrawBalance(p0 context.Context, p1 abi.TokenAmount, p2 uint64) (cid.Cid, error) {
|
||||||
|
if s.Internal.WithdrawBalance == nil {
|
||||||
|
return *new(cid.Cid), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.WithdrawBalance(p0, p1, p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *StorageMinerStub) WithdrawBalance(p0 context.Context, p1 abi.TokenAmount, p2 uint64) (cid.Cid, error) {
|
||||||
|
return *new(cid.Cid), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *StorageMinerStruct) WorkerConnect(p0 context.Context, p1 string) error {
|
func (s *StorageMinerStruct) WorkerConnect(p0 context.Context, p1 string) error {
|
||||||
if s.Internal.WorkerConnect == nil {
|
if s.Internal.WorkerConnect == nil {
|
||||||
return ErrNotSupported
|
return ErrNotSupported
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -218,6 +218,17 @@ var actorWithdrawCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -232,77 +243,24 @@ var actorWithdrawCmd = &cli.Command{
|
|||||||
|
|
||||||
ctx := lcli.ReqContext(cctx)
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
maddr, err := nodeApi.ActorAddress(ctx)
|
res, err := nodeApi.WithdrawBalance(ctx, amount, uint64(cctx.Int("confidence")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
msg, err := api.StateSearchMsg(ctx, res)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
available, err := api.StateMinerAvailableBalance(ctx, maddr, types.EmptyTSK)
|
nv, err := api.StateNetworkVersion(ctx, msg.TipSet)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
amount := available
|
|
||||||
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)
|
|
||||||
|
|
||||||
if amount.GreaterThan(available) {
|
|
||||||
return xerrors.Errorf("can't withdraw more funds than available; requested: %s; available: %s", types.FIL(amount), types.FIL(available))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
params, err := actors.SerializeParams(&miner.WithdrawBalanceParams{
|
|
||||||
AmountRequested: amount, // Default to attempting to withdraw all the extra funds in the miner actor
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
smsg, err := api.MpoolPushMessage(ctx, &types.Message{
|
|
||||||
To: maddr,
|
|
||||||
From: mi.Owner,
|
|
||||||
Value: types.NewInt(0),
|
|
||||||
Method: builtin.MethodsMiner.WithdrawBalance,
|
|
||||||
Params: params,
|
|
||||||
}, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("Requested rewards withdrawal in message %s\n", smsg.Cid())
|
|
||||||
|
|
||||||
// wait for it to get mined into a block
|
|
||||||
fmt.Printf("waiting for %d epochs for confirmation..\n", uint64(cctx.Int("confidence")))
|
|
||||||
|
|
||||||
wait, err := api.StateWaitMsg(ctx, smsg.Cid(), uint64(cctx.Int("confidence")))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// check it executed successfully
|
|
||||||
if wait.Receipt.ExitCode != 0 {
|
|
||||||
fmt.Println(cctx.App.Writer, "withdrawal failed!")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
nv, err := api.StateNetworkVersion(ctx, wait.TipSet)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if nv >= network.Version14 {
|
if nv >= network.Version14 {
|
||||||
var withdrawn abi.TokenAmount
|
var withdrawn abi.TokenAmount
|
||||||
if err := withdrawn.UnmarshalCBOR(bytes.NewReader(wait.Receipt.Return)); err != nil {
|
if err := withdrawn.UnmarshalCBOR(bytes.NewReader(msg.Receipt.Return)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,6 +170,8 @@
|
|||||||
* [StorageReportHealth](#StorageReportHealth)
|
* [StorageReportHealth](#StorageReportHealth)
|
||||||
* [StorageStat](#StorageStat)
|
* [StorageStat](#StorageStat)
|
||||||
* [StorageTryLock](#StorageTryLock)
|
* [StorageTryLock](#StorageTryLock)
|
||||||
|
* [Withdraw](#Withdraw)
|
||||||
|
* [WithdrawBalance](#WithdrawBalance)
|
||||||
* [Worker](#Worker)
|
* [Worker](#Worker)
|
||||||
* [WorkerConnect](#WorkerConnect)
|
* [WorkerConnect](#WorkerConnect)
|
||||||
* [WorkerJobs](#WorkerJobs)
|
* [WorkerJobs](#WorkerJobs)
|
||||||
@ -3662,6 +3664,34 @@ Inputs:
|
|||||||
|
|
||||||
Response: `true`
|
Response: `true`
|
||||||
|
|
||||||
|
## Withdraw
|
||||||
|
|
||||||
|
|
||||||
|
### WithdrawBalance
|
||||||
|
WithdrawBalance allows to withdraw balance from miner actor to owner address
|
||||||
|
Specify amount as "0" to withdraw full balance. This method returns a message CID
|
||||||
|
even when StateWaitMessage() fails and reciept exit code is non-zero
|
||||||
|
User should check for message execution manually if this method returns a
|
||||||
|
"Timeout waiting for withdrawl message" error.
|
||||||
|
|
||||||
|
|
||||||
|
Perms: admin
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"0",
|
||||||
|
42
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Worker
|
## Worker
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,12 +32,15 @@ import (
|
|||||||
filmktsstore "github.com/filecoin-project/go-fil-markets/stores"
|
filmktsstore "github.com/filecoin-project/go-fil-markets/stores"
|
||||||
"github.com/filecoin-project/go-jsonrpc/auth"
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
builtintypes "github.com/filecoin-project/go-state-types/builtin"
|
||||||
minertypes "github.com/filecoin-project/go-state-types/builtin/v8/miner"
|
minertypes "github.com/filecoin-project/go-state-types/builtin/v8/miner"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
"github.com/filecoin-project/lotus/chain/actors/builtin"
|
||||||
"github.com/filecoin-project/lotus/chain/gen"
|
"github.com/filecoin-project/lotus/chain/gen"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
@ -1279,3 +1282,53 @@ func (sm *StorageMinerAPI) ComputeProof(ctx context.Context, ssi []builtin.Exten
|
|||||||
func (sm *StorageMinerAPI) RuntimeSubsystems(context.Context) (res api.MinerSubsystems, err error) {
|
func (sm *StorageMinerAPI) RuntimeSubsystems(context.Context) (res api.MinerSubsystems, err error) {
|
||||||
return sm.EnabledSubsystems, nil
|
return sm.EnabledSubsystems, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sm *StorageMinerAPI) WithdrawBalance(ctx context.Context, amount abi.TokenAmount, confidence uint64) (cid.Cid, error) {
|
||||||
|
available, err := sm.Full.StateMinerAvailableBalance(ctx, sm.Miner.Address(), types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("Error getting miner balance: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if amount.GreaterThan(available) {
|
||||||
|
return cid.Undef, xerrors.Errorf("can't withdraw more funds than available; requested: %s; available: %s", types.FIL(amount), types.FIL(available))
|
||||||
|
}
|
||||||
|
|
||||||
|
if amount.Equals(big.Zero()) {
|
||||||
|
amount = available
|
||||||
|
}
|
||||||
|
|
||||||
|
params, err := actors.SerializeParams(&minertypes.WithdrawBalanceParams{
|
||||||
|
AmountRequested: amount, // Default to attempting to withdraw all the extra funds in the miner actor
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
mi, err := sm.Full.StateMinerInfo(ctx, sm.Miner.Address(), types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("Error getting miner's owner address: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
smsg, err := sm.Full.MpoolPushMessage(ctx, &types.Message{
|
||||||
|
To: sm.Miner.Address(),
|
||||||
|
From: mi.Owner,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
Method: builtintypes.MethodsMiner.WithdrawBalance,
|
||||||
|
Params: params,
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// wait for it to get mined into a block
|
||||||
|
wait, err := sm.Full.StateWaitMsg(ctx, smsg.Cid(), confidence, abi.ChainEpoch(2), true)
|
||||||
|
if err != nil {
|
||||||
|
return smsg.Cid(), xerrors.Errorf("Timeout waiting for withdrawl message")
|
||||||
|
}
|
||||||
|
|
||||||
|
if wait.Receipt.ExitCode != 0 {
|
||||||
|
return wait.Message, xerrors.Errorf("Failed to execute withdrawl message: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return wait.Message, nil
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user