lotus/cli/state.go
2019-12-12 12:31:22 +01:00

370 lines
7.1 KiB
Go

package cli
import (
"fmt"
"github.com/filecoin-project/lotus/chain/address"
"github.com/filecoin-project/lotus/chain/types"
"golang.org/x/xerrors"
"github.com/ipfs/go-cid"
"gopkg.in/urfave/cli.v2"
)
var stateCmd = &cli.Command{
Name: "state",
Usage: "Interact with and query filecoin chain state",
Subcommands: []*cli.Command{
statePowerCmd,
stateSectorsCmd,
stateProvingSetCmd,
statePledgeCollateralCmd,
stateListActorsCmd,
stateListMinersCmd,
stateGetActorCmd,
stateLookupIDCmd,
stateReplaySetCmd,
stateSectorSizeCmd,
},
}
var statePowerCmd = &cli.Command{
Name: "power",
Usage: "Query network or miner power",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
var maddr address.Address
if cctx.Args().Present() {
maddr, err = address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
}
power, err := api.StateMinerPower(ctx, maddr, nil)
if err != nil {
return err
}
res := power.TotalPower
if cctx.Args().Present() {
res = power.MinerPower
}
fmt.Println(res.String())
return nil
},
}
var stateSectorsCmd = &cli.Command{
Name: "sectors",
Usage: "Query the sector set of a miner",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must specify miner to list sectors for")
}
maddr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
sectors, err := api.StateMinerSectors(ctx, maddr, nil)
if err != nil {
return err
}
for _, s := range sectors {
fmt.Printf("%d: %x %x\n", s.SectorID, s.CommR, s.CommD)
}
return nil
},
}
var stateProvingSetCmd = &cli.Command{
Name: "proving",
Usage: "Query the proving set of a miner",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must specify miner to list sectors for")
}
maddr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
sectors, err := api.StateMinerProvingSet(ctx, maddr, nil)
if err != nil {
return err
}
for _, s := range sectors {
fmt.Printf("%d: %x %x\n", s.SectorID, s.CommR, s.CommD)
}
return nil
},
}
var stateReplaySetCmd = &cli.Command{
Name: "replay",
Usage: "Replay a particular message within a tipset",
Action: func(cctx *cli.Context) error {
if cctx.Args().Len() < 2 {
fmt.Println("usage: <tipset> <message cid>")
fmt.Println("The last cid passed will be used as the message CID")
fmt.Println("All preceding ones will be used as the tipset")
return nil
}
args := cctx.Args().Slice()
mcid, err := cid.Decode(args[len(args)-1])
if err != nil {
return fmt.Errorf("message cid was invalid: %s", err)
}
var tscids []cid.Cid
for _, s := range args[:len(args)-1] {
c, err := cid.Decode(s)
if err != nil {
return fmt.Errorf("tipset cid was invalid: %s", err)
}
tscids = append(tscids, c)
}
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
var headers []*types.BlockHeader
for _, c := range tscids {
h, err := api.ChainGetBlock(ctx, c)
if err != nil {
return err
}
headers = append(headers, h)
}
ts, err := types.NewTipSet(headers)
if err != nil {
return err
}
res, err := api.StateReplay(ctx, ts, mcid)
if err != nil {
return xerrors.Errorf("replay call failed: %w", err)
}
fmt.Println("Replay receipt:")
fmt.Printf("Exit code: %d\n", res.Receipt.ExitCode)
fmt.Printf("Return: %x\n", res.Receipt.Return)
fmt.Printf("Gas Used: %s\n", res.Receipt.GasUsed)
if res.Receipt.ExitCode != 0 {
fmt.Printf("Error message: %q\n", res.Error)
}
return nil
},
}
var statePledgeCollateralCmd = &cli.Command{
Name: "pledge-collateral",
Usage: "Get minimum miner pledge collateral",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
coll, err := api.StatePledgeCollateral(ctx, nil)
if err != nil {
return err
}
fmt.Println(types.FIL(coll))
return nil
},
}
var stateListMinersCmd = &cli.Command{
Name: "list-miners",
Usage: "list all miners in the network",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
miners, err := api.StateListMiners(ctx, nil)
if err != nil {
return err
}
for _, m := range miners {
fmt.Println(m.String())
}
return nil
},
}
var stateListActorsCmd = &cli.Command{
Name: "list-actors",
Usage: "list all actors in the network",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
actors, err := api.StateListActors(ctx, nil)
if err != nil {
return err
}
for _, a := range actors {
fmt.Println(a.String())
}
return nil
},
}
var stateGetActorCmd = &cli.Command{
Name: "get-actor",
Usage: "Print actor information",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must pass address of actor to get")
}
addr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
a, err := api.StateGetActor(ctx, addr, nil)
if err != nil {
return err
}
fmt.Printf("Address:\t%s\n", addr)
fmt.Printf("Balance:\t%s\n", types.FIL(a.Balance))
fmt.Printf("Nonce:\t\t%d\n", a.Nonce)
fmt.Printf("Code:\t\t%s\n", a.Code)
fmt.Printf("Head:\t\t%s\n", a.Head)
return nil
},
}
var stateLookupIDCmd = &cli.Command{
Name: "lookup",
Usage: "Find corresponding ID address",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must pass address of actor to get")
}
addr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
a, err := api.StateLookupID(ctx, addr, nil)
if err != nil {
return err
}
fmt.Printf("%s\n", a)
return nil
},
}
var stateSectorSizeCmd = &cli.Command{
Name: "sector-size",
Usage: "Look up miners sector size",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if !cctx.Args().Present() {
return fmt.Errorf("must pass address of actor to get")
}
addr, err := address.NewFromString(cctx.Args().First())
if err != nil {
return err
}
ssize, err := api.StateMinerSectorSize(ctx, addr, nil)
if err != nil {
return err
}
fmt.Printf("%d\n", ssize)
return nil
},
}