2019-08-07 06:35:57 +00:00
|
|
|
package cli
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/go-lotus/chain/address"
|
2019-09-19 20:25:18 +00:00
|
|
|
"github.com/filecoin-project/go-lotus/chain/types"
|
2019-09-20 06:46:15 +00:00
|
|
|
|
2019-09-19 20:25:18 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
2019-09-20 06:46:15 +00:00
|
|
|
"gopkg.in/urfave/cli.v2"
|
2019-08-07 06:35:57 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
var stateCmd = &cli.Command{
|
|
|
|
Name: "state",
|
|
|
|
Usage: "Interact with and query filecoin chain state",
|
|
|
|
Subcommands: []*cli.Command{
|
|
|
|
statePowerCmd,
|
|
|
|
stateSectorsCmd,
|
|
|
|
stateProvingSetCmd,
|
2019-09-27 14:53:34 +00:00
|
|
|
statePledgeCollateralCmd,
|
2019-08-07 06:35:57 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var statePowerCmd = &cli.Command{
|
|
|
|
Name: "power",
|
|
|
|
Usage: "Query network or miner power",
|
|
|
|
Action: func(cctx *cli.Context) error {
|
2019-08-08 03:30:50 +00:00
|
|
|
api, err := GetFullNodeAPI(cctx)
|
2019-08-07 06:35:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := ReqContext(cctx)
|
|
|
|
|
2019-08-21 22:14:58 +00:00
|
|
|
var maddr address.Address
|
2019-08-07 06:35:57 +00:00
|
|
|
if cctx.Args().Present() {
|
2019-08-21 22:14:58 +00:00
|
|
|
maddr, err = address.NewFromString(cctx.Args().First())
|
2019-08-07 06:35:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2019-08-21 22:14:58 +00:00
|
|
|
power, err := api.StateMinerPower(ctx, maddr, nil)
|
2019-08-07 06:35:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-08-21 22:14:58 +00:00
|
|
|
|
|
|
|
res := power.TotalPower
|
|
|
|
if cctx.Args().Present() {
|
|
|
|
res = power.MinerPower
|
2019-08-07 06:35:57 +00:00
|
|
|
}
|
|
|
|
|
2019-08-21 22:14:58 +00:00
|
|
|
fmt.Println(res.String())
|
2019-08-07 06:35:57 +00:00
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
var stateSectorsCmd = &cli.Command{
|
|
|
|
Name: "sectors",
|
|
|
|
Usage: "Query the sector set of a miner",
|
|
|
|
Action: func(cctx *cli.Context) error {
|
2019-08-08 03:30:50 +00:00
|
|
|
api, err := GetFullNodeAPI(cctx)
|
2019-08-07 06:35:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
|
|
|
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 {
|
2019-08-08 03:30:50 +00:00
|
|
|
api, err := GetFullNodeAPI(cctx)
|
2019-08-07 06:35:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2019-09-18 02:50:03 +00:00
|
|
|
sectors, err := api.StateMinerProvingSet(ctx, maddr, nil)
|
2019-08-07 06:35:57 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, s := range sectors {
|
|
|
|
fmt.Printf("%d: %x %x\n", s.SectorID, s.CommR, s.CommD)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
2019-09-19 20:25:18 +00:00
|
|
|
|
|
|
|
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, err := GetFullNodeAPI(cctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
|
|
|
api.StateReplay(ctx, ts, mcid)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|
2019-09-27 14:53:34 +00:00
|
|
|
|
|
|
|
var statePledgeCollateralCmd = &cli.Command{
|
|
|
|
Name: "pledge-collateral",
|
|
|
|
Usage: "Get minimum miner pledge collateral",
|
|
|
|
Action: func(cctx *cli.Context) error {
|
|
|
|
api, err := GetFullNodeAPI(cctx)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
ctx := ReqContext(cctx)
|
|
|
|
|
|
|
|
coll, err := api.StatePledgeCollateral(ctx, nil)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(coll.String())
|
|
|
|
return nil
|
|
|
|
},
|
|
|
|
}
|