2020-06-23 22:54:28 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2020-08-19 20:08:04 +00:00
|
|
|
"os"
|
|
|
|
"strings"
|
2020-06-23 22:54:28 +00:00
|
|
|
|
2020-08-19 20:08:04 +00:00
|
|
|
"github.com/fatih/color"
|
2020-06-23 22:54:28 +00:00
|
|
|
"github.com/urfave/cli/v2"
|
|
|
|
|
2020-08-19 20:08:04 +00:00
|
|
|
"github.com/filecoin-project/go-address"
|
2022-06-14 15:00:51 +00:00
|
|
|
|
2024-04-01 15:30:35 +00:00
|
|
|
lapi "github.com/filecoin-project/lotus/api"
|
2022-07-21 06:14:52 +00:00
|
|
|
builtin2 "github.com/filecoin-project/lotus/chain/actors/builtin"
|
2020-06-23 22:54:28 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
lcli "github.com/filecoin-project/lotus/cli"
|
2024-04-01 15:30:35 +00:00
|
|
|
"github.com/filecoin-project/lotus/cli/spcli"
|
2020-08-19 20:08:04 +00:00
|
|
|
"github.com/filecoin-project/lotus/lib/tablewriter"
|
2020-06-23 22:54:28 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var actorCmd = &cli.Command{
|
2020-06-23 23:00:32 +00:00
|
|
|
Name: "actor",
|
2020-06-23 22:54:28 +00:00
|
|
|
Usage: "manipulate the miner actor",
|
|
|
|
Subcommands: []*cli.Command{
|
2024-04-01 15:30:35 +00:00
|
|
|
spcli.ActorSetAddrsCmd(LMActorGetter),
|
|
|
|
spcli.ActorWithdrawCmd(LMActorGetter),
|
|
|
|
spcli.ActorRepayDebtCmd(LMActorGetter),
|
|
|
|
spcli.ActorSetPeeridCmd(LMActorGetter),
|
|
|
|
spcli.ActorSetOwnerCmd(LMConfigOrActorGetter),
|
|
|
|
spcli.ActorControlCmd(LMConfigOrActorGetter, actorControlListCmd),
|
|
|
|
spcli.ActorProposeChangeWorkerCmd(LMActorGetter),
|
|
|
|
spcli.ActorConfirmChangeWorkerCmd(LMActorGetter),
|
|
|
|
spcli.ActorCompactAllocatedCmd(LMActorGetter),
|
|
|
|
spcli.ActorProposeChangeBeneficiaryCmd(LMActorGetter),
|
|
|
|
spcli.ActorConfirmChangeBeneficiaryCmd(LMConfigOrActorGetter),
|
2020-06-23 22:54:28 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2024-04-01 15:30:35 +00:00
|
|
|
func LMConfigOrActorGetter(cctx *cli.Context) (address.Address, error) {
|
|
|
|
ctx := lcli.ReqContext(cctx)
|
|
|
|
return getActorAddress(ctx, cctx)
|
2020-08-13 08:20:09 +00:00
|
|
|
}
|
2020-08-19 20:08:04 +00:00
|
|
|
|
2024-04-01 15:30:35 +00:00
|
|
|
func getControlAddresses(cctx *cli.Context, actor address.Address) (lapi.AddressConfig, error) {
|
|
|
|
minerApi, closer, err := lcli.GetStorageMinerAPI(cctx)
|
|
|
|
if err != nil {
|
|
|
|
return lapi.AddressConfig{}, err
|
|
|
|
}
|
|
|
|
defer closer()
|
2020-10-11 23:49:57 +00:00
|
|
|
|
2024-04-01 15:30:35 +00:00
|
|
|
ctx := lcli.ReqContext(cctx)
|
|
|
|
return minerApi.ActorAddressConfig(ctx)
|
2020-08-19 20:08:04 +00:00
|
|
|
}
|
|
|
|
|
2024-04-01 15:30:35 +00:00
|
|
|
var actorControlListCmd = &cli.Command{
|
2020-08-19 23:26:13 +00:00
|
|
|
Name: "list",
|
|
|
|
Usage: "Get currently set control addresses",
|
2020-08-19 20:08:04 +00:00
|
|
|
Flags: []cli.Flag{
|
|
|
|
&cli.BoolFlag{
|
|
|
|
Name: "verbose",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Action: func(cctx *cli.Context) error {
|
2022-07-21 06:14:52 +00:00
|
|
|
api, acloser, err := lcli.GetFullNodeAPIV1(cctx)
|
2020-08-19 20:08:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer acloser()
|
|
|
|
|
|
|
|
ctx := lcli.ReqContext(cctx)
|
|
|
|
|
2024-04-01 15:30:35 +00:00
|
|
|
maddr, err := LMActorOrEnvGetter(cctx)
|
2020-08-19 20:08:04 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
tw := tablewriter.New(
|
|
|
|
tablewriter.Col("name"),
|
|
|
|
tablewriter.Col("ID"),
|
|
|
|
tablewriter.Col("key"),
|
|
|
|
tablewriter.Col("use"),
|
|
|
|
tablewriter.Col("balance"),
|
|
|
|
)
|
|
|
|
|
2024-04-01 15:30:35 +00:00
|
|
|
ac, err := getControlAddresses(cctx, maddr)
|
2020-08-19 20:08:04 +00:00
|
|
|
if err != nil {
|
2020-12-02 19:46:07 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
commit := map[address.Address]struct{}{}
|
|
|
|
precommit := map[address.Address]struct{}{}
|
2021-02-17 15:56:32 +00:00
|
|
|
terminate := map[address.Address]struct{}{}
|
2021-07-07 16:00:54 +00:00
|
|
|
dealPublish := map[address.Address]struct{}{}
|
2020-12-02 19:46:07 +00:00
|
|
|
post := map[address.Address]struct{}{}
|
|
|
|
|
|
|
|
for _, ca := range mi.ControlAddresses {
|
|
|
|
post[ca] = struct{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, ca := range ac.PreCommitControl {
|
|
|
|
ca, err := api.StateLookupID(ctx, ca, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(post, ca)
|
|
|
|
precommit[ca] = struct{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, ca := range ac.CommitControl {
|
|
|
|
ca, err := api.StateLookupID(ctx, ca, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(post, ca)
|
|
|
|
commit[ca] = struct{}{}
|
2020-08-19 20:08:04 +00:00
|
|
|
}
|
|
|
|
|
2021-02-17 15:56:32 +00:00
|
|
|
for _, ca := range ac.TerminateControl {
|
|
|
|
ca, err := api.StateLookupID(ctx, ca, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(post, ca)
|
|
|
|
terminate[ca] = struct{}{}
|
|
|
|
}
|
|
|
|
|
2021-07-07 16:00:54 +00:00
|
|
|
for _, ca := range ac.DealPublishControl {
|
|
|
|
ca, err := api.StateLookupID(ctx, ca, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
delete(post, ca)
|
|
|
|
dealPublish[ca] = struct{}{}
|
2020-08-19 20:08:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
printKey := func(name string, a address.Address) {
|
2022-07-21 06:14:52 +00:00
|
|
|
var actor *types.Actor
|
|
|
|
if actor, err = api.StateGetActor(ctx, a, types.EmptyTSK); err != nil {
|
|
|
|
fmt.Printf("%s\t%s: error getting actor: %s\n", name, a, err)
|
2020-08-19 20:08:04 +00:00
|
|
|
return
|
|
|
|
}
|
2022-07-21 06:14:52 +00:00
|
|
|
b := actor.Balance
|
|
|
|
|
2022-08-04 08:14:56 +00:00
|
|
|
var k = a
|
2022-07-21 06:14:52 +00:00
|
|
|
// 'a' maybe a 'robust', in that case, 'StateAccountKey' returns an error.
|
|
|
|
if builtin2.IsAccountActor(actor.Code) {
|
|
|
|
if k, err = api.StateAccountKey(ctx, a, types.EmptyTSK); err != nil {
|
|
|
|
fmt.Printf("%s\t%s: error getting account key: %s\n", name, a, err)
|
|
|
|
return
|
|
|
|
}
|
2020-08-19 20:08:04 +00:00
|
|
|
}
|
|
|
|
kstr := k.String()
|
|
|
|
if !cctx.Bool("verbose") {
|
2022-09-02 08:33:32 +00:00
|
|
|
if len(kstr) > 9 {
|
|
|
|
kstr = kstr[:6] + "..."
|
|
|
|
}
|
2020-08-19 20:08:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bstr := types.FIL(b).String()
|
|
|
|
switch {
|
|
|
|
case b.LessThan(types.FromFil(10)):
|
|
|
|
bstr = color.RedString(bstr)
|
|
|
|
case b.LessThan(types.FromFil(50)):
|
|
|
|
bstr = color.YellowString(bstr)
|
|
|
|
default:
|
|
|
|
bstr = color.GreenString(bstr)
|
|
|
|
}
|
|
|
|
|
|
|
|
var uses []string
|
|
|
|
if a == mi.Worker {
|
|
|
|
uses = append(uses, color.YellowString("other"))
|
|
|
|
}
|
2020-12-02 19:46:07 +00:00
|
|
|
if _, ok := post[a]; ok {
|
2020-08-19 20:08:04 +00:00
|
|
|
uses = append(uses, color.GreenString("post"))
|
|
|
|
}
|
2020-12-02 19:46:07 +00:00
|
|
|
if _, ok := precommit[a]; ok {
|
|
|
|
uses = append(uses, color.CyanString("precommit"))
|
|
|
|
}
|
|
|
|
if _, ok := commit[a]; ok {
|
|
|
|
uses = append(uses, color.BlueString("commit"))
|
|
|
|
}
|
2021-02-17 15:56:32 +00:00
|
|
|
if _, ok := terminate[a]; ok {
|
|
|
|
uses = append(uses, color.YellowString("terminate"))
|
|
|
|
}
|
2021-07-07 16:00:54 +00:00
|
|
|
if _, ok := dealPublish[a]; ok {
|
|
|
|
uses = append(uses, color.MagentaString("deals"))
|
|
|
|
}
|
2020-08-19 20:08:04 +00:00
|
|
|
|
|
|
|
tw.Write(map[string]interface{}{
|
2020-08-19 23:26:13 +00:00
|
|
|
"name": name,
|
|
|
|
"ID": a,
|
|
|
|
"key": kstr,
|
|
|
|
"use": strings.Join(uses, " "),
|
2020-08-19 20:08:04 +00:00
|
|
|
"balance": bstr,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
printKey("owner", mi.Owner)
|
|
|
|
printKey("worker", mi.Worker)
|
2022-11-12 02:58:30 +00:00
|
|
|
printKey("beneficiary", mi.Beneficiary)
|
2020-08-19 20:08:04 +00:00
|
|
|
for i, ca := range mi.ControlAddresses {
|
|
|
|
printKey(fmt.Sprintf("control-%d", i), ca)
|
|
|
|
}
|
|
|
|
|
|
|
|
return tw.Flush(os.Stdout)
|
|
|
|
},
|
|
|
|
}
|