Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

feat: sealing: Use bitfields to manage sector numbers #9183

Merged
merged 10 commits into from
Aug 26, 2022
5 changes: 5 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,11 @@ workflows:
suite: itest-sector_miner_collateral
target: "./itests/sector_miner_collateral_test.go"

- test:
name: test-itest-sector_numassign
suite: itest-sector_numassign
target: "./itests/sector_numassign_test.go"

- test:
name: test-itest-sector_pledge
suite: itest-sector_pledge
Expand Down
2 changes: 2 additions & 0 deletions api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ type FullNode interface {
StateChangedActors(context.Context, cid.Cid, cid.Cid) (map[string]types.Actor, error) //perm:read
// StateMinerSectorCount returns the number of sectors in a miner's sector set and proving set
StateMinerSectorCount(context.Context, address.Address, types.TipSetKey) (MinerSectors, error) //perm:read
// StateMinerAllocated returns a bitfield containing all sector numbers marked as allocated in miner state
StateMinerAllocated(context.Context, address.Address, types.TipSetKey) (*bitfield.BitField, error) //perm:read
// StateCompute is a flexible command that applies the given messages on the given tipset.
// The messages are run as though the VM were at the provided height.
//
Expand Down
26 changes: 26 additions & 0 deletions api/api_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/libp2p/go-libp2p-core/peer"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-bitfield"
datatransfer "github.com/filecoin-project/go-data-transfer"
"github.com/filecoin-project/go-fil-markets/piecestore"
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
Expand Down Expand Up @@ -123,6 +124,21 @@ type StorageMiner interface {
// SectorAbortUpgrade can be called on sectors that are in the process of being upgraded to abort it
SectorAbortUpgrade(context.Context, abi.SectorNumber) error //perm:admin

// SectorNumAssignerMeta returns sector number assigner metadata - reserved/allocated
SectorNumAssignerMeta(ctx context.Context) (NumAssignerMeta, error) //perm:read
// SectorNumReservations returns a list of sector number reservations
SectorNumReservations(ctx context.Context) (map[string]bitfield.BitField, error) //perm:read
// SectorNumReserve creates a new sector number reservation. Will fail if any other reservation has colliding
// numbers or name. Set force to true to override safety checks.
// Valid characters for name: a-z, A-Z, 0-9, _, -
SectorNumReserve(ctx context.Context, name string, sectors bitfield.BitField, force bool) error //perm:admin
// SectorNumReserveCount creates a new sector number reservation for `count` sector numbers.
// by default lotus will allocate lowest-available sector numbers to the reservation.
// For restrictions on `name` see SectorNumReserve
SectorNumReserveCount(ctx context.Context, name string, count uint64) (bitfield.BitField, error) //perm:admin
// SectorNumFree drops a sector reservation
SectorNumFree(ctx context.Context, name string) error //perm:admin

// WorkerConnect tells the node to connect to workers RPC
WorkerConnect(context.Context, string) error //perm:admin retry:true
WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error) //perm:admin
Expand Down Expand Up @@ -468,3 +484,13 @@ type DagstoreInitializeAllEvent struct {
Total int
Current int
}

type NumAssignerMeta struct {
Reserved bitfield.BitField
Allocated bitfield.BitField

// ChainAllocated+Reserved+Allocated
InUse bitfield.BitField

Next abi.SectorNumber
}
3 changes: 3 additions & 0 deletions api/docgen/docgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,9 @@ func init() {
Conns: 4,
FD: 5,
})
addExample(map[string]bitfield.BitField{
"": bitfield.NewFromSet([]uint64{5, 6, 7, 10}),
})

}

Expand Down
15 changes: 15 additions & 0 deletions api/mocks/mock_full.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

78 changes: 78 additions & 0 deletions api/proxy_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified build/openrpc/full.json.gz
Binary file not shown.
Binary file modified build/openrpc/gateway.json.gz
Binary file not shown.
Binary file modified build/openrpc/miner.json.gz
Binary file not shown.
Binary file modified build/openrpc/worker.json.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion cmd/lotus-miner/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ func migratePreSealMeta(ctx context.Context, api v1api.FullNode, metadata string

buf := make([]byte, binary.MaxVarintLen64)
size := binary.PutUvarint(buf, uint64(maxSectorID))
return mds.Put(ctx, datastore.NewKey(modules.StorageCounterDSPrefix), buf[:size])
return mds.Put(ctx, datastore.NewKey(pipeline.StorageCounterDSPrefix), buf[:size])
}

func findMarketDealID(ctx context.Context, api v1api.FullNode, deal market8.DealProposal) (abi.DealID, error) {
Expand Down
141 changes: 141 additions & 0 deletions cmd/lotus-miner/sectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/types"
lcli "github.com/filecoin-project/lotus/cli"
"github.com/filecoin-project/lotus/lib/strle"
"github.com/filecoin-project/lotus/lib/tablewriter"
sealing "github.com/filecoin-project/lotus/storage/pipeline"
)
Expand All @@ -45,6 +46,7 @@ var sectorsCmd = &cli.Command{
sectorsRefsCmd,
sectorsUpdateCmd,
sectorsPledgeCmd,
sectorsNumbersCmd,
sectorPreCommitsCmd,
sectorsCheckExpireCmd,
sectorsExpiredCmd,
Expand Down Expand Up @@ -2201,3 +2203,142 @@ var sectorsCompactPartitionsCmd = &cli.Command{
return nil
},
}

var sectorsNumbersCmd = &cli.Command{
Name: "numbers",
Usage: "manage sector number assignments",
Subcommands: []*cli.Command{
sectorsNumbersInfoCmd,
sectorsNumbersReservationsCmd,
sectorsNumbersReserveCmd,
sectorsNumbersFreeCmd,
},
}

var sectorsNumbersInfoCmd = &cli.Command{
Name: "info",
Usage: "view sector assigner state",
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)

am, err := api.SectorNumAssignerMeta(ctx)
if err != nil {
return err
}

alloc, err := strle.BitfieldToHumanRanges(am.Allocated)
if err != nil {
return err
}

reserved, err := strle.BitfieldToHumanRanges(am.Reserved)
if err != nil {
return err
}

fmt.Printf("Next free: %s\n", am.Next)
fmt.Printf("Allocated: %s\n", alloc)
fmt.Printf("Reserved: %s\n", reserved)

return nil
},
}

var sectorsNumbersReservationsCmd = &cli.Command{
Name: "reservations",
Usage: "list sector number reservations",
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)

rs, err := api.SectorNumReservations(ctx)
if err != nil {
return err
}

var out []string

for name, field := range rs {
hr, err := strle.BitfieldToHumanRanges(field)
if err != nil {
return err
}
count, err := field.Count()
if err != nil {
return err
}

out = append(out, fmt.Sprintf("%s: count=%d %s", name, count, hr))
}

fmt.Printf("reservations: %d\n", len(out))

sort.Strings(out)

for _, s := range out {
fmt.Println(s)
}

return nil
},
}

var sectorsNumbersReserveCmd = &cli.Command{
Name: "reserve",
Usage: "create sector number reservations",
Flags: []cli.Flag{
&cli.BoolFlag{
Name: "force",
Usage: "skip duplicate reservation checks (note: can lead to damaging other reservations on free)",
},
},
geoff-vball marked this conversation as resolved.
Show resolved Hide resolved
ArgsUsage: "[reservation name] [reserved ranges]",
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)

if cctx.Args().Len() != 2 {
return xerrors.Errorf("expected 2 arguments: [reservation name] [reserved ranges]")
}

bf, err := strle.HumanRangesToBitField(cctx.Args().Get(1))
if err != nil {
return xerrors.Errorf("parsing ranges: %w", err)
}

return api.SectorNumReserve(ctx, cctx.Args().First(), bf, cctx.Bool("force"))
},
}

var sectorsNumbersFreeCmd = &cli.Command{
Name: "free",
Usage: "remove sector number reservations",
ArgsUsage: "[reservation name]",
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)

if cctx.Args().Len() != 1 {
return xerrors.Errorf("expected 1 argument: [reservation name]")
}

return api.SectorNumFree(ctx, cctx.Args().First())
},
}
Loading