add command to inspect and redeem block rewards
This commit is contained in:
parent
56cb88819c
commit
1183e082af
@ -11,6 +11,7 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
"github.com/ipfs/go-cid"
|
||||
"github.com/ipfs/go-filestore"
|
||||
@ -132,6 +133,7 @@ type FullNode interface {
|
||||
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error)
|
||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error)
|
||||
StateListRewards(context.Context, address.Address, types.TipSetKey) ([]reward.Reward, error)
|
||||
StateCompute(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (cid.Cid, error)
|
||||
|
||||
MsigGetAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error)
|
||||
|
@ -13,6 +13,7 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
@ -127,6 +128,7 @@ type FullNodeStruct struct {
|
||||
StateGetReceipt func(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error) `perm:"read"`
|
||||
StateMinerSectorCount func(context.Context, address.Address, types.TipSetKey) (api.MinerSectors, error) `perm:"read"`
|
||||
StateListMessages func(ctx context.Context, match *types.Message, tsk types.TipSetKey, toht abi.ChainEpoch) ([]cid.Cid, error) `perm:"read"`
|
||||
StateListRewards func(context.Context, address.Address, types.TipSetKey) ([]reward.Reward, error) `perm:"read"`
|
||||
StateCompute func(context.Context, abi.ChainEpoch, []*types.Message, types.TipSetKey) (cid.Cid, error) `perm:"read"`
|
||||
|
||||
MsigGetAvailableBalance func(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) `perm:"read"`
|
||||
@ -521,6 +523,10 @@ func (c *FullNodeStruct) StateListMessages(ctx context.Context, match *types.Mes
|
||||
return c.Internal.StateListMessages(ctx, match, tsk, toht)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateListRewards(ctx context.Context, miner address.Address, tsk types.TipSetKey) ([]reward.Reward, error) {
|
||||
return c.Internal.StateListRewards(ctx, miner, tsk)
|
||||
}
|
||||
|
||||
func (c *FullNodeStruct) StateCompute(ctx context.Context, height abi.ChainEpoch, msgs []*types.Message, tsk types.TipSetKey) (cid.Cid, error) {
|
||||
return c.Internal.StateCompute(ctx, height, msgs, tsk)
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ func main() {
|
||||
infoCmd,
|
||||
initCmd,
|
||||
pledgeSectorCmd,
|
||||
rewardsCmd,
|
||||
runCmd,
|
||||
sectorsCmd,
|
||||
setPriceCmd,
|
||||
|
120
cmd/lotus-storage-miner/rewards.go
Normal file
120
cmd/lotus-storage-miner/rewards.go
Normal file
@ -0,0 +1,120 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gopkg.in/urfave/cli.v2"
|
||||
|
||||
"github.com/filecoin-project/lotus/chain/actors"
|
||||
"github.com/filecoin-project/lotus/chain/types"
|
||||
lcli "github.com/filecoin-project/lotus/cli"
|
||||
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||
)
|
||||
|
||||
var rewardsCmd = &cli.Command{
|
||||
Name: "rewards",
|
||||
Subcommands: []*cli.Command{
|
||||
rewardsListCmd,
|
||||
rewardsRedeemCmd,
|
||||
},
|
||||
}
|
||||
|
||||
var rewardsListCmd = &cli.Command{
|
||||
Name: "list",
|
||||
Usage: "Print unclaimed block rewards earned",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
nodeApi, 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)
|
||||
|
||||
maddr, err := nodeApi.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rewards, err := api.StateListRewards(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, r := range rewards {
|
||||
fmt.Printf("%d\t%d\t%s\n", r.StartEpoch, r.EndEpoch, r.Value)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
var rewardsRedeemCmd = &cli.Command{
|
||||
Name: "redeem",
|
||||
Usage: "Redeem block rewards",
|
||||
Action: func(cctx *cli.Context) error {
|
||||
nodeApi, 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)
|
||||
|
||||
maddr, err := nodeApi.ActorAddress(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
worker, err := api.StateMinerWorker(ctx, maddr, types.EmptyTSK)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
params, err := actors.SerializeParams(&maddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
workerNonce, err := api.MpoolGetNonce(ctx, worker)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
smsg, err := api.WalletSignMessage(ctx, worker, &types.Message{
|
||||
To: builtin.RewardActorAddr,
|
||||
From: worker,
|
||||
Nonce: workerNonce,
|
||||
Value: types.NewInt(0),
|
||||
GasPrice: types.NewInt(1),
|
||||
GasLimit: types.NewInt(100000),
|
||||
Method: builtin.MethodsReward.WithdrawReward,
|
||||
Params: params,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mcid, err := api.MpoolPush(ctx, smsg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Requested rewards withdrawal in message %s\n", mcid)
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
2
go.mod
2
go.mod
@ -23,7 +23,7 @@ require (
|
||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663
|
||||
github.com/filecoin-project/go-sectorbuilder v0.0.2-0.20200304050010-2cfac00a93e7
|
||||
github.com/filecoin-project/go-statestore v0.1.0
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200306001214-5b98d3ed4bc4
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200306043603-709a3ce21094
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||
github.com/go-ole/go-ole v1.2.4 // indirect
|
||||
github.com/google/uuid v1.1.1
|
||||
|
2
go.sum
2
go.sum
@ -133,6 +133,8 @@ github.com/filecoin-project/specs-actors v0.0.0-20200305205312-53bb01da9aeb/go.m
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200306000749-99e98e61e2a0 h1:n7Q8UMP2Jsj1dQkM0tRKVWUeAbrz8x2f8l1UVeB4PC4=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200306001214-5b98d3ed4bc4 h1:EFOQ/DA3jOu2r2/r7/vnkGRXoCoDGY5knXb/bVl/X/c=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200306001214-5b98d3ed4bc4/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200306043603-709a3ce21094 h1:iHTwtiM9/gGU1WL1GfDAY04dJcojSg8BK4TOaIqHVYQ=
|
||||
github.com/filecoin-project/specs-actors v0.0.0-20200306043603-709a3ce21094/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 h1:EzDjxMg43q1tA2c0MV3tNbaontnHLplHyFF6M5KiVP0=
|
||||
|
@ -23,6 +23,8 @@ import (
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||
samsig "github.com/filecoin-project/specs-actors/actors/builtin/multisig"
|
||||
"github.com/filecoin-project/specs-actors/actors/builtin/reward"
|
||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||
|
||||
"github.com/filecoin-project/lotus/api"
|
||||
"github.com/filecoin-project/lotus/chain/gen"
|
||||
@ -575,3 +577,40 @@ func (a *StateAPI) MsigGetAvailableBalance(ctx context.Context, addr address.Add
|
||||
minBalance = types.BigMul(minBalance, types.NewInt(uint64(offset)))
|
||||
return types.BigSub(act.Balance, minBalance), nil
|
||||
}
|
||||
|
||||
func (a *StateAPI) StateListRewards(ctx context.Context, miner address.Address, tsk types.TipSetKey) ([]reward.Reward, error) {
|
||||
ts, err := a.Chain.GetTipSetFromKey(tsk)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var st reward.State
|
||||
if _, err := a.StateManager.LoadActorState(ctx, builtin.RewardActorAddr, &st, ts); err != nil {
|
||||
return nil, xerrors.Errorf("failed to load reward actor state: %w", err)
|
||||
}
|
||||
|
||||
as := store.ActorStore(ctx, a.Chain.Blockstore())
|
||||
rmap := adt.AsMultimap(as, st.RewardMap)
|
||||
rewards, found, err := rmap.Get(adt.AddrKey(miner))
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to get rewards set for miner: %w", err)
|
||||
}
|
||||
|
||||
if !found {
|
||||
return nil, xerrors.Errorf("no rewards found for miner")
|
||||
}
|
||||
|
||||
var out []reward.Reward
|
||||
|
||||
var r reward.Reward
|
||||
err = rewards.ForEach(&r, func(i int64) error {
|
||||
or := r
|
||||
out = append(out, or)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("rewards.ForEach failed: %w", err)
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user