Merge pull request #1517 from filecoin-project/feat/lotus-agnostic-node-interface
remove lotus types from sealing package in preparation for extraction
This commit is contained in:
commit
086a66efc9
@ -8,39 +8,12 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/sector-storage"
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
"github.com/filecoin-project/sector-storage/stores"
|
|
||||||
)
|
|
||||||
|
|
||||||
type SectorState string
|
|
||||||
|
|
||||||
const (
|
|
||||||
UndefinedSectorState SectorState = ""
|
|
||||||
|
|
||||||
// happy path
|
|
||||||
Empty SectorState = "Empty"
|
|
||||||
Packing SectorState = "Packing" // sector not in sealStore, and not on chain
|
|
||||||
PreCommit1 SectorState = "PreCommit1" // do PreCommit1
|
|
||||||
PreCommit2 SectorState = "PreCommit2" // do PreCommit1
|
|
||||||
PreCommitting SectorState = "PreCommitting" // on chain pre-commit
|
|
||||||
WaitSeed SectorState = "WaitSeed" // waiting for seed
|
|
||||||
Committing SectorState = "Committing"
|
|
||||||
CommitWait SectorState = "CommitWait" // waiting for message to land on chain
|
|
||||||
FinalizeSector SectorState = "FinalizeSector"
|
|
||||||
Proving SectorState = "Proving"
|
|
||||||
// error modes
|
|
||||||
FailedUnrecoverable SectorState = "FailedUnrecoverable"
|
|
||||||
SealFailed SectorState = "SealFailed"
|
|
||||||
PreCommitFailed SectorState = "PreCommitFailed"
|
|
||||||
ComputeProofFailed SectorState = "ComputeProofFailed"
|
|
||||||
CommitFailed SectorState = "CommitFailed"
|
|
||||||
PackingFailed SectorState = "PackingFailed"
|
|
||||||
Faulty SectorState = "Faulty" // sector is corrupted or gone for some reason
|
|
||||||
FaultReported SectorState = "FaultReported" // sector has been declared as a fault on chain
|
|
||||||
FaultedFinal SectorState = "FaultedFinal" // fault declared on chain
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// StorageMiner is a low-level interface to the Filecoin network storage miner node
|
// StorageMiner is a low-level interface to the Filecoin network storage miner node
|
||||||
@ -62,7 +35,7 @@ type StorageMiner interface {
|
|||||||
|
|
||||||
SectorsRefs(context.Context) (map[string][]SealedRef, error)
|
SectorsRefs(context.Context) (map[string][]SealedRef, error)
|
||||||
|
|
||||||
SectorsUpdate(context.Context, abi.SectorNumber, SectorState) error
|
SectorsUpdate(context.Context, abi.SectorNumber, sealing.SectorState) error
|
||||||
|
|
||||||
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error)
|
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error)
|
||||||
StorageLocal(ctx context.Context) (map[stores.ID]string, error)
|
StorageLocal(ctx context.Context) (map[stores.ID]string, error)
|
||||||
@ -103,7 +76,7 @@ type SectorLog struct {
|
|||||||
|
|
||||||
type SectorInfo struct {
|
type SectorInfo struct {
|
||||||
SectorID abi.SectorNumber
|
SectorID abi.SectorNumber
|
||||||
State SectorState
|
State sealing.SectorState
|
||||||
CommD *cid.Cid
|
CommD *cid.Cid
|
||||||
CommR *cid.Cid
|
CommR *cid.Cid
|
||||||
Proof []byte
|
Proof []byte
|
||||||
|
@ -9,6 +9,9 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
"github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
|
"github.com/filecoin-project/sector-storage/sealtasks"
|
||||||
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
@ -22,9 +25,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
sectorstorage "github.com/filecoin-project/sector-storage"
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
"github.com/filecoin-project/sector-storage/sealtasks"
|
|
||||||
"github.com/filecoin-project/sector-storage/stores"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// All permissions are listed in permissioned.go
|
// All permissions are listed in permissioned.go
|
||||||
@ -184,7 +185,7 @@ type StorageMinerStruct struct {
|
|||||||
SectorsStatus func(context.Context, abi.SectorNumber) (api.SectorInfo, error) `perm:"read"`
|
SectorsStatus func(context.Context, abi.SectorNumber) (api.SectorInfo, error) `perm:"read"`
|
||||||
SectorsList func(context.Context) ([]abi.SectorNumber, error) `perm:"read"`
|
SectorsList func(context.Context) ([]abi.SectorNumber, error) `perm:"read"`
|
||||||
SectorsRefs func(context.Context) (map[string][]api.SealedRef, 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"`
|
SectorsUpdate func(context.Context, abi.SectorNumber, sealing.SectorState) error `perm:"write"`
|
||||||
|
|
||||||
WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm
|
WorkerConnect func(context.Context, string) error `perm:"admin"` // TODO: worker perm
|
||||||
WorkerStats func(context.Context) (map[uint64]sectorstorage.WorkerStats, error) `perm:"admin"`
|
WorkerStats func(context.Context) (map[uint64]sectorstorage.WorkerStats, error) `perm:"admin"`
|
||||||
@ -675,7 +676,7 @@ func (c *StorageMinerStruct) SectorsRefs(ctx context.Context) (map[string][]api.
|
|||||||
return c.Internal.SectorsRefs(ctx)
|
return c.Internal.SectorsRefs(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *StorageMinerStruct) SectorsUpdate(ctx context.Context, id abi.SectorNumber, state api.SectorState) error {
|
func (c *StorageMinerStruct) SectorsUpdate(ctx context.Context, id abi.SectorNumber, state sealing.SectorState) error {
|
||||||
return c.Internal.SectorsUpdate(ctx, id, state)
|
return c.Internal.SectorsUpdate(ctx, id, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
cid "github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
cid "github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
@ -4,13 +4,15 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/power"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var infoCmd = &cli.Command{
|
var infoCmd = &cli.Command{
|
||||||
@ -127,13 +129,13 @@ var infoCmd = &cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func sectorsInfo(ctx context.Context, napi api.StorageMiner) (map[api.SectorState]int, error) {
|
func sectorsInfo(ctx context.Context, napi api.StorageMiner) (map[sealing.SectorState]int, error) {
|
||||||
sectors, err := napi.SectorsList(ctx)
|
sectors, err := napi.SectorsList(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
out := map[api.SectorState]int{
|
out := map[sealing.SectorState]int{
|
||||||
"Total": len(sectors),
|
"Total": len(sectors),
|
||||||
}
|
}
|
||||||
for _, s := range sectors {
|
for _, s := range sectors {
|
||||||
|
@ -12,8 +12,6 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/node/modules"
|
|
||||||
|
|
||||||
"github.com/docker/go-units"
|
"github.com/docker/go-units"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
@ -26,6 +24,9 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
cborutil "github.com/filecoin-project/go-cbor-util"
|
cborutil "github.com/filecoin-project/go-cbor-util"
|
||||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||||
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
@ -40,13 +41,11 @@ import (
|
|||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
"github.com/filecoin-project/lotus/genesis"
|
"github.com/filecoin-project/lotus/genesis"
|
||||||
"github.com/filecoin-project/lotus/miner"
|
"github.com/filecoin-project/lotus/miner"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
"github.com/filecoin-project/lotus/node/repo"
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
"github.com/filecoin-project/lotus/storage"
|
"github.com/filecoin-project/lotus/storage"
|
||||||
"github.com/filecoin-project/lotus/storage/sealing"
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
sectorstorage "github.com/filecoin-project/sector-storage"
|
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
|
||||||
"github.com/filecoin-project/sector-storage/stores"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var initCmd = &cli.Command{
|
var initCmd = &cli.Command{
|
||||||
@ -287,8 +286,8 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string,
|
|||||||
commR := sector.CommR
|
commR := sector.CommR
|
||||||
|
|
||||||
info := &sealing.SectorInfo{
|
info := &sealing.SectorInfo{
|
||||||
State: lapi.Proving,
|
State: sealing.Proving,
|
||||||
SectorID: sector.SectorID,
|
SectorNumber: sector.SectorID,
|
||||||
Pieces: []sealing.Piece{
|
Pieces: []sealing.Piece{
|
||||||
{
|
{
|
||||||
DealID: &dealID,
|
DealID: &dealID,
|
||||||
@ -299,9 +298,11 @@ func migratePreSealMeta(ctx context.Context, api lapi.FullNode, metadata string,
|
|||||||
CommD: &commD,
|
CommD: &commD,
|
||||||
CommR: &commR,
|
CommR: &commR,
|
||||||
Proof: nil,
|
Proof: nil,
|
||||||
Ticket: lapi.SealTicket{},
|
TicketValue: abi.SealRandomness{},
|
||||||
|
TicketEpoch: 0,
|
||||||
PreCommitMessage: nil,
|
PreCommitMessage: nil,
|
||||||
Seed: lapi.SealSeed{},
|
SeedValue: abi.InteractiveSealRandomness{},
|
||||||
|
SeedEpoch: 0,
|
||||||
CommitMessage: nil,
|
CommitMessage: nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,14 +8,14 @@ import (
|
|||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
"gopkg.in/urfave/cli.v2"
|
"gopkg.in/urfave/cli.v2"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
lcli "github.com/filecoin-project/lotus/cli"
|
lcli "github.com/filecoin-project/lotus/cli"
|
||||||
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
)
|
)
|
||||||
|
|
||||||
var sectorsCmd = &cli.Command{
|
var sectorsCmd = &cli.Command{
|
||||||
@ -236,7 +236,7 @@ var sectorsUpdateCmd = &cli.Command{
|
|||||||
return xerrors.Errorf("could not parse sector ID: %w", err)
|
return xerrors.Errorf("could not parse sector ID: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodeApi.SectorsUpdate(ctx, abi.SectorNumber(id), api.SectorState(cctx.Args().Get(1)))
|
return nodeApi.SectorsUpdate(ctx, abi.SectorNumber(id), sealing.SectorState(cctx.Args().Get(1)))
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
2
go.mod
2
go.mod
@ -24,7 +24,7 @@ require (
|
|||||||
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663
|
github.com/filecoin-project/go-paramfetch v0.0.2-0.20200218225740-47c639bab663
|
||||||
github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9
|
github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9
|
||||||
github.com/filecoin-project/go-statestore v0.1.0
|
github.com/filecoin-project/go-statestore v0.1.0
|
||||||
github.com/filecoin-project/sector-storage v0.0.0-20200327233338-c4b928d44163
|
github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576
|
||||||
github.com/filecoin-project/specs-actors v0.0.0-20200324235424-aef9b20a9fb1
|
github.com/filecoin-project/specs-actors v0.0.0-20200324235424-aef9b20a9fb1
|
||||||
github.com/filecoin-project/specs-storage v0.0.0-20200317225704-7420bc655c38
|
github.com/filecoin-project/specs-storage v0.0.0-20200317225704-7420bc655c38
|
||||||
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1
|
||||||
|
4
go.sum
4
go.sum
@ -150,8 +150,8 @@ github.com/filecoin-project/go-statemachine v0.0.0-20200226041606-2074af6d51d9/g
|
|||||||
github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ=
|
github.com/filecoin-project/go-statestore v0.1.0 h1:t56reH59843TwXHkMcwyuayStBIiWBRilQjQ+5IiwdQ=
|
||||||
github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI=
|
github.com/filecoin-project/go-statestore v0.1.0/go.mod h1:LFc9hD+fRxPqiHiaqUEZOinUJB4WARkRfNl10O7kTnI=
|
||||||
github.com/filecoin-project/lotus v0.2.10/go.mod h1:om5PQA9ZT0lf16qI7Fz/ZGLn4LDCMqPC8ntZA9uncRE=
|
github.com/filecoin-project/lotus v0.2.10/go.mod h1:om5PQA9ZT0lf16qI7Fz/ZGLn4LDCMqPC8ntZA9uncRE=
|
||||||
github.com/filecoin-project/sector-storage v0.0.0-20200327233338-c4b928d44163 h1:ZCvy0S7RI96OYRqMslHFi75vsD/DRYcY3yjRvdawC08=
|
github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576 h1:MzBqbddYp/vdFOC3WNu3tSWfLFwHUP8Orcx2CxjRPyo=
|
||||||
github.com/filecoin-project/sector-storage v0.0.0-20200327233338-c4b928d44163/go.mod h1:yT100eeKHGO9xU3rfkeM2/8NcBktxe2nBkDT4WmD1lA=
|
github.com/filecoin-project/sector-storage v0.0.0-20200406195014-a6d093838576/go.mod h1:yT100eeKHGO9xU3rfkeM2/8NcBktxe2nBkDT4WmD1lA=
|
||||||
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
|
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
|
||||||
github.com/filecoin-project/specs-actors v0.0.0-20200226200336-94c9b92b2775/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
github.com/filecoin-project/specs-actors v0.0.0-20200226200336-94c9b92b2775/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||||
github.com/filecoin-project/specs-actors v0.0.0-20200302223606-0eaf97b10aaf/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
github.com/filecoin-project/specs-actors v0.0.0-20200302223606-0eaf97b10aaf/go.mod h1:0HAWYrvajFHDgRaKbF0rl+IybVLZL5z4gQ8koCMPhoU=
|
||||||
|
@ -7,14 +7,14 @@ import (
|
|||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
"github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
||||||
"github.com/filecoin-project/go-fil-markets/shared"
|
"github.com/filecoin-project/go-fil-markets/shared"
|
||||||
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
"github.com/filecoin-project/specs-actors/actors/builtin/paych"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/storage"
|
"github.com/filecoin-project/lotus/storage"
|
||||||
"github.com/filecoin-project/sector-storage"
|
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type retrievalProviderNode struct {
|
type retrievalProviderNode struct {
|
||||||
@ -54,7 +54,7 @@ func (rpn *retrievalProviderNode) UnsealSector(ctx context.Context, sectorID uin
|
|||||||
Miner: abi.ActorID(mid),
|
Miner: abi.ActorID(mid),
|
||||||
Number: abi.SectorNumber(sectorID),
|
Number: abi.SectorNumber(sectorID),
|
||||||
}
|
}
|
||||||
return rpn.sealer.ReadPieceFromSealedSector(ctx, sid, ffiwrapper.UnpaddedByteIndex(offset), abi.UnpaddedPieceSize(length), si.Ticket.Value, *si.CommD)
|
return rpn.sealer.ReadPieceFromSealedSector(ctx, sid, ffiwrapper.UnpaddedByteIndex(offset), abi.UnpaddedPieceSize(length), si.TicketValue, *si.CommD)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rpn *retrievalProviderNode) SavePaymentVoucher(ctx context.Context, paymentChannel address.Address, voucher *paych.SignedVoucher, proof []byte, expectedAmount abi.TokenAmount, tok shared.TipSetToken) (abi.TokenAmount, error) {
|
func (rpn *retrievalProviderNode) SavePaymentVoucher(ctx context.Context, paymentChannel address.Address, voucher *paych.SignedVoucher, proof []byte, expectedAmount abi.TokenAmount, tok shared.TipSetToken) (abi.TokenAmount, error) {
|
||||||
|
@ -208,13 +208,13 @@ func (n *ProviderNodeAdapter) LocatePieceForDealWithinSector(ctx context.Context
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, 0, 0, xerrors.Errorf("getting sector info: %w", err)
|
return 0, 0, 0, xerrors.Errorf("getting sector info: %w", err)
|
||||||
}
|
}
|
||||||
if si.State == api.Proving {
|
if si.State == sealing.Proving {
|
||||||
best = r
|
best = r
|
||||||
bestSi = si
|
bestSi = si
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if bestSi.State == api.UndefinedSectorState {
|
if bestSi.State == sealing.UndefinedSectorState {
|
||||||
return 0, 0, 0, xerrors.New("no sealed sector found")
|
return 0, 0, 0, xerrors.New("no sealed sector found")
|
||||||
}
|
}
|
||||||
return uint64(best.SectorID), best.Offset, uint64(best.Size), nil
|
return uint64(best.SectorID), best.Offset, uint64(best.Size), nil
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
cid "github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
@ -12,6 +12,9 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket"
|
storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket"
|
||||||
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
@ -20,10 +23,8 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/miner"
|
"github.com/filecoin-project/lotus/miner"
|
||||||
"github.com/filecoin-project/lotus/node/impl/common"
|
"github.com/filecoin-project/lotus/node/impl/common"
|
||||||
"github.com/filecoin-project/lotus/storage"
|
"github.com/filecoin-project/lotus/storage"
|
||||||
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
||||||
"github.com/filecoin-project/sector-storage"
|
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
|
||||||
"github.com/filecoin-project/sector-storage/stores"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type StorageMinerAPI struct {
|
type StorageMinerAPI struct {
|
||||||
@ -97,8 +98,14 @@ func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid abi.SectorNumb
|
|||||||
CommR: info.CommR,
|
CommR: info.CommR,
|
||||||
Proof: info.Proof,
|
Proof: info.Proof,
|
||||||
Deals: deals,
|
Deals: deals,
|
||||||
Ticket: info.Ticket,
|
Ticket: api.SealTicket{
|
||||||
Seed: info.Seed,
|
Value: info.TicketValue,
|
||||||
|
Epoch: info.TicketEpoch,
|
||||||
|
},
|
||||||
|
Seed: api.SealSeed{
|
||||||
|
Value: info.SeedValue,
|
||||||
|
Epoch: info.SeedEpoch,
|
||||||
|
},
|
||||||
Retries: info.Nonce,
|
Retries: info.Nonce,
|
||||||
|
|
||||||
LastErr: info.LastErr,
|
LastErr: info.LastErr,
|
||||||
@ -115,7 +122,7 @@ func (sm *StorageMinerAPI) SectorsList(context.Context) ([]abi.SectorNumber, err
|
|||||||
|
|
||||||
out := make([]abi.SectorNumber, len(sectors))
|
out := make([]abi.SectorNumber, len(sectors))
|
||||||
for i, sector := range sectors {
|
for i, sector := range sectors {
|
||||||
out[i] = sector.SectorID
|
out[i] = sector.SectorNumber
|
||||||
}
|
}
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
@ -144,7 +151,7 @@ func (sm *StorageMinerAPI) StorageStat(ctx context.Context, id stores.ID) (store
|
|||||||
return sm.StorageMgr.FsStat(ctx, id)
|
return sm.StorageMgr.FsStat(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *StorageMinerAPI) SectorsUpdate(ctx context.Context, id abi.SectorNumber, state api.SectorState) error {
|
func (sm *StorageMinerAPI) SectorsUpdate(ctx context.Context, id abi.SectorNumber, state sealing.SectorState) error {
|
||||||
return sm.Miner.ForceSectorState(ctx, id, state)
|
return sm.Miner.ForceSectorState(ctx, id, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,6 +35,9 @@ import (
|
|||||||
"github.com/filecoin-project/go-fil-markets/storedcounter"
|
"github.com/filecoin-project/go-fil-markets/storedcounter"
|
||||||
paramfetch "github.com/filecoin-project/go-paramfetch"
|
paramfetch "github.com/filecoin-project/go-paramfetch"
|
||||||
"github.com/filecoin-project/go-statestore"
|
"github.com/filecoin-project/go-statestore"
|
||||||
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
|
"github.com/filecoin-project/sector-storage/stores"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
|
||||||
@ -49,9 +52,6 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/node/repo"
|
"github.com/filecoin-project/lotus/node/repo"
|
||||||
"github.com/filecoin-project/lotus/storage"
|
"github.com/filecoin-project/lotus/storage"
|
||||||
"github.com/filecoin-project/lotus/storage/sealing"
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
"github.com/filecoin-project/sector-storage"
|
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
|
||||||
"github.com/filecoin-project/sector-storage/stores"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func minerAddrFromDS(ds dtypes.MetadataDS) (address.Address, error) {
|
func minerAddrFromDS(ds dtypes.MetadataDS) (address.Address, error) {
|
||||||
@ -281,21 +281,18 @@ func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SealTicketGen(fapi lapi.FullNode) sealing.TicketFn {
|
func SealTicketGen(fapi lapi.FullNode) sealing.TicketFn {
|
||||||
return func(ctx context.Context) (*lapi.SealTicket, error) {
|
return func(ctx context.Context) (abi.SealRandomness, abi.ChainEpoch, error) {
|
||||||
ts, err := fapi.ChainHead(ctx)
|
ts, err := fapi.ChainHead(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("getting head ts for SealTicket failed: %w", err)
|
return nil, 0, xerrors.Errorf("getting head ts for SealTicket failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
r, err := fapi.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_SealRandomness, ts.Height()-build.SealRandomnessLookback, nil)
|
r, err := fapi.ChainGetRandomness(ctx, ts.Key(), crypto.DomainSeparationTag_SealRandomness, ts.Height()-build.SealRandomnessLookback, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("getting randomness for SealTicket failed: %w", err)
|
return nil, 0, xerrors.Errorf("getting randomness for SealTicket failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &lapi.SealTicket{
|
return abi.SealRandomness(r), ts.Height() - build.SealRandomnessLookback, nil
|
||||||
Epoch: ts.Height() - build.SealRandomnessLookback,
|
|
||||||
Value: abi.SealRandomness(r),
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
29
storage/adapter_events.go
Normal file
29
storage/adapter_events.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/events"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ sealing.Events = new(EventsAdapter)
|
||||||
|
|
||||||
|
type EventsAdapter struct {
|
||||||
|
delegate *events.Events
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEventsAdapter(api *events.Events) EventsAdapter {
|
||||||
|
return EventsAdapter{delegate: api}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e EventsAdapter) ChainAt(hnd sealing.HeightHandler, rev sealing.RevertHandler, confidence int, h abi.ChainEpoch) error {
|
||||||
|
return e.delegate.ChainAt(func(ctx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error {
|
||||||
|
return hnd(ctx, ts.Key().Bytes(), curH)
|
||||||
|
}, func(ctx context.Context, ts *types.TipSet) error {
|
||||||
|
return rev(ctx, ts.Key().Bytes())
|
||||||
|
}, confidence, h)
|
||||||
|
}
|
185
storage/adapter_storage_miner.go
Normal file
185
storage/adapter_storage_miner.go
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
package storage
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/ipfs/go-cid"
|
||||||
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/api/apibstore"
|
||||||
|
"github.com/filecoin-project/lotus/chain/actors"
|
||||||
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ sealing.SealingAPI = new(SealingAPIAdapter)
|
||||||
|
|
||||||
|
type SealingAPIAdapter struct {
|
||||||
|
delegate storageMinerApi
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSealingAPIAdapter(api storageMinerApi) SealingAPIAdapter {
|
||||||
|
return SealingAPIAdapter{delegate: api}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) StateMinerSectorSize(ctx context.Context, maddr address.Address, tok sealing.TipSetToken) (abi.SectorSize, error) {
|
||||||
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
||||||
|
if err != nil {
|
||||||
|
return 0, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.delegate.StateMinerSectorSize(ctx, maddr, tsk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) StateWaitMsg(ctx context.Context, mcid cid.Cid) (sealing.MsgLookup, error) {
|
||||||
|
wmsg, err := s.delegate.StateWaitMsg(ctx, mcid)
|
||||||
|
if err != nil {
|
||||||
|
return sealing.MsgLookup{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return sealing.MsgLookup{
|
||||||
|
Receipt: sealing.MessageReceipt{
|
||||||
|
ExitCode: wmsg.Receipt.ExitCode,
|
||||||
|
Return: wmsg.Receipt.Return,
|
||||||
|
GasUsed: wmsg.Receipt.GasUsed,
|
||||||
|
},
|
||||||
|
TipSetTok: wmsg.TipSet.Key().Bytes(),
|
||||||
|
Height: wmsg.TipSet.Height(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) StateComputeDataCommitment(ctx context.Context, maddr address.Address, sectorType abi.RegisteredProof, deals []abi.DealID, tok sealing.TipSetToken) (cid.Cid, error) {
|
||||||
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ccparams, err := actors.SerializeParams(&market.ComputeDataCommitmentParams{
|
||||||
|
DealIDs: deals,
|
||||||
|
SectorType: sectorType,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("computing params for ComputeDataCommitment: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ccmt := &types.Message{
|
||||||
|
To: builtin.StorageMarketActorAddr,
|
||||||
|
From: maddr,
|
||||||
|
Value: types.NewInt(0),
|
||||||
|
GasPrice: types.NewInt(0),
|
||||||
|
GasLimit: 9999999999,
|
||||||
|
Method: builtin.MethodsMarket.ComputeDataCommitment,
|
||||||
|
Params: ccparams,
|
||||||
|
}
|
||||||
|
r, err := s.delegate.StateCall(ctx, ccmt, tsk)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("calling ComputeDataCommitment: %w", err)
|
||||||
|
}
|
||||||
|
if r.MsgRct.ExitCode != 0 {
|
||||||
|
return cid.Undef, xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.MsgRct.ExitCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
var c cbg.CborCid
|
||||||
|
if err := c.UnmarshalCBOR(bytes.NewReader(r.MsgRct.Return)); err != nil {
|
||||||
|
return cid.Undef, xerrors.Errorf("failed to unmarshal CBOR to CborCid: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return cid.Cid(c), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok sealing.TipSetToken) (*miner.SectorPreCommitOnChainInfo, error) {
|
||||||
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("failed to unmarshal TipSetToken to TipSetKey: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
act, err := s.delegate.StateGetActor(ctx, maddr, tsk)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: %+v", sectorNumber, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
st, err := s.delegate.ChainReadObj(ctx, act.Head)
|
||||||
|
if err != nil {
|
||||||
|
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: %+v", sectorNumber, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var state miner.State
|
||||||
|
if err := state.UnmarshalCBOR(bytes.NewReader(st)); err != nil {
|
||||||
|
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: unmarshaling miner state: %+v", sectorNumber, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var pci miner.SectorPreCommitOnChainInfo
|
||||||
|
precommits := adt.AsMap(store.ActorStore(ctx, apibstore.NewAPIBlockstore(s.delegate)), state.PreCommittedSectors)
|
||||||
|
if _, err := precommits.Get(adt.UIntKey(uint64(sectorNumber)), &pci); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &pci, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) StateMarketStorageDeal(ctx context.Context, dealID abi.DealID, tok sealing.TipSetToken) (market.DealProposal, market.DealState, error) {
|
||||||
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
||||||
|
if err != nil {
|
||||||
|
return market.DealProposal{}, market.DealState{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
deal, err := s.delegate.StateMarketStorageDeal(ctx, dealID, tsk)
|
||||||
|
if err != nil {
|
||||||
|
return market.DealProposal{}, market.DealState{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return deal.Proposal, deal.State, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error) {
|
||||||
|
msg := types.Message{
|
||||||
|
To: to,
|
||||||
|
From: from,
|
||||||
|
Value: value,
|
||||||
|
GasPrice: gasPrice,
|
||||||
|
GasLimit: gasLimit,
|
||||||
|
Method: method,
|
||||||
|
Params: params,
|
||||||
|
}
|
||||||
|
|
||||||
|
smsg, err := s.delegate.MpoolPushMessage(ctx, &msg)
|
||||||
|
if err != nil {
|
||||||
|
return cid.Undef, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return smsg.Cid(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) ChainHead(ctx context.Context) (sealing.TipSetToken, abi.ChainEpoch, error) {
|
||||||
|
head, err := s.delegate.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return head.Key().Bytes(), head.Height(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) ChainGetRandomness(ctx context.Context, tok sealing.TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
|
||||||
|
tsk, err := types.TipSetKeyFromBytes(tok)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.delegate.ChainGetRandomness(ctx, tsk, personalization, randEpoch, entropy)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s SealingAPIAdapter) ChainReadObj(ctx context.Context, ocid cid.Cid) ([]byte, error) {
|
||||||
|
return s.delegate.ChainReadObj(ctx, ocid)
|
||||||
|
}
|
@ -5,20 +5,19 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/sector-storage"
|
"github.com/filecoin-project/go-address"
|
||||||
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-storage/storage"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
@ -100,7 +99,7 @@ func (m *Miner) Run(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
evts := events.NewEvents(ctx, m.api)
|
evts := events.NewEvents(ctx, m.api)
|
||||||
m.sealing = sealing.New(m.api, evts, m.maddr, m.worker, m.ds, m.sealer, m.sc, m.verif, m.tktFn)
|
m.sealing = sealing.New(NewSealingAPIAdapter(m.api), NewEventsAdapter(evts), m.maddr, m.worker, m.ds, m.sealer, m.sc, m.verif, m.tktFn)
|
||||||
|
|
||||||
go m.sealing.Run(ctx)
|
go m.sealing.Run(ctx)
|
||||||
|
|
||||||
|
@ -2,12 +2,11 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/lotus/storage/sealing"
|
"github.com/filecoin-project/lotus/storage/sealing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -37,6 +36,6 @@ func (m *Miner) PledgeSector() error {
|
|||||||
return m.sealing.PledgeSector()
|
return m.sealing.PledgeSector()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Miner) ForceSectorState(ctx context.Context, id abi.SectorNumber, state api.SectorState) error {
|
func (m *Miner) ForceSectorState(ctx context.Context, id abi.SectorNumber, state sealing.SectorState) error {
|
||||||
return m.sealing.ForceSectorState(ctx, id, state)
|
return m.sealing.ForceSectorState(ctx, id, state)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
@ -178,11 +177,11 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
|
|||||||
_, err := w.Write(cbg.CborNull)
|
_, err := w.Write(cbg.CborNull)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := w.Write([]byte{177}); err != nil {
|
if _, err := w.Write([]byte{179}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.State (api.SectorState) (string)
|
// t.State (sealing.SectorState) (string)
|
||||||
if len("State") > cbg.MaxLength {
|
if len("State") > cbg.MaxLength {
|
||||||
return xerrors.Errorf("Value in field \"State\" was too long")
|
return xerrors.Errorf("Value in field \"State\" was too long")
|
||||||
}
|
}
|
||||||
@ -205,19 +204,19 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.SectorID (abi.SectorNumber) (uint64)
|
// t.SectorNumber (abi.SectorNumber) (uint64)
|
||||||
if len("SectorID") > cbg.MaxLength {
|
if len("SectorNumber") > cbg.MaxLength {
|
||||||
return xerrors.Errorf("Value in field \"SectorID\" was too long")
|
return xerrors.Errorf("Value in field \"SectorNumber\" was too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorID")))); err != nil {
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SectorNumber")))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := w.Write([]byte("SectorID")); err != nil {
|
if _, err := w.Write([]byte("SectorNumber")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorID))); err != nil {
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SectorNumber))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,21 +283,50 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.Ticket (api.SealTicket) (struct)
|
// t.TicketValue (abi.SealRandomness) (slice)
|
||||||
if len("Ticket") > cbg.MaxLength {
|
if len("TicketValue") > cbg.MaxLength {
|
||||||
return xerrors.Errorf("Value in field \"Ticket\" was too long")
|
return xerrors.Errorf("Value in field \"TicketValue\" was too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Ticket")))); err != nil {
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketValue")))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := w.Write([]byte("Ticket")); err != nil {
|
if _, err := w.Write([]byte("TicketValue")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.Ticket.MarshalCBOR(w); err != nil {
|
if len(t.TicketValue) > cbg.ByteArrayMaxLen {
|
||||||
|
return xerrors.Errorf("Byte array in field t.TicketValue was too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.TicketValue)))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if _, err := w.Write(t.TicketValue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// t.TicketEpoch (abi.ChainEpoch) (int64)
|
||||||
|
if len("TicketEpoch") > cbg.MaxLength {
|
||||||
|
return xerrors.Errorf("Value in field \"TicketEpoch\" was too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("TicketEpoch")))); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.Write([]byte("TicketEpoch")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.TicketEpoch >= 0 {
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.TicketEpoch))); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.TicketEpoch)-1)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// t.PreCommit1Out (storage.PreCommit1Out) (slice)
|
// t.PreCommit1Out (storage.PreCommit1Out) (slice)
|
||||||
if len("PreCommit1Out") > cbg.MaxLength {
|
if len("PreCommit1Out") > cbg.MaxLength {
|
||||||
@ -412,21 +440,50 @@ func (t *SectorInfo) MarshalCBOR(w io.Writer) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.Seed (api.SealSeed) (struct)
|
// t.SeedValue (abi.InteractiveSealRandomness) (slice)
|
||||||
if len("Seed") > cbg.MaxLength {
|
if len("SeedValue") > cbg.MaxLength {
|
||||||
return xerrors.Errorf("Value in field \"Seed\" was too long")
|
return xerrors.Errorf("Value in field \"SeedValue\" was too long")
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("Seed")))); err != nil {
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SeedValue")))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := w.Write([]byte("Seed")); err != nil {
|
if _, err := w.Write([]byte("SeedValue")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := t.Seed.MarshalCBOR(w); err != nil {
|
if len(t.SeedValue) > cbg.ByteArrayMaxLen {
|
||||||
|
return xerrors.Errorf("Byte array in field t.SeedValue was too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.SeedValue)))); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if _, err := w.Write(t.SeedValue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// t.SeedEpoch (abi.ChainEpoch) (int64)
|
||||||
|
if len("SeedEpoch") > cbg.MaxLength {
|
||||||
|
return xerrors.Errorf("Value in field \"SeedEpoch\" was too long")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajTextString, uint64(len("SeedEpoch")))); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := w.Write([]byte("SeedEpoch")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if t.SeedEpoch >= 0 {
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajUnsignedInt, uint64(t.SeedEpoch))); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajNegativeInt, uint64(-t.SeedEpoch)-1)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// t.CommitMessage (cid.Cid) (struct)
|
// t.CommitMessage (cid.Cid) (struct)
|
||||||
if len("CommitMessage") > cbg.MaxLength {
|
if len("CommitMessage") > cbg.MaxLength {
|
||||||
@ -568,7 +625,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch name {
|
switch name {
|
||||||
// t.State (api.SectorState) (string)
|
// t.State (sealing.SectorState) (string)
|
||||||
case "State":
|
case "State":
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -577,10 +634,10 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
t.State = api.SectorState(sval)
|
t.State = SectorState(sval)
|
||||||
}
|
}
|
||||||
// t.SectorID (abi.SectorNumber) (uint64)
|
// t.SectorNumber (abi.SectorNumber) (uint64)
|
||||||
case "SectorID":
|
case "SectorNumber":
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -591,7 +648,7 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error {
|
|||||||
if maj != cbg.MajUnsignedInt {
|
if maj != cbg.MajUnsignedInt {
|
||||||
return fmt.Errorf("wrong type for uint64 field")
|
return fmt.Errorf("wrong type for uint64 field")
|
||||||
}
|
}
|
||||||
t.SectorID = abi.SectorNumber(extra)
|
t.SectorNumber = abi.SectorNumber(extra)
|
||||||
|
|
||||||
}
|
}
|
||||||
// t.Nonce (uint64) (uint64)
|
// t.Nonce (uint64) (uint64)
|
||||||
@ -663,15 +720,49 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error {
|
|||||||
t.Pieces[i] = v
|
t.Pieces[i] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.Ticket (api.SealTicket) (struct)
|
// t.TicketValue (abi.SealRandomness) (slice)
|
||||||
case "Ticket":
|
case "TicketValue":
|
||||||
|
|
||||||
{
|
maj, extra, err = cbg.CborReadHeader(br)
|
||||||
|
if err != nil {
|
||||||
if err := t.Ticket.UnmarshalCBOR(br); err != nil {
|
return err
|
||||||
return xerrors.Errorf("unmarshaling t.Ticket: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if extra > cbg.ByteArrayMaxLen {
|
||||||
|
return fmt.Errorf("t.TicketValue: byte array too large (%d)", extra)
|
||||||
|
}
|
||||||
|
if maj != cbg.MajByteString {
|
||||||
|
return fmt.Errorf("expected byte array")
|
||||||
|
}
|
||||||
|
t.TicketValue = make([]byte, extra)
|
||||||
|
if _, err := io.ReadFull(br, t.TicketValue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// t.TicketEpoch (abi.ChainEpoch) (int64)
|
||||||
|
case "TicketEpoch":
|
||||||
|
{
|
||||||
|
maj, extra, err := cbg.CborReadHeader(br)
|
||||||
|
var extraI int64
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch maj {
|
||||||
|
case cbg.MajUnsignedInt:
|
||||||
|
extraI = int64(extra)
|
||||||
|
if extraI < 0 {
|
||||||
|
return fmt.Errorf("int64 positive overflow")
|
||||||
|
}
|
||||||
|
case cbg.MajNegativeInt:
|
||||||
|
extraI = int64(extra)
|
||||||
|
if extraI < 0 {
|
||||||
|
return fmt.Errorf("int64 negative oveflow")
|
||||||
|
}
|
||||||
|
extraI = -1 - extraI
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.TicketEpoch = abi.ChainEpoch(extraI)
|
||||||
}
|
}
|
||||||
// t.PreCommit1Out (storage.PreCommit1Out) (slice)
|
// t.PreCommit1Out (storage.PreCommit1Out) (slice)
|
||||||
case "PreCommit1Out":
|
case "PreCommit1Out":
|
||||||
@ -784,15 +875,49 @@ func (t *SectorInfo) UnmarshalCBOR(r io.Reader) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// t.Seed (api.SealSeed) (struct)
|
// t.SeedValue (abi.InteractiveSealRandomness) (slice)
|
||||||
case "Seed":
|
case "SeedValue":
|
||||||
|
|
||||||
{
|
maj, extra, err = cbg.CborReadHeader(br)
|
||||||
|
if err != nil {
|
||||||
if err := t.Seed.UnmarshalCBOR(br); err != nil {
|
return err
|
||||||
return xerrors.Errorf("unmarshaling t.Seed: %w", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if extra > cbg.ByteArrayMaxLen {
|
||||||
|
return fmt.Errorf("t.SeedValue: byte array too large (%d)", extra)
|
||||||
|
}
|
||||||
|
if maj != cbg.MajByteString {
|
||||||
|
return fmt.Errorf("expected byte array")
|
||||||
|
}
|
||||||
|
t.SeedValue = make([]byte, extra)
|
||||||
|
if _, err := io.ReadFull(br, t.SeedValue); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// t.SeedEpoch (abi.ChainEpoch) (int64)
|
||||||
|
case "SeedEpoch":
|
||||||
|
{
|
||||||
|
maj, extra, err := cbg.CborReadHeader(br)
|
||||||
|
var extraI int64
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch maj {
|
||||||
|
case cbg.MajUnsignedInt:
|
||||||
|
extraI = int64(extra)
|
||||||
|
if extraI < 0 {
|
||||||
|
return fmt.Errorf("int64 positive overflow")
|
||||||
|
}
|
||||||
|
case cbg.MajNegativeInt:
|
||||||
|
extraI = int64(extra)
|
||||||
|
if extraI < 0 {
|
||||||
|
return fmt.Errorf("int64 negative oveflow")
|
||||||
|
}
|
||||||
|
extraI = -1 - extraI
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("wrong type for int64 field: %d", maj)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.SeedEpoch = abi.ChainEpoch(extraI)
|
||||||
}
|
}
|
||||||
// t.CommitMessage (cid.Cid) (struct)
|
// t.CommitMessage (cid.Cid) (struct)
|
||||||
case "CommitMessage":
|
case "CommitMessage":
|
||||||
|
@ -1,25 +1,16 @@
|
|||||||
package sealing
|
package sealing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
|
"github.com/filecoin-project/sector-storage/zerocomm"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
"github.com/filecoin-project/sector-storage/zerocomm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting
|
// TODO: For now we handle this by halting state execution, when we get jsonrpc reconnecting
|
||||||
@ -41,8 +32,8 @@ type ErrInvalidProof struct{ error }
|
|||||||
// - Piece commitments match with on chain deals
|
// - Piece commitments match with on chain deals
|
||||||
// - Piece sizes match
|
// - Piece sizes match
|
||||||
// - Deals aren't expired
|
// - Deals aren't expired
|
||||||
func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error {
|
func checkPieces(ctx context.Context, si SectorInfo, api SealingAPI) error {
|
||||||
head, err := api.ChainHead(ctx)
|
tok, height, err := api.ChainHead(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ErrApi{xerrors.Errorf("getting chain head: %w", err)}
|
return &ErrApi{xerrors.Errorf("getting chain head: %w", err)}
|
||||||
}
|
}
|
||||||
@ -55,21 +46,21 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error {
|
|||||||
}
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
deal, err := api.StateMarketStorageDeal(ctx, *piece.DealID, types.EmptyTSK)
|
proposal, _, err := api.StateMarketStorageDeal(ctx, *piece.DealID, tok)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)}
|
return &ErrApi{xerrors.Errorf("getting deal %d for piece %d: %w", piece.DealID, i, err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if deal.Proposal.PieceCID != piece.CommP {
|
if proposal.PieceCID != piece.CommP {
|
||||||
return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorID, piece.DealID, piece.CommP, deal.Proposal.PieceCID)}
|
return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with wrong CommP: %x != %x", i, len(si.Pieces), si.SectorNumber, piece.DealID, piece.CommP, proposal.PieceCID)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if piece.Size != deal.Proposal.PieceSize.Unpadded() {
|
if piece.Size != proposal.PieceSize.Unpadded() {
|
||||||
return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorID, piece.DealID, piece.Size, deal.Proposal.PieceSize)}
|
return &ErrInvalidDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers deal %d with different size: %d != %d", i, len(si.Pieces), si.SectorNumber, piece.DealID, piece.Size, proposal.PieceSize)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if head.Height() >= deal.Proposal.StartEpoch {
|
if height >= proposal.StartEpoch {
|
||||||
return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorID, piece.DealID, deal.Proposal.StartEpoch, head.Height())}
|
return &ErrExpiredDeals{xerrors.Errorf("piece %d (or %d) of sector %d refers expired deal %d - should start at %d, head %d", i, len(si.Pieces), si.SectorNumber, piece.DealID, proposal.StartEpoch, height)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,82 +69,57 @@ func checkPieces(ctx context.Context, si SectorInfo, api sealingApi) error {
|
|||||||
|
|
||||||
// checkPrecommit checks that data commitment generated in the sealing process
|
// checkPrecommit checks that data commitment generated in the sealing process
|
||||||
// matches pieces, and that the seal ticket isn't expired
|
// matches pieces, and that the seal ticket isn't expired
|
||||||
func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, api sealingApi) (err error) {
|
func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, api SealingAPI) (err error) {
|
||||||
head, err := api.ChainHead(ctx)
|
tok, height, err := api.ChainHead(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ErrApi{xerrors.Errorf("getting chain head: %w", err)}
|
return &ErrApi{xerrors.Errorf("getting chain head: %w", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
ccparams, err := actors.SerializeParams(&market.ComputeDataCommitmentParams{
|
commD, err := api.StateComputeDataCommitment(ctx, maddr, si.SectorType, si.deals(), tok)
|
||||||
DealIDs: si.deals(),
|
|
||||||
SectorType: si.SectorType,
|
|
||||||
})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("computing params for ComputeDataCommitment: %w", err)
|
return &ErrApi{xerrors.Errorf("calling StateComputeDataCommitment: %w", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
ccmt := &types.Message{
|
if !commD.Equals(*si.CommD) {
|
||||||
To: builtin.StorageMarketActorAddr,
|
return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", commD, si.CommD)}
|
||||||
From: maddr,
|
|
||||||
Value: types.NewInt(0),
|
|
||||||
GasPrice: types.NewInt(0),
|
|
||||||
GasLimit: 9999999999,
|
|
||||||
Method: builtin.MethodsMarket.ComputeDataCommitment,
|
|
||||||
Params: ccparams,
|
|
||||||
}
|
|
||||||
r, err := api.StateCall(ctx, ccmt, types.EmptyTSK)
|
|
||||||
if err != nil {
|
|
||||||
return &ErrApi{xerrors.Errorf("calling ComputeDataCommitment: %w", err)}
|
|
||||||
}
|
|
||||||
if r.MsgRct.ExitCode != 0 {
|
|
||||||
return &ErrBadCommD{xerrors.Errorf("receipt for ComputeDataCommitment had exit code %d", r.MsgRct.ExitCode)}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var c cbg.CborCid
|
if int64(height)-int64(si.TicketEpoch+SealRandomnessLookback) > SealRandomnessLookbackLimit {
|
||||||
if err := c.UnmarshalCBOR(bytes.NewReader(r.MsgRct.Return)); err != nil {
|
return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.TicketEpoch+SealRandomnessLookback, height)}
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if cid.Cid(c) != *si.CommD {
|
|
||||||
return &ErrBadCommD{xerrors.Errorf("on chain CommD differs from sector: %s != %s", cid.Cid(c), si.CommD)}
|
|
||||||
}
|
|
||||||
|
|
||||||
if int64(head.Height())-int64(si.Ticket.Epoch+build.SealRandomnessLookback) > build.SealRandomnessLookbackLimit {
|
|
||||||
return &ErrExpiredTicket{xerrors.Errorf("ticket expired: seal height: %d, head: %d", si.Ticket.Epoch+build.SealRandomnessLookback, head.Height())}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) (err error) {
|
func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte) (err error) {
|
||||||
head, err := m.api.ChainHead(ctx)
|
tok, _, err := m.api.ChainHead(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ErrApi{xerrors.Errorf("getting chain head: %w", err)}
|
return &ErrApi{xerrors.Errorf("getting chain head: %w", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if si.Seed.Epoch == 0 {
|
if si.SeedEpoch == 0 {
|
||||||
return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")}
|
return &ErrBadSeed{xerrors.Errorf("seed epoch was not set")}
|
||||||
}
|
}
|
||||||
|
|
||||||
pci, err := m.api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorID, types.EmptyTSK)
|
pci, err := m.api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorNumber, tok)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("getting precommit info: %w", err)
|
return xerrors.Errorf("getting precommit info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if pci.PreCommitEpoch+miner.PreCommitChallengeDelay != si.Seed.Epoch {
|
if pci.PreCommitEpoch+miner.PreCommitChallengeDelay != si.SeedEpoch {
|
||||||
return &ErrBadSeed{xerrors.Errorf("seed epoch doesn't match on chain info: %d != %d", pci.PreCommitEpoch+miner.PreCommitChallengeDelay, si.Seed.Epoch)}
|
return &ErrBadSeed{xerrors.Errorf("seed epoch doesn't match on chain info: %d != %d", pci.PreCommitEpoch+miner.PreCommitChallengeDelay, si.SeedEpoch)}
|
||||||
}
|
}
|
||||||
|
|
||||||
seed, err := m.api.ChainGetRandomness(ctx, head.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.Seed.Epoch, nil)
|
seed, err := m.api.ChainGetRandomness(ctx, tok, crypto.DomainSeparationTag_InteractiveSealChallengeSeed, si.SeedEpoch, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ErrApi{xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)}
|
return &ErrApi{xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)}
|
||||||
}
|
}
|
||||||
|
|
||||||
if string(seed) != string(si.Seed.Value) {
|
if string(seed) != string(si.SeedValue) {
|
||||||
return &ErrBadSeed{xerrors.Errorf("seed has changed")}
|
return &ErrBadSeed{xerrors.Errorf("seed has changed")}
|
||||||
}
|
}
|
||||||
|
|
||||||
ss, err := m.api.StateMinerSectorSize(ctx, m.maddr, head.Key())
|
ss, err := m.api.StateMinerSectorSize(ctx, m.maddr, tok)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &ErrApi{err}
|
return &ErrApi{err}
|
||||||
}
|
}
|
||||||
@ -167,17 +133,17 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ok, err := m.verif.VerifySeal(abi.SealVerifyInfo{
|
ok, err := m.verif.VerifySeal(abi.SealVerifyInfo{
|
||||||
SectorID: m.minerSector(si.SectorID),
|
SectorID: m.minerSector(si.SectorNumber),
|
||||||
OnChain: abi.OnChainSealVerifyInfo{
|
OnChain: abi.OnChainSealVerifyInfo{
|
||||||
SealedCID: pci.Info.SealedCID,
|
SealedCID: pci.Info.SealedCID,
|
||||||
InteractiveEpoch: si.Seed.Epoch,
|
InteractiveEpoch: si.SeedEpoch,
|
||||||
RegisteredProof: spt,
|
RegisteredProof: spt,
|
||||||
Proof: proof,
|
Proof: proof,
|
||||||
SectorNumber: si.SectorID,
|
SectorNumber: si.SectorNumber,
|
||||||
SealRandEpoch: si.Ticket.Epoch,
|
SealRandEpoch: si.TicketEpoch,
|
||||||
},
|
},
|
||||||
Randomness: si.Ticket.Value,
|
Randomness: si.TicketValue,
|
||||||
InteractiveRandomness: si.Seed.Value,
|
InteractiveRandomness: si.SeedValue,
|
||||||
UnsealedCID: *si.CommD,
|
UnsealedCID: *si.CommD,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
13
storage/sealing/constants.go
Normal file
13
storage/sealing/constants.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package sealing
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const Finality = 500
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const SealRandomnessLookback = Finality
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
|
||||||
|
|
||||||
|
// Epochs
|
||||||
|
const InteractivePoRepConfidence = 6
|
15
storage/sealing/events.go
Normal file
15
storage/sealing/events.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package sealing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
)
|
||||||
|
|
||||||
|
// `curH`-`ts.Height` = `confidence`
|
||||||
|
type HeightHandler func(ctx context.Context, tok TipSetToken, curH abi.ChainEpoch) error
|
||||||
|
type RevertHandler func(ctx context.Context, tok TipSetToken) error
|
||||||
|
|
||||||
|
type Events interface {
|
||||||
|
ChainAt(hnd HeightHandler, rev RevertHandler, confidence int, h abi.ChainEpoch) error
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package sealing
|
package sealing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -9,10 +10,8 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-statemachine"
|
statemachine "github.com/filecoin-project/go-statemachine"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, uint64, error) {
|
func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface{}, uint64, error) {
|
||||||
@ -24,7 +23,7 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface
|
|||||||
return func(ctx statemachine.Context, si SectorInfo) error {
|
return func(ctx statemachine.Context, si SectorInfo) error {
|
||||||
err := next(ctx, si)
|
err := next(ctx, si)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("unhandled sector error (%d): %+v", si.SectorID, err)
|
log.Errorf("unhandled sector error (%d): %+v", si.SectorNumber, err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,65 +31,65 @@ func (m *Sealing) Plan(events []statemachine.Event, user interface{}) (interface
|
|||||||
}, uint64(len(events)), nil // TODO: This processed event count is not very correct
|
}, uint64(len(events)), nil // TODO: This processed event count is not very correct
|
||||||
}
|
}
|
||||||
|
|
||||||
var fsmPlanners = map[api.SectorState]func(events []statemachine.Event, state *SectorInfo) error{
|
var fsmPlanners = map[SectorState]func(events []statemachine.Event, state *SectorInfo) error{
|
||||||
api.UndefinedSectorState: planOne(on(SectorStart{}, api.Packing)),
|
UndefinedSectorState: planOne(on(SectorStart{}, Packing)),
|
||||||
api.Packing: planOne(on(SectorPacked{}, api.PreCommit1)),
|
Packing: planOne(on(SectorPacked{}, PreCommit1)),
|
||||||
api.PreCommit1: planOne(
|
PreCommit1: planOne(
|
||||||
on(SectorPreCommit1{}, api.PreCommit2),
|
on(SectorPreCommit1{}, PreCommit2),
|
||||||
on(SectorSealPreCommitFailed{}, api.SealFailed),
|
on(SectorSealPreCommitFailed{}, SealFailed),
|
||||||
on(SectorPackingFailed{}, api.PackingFailed),
|
on(SectorPackingFailed{}, PackingFailed),
|
||||||
),
|
),
|
||||||
api.PreCommit2: planOne(
|
PreCommit2: planOne(
|
||||||
on(SectorPreCommit2{}, api.PreCommitting),
|
on(SectorPreCommit2{}, PreCommitting),
|
||||||
on(SectorSealPreCommitFailed{}, api.SealFailed),
|
on(SectorSealPreCommitFailed{}, SealFailed),
|
||||||
on(SectorPackingFailed{}, api.PackingFailed),
|
on(SectorPackingFailed{}, PackingFailed),
|
||||||
),
|
),
|
||||||
api.PreCommitting: planOne(
|
PreCommitting: planOne(
|
||||||
on(SectorSealPreCommitFailed{}, api.SealFailed),
|
on(SectorSealPreCommitFailed{}, SealFailed),
|
||||||
on(SectorPreCommitted{}, api.WaitSeed),
|
on(SectorPreCommitted{}, WaitSeed),
|
||||||
on(SectorChainPreCommitFailed{}, api.PreCommitFailed),
|
on(SectorChainPreCommitFailed{}, PreCommitFailed),
|
||||||
),
|
),
|
||||||
api.WaitSeed: planOne(
|
WaitSeed: planOne(
|
||||||
on(SectorSeedReady{}, api.Committing),
|
on(SectorSeedReady{}, Committing),
|
||||||
on(SectorChainPreCommitFailed{}, api.PreCommitFailed),
|
on(SectorChainPreCommitFailed{}, PreCommitFailed),
|
||||||
),
|
),
|
||||||
api.Committing: planCommitting,
|
Committing: planCommitting,
|
||||||
api.CommitWait: planOne(
|
CommitWait: planOne(
|
||||||
on(SectorProving{}, api.FinalizeSector),
|
on(SectorProving{}, FinalizeSector),
|
||||||
on(SectorCommitFailed{}, api.CommitFailed),
|
on(SectorCommitFailed{}, CommitFailed),
|
||||||
),
|
),
|
||||||
|
|
||||||
api.FinalizeSector: planOne(
|
FinalizeSector: planOne(
|
||||||
on(SectorFinalized{}, api.Proving),
|
on(SectorFinalized{}, Proving),
|
||||||
),
|
),
|
||||||
|
|
||||||
api.Proving: planOne(
|
Proving: planOne(
|
||||||
on(SectorFaultReported{}, api.FaultReported),
|
on(SectorFaultReported{}, FaultReported),
|
||||||
on(SectorFaulty{}, api.Faulty),
|
on(SectorFaulty{}, Faulty),
|
||||||
),
|
),
|
||||||
|
|
||||||
api.SealFailed: planOne(
|
SealFailed: planOne(
|
||||||
on(SectorRetrySeal{}, api.PreCommit1),
|
on(SectorRetrySeal{}, PreCommit1),
|
||||||
),
|
),
|
||||||
api.PreCommitFailed: planOne(
|
PreCommitFailed: planOne(
|
||||||
on(SectorRetryPreCommit{}, api.PreCommitting),
|
on(SectorRetryPreCommit{}, PreCommitting),
|
||||||
on(SectorRetryWaitSeed{}, api.WaitSeed),
|
on(SectorRetryWaitSeed{}, WaitSeed),
|
||||||
on(SectorSealPreCommitFailed{}, api.SealFailed),
|
on(SectorSealPreCommitFailed{}, SealFailed),
|
||||||
),
|
),
|
||||||
api.ComputeProofFailed: planOne(
|
ComputeProofFailed: planOne(
|
||||||
on(SectorRetryComputeProof{}, api.Committing),
|
on(SectorRetryComputeProof{}, Committing),
|
||||||
),
|
),
|
||||||
api.CommitFailed: planOne(
|
CommitFailed: planOne(
|
||||||
on(SectorSealPreCommitFailed{}, api.SealFailed),
|
on(SectorSealPreCommitFailed{}, SealFailed),
|
||||||
on(SectorRetryWaitSeed{}, api.WaitSeed),
|
on(SectorRetryWaitSeed{}, WaitSeed),
|
||||||
on(SectorRetryComputeProof{}, api.Committing),
|
on(SectorRetryComputeProof{}, Committing),
|
||||||
on(SectorRetryInvalidProof{}, api.Committing),
|
on(SectorRetryInvalidProof{}, Committing),
|
||||||
),
|
),
|
||||||
|
|
||||||
api.Faulty: planOne(
|
Faulty: planOne(
|
||||||
on(SectorFaultReported{}, api.FaultReported),
|
on(SectorFaultReported{}, FaultReported),
|
||||||
),
|
),
|
||||||
api.FaultedFinal: final,
|
FaultedFinal: final,
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(statemachine.Context, SectorInfo) error, error) {
|
func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(statemachine.Context, SectorInfo) error, error) {
|
||||||
@ -170,47 +169,47 @@ func (m *Sealing) plan(events []statemachine.Event, state *SectorInfo) (func(sta
|
|||||||
|
|
||||||
switch state.State {
|
switch state.State {
|
||||||
// Happy path
|
// Happy path
|
||||||
case api.Packing:
|
case Packing:
|
||||||
return m.handlePacking, nil
|
return m.handlePacking, nil
|
||||||
case api.PreCommit1:
|
case PreCommit1:
|
||||||
return m.handlePreCommit1, nil
|
return m.handlePreCommit1, nil
|
||||||
case api.PreCommit2:
|
case PreCommit2:
|
||||||
return m.handlePreCommit2, nil
|
return m.handlePreCommit2, nil
|
||||||
case api.PreCommitting:
|
case PreCommitting:
|
||||||
return m.handlePreCommitting, nil
|
return m.handlePreCommitting, nil
|
||||||
case api.WaitSeed:
|
case WaitSeed:
|
||||||
return m.handleWaitSeed, nil
|
return m.handleWaitSeed, nil
|
||||||
case api.Committing:
|
case Committing:
|
||||||
return m.handleCommitting, nil
|
return m.handleCommitting, nil
|
||||||
case api.CommitWait:
|
case CommitWait:
|
||||||
return m.handleCommitWait, nil
|
return m.handleCommitWait, nil
|
||||||
case api.FinalizeSector:
|
case FinalizeSector:
|
||||||
return m.handleFinalizeSector, nil
|
return m.handleFinalizeSector, nil
|
||||||
case api.Proving:
|
case Proving:
|
||||||
// TODO: track sector health / expiration
|
// TODO: track sector health / expiration
|
||||||
log.Infof("Proving sector %d", state.SectorID)
|
log.Infof("Proving sector %d", state.SectorNumber)
|
||||||
|
|
||||||
// Handled failure modes
|
// Handled failure modes
|
||||||
case api.SealFailed:
|
case SealFailed:
|
||||||
return m.handleSealFailed, nil
|
return m.handleSealFailed, nil
|
||||||
case api.PreCommitFailed:
|
case PreCommitFailed:
|
||||||
return m.handlePreCommitFailed, nil
|
return m.handlePreCommitFailed, nil
|
||||||
case api.ComputeProofFailed:
|
case ComputeProofFailed:
|
||||||
return m.handleComputeProofFailed, nil
|
return m.handleComputeProofFailed, nil
|
||||||
case api.CommitFailed:
|
case CommitFailed:
|
||||||
return m.handleCommitFailed, nil
|
return m.handleCommitFailed, nil
|
||||||
|
|
||||||
// Faults
|
// Faults
|
||||||
case api.Faulty:
|
case Faulty:
|
||||||
return m.handleFaulty, nil
|
return m.handleFaulty, nil
|
||||||
case api.FaultReported:
|
case FaultReported:
|
||||||
return m.handleFaultReported, nil
|
return m.handleFaultReported, nil
|
||||||
|
|
||||||
// Fatal errors
|
// Fatal errors
|
||||||
case api.UndefinedSectorState:
|
case UndefinedSectorState:
|
||||||
log.Error("sector update with undefined state!")
|
log.Error("sector update with undefined state!")
|
||||||
case api.FailedUnrecoverable:
|
case FailedUnrecoverable:
|
||||||
log.Errorf("sector %d failed unrecoverably", state.SectorID)
|
log.Errorf("sector %d failed unrecoverably", state.SectorNumber)
|
||||||
default:
|
default:
|
||||||
log.Errorf("unexpected sector update state: %d", state.State)
|
log.Errorf("unexpected sector update state: %d", state.State)
|
||||||
}
|
}
|
||||||
@ -227,22 +226,22 @@ func planCommitting(events []statemachine.Event, state *SectorInfo) error {
|
|||||||
}
|
}
|
||||||
case SectorCommitted: // the normal case
|
case SectorCommitted: // the normal case
|
||||||
e.apply(state)
|
e.apply(state)
|
||||||
state.State = api.CommitWait
|
state.State = CommitWait
|
||||||
case SectorSeedReady: // seed changed :/
|
case SectorSeedReady: // seed changed :/
|
||||||
if e.Seed.Equals(&state.Seed) {
|
if e.SeedEpoch == state.SeedEpoch && bytes.Equal(e.SeedValue, state.SeedValue) {
|
||||||
log.Warnf("planCommitting: got SectorSeedReady, but the seed didn't change")
|
log.Warnf("planCommitting: got SectorSeedReady, but the seed didn't change")
|
||||||
continue // or it didn't!
|
continue // or it didn't!
|
||||||
}
|
}
|
||||||
log.Warnf("planCommitting: commit Seed changed")
|
log.Warnf("planCommitting: commit Seed changed")
|
||||||
e.apply(state)
|
e.apply(state)
|
||||||
state.State = api.Committing
|
state.State = Committing
|
||||||
return nil
|
return nil
|
||||||
case SectorComputeProofFailed:
|
case SectorComputeProofFailed:
|
||||||
state.State = api.ComputeProofFailed
|
state.State = ComputeProofFailed
|
||||||
case SectorSealPreCommitFailed:
|
case SectorSealPreCommitFailed:
|
||||||
state.State = api.CommitFailed
|
state.State = CommitFailed
|
||||||
case SectorCommitFailed:
|
case SectorCommitFailed:
|
||||||
state.State = api.CommitFailed
|
state.State = CommitFailed
|
||||||
default:
|
default:
|
||||||
return xerrors.Errorf("planCommitting got event of unknown type %T, events: %+v", event.User, events)
|
return xerrors.Errorf("planCommitting got event of unknown type %T, events: %+v", event.User, events)
|
||||||
}
|
}
|
||||||
@ -257,8 +256,8 @@ func (m *Sealing) restartSectors(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, sector := range trackedSectors {
|
for _, sector := range trackedSectors {
|
||||||
if err := m.sectors.Send(uint64(sector.SectorID), SectorRestart{}); err != nil {
|
if err := m.sectors.Send(uint64(sector.SectorNumber), SectorRestart{}); err != nil {
|
||||||
log.Errorf("restarting sector %d: %+v", sector.SectorID, err)
|
log.Errorf("restarting sector %d: %+v", sector.SectorNumber, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +266,7 @@ func (m *Sealing) restartSectors(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, state api.SectorState) error {
|
func (m *Sealing) ForceSectorState(ctx context.Context, id abi.SectorNumber, state SectorState) error {
|
||||||
return m.sectors.Send(id, SectorForceState{state})
|
return m.sectors.Send(id, SectorForceState{state})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,13 +274,13 @@ func final(events []statemachine.Event, state *SectorInfo) error {
|
|||||||
return xerrors.Errorf("didn't expect any events in state %s, got %+v", state.State, events)
|
return xerrors.Errorf("didn't expect any events in state %s, got %+v", state.State, events)
|
||||||
}
|
}
|
||||||
|
|
||||||
func on(mut mutator, next api.SectorState) func() (mutator, api.SectorState) {
|
func on(mut mutator, next SectorState) func() (mutator, SectorState) {
|
||||||
return func() (mutator, api.SectorState) {
|
return func() (mutator, SectorState) {
|
||||||
return mut, next
|
return mut, next
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []statemachine.Event, state *SectorInfo) error {
|
func planOne(ts ...func() (mut mutator, next SectorState)) func(events []statemachine.Event, state *SectorInfo) error {
|
||||||
return func(events []statemachine.Event, state *SectorInfo) error {
|
return func(events []statemachine.Event, state *SectorInfo) error {
|
||||||
if len(events) != 1 {
|
if len(events) != 1 {
|
||||||
for _, event := range events {
|
for _, event := range events {
|
||||||
@ -306,7 +305,7 @@ func planOne(ts ...func() (mut mutator, next api.SectorState)) func(events []sta
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err, iserr := events[0].User.(error); iserr {
|
if err, iserr := events[0].User.(error); iserr {
|
||||||
log.Warnf("sector %d got error event %T: %+v", state.SectorID, events[0].User, err)
|
log.Warnf("sector %d got error event %T: %+v", state.SectorNumber, events[0].User, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
events[0].User.(mutator).apply(state)
|
events[0].User.(mutator).apply(state)
|
||||||
|
@ -5,8 +5,6 @@ import (
|
|||||||
"github.com/filecoin-project/specs-storage/storage"
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type mutator interface {
|
type mutator interface {
|
||||||
@ -31,7 +29,7 @@ type SectorFatalError struct{ error }
|
|||||||
func (evt SectorFatalError) FormatError(xerrors.Printer) (next error) { return evt.error }
|
func (evt SectorFatalError) FormatError(xerrors.Printer) (next error) { return evt.error }
|
||||||
|
|
||||||
func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool {
|
func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool {
|
||||||
log.Errorf("Fatal error on sector %d: %+v", state.SectorID, evt.error)
|
log.Errorf("Fatal error on sector %d: %+v", state.SectorNumber, evt.error)
|
||||||
// TODO: Do we want to mark the state as unrecoverable?
|
// TODO: Do we want to mark the state as unrecoverable?
|
||||||
// I feel like this should be a softer error, where the user would
|
// I feel like this should be a softer error, where the user would
|
||||||
// be able to send a retry event of some kind
|
// be able to send a retry event of some kind
|
||||||
@ -39,7 +37,7 @@ func (evt SectorFatalError) applyGlobal(state *SectorInfo) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SectorForceState struct {
|
type SectorForceState struct {
|
||||||
State api.SectorState
|
State SectorState
|
||||||
}
|
}
|
||||||
|
|
||||||
func (evt SectorForceState) applyGlobal(state *SectorInfo) bool {
|
func (evt SectorForceState) applyGlobal(state *SectorInfo) bool {
|
||||||
@ -56,7 +54,7 @@ type SectorStart struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (evt SectorStart) apply(state *SectorInfo) {
|
func (evt SectorStart) apply(state *SectorInfo) {
|
||||||
state.SectorID = evt.ID
|
state.SectorNumber = evt.ID
|
||||||
state.Pieces = evt.Pieces
|
state.Pieces = evt.Pieces
|
||||||
state.SectorType = evt.SectorType
|
state.SectorType = evt.SectorType
|
||||||
}
|
}
|
||||||
@ -73,12 +71,14 @@ func (evt SectorPackingFailed) apply(*SectorInfo) {}
|
|||||||
|
|
||||||
type SectorPreCommit1 struct {
|
type SectorPreCommit1 struct {
|
||||||
PreCommit1Out storage.PreCommit1Out
|
PreCommit1Out storage.PreCommit1Out
|
||||||
Ticket api.SealTicket
|
TicketValue abi.SealRandomness
|
||||||
|
TicketEpoch abi.ChainEpoch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (evt SectorPreCommit1) apply(state *SectorInfo) {
|
func (evt SectorPreCommit1) apply(state *SectorInfo) {
|
||||||
state.PreCommit1Out = evt.PreCommit1Out
|
state.PreCommit1Out = evt.PreCommit1Out
|
||||||
state.Ticket = evt.Ticket
|
state.TicketEpoch = evt.TicketEpoch
|
||||||
|
state.TicketValue = evt.TicketValue
|
||||||
}
|
}
|
||||||
|
|
||||||
type SectorPreCommit2 struct {
|
type SectorPreCommit2 struct {
|
||||||
@ -114,11 +114,13 @@ func (evt SectorPreCommitted) apply(state *SectorInfo) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SectorSeedReady struct {
|
type SectorSeedReady struct {
|
||||||
Seed api.SealSeed
|
SeedValue abi.InteractiveSealRandomness
|
||||||
|
SeedEpoch abi.ChainEpoch
|
||||||
}
|
}
|
||||||
|
|
||||||
func (evt SectorSeedReady) apply(state *SectorInfo) {
|
func (evt SectorSeedReady) apply(state *SectorInfo) {
|
||||||
state.Seed = evt.Seed
|
state.SeedEpoch = evt.SeedEpoch
|
||||||
|
state.SeedValue = evt.SeedValue
|
||||||
}
|
}
|
||||||
|
|
||||||
type SectorComputeProofFailed struct{ error }
|
type SectorComputeProofFailed struct{ error }
|
||||||
|
@ -7,8 +7,6 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-statemachine"
|
"github.com/filecoin-project/go-statemachine"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -32,81 +30,81 @@ func TestHappyPath(t *testing.T) {
|
|||||||
m := test{
|
m := test{
|
||||||
s: &Sealing{},
|
s: &Sealing{},
|
||||||
t: t,
|
t: t,
|
||||||
state: &SectorInfo{State: api.Packing},
|
state: &SectorInfo{State: Packing},
|
||||||
}
|
}
|
||||||
|
|
||||||
m.planSingle(SectorPacked{})
|
m.planSingle(SectorPacked{})
|
||||||
require.Equal(m.t, m.state.State, api.PreCommit1)
|
require.Equal(m.t, m.state.State, PreCommit1)
|
||||||
|
|
||||||
m.planSingle(SectorPreCommit1{})
|
m.planSingle(SectorPreCommit1{})
|
||||||
require.Equal(m.t, m.state.State, api.PreCommit2)
|
require.Equal(m.t, m.state.State, PreCommit2)
|
||||||
|
|
||||||
m.planSingle(SectorPreCommit2{})
|
m.planSingle(SectorPreCommit2{})
|
||||||
require.Equal(m.t, m.state.State, api.PreCommitting)
|
require.Equal(m.t, m.state.State, PreCommitting)
|
||||||
|
|
||||||
m.planSingle(SectorPreCommitted{})
|
m.planSingle(SectorPreCommitted{})
|
||||||
require.Equal(m.t, m.state.State, api.WaitSeed)
|
require.Equal(m.t, m.state.State, WaitSeed)
|
||||||
|
|
||||||
m.planSingle(SectorSeedReady{})
|
m.planSingle(SectorSeedReady{})
|
||||||
require.Equal(m.t, m.state.State, api.Committing)
|
require.Equal(m.t, m.state.State, Committing)
|
||||||
|
|
||||||
m.planSingle(SectorCommitted{})
|
m.planSingle(SectorCommitted{})
|
||||||
require.Equal(m.t, m.state.State, api.CommitWait)
|
require.Equal(m.t, m.state.State, CommitWait)
|
||||||
|
|
||||||
m.planSingle(SectorProving{})
|
m.planSingle(SectorProving{})
|
||||||
require.Equal(m.t, m.state.State, api.FinalizeSector)
|
require.Equal(m.t, m.state.State, FinalizeSector)
|
||||||
|
|
||||||
m.planSingle(SectorFinalized{})
|
m.planSingle(SectorFinalized{})
|
||||||
require.Equal(m.t, m.state.State, api.Proving)
|
require.Equal(m.t, m.state.State, Proving)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSeedRevert(t *testing.T) {
|
func TestSeedRevert(t *testing.T) {
|
||||||
m := test{
|
m := test{
|
||||||
s: &Sealing{},
|
s: &Sealing{},
|
||||||
t: t,
|
t: t,
|
||||||
state: &SectorInfo{State: api.Packing},
|
state: &SectorInfo{State: Packing},
|
||||||
}
|
}
|
||||||
|
|
||||||
m.planSingle(SectorPacked{})
|
m.planSingle(SectorPacked{})
|
||||||
require.Equal(m.t, m.state.State, api.PreCommit1)
|
require.Equal(m.t, m.state.State, PreCommit1)
|
||||||
|
|
||||||
m.planSingle(SectorPreCommit1{})
|
m.planSingle(SectorPreCommit1{})
|
||||||
require.Equal(m.t, m.state.State, api.PreCommit2)
|
require.Equal(m.t, m.state.State, PreCommit2)
|
||||||
|
|
||||||
m.planSingle(SectorPreCommit2{})
|
m.planSingle(SectorPreCommit2{})
|
||||||
require.Equal(m.t, m.state.State, api.PreCommitting)
|
require.Equal(m.t, m.state.State, PreCommitting)
|
||||||
|
|
||||||
m.planSingle(SectorPreCommitted{})
|
m.planSingle(SectorPreCommitted{})
|
||||||
require.Equal(m.t, m.state.State, api.WaitSeed)
|
require.Equal(m.t, m.state.State, WaitSeed)
|
||||||
|
|
||||||
m.planSingle(SectorSeedReady{})
|
m.planSingle(SectorSeedReady{})
|
||||||
require.Equal(m.t, m.state.State, api.Committing)
|
require.Equal(m.t, m.state.State, Committing)
|
||||||
|
|
||||||
_, err := m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state)
|
_, err := m.s.plan([]statemachine.Event{{SectorSeedReady{SeedValue: nil, SeedEpoch: 5}}, {SectorCommitted{}}}, m.state)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(m.t, m.state.State, api.Committing)
|
require.Equal(m.t, m.state.State, Committing)
|
||||||
|
|
||||||
// not changing the seed this time
|
// not changing the seed this time
|
||||||
_, err = m.s.plan([]statemachine.Event{{SectorSeedReady{Seed: api.SealSeed{Epoch: 5}}}, {SectorCommitted{}}}, m.state)
|
_, err = m.s.plan([]statemachine.Event{{SectorSeedReady{SeedValue: nil, SeedEpoch: 5}}, {SectorCommitted{}}}, m.state)
|
||||||
require.Equal(m.t, m.state.State, api.CommitWait)
|
require.Equal(m.t, m.state.State, CommitWait)
|
||||||
|
|
||||||
m.planSingle(SectorProving{})
|
m.planSingle(SectorProving{})
|
||||||
require.Equal(m.t, m.state.State, api.FinalizeSector)
|
require.Equal(m.t, m.state.State, FinalizeSector)
|
||||||
|
|
||||||
m.planSingle(SectorFinalized{})
|
m.planSingle(SectorFinalized{})
|
||||||
require.Equal(m.t, m.state.State, api.Proving)
|
require.Equal(m.t, m.state.State, Proving)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPlanCommittingHandlesSectorCommitFailed(t *testing.T) {
|
func TestPlanCommittingHandlesSectorCommitFailed(t *testing.T) {
|
||||||
m := test{
|
m := test{
|
||||||
s: &Sealing{},
|
s: &Sealing{},
|
||||||
t: t,
|
t: t,
|
||||||
state: &SectorInfo{State: api.Committing},
|
state: &SectorInfo{State: Committing},
|
||||||
}
|
}
|
||||||
|
|
||||||
events := []statemachine.Event{{SectorCommitFailed{}}}
|
events := []statemachine.Event{{SectorCommitFailed{}}}
|
||||||
|
|
||||||
require.NoError(t, planCommitting(events, m.state))
|
require.NoError(t, planCommitting(events, m.state))
|
||||||
|
|
||||||
require.Equal(t, api.CommitFailed, m.state.State)
|
require.Equal(t, CommitFailed, m.state.State)
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@ package sealing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/lib/nullreader"
|
"github.com/filecoin-project/lotus/lib/nullreader"
|
||||||
|
@ -2,71 +2,45 @@ package sealing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
"github.com/ipfs/go-datastore/namespace"
|
"github.com/ipfs/go-datastore/namespace"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-padreader"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-statemachine"
|
padreader "github.com/filecoin-project/go-padreader"
|
||||||
|
statemachine "github.com/filecoin-project/go-statemachine"
|
||||||
|
sectorstorage "github.com/filecoin-project/sector-storage"
|
||||||
|
"github.com/filecoin-project/sector-storage/ffiwrapper"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin/market"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/lotus/chain/events"
|
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
"github.com/filecoin-project/sector-storage"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const SectorStorePrefix = "/sectors"
|
const SectorStorePrefix = "/sectors"
|
||||||
|
|
||||||
var log = logging.Logger("sectors")
|
var log = logging.Logger("sectors")
|
||||||
|
|
||||||
type TicketFn func(context.Context) (*api.SealTicket, error)
|
type SealingAPI interface {
|
||||||
|
StateWaitMsg(context.Context, cid.Cid) (MsgLookup, error)
|
||||||
type SectorIDCounter interface {
|
StateComputeDataCommitment(ctx context.Context, maddr address.Address, sectorType abi.RegisteredProof, deals []abi.DealID, tok TipSetToken) (cid.Cid, error)
|
||||||
Next() (abi.SectorNumber, error)
|
StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok TipSetToken) (*miner.SectorPreCommitOnChainInfo, error)
|
||||||
}
|
StateMinerSectorSize(context.Context, address.Address, TipSetToken) (abi.SectorSize, error)
|
||||||
|
StateMarketStorageDeal(context.Context, abi.DealID, TipSetToken) (market.DealProposal, market.DealState, error)
|
||||||
type sealingApi interface { // TODO: trim down
|
SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, gasPrice big.Int, gasLimit int64, params []byte) (cid.Cid, error)
|
||||||
// Call a read only method on actors (no interaction with the chain required)
|
ChainHead(ctx context.Context) (TipSetToken, abi.ChainEpoch, error)
|
||||||
StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error)
|
ChainGetRandomness(ctx context.Context, tok TipSetToken, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
||||||
StateMinerWorker(context.Context, address.Address, types.TipSetKey) (address.Address, error)
|
|
||||||
StateMinerPostState(ctx context.Context, actor address.Address, ts types.TipSetKey) (*miner.PoStState, error)
|
|
||||||
StateMinerSectors(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
|
|
||||||
StateMinerProvingSet(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error)
|
|
||||||
StateMinerSectorSize(context.Context, address.Address, types.TipSetKey) (abi.SectorSize, error)
|
|
||||||
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
|
|
||||||
StateWaitMsg(context.Context, cid.Cid) (*api.MsgLookup, error) // TODO: removeme eventually
|
|
||||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
|
||||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
|
||||||
StateMarketStorageDeal(context.Context, abi.DealID, types.TipSetKey) (*api.MarketDeal, error)
|
|
||||||
|
|
||||||
MpoolPushMessage(context.Context, *types.Message) (*types.SignedMessage, error)
|
|
||||||
|
|
||||||
ChainHead(context.Context) (*types.TipSet, error)
|
|
||||||
ChainNotify(context.Context) (<-chan []*store.HeadChange, error)
|
|
||||||
ChainGetRandomness(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error)
|
|
||||||
ChainGetTipSetByHeight(context.Context, abi.ChainEpoch, types.TipSetKey) (*types.TipSet, error)
|
|
||||||
ChainGetBlockMessages(context.Context, cid.Cid) (*api.BlockMessages, error)
|
|
||||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||||
ChainHasObj(context.Context, cid.Cid) (bool, error)
|
|
||||||
|
|
||||||
WalletSign(context.Context, address.Address, []byte) (*crypto.Signature, error)
|
|
||||||
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
|
||||||
WalletHas(context.Context, address.Address) (bool, error)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Sealing struct {
|
type Sealing struct {
|
||||||
api sealingApi
|
api SealingAPI
|
||||||
events *events.Events
|
events Events
|
||||||
|
|
||||||
maddr address.Address
|
maddr address.Address
|
||||||
worker address.Address
|
worker address.Address
|
||||||
@ -78,7 +52,7 @@ type Sealing struct {
|
|||||||
tktFn TicketFn
|
tktFn TicketFn
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(api sealingApi, events *events.Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, tktFn TicketFn) *Sealing {
|
func New(api SealingAPI, events Events, maddr address.Address, worker address.Address, ds datastore.Batching, sealer sectorstorage.SectorManager, sc SectorIDCounter, verif ffiwrapper.Verifier, tktFn TicketFn) *Sealing {
|
||||||
s := &Sealing{
|
s := &Sealing{
|
||||||
api: api,
|
api: api,
|
||||||
events: events,
|
events: events,
|
||||||
|
29
storage/sealing/sector_state.go
Normal file
29
storage/sealing/sector_state.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package sealing
|
||||||
|
|
||||||
|
type SectorState string
|
||||||
|
|
||||||
|
const (
|
||||||
|
UndefinedSectorState SectorState = ""
|
||||||
|
|
||||||
|
// happy path
|
||||||
|
Empty SectorState = "Empty"
|
||||||
|
Packing SectorState = "Packing" // sector not in sealStore, and not on chain
|
||||||
|
PreCommit1 SectorState = "PreCommit1" // do PreCommit1
|
||||||
|
PreCommit2 SectorState = "PreCommit2" // do PreCommit1
|
||||||
|
PreCommitting SectorState = "PreCommitting" // on chain pre-commit
|
||||||
|
WaitSeed SectorState = "WaitSeed" // waiting for seed
|
||||||
|
Committing SectorState = "Committing"
|
||||||
|
CommitWait SectorState = "CommitWait" // waiting for message to land on chain
|
||||||
|
FinalizeSector SectorState = "FinalizeSector"
|
||||||
|
Proving SectorState = "Proving"
|
||||||
|
// error modes
|
||||||
|
FailedUnrecoverable SectorState = "FailedUnrecoverable"
|
||||||
|
SealFailed SectorState = "SealFailed"
|
||||||
|
PreCommitFailed SectorState = "PreCommitFailed"
|
||||||
|
ComputeProofFailed SectorState = "ComputeProofFailed"
|
||||||
|
CommitFailed SectorState = "CommitFailed"
|
||||||
|
PackingFailed SectorState = "PackingFailed"
|
||||||
|
Faulty SectorState = "Faulty" // sector is corrupted or gone for some reason
|
||||||
|
FaultReported SectorState = "FaultReported" // sector has been declared as a fault on chain
|
||||||
|
FaultedFinal SectorState = "FaultedFinal" // fault declared on chain
|
||||||
|
)
|
@ -1,25 +1,22 @@
|
|||||||
package sealing
|
package sealing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"github.com/filecoin-project/specs-storage/storage"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/crypto"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-statemachine"
|
"github.com/filecoin-project/go-statemachine"
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi/big"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"golang.org/x/xerrors"
|
"github.com/filecoin-project/specs-actors/actors/crypto"
|
||||||
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/lotus/build"
|
|
||||||
"github.com/filecoin-project/lotus/chain/actors"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
log.Infow("performing filling up rest of the sector...", "sector", sector.SectorID)
|
log.Infow("performing filling up rest of the sector...", "sector", sector.SectorNumber)
|
||||||
|
|
||||||
var allocated abi.UnpaddedPieceSize
|
var allocated abi.UnpaddedPieceSize
|
||||||
for _, piece := range sector.Pieces {
|
for _, piece := range sector.Pieces {
|
||||||
@ -38,10 +35,10 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(fillerSizes) > 0 {
|
if len(fillerSizes) > 0 {
|
||||||
log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorID)
|
log.Warnf("Creating %d filler pieces for sector %d", len(fillerSizes), sector.SectorNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
pieces, err := m.pledgeSector(ctx.Context(), m.minerSector(sector.SectorID), sector.existingPieces(), fillerSizes...)
|
pieces, err := m.pledgeSector(ctx.Context(), m.minerSector(sector.SectorNumber), sector.existingPieces(), fillerSizes...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err)
|
return xerrors.Errorf("filling up the sector (%v): %w", fillerSizes, err)
|
||||||
}
|
}
|
||||||
@ -64,25 +61,26 @@ func (m *Sealing) handlePreCommit1(ctx statemachine.Context, sector SectorInfo)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infow("performing sector replication...", "sector", sector.SectorID)
|
log.Infow("performing sector replication...", "sector", sector.SectorNumber)
|
||||||
ticket, err := m.tktFn(ctx.Context())
|
ticketValue, ticketEpoch, err := m.tktFn(ctx.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("getting ticket failed: %w", err)})
|
return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("getting ticket failed: %w", err)})
|
||||||
}
|
}
|
||||||
|
|
||||||
pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorID), ticket.Value, sector.pieceInfos())
|
pc1o, err := m.sealer.SealPreCommit1(ctx.Context(), m.minerSector(sector.SectorNumber), ticketValue, sector.pieceInfos())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(1) failed: %w", err)})
|
return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(1) failed: %w", err)})
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.Send(SectorPreCommit1{
|
return ctx.Send(SectorPreCommit1{
|
||||||
PreCommit1Out: pc1o,
|
PreCommit1Out: pc1o,
|
||||||
Ticket: *ticket,
|
TicketValue: ticketValue,
|
||||||
|
TicketEpoch: ticketEpoch,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) handlePreCommit2(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handlePreCommit2(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
cids, err := m.sealer.SealPreCommit2(ctx.Context(), m.minerSector(sector.SectorID), sector.PreCommit1Out)
|
cids, err := m.sealer.SealPreCommit2(ctx.Context(), m.minerSector(sector.SectorNumber), sector.PreCommit1Out)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(2) failed: %w", err)})
|
return ctx.Send(SectorSealPreCommitFailed{xerrors.Errorf("seal pre commit(2) failed: %w", err)})
|
||||||
}
|
}
|
||||||
@ -94,7 +92,7 @@ func (m *Sealing) handlePreCommit2(ctx statemachine.Context, sector SectorInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
if err := checkPrecommit(ctx.Context(), m.maddr, sector, m.api); err != nil {
|
if err := checkPrecommit(ctx.Context(), m.Address(), sector, m.api); err != nil {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case *ErrApi:
|
case *ErrApi:
|
||||||
log.Errorf("handlePreCommitting: api error, not proceeding: %+v", err)
|
log.Errorf("handlePreCommitting: api error, not proceeding: %+v", err)
|
||||||
@ -110,40 +108,31 @@ func (m *Sealing) handlePreCommitting(ctx statemachine.Context, sector SectorInf
|
|||||||
|
|
||||||
params := &miner.SectorPreCommitInfo{
|
params := &miner.SectorPreCommitInfo{
|
||||||
Expiration: 10000000, // TODO: implement
|
Expiration: 10000000, // TODO: implement
|
||||||
SectorNumber: sector.SectorID,
|
SectorNumber: sector.SectorNumber,
|
||||||
RegisteredProof: sector.SectorType,
|
RegisteredProof: sector.SectorType,
|
||||||
|
|
||||||
SealedCID: *sector.CommR,
|
SealedCID: *sector.CommR,
|
||||||
SealRandEpoch: sector.Ticket.Epoch,
|
SealRandEpoch: sector.TicketEpoch,
|
||||||
DealIDs: sector.deals(),
|
DealIDs: sector.deals(),
|
||||||
}
|
}
|
||||||
enc, aerr := actors.SerializeParams(params)
|
|
||||||
if aerr != nil {
|
enc := new(bytes.Buffer)
|
||||||
return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)})
|
if err := params.MarshalCBOR(enc); err != nil {
|
||||||
|
return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("could not serialize pre-commit sector parameters: %w", err)})
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := &types.Message{
|
log.Info("submitting precommit for sector: ", sector.SectorNumber)
|
||||||
To: m.maddr,
|
mcid, err := m.api.SendMsg(ctx.Context(), m.worker, m.maddr, builtin.MethodsMiner.PreCommitSector, big.NewInt(0), big.NewInt(1), 1000000, enc.Bytes())
|
||||||
From: m.worker,
|
|
||||||
Method: builtin.MethodsMiner.PreCommitSector,
|
|
||||||
Params: enc,
|
|
||||||
Value: types.NewInt(0), // TODO: need to ensure sufficient collateral
|
|
||||||
GasLimit: 1000000, /* i dont know help */
|
|
||||||
GasPrice: types.NewInt(1),
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("submitting precommit for sector: ", sector.SectorID)
|
|
||||||
smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)})
|
return ctx.Send(SectorChainPreCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)})
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.Send(SectorPreCommitted{Message: smsg.Cid()})
|
return ctx.Send(SectorPreCommitted{Message: mcid})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
// would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts
|
// would be ideal to just use the events.Called handler, but it wouldnt be able to handle individual message timeouts
|
||||||
log.Info("Sector precommitted: ", sector.SectorID)
|
log.Info("Sector precommitted: ", sector.SectorNumber)
|
||||||
mw, err := m.api.StateWaitMsg(ctx.Context(), *sector.PreCommitMessage)
|
mw, err := m.api.StateWaitMsg(ctx.Context(), *sector.PreCommitMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Send(SectorChainPreCommitFailed{err})
|
return ctx.Send(SectorChainPreCommitFailed{err})
|
||||||
@ -154,36 +143,32 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er
|
|||||||
err := xerrors.Errorf("sector precommit failed: %d", mw.Receipt.ExitCode)
|
err := xerrors.Errorf("sector precommit failed: %d", mw.Receipt.ExitCode)
|
||||||
return ctx.Send(SectorChainPreCommitFailed{err})
|
return ctx.Send(SectorChainPreCommitFailed{err})
|
||||||
}
|
}
|
||||||
log.Info("precommit message landed on chain: ", sector.SectorID)
|
log.Info("precommit message landed on chain: ", sector.SectorNumber)
|
||||||
|
|
||||||
pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorID, mw.TipSet.Key())
|
pci, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorNumber, mw.TipSetTok)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("getting precommit info: %w", err)
|
return xerrors.Errorf("getting precommit info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
randHeight := pci.PreCommitEpoch + miner.PreCommitChallengeDelay
|
randHeight := pci.PreCommitEpoch + miner.PreCommitChallengeDelay
|
||||||
log.Infof("precommit for sector %d made it on chain, will start proof computation at height %d", sector.SectorID, randHeight)
|
|
||||||
|
|
||||||
err = m.events.ChainAt(func(ectx context.Context, ts *types.TipSet, curH abi.ChainEpoch) error {
|
err = m.events.ChainAt(func(ectx context.Context, tok TipSetToken, curH abi.ChainEpoch) error {
|
||||||
rand, err := m.api.ChainGetRandomness(ectx, ts.Key(), crypto.DomainSeparationTag_InteractiveSealChallengeSeed, randHeight, nil)
|
rand, err := m.api.ChainGetRandomness(ectx, tok, crypto.DomainSeparationTag_InteractiveSealChallengeSeed, randHeight, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)
|
err = xerrors.Errorf("failed to get randomness for computing seal proof: %w", err)
|
||||||
|
|
||||||
ctx.Send(SectorFatalError{error: err})
|
_ = ctx.Send(SectorFatalError{error: err})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Send(SectorSeedReady{Seed: api.SealSeed{
|
_ = ctx.Send(SectorSeedReady{SeedValue: abi.InteractiveSealRandomness(rand), SeedEpoch: randHeight})
|
||||||
Epoch: randHeight,
|
|
||||||
Value: abi.InteractiveSealRandomness(rand),
|
|
||||||
}})
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, func(ctx context.Context, ts *types.TipSet) error {
|
}, func(ctx context.Context, ts TipSetToken) error {
|
||||||
log.Warn("revert in interactive commit sector step")
|
log.Warn("revert in interactive commit sector step")
|
||||||
// TODO: need to cancel running process and restart...
|
// TODO: need to cancel running process and restart...
|
||||||
return nil
|
return nil
|
||||||
}, build.InteractivePoRepConfidence, randHeight)
|
}, InteractivePoRepConfidence, randHeight)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warn("waitForPreCommitMessage ChainAt errored: ", err)
|
log.Warn("waitForPreCommitMessage ChainAt errored: ", err)
|
||||||
}
|
}
|
||||||
@ -194,18 +179,18 @@ func (m *Sealing) handleWaitSeed(ctx statemachine.Context, sector SectorInfo) er
|
|||||||
func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
log.Info("scheduling seal proof computation...")
|
log.Info("scheduling seal proof computation...")
|
||||||
|
|
||||||
log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorID, sector.Ticket.Value, sector.Ticket.Epoch, sector.Seed.Value, sector.Seed.Epoch, sector.pieceInfos(), sector.CommR, sector.CommD)
|
log.Infof("KOMIT %d %x(%d); %x(%d); %v; r:%x; d:%x", sector.SectorNumber, sector.TicketValue, sector.TicketEpoch, sector.SeedValue, sector.SeedEpoch, sector.pieceInfos(), sector.CommR, sector.CommD)
|
||||||
|
|
||||||
cids := storage.SectorCids{
|
cids := storage.SectorCids{
|
||||||
Unsealed: *sector.CommD,
|
Unsealed: *sector.CommD,
|
||||||
Sealed: *sector.CommR,
|
Sealed: *sector.CommR,
|
||||||
}
|
}
|
||||||
c2in, err := m.sealer.SealCommit1(ctx.Context(), m.minerSector(sector.SectorID), sector.Ticket.Value, sector.Seed.Value, sector.pieceInfos(), cids)
|
c2in, err := m.sealer.SealCommit1(ctx.Context(), m.minerSector(sector.SectorNumber), sector.TicketValue, sector.SeedValue, sector.pieceInfos(), cids)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)})
|
return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)})
|
||||||
}
|
}
|
||||||
|
|
||||||
proof, err := m.sealer.SealCommit2(ctx.Context(), m.minerSector(sector.SectorID), c2in)
|
proof, err := m.sealer.SealCommit2(ctx.Context(), m.minerSector(sector.SectorNumber), c2in)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)})
|
return ctx.Send(SectorComputeProofFailed{xerrors.Errorf("computing seal proof failed: %w", err)})
|
||||||
}
|
}
|
||||||
@ -217,41 +202,30 @@ func (m *Sealing) handleCommitting(ctx statemachine.Context, sector SectorInfo)
|
|||||||
// TODO: Consider splitting states and persist proof for faster recovery
|
// TODO: Consider splitting states and persist proof for faster recovery
|
||||||
|
|
||||||
params := &miner.ProveCommitSectorParams{
|
params := &miner.ProveCommitSectorParams{
|
||||||
SectorNumber: sector.SectorID,
|
SectorNumber: sector.SectorNumber,
|
||||||
Proof: proof,
|
Proof: proof,
|
||||||
}
|
}
|
||||||
|
|
||||||
enc, aerr := actors.SerializeParams(params)
|
enc := new(bytes.Buffer)
|
||||||
if aerr != nil {
|
if err := params.MarshalCBOR(enc); err != nil {
|
||||||
return ctx.Send(SectorCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", aerr)})
|
return ctx.Send(SectorCommitFailed{xerrors.Errorf("could not serialize commit sector parameters: %w", err)})
|
||||||
}
|
|
||||||
|
|
||||||
msg := &types.Message{
|
|
||||||
To: m.maddr,
|
|
||||||
From: m.worker,
|
|
||||||
Method: builtin.MethodsMiner.ProveCommitSector,
|
|
||||||
Params: enc,
|
|
||||||
Value: types.NewInt(0), // TODO: need to ensure sufficient collateral
|
|
||||||
GasLimit: 1000000, /* i dont know help */
|
|
||||||
GasPrice: types.NewInt(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: check seed / ticket are up to date
|
// TODO: check seed / ticket are up to date
|
||||||
|
mcid, err := m.api.SendMsg(ctx.Context(), m.worker, m.maddr, builtin.MethodsMiner.ProveCommitSector, big.NewInt(0), big.NewInt(1), 1000000, enc.Bytes())
|
||||||
smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctx.Send(SectorCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)})
|
return ctx.Send(SectorCommitFailed{xerrors.Errorf("pushing message to mpool: %w", err)})
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.Send(SectorCommitted{
|
return ctx.Send(SectorCommitted{
|
||||||
Proof: proof,
|
Proof: proof,
|
||||||
Message: smsg.Cid(),
|
Message: mcid,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
if sector.CommitMessage == nil {
|
if sector.CommitMessage == nil {
|
||||||
log.Errorf("sector %d entered commit wait state without a message cid", sector.SectorID)
|
log.Errorf("sector %d entered commit wait state without a message cid", sector.SectorNumber)
|
||||||
return ctx.Send(SectorCommitFailed{xerrors.Errorf("entered commit wait with no commit cid")})
|
return ctx.Send(SectorCommitFailed{xerrors.Errorf("entered commit wait with no commit cid")})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,7 +235,7 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if mw.Receipt.ExitCode != 0 {
|
if mw.Receipt.ExitCode != 0 {
|
||||||
return ctx.Send(SectorCommitFailed{xerrors.Errorf("submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.Ticket.Value, sector.Seed.Value, sector.Seed.Epoch, sector.Proof)})
|
return ctx.Send(SectorCommitFailed{xerrors.Errorf("submitting sector proof failed (exit=%d, msg=%s) (t:%x; s:%x(%d); p:%x)", mw.Receipt.ExitCode, sector.CommitMessage, sector.TicketValue, sector.SeedValue, sector.SeedEpoch, sector.Proof)})
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.Send(SectorProving{})
|
return ctx.Send(SectorProving{})
|
||||||
@ -270,7 +244,7 @@ func (m *Sealing) handleCommitWait(ctx statemachine.Context, sector SectorInfo)
|
|||||||
func (m *Sealing) handleFinalizeSector(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handleFinalizeSector(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
// TODO: Maybe wait for some finality
|
// TODO: Maybe wait for some finality
|
||||||
|
|
||||||
if err := m.sealer.FinalizeSector(ctx.Context(), m.minerSector(sector.SectorID)); err != nil {
|
if err := m.sealer.FinalizeSector(ctx.Context(), m.minerSector(sector.SectorNumber)); err != nil {
|
||||||
return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("finalize sector: %w", err)})
|
return ctx.Send(SectorFinalizeFailed{xerrors.Errorf("finalize sector: %w", err)})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,32 +256,24 @@ func (m *Sealing) handleFaulty(ctx statemachine.Context, sector SectorInfo) erro
|
|||||||
|
|
||||||
// TODO: coalesce faulty sector reporting
|
// TODO: coalesce faulty sector reporting
|
||||||
bf := abi.NewBitField()
|
bf := abi.NewBitField()
|
||||||
bf.Set(uint64(sector.SectorID))
|
bf.Set(uint64(sector.SectorNumber))
|
||||||
|
|
||||||
enc, aerr := actors.SerializeParams(&miner.DeclareTemporaryFaultsParams{
|
params := &miner.DeclareTemporaryFaultsParams{
|
||||||
SectorNumbers: bf,
|
SectorNumbers: bf,
|
||||||
Duration: 99999999, // TODO: This is very unlikely to be the correct number
|
Duration: 99999999, // TODO: This is very unlikely to be the correct number
|
||||||
})
|
|
||||||
if aerr != nil {
|
|
||||||
return xerrors.Errorf("failed to serialize declare fault params: %w", aerr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := &types.Message{
|
enc := new(bytes.Buffer)
|
||||||
To: m.maddr,
|
if err := params.MarshalCBOR(enc); err != nil {
|
||||||
From: m.worker,
|
return ctx.Send(SectorCommitFailed{xerrors.Errorf("failed to serialize declare fault params: %w", err)})
|
||||||
Method: builtin.MethodsMiner.DeclareTemporaryFaults,
|
|
||||||
Params: enc,
|
|
||||||
Value: types.NewInt(0), // TODO: need to ensure sufficient collateral
|
|
||||||
GasLimit: 1000000, /* i dont know help */
|
|
||||||
GasPrice: types.NewInt(1),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
smsg, err := m.api.MpoolPushMessage(ctx.Context(), msg)
|
mcid, err := m.api.SendMsg(ctx.Context(), m.worker, m.maddr, builtin.MethodsMiner.DeclareTemporaryFaults, big.NewInt(0), big.NewInt(1), 1000000, enc.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to push declare faults message to network: %w", err)
|
return xerrors.Errorf("failed to push declare faults message to network: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.Send(SectorFaultReported{reportMsg: smsg.Cid()})
|
return ctx.Send(SectorFaultReported{reportMsg: mcid})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) handleFaultReported(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handleFaultReported(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
@ -321,7 +287,7 @@ func (m *Sealing) handleFaultReported(ctx statemachine.Context, sector SectorInf
|
|||||||
}
|
}
|
||||||
|
|
||||||
if mw.Receipt.ExitCode != 0 {
|
if mw.Receipt.ExitCode != 0 {
|
||||||
log.Errorf("UNHANDLED: declaring sector fault failed (exit=%d, msg=%s) (id: %d)", mw.Receipt.ExitCode, *sector.FaultReportMsg, sector.SectorID)
|
log.Errorf("UNHANDLED: declaring sector fault failed (exit=%d, msg=%s) (id: %d)", mw.Receipt.ExitCode, *sector.FaultReportMsg, sector.SectorNumber)
|
||||||
return xerrors.Errorf("UNHANDLED: submitting fault declaration failed (exit %d)", mw.Receipt.ExitCode)
|
return xerrors.Errorf("UNHANDLED: submitting fault declaration failed (exit %d)", mw.Receipt.ExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,17 +1,12 @@
|
|||||||
package sealing
|
package sealing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-statemachine"
|
"github.com/filecoin-project/go-statemachine"
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api/apibstore"
|
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const minRetryTime = 1 * time.Minute
|
const minRetryTime = 1 * time.Minute
|
||||||
@ -21,7 +16,7 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error {
|
|||||||
|
|
||||||
retryStart := time.Unix(int64(sector.Log[len(sector.Log)-1].Timestamp), 0).Add(minRetryTime)
|
retryStart := time.Unix(int64(sector.Log[len(sector.Log)-1].Timestamp), 0).Add(minRetryTime)
|
||||||
if len(sector.Log) > 0 && !time.Now().After(retryStart) {
|
if len(sector.Log) > 0 && !time.Now().After(retryStart) {
|
||||||
log.Infof("%s(%d), waiting %s before retrying", sector.State, sector.SectorID, time.Until(retryStart))
|
log.Infof("%s(%d), waiting %s before retrying", sector.State, sector.SectorNumber, time.Until(retryStart))
|
||||||
select {
|
select {
|
||||||
case <-time.After(time.Until(retryStart)):
|
case <-time.After(time.Until(retryStart)):
|
||||||
case <-ctx.Context().Done():
|
case <-ctx.Context().Done():
|
||||||
@ -33,36 +28,22 @@ func failedCooldown(ctx statemachine.Context, sector SectorInfo) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*miner.SectorPreCommitOnChainInfo, bool) {
|
func (m *Sealing) checkPreCommitted(ctx statemachine.Context, sector SectorInfo) (*miner.SectorPreCommitOnChainInfo, bool) {
|
||||||
act, err := m.api.StateGetActor(ctx.Context(), m.maddr, types.EmptyTSK)
|
tok, _, err := m.api.ChainHead(ctx.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err)
|
log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorNumber, err)
|
||||||
return nil, true
|
return nil, true
|
||||||
}
|
}
|
||||||
|
|
||||||
st, err := m.api.ChainReadObj(ctx.Context(), act.Head)
|
info, err := m.api.StateSectorPreCommitInfo(ctx.Context(), m.maddr, sector.SectorNumber, tok)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorID, err)
|
log.Errorf("handleSealFailed(%d): temp error: %+v", sector.SectorNumber, err)
|
||||||
return nil, true
|
return nil, true
|
||||||
}
|
}
|
||||||
|
|
||||||
var state miner.State
|
return info, false
|
||||||
if err := state.UnmarshalCBOR(bytes.NewReader(st)); err != nil {
|
|
||||||
log.Errorf("handleSealFailed(%d): temp error: unmarshaling miner state: %+v", sector.SectorID, err)
|
|
||||||
return nil, true
|
|
||||||
}
|
|
||||||
|
|
||||||
var pci miner.SectorPreCommitOnChainInfo
|
|
||||||
precommits := adt.AsMap(store.ActorStore(ctx.Context(), apibstore.NewAPIBlockstore(m.api)), state.PreCommittedSectors)
|
|
||||||
if _, err := precommits.Get(adt.UIntKey(uint64(sector.SectorID)), &pci); err != nil {
|
|
||||||
log.Error(err)
|
|
||||||
return nil, true
|
|
||||||
}
|
|
||||||
|
|
||||||
return &pci, false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
|
|
||||||
if _, is := m.checkPreCommitted(ctx, sector); is {
|
if _, is := m.checkPreCommitted(ctx, sector); is {
|
||||||
// TODO: Remove this after we can re-precommit
|
// TODO: Remove this after we can re-precommit
|
||||||
return nil // noop, for now
|
return nil // noop, for now
|
||||||
@ -76,7 +57,7 @@ func (m *Sealing) handleSealFailed(ctx statemachine.Context, sector SectorInfo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorInfo) error {
|
func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorInfo) error {
|
||||||
if err := checkPrecommit(ctx.Context(), m.maddr, sector, m.api); err != nil {
|
if err := checkPrecommit(ctx.Context(), m.Address(), sector, m.api); err != nil {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case *ErrApi:
|
case *ErrApi:
|
||||||
log.Errorf("handlePreCommitFailed: api error, not proceeding: %+v", err)
|
log.Errorf("handlePreCommitFailed: api error, not proceeding: %+v", err)
|
||||||
@ -92,12 +73,12 @@ func (m *Sealing) handlePreCommitFailed(ctx statemachine.Context, sector SectorI
|
|||||||
|
|
||||||
if pci, is := m.checkPreCommitted(ctx, sector); is && pci != nil {
|
if pci, is := m.checkPreCommitted(ctx, sector); is && pci != nil {
|
||||||
if sector.PreCommitMessage != nil {
|
if sector.PreCommitMessage != nil {
|
||||||
log.Warn("sector %d is precommitted on chain, but we don't have precommit message", sector.SectorID)
|
log.Warn("sector %d is precommitted on chain, but we don't have precommit message", sector.SectorNumber)
|
||||||
return nil // TODO: SeedWait needs this currently
|
return nil // TODO: SeedWait needs this currently
|
||||||
}
|
}
|
||||||
|
|
||||||
if pci.Info.SealedCID != *sector.CommR {
|
if pci.Info.SealedCID != *sector.CommR {
|
||||||
log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorID, pci.Info.SealedCID, sector.CommR)
|
log.Warn("sector %d is precommitted on chain, with different CommR: %x != %x", sector.SectorNumber, pci.Info.SealedCID, sector.CommR)
|
||||||
return nil // TODO: remove when the actor allows re-precommit
|
return nil // TODO: remove when the actor allows re-precommit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package sealing
|
package sealing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"bytes"
|
||||||
"github.com/filecoin-project/specs-storage/storage"
|
"context"
|
||||||
|
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/runtime/exitcode"
|
||||||
|
"github.com/filecoin-project/specs-storage/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Piece struct {
|
type Piece struct {
|
||||||
@ -26,8 +29,8 @@ type Log struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SectorInfo struct {
|
type SectorInfo struct {
|
||||||
State api.SectorState
|
State SectorState
|
||||||
SectorID abi.SectorNumber
|
SectorNumber abi.SectorNumber // TODO: this field's name should be changed to SectorNumber
|
||||||
Nonce uint64 // TODO: remove
|
Nonce uint64 // TODO: remove
|
||||||
|
|
||||||
SectorType abi.RegisteredProof
|
SectorType abi.RegisteredProof
|
||||||
@ -37,7 +40,8 @@ type SectorInfo struct {
|
|||||||
Pieces []Piece
|
Pieces []Piece
|
||||||
|
|
||||||
// PreCommit1
|
// PreCommit1
|
||||||
Ticket api.SealTicket
|
TicketValue abi.SealRandomness
|
||||||
|
TicketEpoch abi.ChainEpoch
|
||||||
PreCommit1Out storage.PreCommit1Out
|
PreCommit1Out storage.PreCommit1Out
|
||||||
|
|
||||||
// PreCommit2
|
// PreCommit2
|
||||||
@ -48,7 +52,8 @@ type SectorInfo struct {
|
|||||||
PreCommitMessage *cid.Cid
|
PreCommitMessage *cid.Cid
|
||||||
|
|
||||||
// WaitSeed
|
// WaitSeed
|
||||||
Seed api.SealSeed
|
SeedValue abi.InteractiveSealRandomness
|
||||||
|
SeedEpoch abi.ChainEpoch
|
||||||
|
|
||||||
// Committing
|
// Committing
|
||||||
CommitMessage *cid.Cid
|
CommitMessage *cid.Cid
|
||||||
@ -92,3 +97,27 @@ func (t *SectorInfo) existingPieces() []abi.UnpaddedPieceSize {
|
|||||||
}
|
}
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TicketFn func(context.Context) (abi.SealRandomness, abi.ChainEpoch, error)
|
||||||
|
|
||||||
|
type SectorIDCounter interface {
|
||||||
|
Next() (abi.SectorNumber, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type TipSetToken []byte
|
||||||
|
|
||||||
|
type MsgLookup struct {
|
||||||
|
Receipt MessageReceipt
|
||||||
|
TipSetTok TipSetToken
|
||||||
|
Height abi.ChainEpoch
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageReceipt struct {
|
||||||
|
ExitCode exitcode.ExitCode
|
||||||
|
Return []byte
|
||||||
|
GasUsed int64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (mr *MessageReceipt) Equals(o *MessageReceipt) bool {
|
||||||
|
return mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed
|
||||||
|
}
|
||||||
|
@ -4,12 +4,11 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/builtin"
|
|
||||||
"gotest.tools/assert"
|
"gotest.tools/assert"
|
||||||
|
|
||||||
cborutil "github.com/filecoin-project/go-cbor-util"
|
cborutil "github.com/filecoin-project/go-cbor-util"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/builtin"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSectorInfoSelialization(t *testing.T) {
|
func TestSectorInfoSelialization(t *testing.T) {
|
||||||
@ -19,7 +18,7 @@ func TestSectorInfoSelialization(t *testing.T) {
|
|||||||
|
|
||||||
si := &SectorInfo{
|
si := &SectorInfo{
|
||||||
State: "stateful",
|
State: "stateful",
|
||||||
SectorID: 234,
|
SectorNumber: 234,
|
||||||
Nonce: 345,
|
Nonce: 345,
|
||||||
Pieces: []Piece{{
|
Pieces: []Piece{{
|
||||||
DealID: &d,
|
DealID: &d,
|
||||||
@ -29,12 +28,11 @@ func TestSectorInfoSelialization(t *testing.T) {
|
|||||||
CommD: &dummyCid,
|
CommD: &dummyCid,
|
||||||
CommR: nil,
|
CommR: nil,
|
||||||
Proof: nil,
|
Proof: nil,
|
||||||
Ticket: api.SealTicket{
|
TicketValue: []byte{87, 78, 7, 87},
|
||||||
Epoch: 345,
|
TicketEpoch: 345,
|
||||||
Value: []byte{87, 78, 7, 87},
|
|
||||||
},
|
|
||||||
PreCommitMessage: nil,
|
PreCommitMessage: nil,
|
||||||
Seed: api.SealSeed{},
|
SeedValue: []byte{},
|
||||||
|
SeedEpoch: 0,
|
||||||
CommitMessage: nil,
|
CommitMessage: nil,
|
||||||
FaultReportMsg: nil,
|
FaultReportMsg: nil,
|
||||||
LastErr: "hi",
|
LastErr: "hi",
|
||||||
@ -52,11 +50,12 @@ func TestSectorInfoSelialization(t *testing.T) {
|
|||||||
|
|
||||||
assert.Equal(t, si.State, si2.State)
|
assert.Equal(t, si.State, si2.State)
|
||||||
assert.Equal(t, si.Nonce, si2.Nonce)
|
assert.Equal(t, si.Nonce, si2.Nonce)
|
||||||
assert.Equal(t, si.SectorID, si2.SectorID)
|
assert.Equal(t, si.SectorNumber, si2.SectorNumber)
|
||||||
|
|
||||||
assert.Equal(t, si.Pieces, si2.Pieces)
|
assert.Equal(t, si.Pieces, si2.Pieces)
|
||||||
assert.Equal(t, si.CommD, si2.CommD)
|
assert.Equal(t, si.CommD, si2.CommD)
|
||||||
assert.Equal(t, si.Ticket, si2.Ticket)
|
assert.Equal(t, si.TicketValue, si2.TicketValue)
|
||||||
|
assert.Equal(t, si.TicketEpoch, si2.TicketEpoch)
|
||||||
|
|
||||||
assert.Equal(t, si, si2)
|
assert.Equal(t, si, si2)
|
||||||
|
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package sealing
|
package sealing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
|
||||||
"math/bits"
|
"math/bits"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) {
|
func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user