feat: cli: Make compact partitions cmd better

This commit is contained in:
Aayush 2022-07-20 14:11:01 -04:00
parent 867a7b1c01
commit c0942ebc2c

View File

@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"math"
"os"
"sort"
"strconv"
@ -2056,7 +2057,6 @@ func yesno(b bool) string {
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",
@ -2082,12 +2082,7 @@ var sectorsCompactPartitionsCmd = &cli.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)
fullNodeAPI, acloser, err := lcli.GetFullNodeAPI(cctx)
if err != nil {
return err
}
@ -2100,7 +2095,7 @@ var sectorsCompactPartitionsCmd = &cli.Command{
return err
}
minfo, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK)
minfo, err := fullNodeAPI.StateMinerInfo(ctx, maddr, types.EmptyTSK)
if err != nil {
return err
}
@ -2116,46 +2111,118 @@ var sectorsCompactPartitionsCmd = &cli.Command{
}
fmt.Printf("compacting %d paritions\n", len(parts))
var makeMsgForPartitions func(partitionsBf bitfield.BitField) ([]*types.Message, error)
makeMsgForPartitions = func(partitionsBf bitfield.BitField) ([]*types.Message, error) {
params := miner.CompactPartitionsParams{
Deadline: deadline,
Partitions: partitionsBf,
}
sp, aerr := actors.SerializeParams(&params)
if aerr != nil {
return nil, xerrors.Errorf("serializing params: %w", err)
}
msg := &types.Message{
From: minfo.Worker,
To: maddr,
Method: builtin.MethodsMiner.CompactPartitions,
Value: big.Zero(),
Params: sp,
}
estimatedMsg, err := fullNodeAPI.GasEstimateMessageGas(ctx, msg, nil, types.EmptyTSK)
if err != nil && xerrors.Is(err, &api.ErrOutOfGas{}) {
// the message is too big -- split into 2
partitionsSlice, err := partitionsBf.All(math.MaxUint64)
if err != nil {
return nil, err
}
partitions1 := bitfield.New()
for i := 0; i < len(partitionsSlice)/2; i++ {
partitions1.Set(uint64(i))
}
msgs1, err := makeMsgForPartitions(partitions1)
if err != nil {
return nil, err
}
// time for the second half
partitions2 := bitfield.New()
for i := len(partitionsSlice) / 2; i < len(partitionsSlice); i++ {
partitions2.Set(uint64(i))
}
msgs2, err := makeMsgForPartitions(partitions2)
if err != nil {
return nil, err
}
return append(msgs1, msgs2...), nil
} else if err != nil {
return nil, err
}
return []*types.Message{estimatedMsg}, nil
}
partitions := bitfield.New()
for _, partition := range parts {
partitions.Set(uint64(partition))
}
params := miner.CompactPartitionsParams{
Deadline: deadline,
Partitions: partitions,
}
sp, err := actors.SerializeParams(&params)
msgs, err := makeMsgForPartitions(partitions)
if err != nil {
return xerrors.Errorf("serializing params: %w", err)
return xerrors.Errorf("failed to make messages: %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)
// Actually send the messages if really-do-it provided, simulate otherwise
if cctx.Bool("really-do-it") {
smsgs, err := fullNodeAPI.MpoolBatchPushMessage(ctx, msgs, nil)
if err != nil {
return xerrors.Errorf("mpool push: %w", err)
}
if len(smsgs) == 1 {
fmt.Printf("Requested compact partitions in message %s\n", smsgs[0].Cid())
} else {
fmt.Printf("Requested compact partitions in %d messages\n\n", len(smsgs))
for _, v := range smsgs {
fmt.Println(v.Cid())
}
}
for _, v := range smsgs {
wait, err := fullNodeAPI.StateWaitMsg(ctx, v.Cid(), 2)
if err != nil {
return err
}
// check it executed successfully
if wait.Receipt.ExitCode.IsError() {
fmt.Println(cctx.App.Writer, "compact partitions msg %s failed!", v.Cid())
return err
}
}
return nil
}
fmt.Printf("Requested compact partitions in message %s\n", smsg.Cid())
for i, v := range msgs {
fmt.Printf("total of %d CompactPartitions msgs would be sent\n", len(msgs))
wait, err := api.StateWaitMsg(ctx, smsg.Cid(), 0)
if err != nil {
return err
}
estMsg, err := fullNodeAPI.GasEstimateMessageGas(ctx, v, nil, types.EmptyTSK)
if err != nil {
return err
}
// check it executed successfully
if wait.Receipt.ExitCode.IsError() {
fmt.Println(cctx.App.Writer, "compact partitions failed!")
return err
fmt.Printf("msg %d would cost up to %s\n", i+1, types.FIL(estMsg.RequiredFunds()))
}
return nil
},
}