Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: cli: New commands for testing. #8719

Merged
merged 8 commits into from
May 25, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions cmd/lotus-miner/sectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ var sectorsCmd = &cli.Command{
sectorsCapacityCollateralCmd,
sectorsBatching,
sectorsRefreshPieceMatchingCmd,
sectorsCompactPartitionsCmd,
},
}

Expand Down Expand Up @@ -2089,3 +2090,91 @@ func yesno(b bool) string {
}
return color.RedString("NO")
}

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: "TODO",
},
},
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")

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(&params)
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.Println("Message CID:", smsg.Cid())

return nil
},
}
238 changes: 231 additions & 7 deletions cmd/lotus-shed/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,18 @@ import (
"path/filepath"
"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-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/go-address"
"github.com/filecoin-project/lotus/build"
Expand All @@ -37,6 +42,8 @@ var minerCmd = &cli.Command{
minerUnpackInfoCmd,
minerCreateCmd,
minerFaultsCmd,
sendInvalidWindowPoStCmd,
generateAndSendConsensusFaultCmd,
},
}

Expand Down Expand Up @@ -75,7 +82,7 @@ var minerFaultsCmd = &cli.Command{
return err
}

faults, err := faultBf.All(miner2.SectorsMax)
faults, err := faultBf.All(abi.MaxSectorNumber)
if err != nil {
return err
}
Expand Down Expand Up @@ -216,7 +223,7 @@ var minerCreateCmd = &cli.Command{
return xerrors.Errorf("getting post proof type: %w", err)
}

params, err := actors.SerializeParams(&power6.CreateMinerParams{
params, err := actors.SerializeParams(&power7.CreateMinerParams{
Owner: owner,
Worker: worker,
WindowPoStProofType: spt,
Expand Down Expand Up @@ -252,7 +259,7 @@ var minerCreateCmd = &cli.Command{
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 {
return err
}
Expand Down Expand Up @@ -354,3 +361,220 @@ 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",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i don't think shed commands need really-do-its, but also no harm in having it...

Usage: "Actually send transaction performing the action",
Value: false,
},
&cli.Int64SliceFlag{
Name: "partitions",
Usage: "list of partitions to compact sectors in",
Required: true,
},
&cli.StringFlag{
Name: "actor",
Usage: "TODO",
},
},
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")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also ?

}

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(&params)
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.Println("Message CID:", smsg.Cid())

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`,
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "really-do-it",
Usage: "Actually send transaction performing the action",
Value: false,
},
&cli.StringFlag{
Name: "actor",
Usage: "TODO",
},
},
Action: func(cctx *cli.Context) error {
if !cctx.Bool("really-do-it") {
return xerrors.Errorf("Pass --really-do-it to actually execute this action")
}

if cctx.Args().Len() != 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)

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 miner info: %w", err)
}

blockHeader, err := api.ChainGetBlock(ctx, blockCid)
if err != nil {
return xerrors.Errorf("getting block header: %w", err)
}

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(&params)
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.Println("Message CID:", smsg.Cid())

return nil
},
}
Loading