Merge pull request #8719 from filecoin-project/gstuart/cli-bad-post
feat: cli: New commands for testing.
This commit is contained in:
commit
966f6816eb
@ -59,6 +59,7 @@ var sectorsCmd = &cli.Command{
|
|||||||
sectorsCapacityCollateralCmd,
|
sectorsCapacityCollateralCmd,
|
||||||
sectorsBatching,
|
sectorsBatching,
|
||||||
sectorsRefreshPieceMatchingCmd,
|
sectorsRefreshPieceMatchingCmd,
|
||||||
|
sectorsCompactPartitionsCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2089,3 +2090,106 @@ func yesno(b bool) string {
|
|||||||
}
|
}
|
||||||
return color.RedString("NO")
|
return color.RedString("NO")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO simulate this call if --really-do-it is not used
|
||||||
|
var sectorsCompactPartitionsCmd = &cli.Command{
|
||||||
|
Name: "compact-partitions",
|
||||||
|
Usage: "removes dead sectors from partitions and reduces the number of partitions used if possible",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.Uint64Flag{
|
||||||
|
Name: "deadline",
|
||||||
|
Usage: "the deadline to compact the partitions in",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
&cli.Int64SliceFlag{
|
||||||
|
Name: "partitions",
|
||||||
|
Usage: "list of partitions to compact sectors in",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "really-do-it",
|
||||||
|
Usage: "Actually send transaction performing the action",
|
||||||
|
Value: false,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "actor",
|
||||||
|
Usage: "Specify the address of the miner to run this command",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if !cctx.Bool("really-do-it") {
|
||||||
|
fmt.Println("Pass --really-do-it to actually execute this action")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer acloser()
|
||||||
|
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
maddr, err := getActorAddress(ctx, cctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
minfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
deadline := cctx.Uint64("deadline")
|
||||||
|
if deadline > miner.WPoStPeriodDeadlines {
|
||||||
|
return fmt.Errorf("deadline %d out of range", deadline)
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := cctx.Int64Slice("partitions")
|
||||||
|
if len(parts) <= 0 {
|
||||||
|
return fmt.Errorf("must include at least one partition to compact")
|
||||||
|
}
|
||||||
|
fmt.Printf("compacting %d paritions\n", len(parts))
|
||||||
|
|
||||||
|
partitions := bitfield.New()
|
||||||
|
for _, partition := range parts {
|
||||||
|
partitions.Set(uint64(partition))
|
||||||
|
}
|
||||||
|
|
||||||
|
params := miner.CompactPartitionsParams{
|
||||||
|
Deadline: deadline,
|
||||||
|
Partitions: partitions,
|
||||||
|
}
|
||||||
|
|
||||||
|
sp, err := actors.SerializeParams(¶ms)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("serializing params: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
smsg, err := api.MpoolPushMessage(ctx, &types.Message{
|
||||||
|
From: minfo.Worker,
|
||||||
|
To: maddr,
|
||||||
|
Method: builtin.MethodsMiner.CompactPartitions,
|
||||||
|
Value: big.Zero(),
|
||||||
|
Params: sp,
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("mpool push: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Requested compact partitions in message %s\n", smsg.Cid())
|
||||||
|
|
||||||
|
wait, err := api.StateWaitMsg(ctx, smsg.Cid(), 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check it executed successfully
|
||||||
|
if wait.Receipt.ExitCode != 0 {
|
||||||
|
fmt.Println(cctx.App.Writer, "compact partitions failed!")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -9,15 +9,20 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
miner2 "github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
power6 "github.com/filecoin-project/specs-actors/v6/actors/builtin/power"
|
|
||||||
|
|
||||||
"github.com/docker/go-units"
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/go-state-types/big"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/go-bitfield"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
"github.com/filecoin-project/go-state-types/builtin"
|
||||||
|
miner8 "github.com/filecoin-project/go-state-types/builtin/v8/miner"
|
||||||
|
"github.com/filecoin-project/go-state-types/crypto"
|
||||||
|
power7 "github.com/filecoin-project/specs-actors/v7/actors/builtin/power"
|
||||||
|
"github.com/filecoin-project/specs-actors/v7/actors/runtime/proof"
|
||||||
|
|
||||||
|
"github.com/docker/go-units"
|
||||||
|
|
||||||
"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"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
@ -37,6 +42,8 @@ var minerCmd = &cli.Command{
|
|||||||
minerUnpackInfoCmd,
|
minerUnpackInfoCmd,
|
||||||
minerCreateCmd,
|
minerCreateCmd,
|
||||||
minerFaultsCmd,
|
minerFaultsCmd,
|
||||||
|
sendInvalidWindowPoStCmd,
|
||||||
|
generateAndSendConsensusFaultCmd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +82,7 @@ var minerFaultsCmd = &cli.Command{
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
faults, err := faultBf.All(miner2.SectorsMax)
|
faults, err := faultBf.All(abi.MaxSectorNumber)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -216,7 +223,7 @@ var minerCreateCmd = &cli.Command{
|
|||||||
return xerrors.Errorf("getting post proof type: %w", err)
|
return xerrors.Errorf("getting post proof type: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
params, err := actors.SerializeParams(&power6.CreateMinerParams{
|
params, err := actors.SerializeParams(&power7.CreateMinerParams{
|
||||||
Owner: owner,
|
Owner: owner,
|
||||||
Worker: worker,
|
Worker: worker,
|
||||||
WindowPoStProofType: spt,
|
WindowPoStProofType: spt,
|
||||||
@ -252,7 +259,7 @@ var minerCreateCmd = &cli.Command{
|
|||||||
return xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode)
|
return xerrors.Errorf("create miner failed: exit code %d", mw.Receipt.ExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
var retval power6.CreateMinerReturn
|
var retval power7.CreateMinerReturn
|
||||||
if err := retval.UnmarshalCBOR(bytes.NewReader(mw.Receipt.Return)); err != nil {
|
if err := retval.UnmarshalCBOR(bytes.NewReader(mw.Receipt.Return)); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -354,3 +361,226 @@ var minerUnpackInfoCmd = &cli.Command{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var sendInvalidWindowPoStCmd = &cli.Command{
|
||||||
|
Name: "send-invalid-windowed-post",
|
||||||
|
Usage: "Sends an invalid windowed post for a specific deadline",
|
||||||
|
Description: `Note: This is meant for testing purposes and should NOT be used on mainnet or you will be slashed`,
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.BoolFlag{
|
||||||
|
Name: "really-do-it",
|
||||||
|
Usage: "Actually send transaction performing the action",
|
||||||
|
Value: false,
|
||||||
|
},
|
||||||
|
&cli.Int64SliceFlag{
|
||||||
|
Name: "partitions",
|
||||||
|
Usage: "list of partitions to submit invalid post for",
|
||||||
|
Required: true,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "actor",
|
||||||
|
Usage: "Specify the address of the miner to run this command",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if !cctx.Bool("really-do-it") {
|
||||||
|
return xerrors.Errorf("Pass --really-do-it to actually execute this action")
|
||||||
|
}
|
||||||
|
|
||||||
|
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting api: %w", err)
|
||||||
|
}
|
||||||
|
defer acloser()
|
||||||
|
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
maddr, err := address.NewFromString(cctx.String("actor"))
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting actor address: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
minfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting mienr info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
deadline, err := api.StateMinerProvingDeadline(ctx, maddr, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting deadline: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
partitionIndices := cctx.Int64Slice("partitions")
|
||||||
|
if len(partitionIndices) <= 0 {
|
||||||
|
return fmt.Errorf("must include at least one partition to compact")
|
||||||
|
}
|
||||||
|
|
||||||
|
chainHead, err := api.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting chain head: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
checkRand, err := api.StateGetRandomnessFromTickets(ctx, crypto.DomainSeparationTag_PoStChainCommit, deadline.Challenge, nil, chainHead.Key())
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting randomness: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
proofSize, err := minfo.WindowPoStProofType.ProofSize()
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting proof size: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var partitions []miner8.PoStPartition
|
||||||
|
|
||||||
|
emptyProof := []proof.PoStProof{{
|
||||||
|
PoStProof: minfo.WindowPoStProofType,
|
||||||
|
ProofBytes: make([]byte, proofSize)}}
|
||||||
|
|
||||||
|
for _, partition := range partitionIndices {
|
||||||
|
newPartition := miner8.PoStPartition{
|
||||||
|
Index: uint64(partition),
|
||||||
|
Skipped: bitfield.New(),
|
||||||
|
}
|
||||||
|
partitions = append(partitions, newPartition)
|
||||||
|
}
|
||||||
|
|
||||||
|
params := miner8.SubmitWindowedPoStParams{
|
||||||
|
Deadline: deadline.Index,
|
||||||
|
Partitions: partitions,
|
||||||
|
Proofs: emptyProof,
|
||||||
|
ChainCommitEpoch: deadline.Challenge,
|
||||||
|
ChainCommitRand: checkRand,
|
||||||
|
}
|
||||||
|
|
||||||
|
sp, err := actors.SerializeParams(¶ms)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("serializing params: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("submitting bad PoST for %d paritions\n", len(partitionIndices))
|
||||||
|
smsg, err := api.MpoolPushMessage(ctx, &types.Message{
|
||||||
|
From: minfo.Worker,
|
||||||
|
To: maddr,
|
||||||
|
Method: builtin.MethodsMiner.SubmitWindowedPoSt,
|
||||||
|
Value: big.Zero(),
|
||||||
|
Params: sp,
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("mpool push: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Invalid PoST in message %s\n", smsg.Cid())
|
||||||
|
|
||||||
|
wait, err := api.StateWaitMsg(ctx, smsg.Cid(), 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check it executed successfully
|
||||||
|
if wait.Receipt.ExitCode != 0 {
|
||||||
|
fmt.Println(cctx.App.Writer, "Invalid PoST message failed!")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
var generateAndSendConsensusFaultCmd = &cli.Command{
|
||||||
|
Name: "generate-and-send-consensus-fault",
|
||||||
|
Usage: "Provided a block CID mined by the miner, will create another block at the same height, and send both block headers to generate a consensus fault.",
|
||||||
|
Description: `Note: This is meant for testing purposes and should NOT be used on mainnet or you will be slashed`,
|
||||||
|
Action: func(cctx *cli.Context) error {
|
||||||
|
if cctx.NArg() != 1 {
|
||||||
|
return xerrors.Errorf("expected 1 arg (blockCID)")
|
||||||
|
}
|
||||||
|
|
||||||
|
blockCid, err := cid.Parse(cctx.Args().First())
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting first arg: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
api, acloser, err := lcli.GetFullNodeAPI(cctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting chain head: %w", err)
|
||||||
|
}
|
||||||
|
defer acloser()
|
||||||
|
|
||||||
|
ctx := lcli.ReqContext(cctx)
|
||||||
|
|
||||||
|
blockHeader, err := api.ChainGetBlock(ctx, blockCid)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting block header: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
maddr := blockHeader.Miner
|
||||||
|
|
||||||
|
minfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting miner info: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// We are changing one field in the block header, then resigning the new block.
|
||||||
|
// This gives two different blocks signed by the same miner at the same height which will result in a consensus fault.
|
||||||
|
blockHeaderCopy := *blockHeader
|
||||||
|
blockHeaderCopy.ForkSignaling = blockHeader.ForkSignaling + 1
|
||||||
|
|
||||||
|
signingBytes, err := blockHeaderCopy.SigningBytes()
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("getting bytes to sign second block: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := api.WalletSign(ctx, minfo.Worker, signingBytes)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("signing second block: %w", err)
|
||||||
|
}
|
||||||
|
blockHeaderCopy.BlockSig = sig
|
||||||
|
|
||||||
|
buf1 := new(bytes.Buffer)
|
||||||
|
err = blockHeader.MarshalCBOR(buf1)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("marshalling block header 1: %w", err)
|
||||||
|
}
|
||||||
|
buf2 := new(bytes.Buffer)
|
||||||
|
err = blockHeaderCopy.MarshalCBOR(buf2)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("marshalling block header 2: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
params := miner8.ReportConsensusFaultParams{
|
||||||
|
BlockHeader1: buf1.Bytes(),
|
||||||
|
BlockHeader2: buf2.Bytes(),
|
||||||
|
}
|
||||||
|
|
||||||
|
sp, err := actors.SerializeParams(¶ms)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("serializing params: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
smsg, err := api.MpoolPushMessage(ctx, &types.Message{
|
||||||
|
From: minfo.Worker,
|
||||||
|
To: maddr,
|
||||||
|
Method: builtin.MethodsMiner.ReportConsensusFault,
|
||||||
|
Value: big.Zero(),
|
||||||
|
Params: sp,
|
||||||
|
}, nil)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("mpool push: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("Consensus fault reported in message %s\n", smsg.Cid())
|
||||||
|
|
||||||
|
wait, err := api.StateWaitMsg(ctx, smsg.Cid(), 0)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check it executed successfully
|
||||||
|
if wait.Receipt.ExitCode != 0 {
|
||||||
|
fmt.Println(cctx.App.Writer, "Report consensus fault failed!")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
@ -195,7 +195,7 @@ var verifRegVerifyClientCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`")
|
fmt.Println("DEPRECATED: This behavior is being moved to `lotus filplus`")
|
||||||
froms := cctx.String("from")
|
froms := cctx.String("from")
|
||||||
if froms == "" {
|
if froms == "" {
|
||||||
return fmt.Errorf("must specify from address with --from")
|
return fmt.Errorf("must specify from address with --from")
|
||||||
@ -264,7 +264,7 @@ var verifRegListVerifiersCmd = &cli.Command{
|
|||||||
Usage: "list all verifiers",
|
Usage: "list all verifiers",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`")
|
fmt.Println("DEPRECATED: This behavior is being moved to `lotus filplus`")
|
||||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -296,7 +296,7 @@ var verifRegListClientsCmd = &cli.Command{
|
|||||||
Usage: "list all verified clients",
|
Usage: "list all verified clients",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`")
|
fmt.Println("DEPRECATED: This behavior is being moved to `lotus filplus`")
|
||||||
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
api, closer, err := lcli.GetFullNodeAPI(cctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -328,7 +328,7 @@ var verifRegCheckClientCmd = &cli.Command{
|
|||||||
Usage: "check verified client remaining bytes",
|
Usage: "check verified client remaining bytes",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`")
|
fmt.Println("DEPRECATED: This behavior is being moved to `lotus filplus`")
|
||||||
if !cctx.Args().Present() {
|
if !cctx.Args().Present() {
|
||||||
return fmt.Errorf("must specify client address to check")
|
return fmt.Errorf("must specify client address to check")
|
||||||
}
|
}
|
||||||
@ -364,7 +364,7 @@ var verifRegCheckVerifierCmd = &cli.Command{
|
|||||||
Usage: "check verifiers remaining bytes",
|
Usage: "check verifiers remaining bytes",
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Action: func(cctx *cli.Context) error {
|
Action: func(cctx *cli.Context) error {
|
||||||
fmt.Println("DEPRECATED: This behavior is being moved to `lotus verifreg`")
|
fmt.Println("DEPRECATED: This behavior is being moved to `lotus filplus`")
|
||||||
if !cctx.Args().Present() {
|
if !cctx.Args().Present() {
|
||||||
return fmt.Errorf("must specify verifier address to check")
|
return fmt.Errorf("must specify verifier address to check")
|
||||||
}
|
}
|
||||||
|
@ -1685,6 +1685,7 @@ COMMANDS:
|
|||||||
get-cc-collateral Get the collateral required to pledge a committed capacity sector
|
get-cc-collateral Get the collateral required to pledge a committed capacity sector
|
||||||
batching manage batch sector operations
|
batching manage batch sector operations
|
||||||
match-pending-pieces force a refreshed match of pending pieces to open sectors without manually waiting for more deals
|
match-pending-pieces force a refreshed match of pending pieces to open sectors without manually waiting for more deals
|
||||||
|
compact-partitions removes dead sectors from partitions and reduces the number of partitions used if possible
|
||||||
help, h Shows a list of commands or help for one command
|
help, h Shows a list of commands or help for one command
|
||||||
|
|
||||||
OPTIONS:
|
OPTIONS:
|
||||||
@ -2026,6 +2027,23 @@ OPTIONS:
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### lotus-miner sectors compact-partitions
|
||||||
|
```
|
||||||
|
NAME:
|
||||||
|
lotus-miner sectors compact-partitions - removes dead sectors from partitions and reduces the number of partitions used if possible
|
||||||
|
|
||||||
|
USAGE:
|
||||||
|
lotus-miner sectors compact-partitions [command options] [arguments...]
|
||||||
|
|
||||||
|
OPTIONS:
|
||||||
|
--deadline value the deadline to compact the partitions in (default: 0)
|
||||||
|
--partitions value list of partitions to compact sectors in
|
||||||
|
--really-do-it Actually send transaction performing the action (default: false)
|
||||||
|
--actor value Specify the address of the miner to run this command
|
||||||
|
--help, -h show help (default: false)
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## lotus-miner proving
|
## lotus-miner proving
|
||||||
```
|
```
|
||||||
NAME:
|
NAME:
|
||||||
|
Loading…
Reference in New Issue
Block a user