diff --git a/.circleci/config.yml b/.circleci/config.yml index b502c8986..0c4f29c87 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -314,7 +314,7 @@ workflows: ci: jobs: - lint-changes: - args: "--new-from-rev origin/next" + args: "--new-from-rev origin/master" - mod-tidy-check - gofmt - test: diff --git a/api/api_storage.go b/api/api_storage.go index 29ae5ea2e..6ce8e7f2e 100644 --- a/api/api_storage.go +++ b/api/api_storage.go @@ -36,6 +36,7 @@ type StorageMiner interface { SectorsRefs(context.Context) (map[string][]SealedRef, error) SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error + SectorRemove(context.Context, abi.SectorNumber) error StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) StorageLocal(ctx context.Context) (map[stores.ID]string, error) diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index fb11cbda2..e09b57df6 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -206,6 +206,7 @@ type StorageMinerStruct struct { SectorsList func(context.Context) ([]abi.SectorNumber, error) `perm:"read"` SectorsRefs func(context.Context) (map[string][]api.SealedRef, error) `perm:"read"` SectorsUpdate func(context.Context, abi.SectorNumber, api.SectorState) error `perm:"write"` + SectorRemove func(context.Context, abi.SectorNumber) error `perm:"admin"` WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm WorkerStats func(context.Context) (map[uint64]storiface.WorkerStats, error) `perm:"admin"` @@ -243,12 +244,14 @@ type WorkerStruct struct { Paths func(context.Context) ([]stores.StoragePath, error) `perm:"admin"` Info func(context.Context) (storiface.WorkerInfo, error) `perm:"admin"` - SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) `perm:"admin"` - SealPreCommit2 func(context.Context, abi.SectorID, storage.PreCommit1Out) (cids storage.SectorCids, err error) `perm:"admin"` - SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"` - SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"` - FinalizeSector func(context.Context, abi.SectorID) error `perm:"admin"` - MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` + SealPreCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, pieces []abi.PieceInfo) (storage.PreCommit1Out, error) `perm:"admin"` + SealPreCommit2 func(context.Context, abi.SectorID, storage.PreCommit1Out) (cids storage.SectorCids, err error) `perm:"admin"` + SealCommit1 func(ctx context.Context, sector abi.SectorID, ticket abi.SealRandomness, seed abi.InteractiveSealRandomness, pieces []abi.PieceInfo, cids storage.SectorCids) (storage.Commit1Out, error) `perm:"admin"` + SealCommit2 func(context.Context, abi.SectorID, storage.Commit1Out) (storage.Proof, error) `perm:"admin"` + FinalizeSector func(context.Context, abi.SectorID, []storage.Range) error `perm:"admin"` + ReleaseUnsealed func(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) error `perm:"admin"` + Remove func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` + MoveStorage func(ctx context.Context, sector abi.SectorID) error `perm:"admin"` UnsealPiece func(context.Context, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize, abi.SealRandomness, cid.Cid) error `perm:"admin"` ReadPiece func(context.Context, io.Writer, abi.SectorID, storiface.UnpaddedByteIndex, abi.UnpaddedPieceSize) error `perm:"admin"` @@ -786,6 +789,10 @@ func (c *StorageMinerStruct) SectorsUpdate(ctx context.Context, id abi.SectorNum return c.Internal.SectorsUpdate(ctx, id, state) } +func (c *StorageMinerStruct) SectorRemove(ctx context.Context, number abi.SectorNumber) error { + return c.Internal.SectorRemove(ctx, number) +} + func (c *StorageMinerStruct) WorkerConnect(ctx context.Context, url string) error { return c.Internal.WorkerConnect(ctx, url) } @@ -920,8 +927,16 @@ func (w *WorkerStruct) SealCommit2(ctx context.Context, sector abi.SectorID, c1o return w.Internal.SealCommit2(ctx, sector, c1o) } -func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID) error { - return w.Internal.FinalizeSector(ctx, sector) +func (w *WorkerStruct) FinalizeSector(ctx context.Context, sector abi.SectorID, keepUnsealed []storage.Range) error { + return w.Internal.FinalizeSector(ctx, sector, keepUnsealed) +} + +func (w *WorkerStruct) ReleaseUnsealed(ctx context.Context, sector abi.SectorID, safeToFree []storage.Range) error { + return w.Internal.ReleaseUnsealed(ctx, sector, safeToFree) +} + +func (w *WorkerStruct) Remove(ctx context.Context, sector abi.SectorID) error { + return w.Internal.Remove(ctx, sector) } func (w *WorkerStruct) MoveStorage(ctx context.Context, sector abi.SectorID) error { diff --git a/build/version.go b/build/version.go index d5766ce6e..03d5c0792 100644 --- a/build/version.go +++ b/build/version.go @@ -53,7 +53,7 @@ func (ve Version) EqMajorMinor(v2 Version) bool { } // APIVersion is a semver version of the rpc api exposed -var APIVersion Version = newVer(0, 3, 0) +var APIVersion Version = newVer(0, 4, 0) //nolint:varcheck,deadcode const ( diff --git a/cmd/lotus-seed/seed/seed.go b/cmd/lotus-seed/seed/seed.go index be366d4db..08ae91200 100644 --- a/cmd/lotus-seed/seed/seed.go +++ b/cmd/lotus-seed/seed/seed.go @@ -88,7 +88,7 @@ func PreSeal(maddr address.Address, spt abi.RegisteredSealProof, offset abi.Sect return nil, nil, xerrors.Errorf("commit: %w", err) } - if err := sb.FinalizeSector(context.TODO(), sid); err != nil { + if err := sb.FinalizeSector(context.TODO(), sid, nil); err != nil { return nil, nil, xerrors.Errorf("trim cache: %w", err) } diff --git a/cmd/lotus-storage-miner/sectors.go b/cmd/lotus-storage-miner/sectors.go index 4a3109f37..0dfce2f38 100644 --- a/cmd/lotus-storage-miner/sectors.go +++ b/cmd/lotus-storage-miner/sectors.go @@ -27,6 +27,7 @@ var sectorsCmd = &cli.Command{ sectorsRefsCmd, sectorsUpdateCmd, sectorsPledgeCmd, + sectorsRemoveCmd, }, } @@ -46,8 +47,9 @@ var sectorsPledgeCmd = &cli.Command{ } var sectorsStatusCmd = &cli.Command{ - Name: "status", - Usage: "Get the seal status of a sector by its ID", + Name: "status", + Usage: "Get the seal status of a sector by its number", + ArgsUsage: "", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "log", @@ -63,7 +65,7 @@ var sectorsStatusCmd = &cli.Command{ ctx := lcli.ReqContext(cctx) if !cctx.Args().Present() { - return fmt.Errorf("must specify sector ID to get status of") + return fmt.Errorf("must specify sector number to get status of") } id, err := strconv.ParseUint(cctx.Args().First(), 10, 64) @@ -208,6 +210,39 @@ var sectorsRefsCmd = &cli.Command{ }, } +var sectorsRemoveCmd = &cli.Command{ + Name: "remove", + Usage: "Forcefully remove a sector (WARNING: This means losing power and collateral for the removed sector)", + ArgsUsage: "", + Flags: []cli.Flag{ + &cli.BoolFlag{ + Name: "really-do-it", + Usage: "pass this flag if you know what you are doing", + }, + }, + Action: func(cctx *cli.Context) error { + if !cctx.Bool("really-do-it") { + return xerrors.Errorf("this is a command for advanced users, only use it if you are sure of what you are doing") + } + nodeApi, closer, err := lcli.GetStorageMinerAPI(cctx) + if err != nil { + return err + } + defer closer() + ctx := lcli.ReqContext(cctx) + if cctx.Args().Len() != 1 { + return xerrors.Errorf("must pass sector number") + } + + id, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64) + if err != nil { + return xerrors.Errorf("could not parse sector number: %w", err) + } + + return nodeApi.SectorRemove(ctx, abi.SectorNumber(id)) + }, +} + var sectorsUpdateCmd = &cli.Command{ Name: "update-state", Usage: "ADVANCED: manually update the state of a sector, this may aid in error recovery", @@ -228,12 +263,12 @@ var sectorsUpdateCmd = &cli.Command{ defer closer() ctx := lcli.ReqContext(cctx) if cctx.Args().Len() < 2 { - return xerrors.Errorf("must pass sector ID and new state") + return xerrors.Errorf("must pass sector number and new state") } id, err := strconv.ParseUint(cctx.Args().Get(0), 10, 64) if err != nil { - return xerrors.Errorf("could not parse sector ID: %w", err) + return xerrors.Errorf("could not parse sector number: %w", err) } return nodeApi.SectorsUpdate(ctx, abi.SectorNumber(id), api.SectorState(cctx.Args().Get(1))) diff --git a/go.mod b/go.mod index 655f402c9..33e0e628b 100644 --- a/go.mod +++ b/go.mod @@ -29,10 +29,10 @@ require ( github.com/filecoin-project/go-paramfetch v0.0.2-0.20200605171344-fcac609550ca github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4 + github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 - github.com/filecoin-project/specs-storage v0.1.0 - github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94 + github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea + github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 github.com/go-kit/kit v0.10.0 github.com/go-ole/go-ole v1.2.4 // indirect diff --git a/go.sum b/go.sum index 113c73c53..7b692a145 100644 --- a/go.sum +++ b/go.sum @@ -252,8 +252,10 @@ github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZO github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b h1:fkRZSPrYpk42PV3/lIXiL0LHetxde7vyYYvSsttQtfg= github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/go.mod h1:Q0GQOBtKf1oE10eSXSlhN45kDBdGvEcVOqMiffqX+N8= github.com/filecoin-project/sector-storage v0.0.0-20200615154852-728a47ab99d6/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= -github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4 h1:lQC8Fbyn31/H4QxYAYwVV3PYZ9vS61EmjktZc5CaiYs= -github.com/filecoin-project/sector-storage v0.0.0-20200618073200-d9de9b7cb4b4/go.mod h1:M59QnAeA/oV+Z8oHFLoNpGMv0LZ8Rll+vHVXX7GirPM= +github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d h1:yJJqXCMEhvXJoOS6T1O46FXl+A3mlttXhgjcTCp+Tgo= +github.com/filecoin-project/sector-storage v0.0.0-20200623210524-47d93356586d/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= +github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8 h1:lqv3F5WgjRUH6qLbWQp3Of5IIQXLRT37R1AsFEFAJPc= +github.com/filecoin-project/sector-storage v0.0.0-20200623221933-1cb2b0ac1cd8/go.mod h1:8f0hWDzzIi1hKs4IVKH9RnDsO4LEHVz8BNat0okDOuY= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= @@ -261,8 +263,10 @@ github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1 github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= -github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94 h1:zPKiZPMgkFF0Lq13hsk8lcWlxeVAs6vvJaa3uHn9v70= -github.com/filecoin-project/storage-fsm v0.0.0-20200617183754-4380106d3e94/go.mod h1:q1YCutTSMq/yGYvDPHReT37bPfDLHltnwJutzR9kOY0= +github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea h1:iixjULRQFPn7Q9KlIqfwLJnlAXO10bbkI+xy5GKGdLY= +github.com/filecoin-project/specs-storage v0.1.1-0.20200622113353-88a9704877ea/go.mod h1:Pr5ntAaxsh+sLG/LYiL4tKzvA83Vk5vLODYhfNwOg7k= +github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3 h1:nH3L7YVqrHINOmvZ+5jFjFNSi9/swXcm+uufXpkFJfo= +github.com/filecoin-project/storage-fsm v0.0.0-20200623213010-fe71d5b42de3/go.mod h1:Nl0JX9I3fIVtPEJ9HzGzO4D8LXehT9PqvUQUbNvcstc= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= diff --git a/node/impl/storminer.go b/node/impl/storminer.go index 360a9442c..d7a8d4d33 100644 --- a/node/impl/storminer.go +++ b/node/impl/storminer.go @@ -174,6 +174,10 @@ func (sm *StorageMinerAPI) SectorsUpdate(ctx context.Context, id abi.SectorNumbe return sm.Miner.ForceSectorState(ctx, id, sealing.SectorState(state)) } +func (sm *StorageMinerAPI) SectorRemove(ctx context.Context, id abi.SectorNumber) error { + return sm.Miner.RemoveSector(ctx, id) +} + func (sm *StorageMinerAPI) WorkerConnect(ctx context.Context, url string) error { w, err := connectRemoteWorker(ctx, sm, url) if err != nil { diff --git a/storage/sealing.go b/storage/sealing.go index c8b485379..f5716e85d 100644 --- a/storage/sealing.go +++ b/storage/sealing.go @@ -39,3 +39,7 @@ func (m *Miner) PledgeSector() error { func (m *Miner) ForceSectorState(ctx context.Context, id abi.SectorNumber, state sealing.SectorState) error { return m.sealing.ForceSectorState(ctx, id, state) } + +func (m *Miner) RemoveSector(ctx context.Context, id abi.SectorNumber) error { + return m.sealing.Remove(ctx, id) +}