Skip to content

Commit

Permalink
api: handle no-precommit in StateSectorPreCommitInfo gracefully
Browse files Browse the repository at this point in the history
  • Loading branch information
magik6k committed Jun 16, 2022
1 parent 06b3e55 commit 9c4d10e
Show file tree
Hide file tree
Showing 21 changed files with 83 additions and 96 deletions.
11 changes: 8 additions & 3 deletions api/api_full.go
Original file line number Diff line number Diff line change
Expand Up @@ -457,10 +457,15 @@ type FullNode interface {
StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) //perm:read
// StateMinerAvailableBalance returns the portion of a miner's balance that can be withdrawn or spent
StateMinerAvailableBalance(context.Context, address.Address, types.TipSetKey) (types.BigInt, error) //perm:read
// StateMinerSectorAllocated checks if a sector is allocated
// StateMinerSectorAllocated checks if a sector number is marked as allocated.
StateMinerSectorAllocated(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (bool, error) //perm:read
// StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) //perm:read
// StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector.
// Returns nil and no error if the sector isn't precommitted.
//
// Note that the sector number may be allocated while PreCommitInfo is nil. This means that either allocated sector
// numbers were compacted, and the sector number was marked as allocated in order to reduce size of the allocated
// sectors bitfield, or that the sector was precommitted, but the precommit has expired.
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorPreCommitOnChainInfo, error) //perm:read
// StateSectorGetInfo returns the on-chain info for the specified miner's sector. Returns null in case the sector info isn't found
// NOTE: returned info.Expiration may not be accurate in some cases, use StateSectorExpiration to get accurate
// expiration epoch
Expand Down
4 changes: 2 additions & 2 deletions api/mocks/mock_full.go

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

10 changes: 5 additions & 5 deletions api/proxy_gen.go

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

13 changes: 13 additions & 0 deletions api/v0api/v1_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/filecoin-project/go-fil-markets/storagemarket"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/builtin/v8/miner"
"github.com/filecoin-project/go-state-types/crypto"

"github.com/filecoin-project/lotus/api"
Expand All @@ -24,6 +25,18 @@ type WrapperV1Full struct {
v1api.FullNode
}

func (w *WrapperV1Full) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, s abi.SectorNumber, tsk types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error) {
pi, err := w.FullNode.StateSectorPreCommitInfo(ctx, maddr, s, tsk)
if err != nil {
return miner.SectorPreCommitOnChainInfo{}, err
}
if pi == nil {
return miner.SectorPreCommitOnChainInfo{}, xerrors.Errorf("precommit info does not exist")
}

return *pi, nil
}

func (w *WrapperV1Full) StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error) {
return w.FullNode.StateSearchMsg(ctx, types.EmptyTSK, msg, api.LookbackNoLimit, true)
}
Expand Down
2 changes: 1 addition & 1 deletion api/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func VersionForType(nodeType NodeType) (Version, error) {
// semver versions of the rpc api exposed
var (
FullAPIVersion0 = newVer(1, 5, 0)
FullAPIVersion1 = newVer(2, 2, 0)
FullAPIVersion1 = newVer(2, 3, 0)

MinerAPIVersion0 = newVer(1, 5, 0)
WorkerAPIVersion0 = newVer(1, 6, 0)
Expand Down
Binary file modified build/openrpc/full.json.gz
Binary file not shown.
Binary file modified build/openrpc/gateway.json.gz
Binary file not shown.
Binary file modified build/openrpc/worker.json.gz
Binary file not shown.
2 changes: 1 addition & 1 deletion documentation/en/api-v0-methods-miner.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ Response:
```json
{
"Version": "string value",
"APIVersion": 131584,
"APIVersion": 131840,
"BlockDelay": 42
}
```
Expand Down
2 changes: 1 addition & 1 deletion documentation/en/api-v0-methods-worker.md
Original file line number Diff line number Diff line change
Expand Up @@ -1460,7 +1460,7 @@ Perms: admin

Inputs: `null`

Response: `131584`
Response: `131840`

## Add

Expand Down
2 changes: 1 addition & 1 deletion documentation/en/api-v0-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@ Response:
```json
{
"Version": "string value",
"APIVersion": 131584,
"APIVersion": 131840,
"BlockDelay": 42
}
```
Expand Down
11 changes: 8 additions & 3 deletions documentation/en/api-v1-unstable-methods.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ Response:
```json
{
"Version": "string value",
"APIVersion": 131584,
"APIVersion": 131840,
"BlockDelay": 42
}
```
Expand Down Expand Up @@ -6477,7 +6477,7 @@ Response:
```

### StateMinerSectorAllocated
StateMinerSectorAllocated checks if a sector is allocated
StateMinerSectorAllocated checks if a sector number is marked as allocated.


Perms: read
Expand Down Expand Up @@ -6990,7 +6990,12 @@ Response:
```

### StateSectorPreCommitInfo
StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector
StateSectorPreCommitInfo returns the PreCommit info for the specified miner's sector.
Returns nil and no error if the sector isn't precommitted.

Note that the sector number may be allocated while PreCommitInfo is nil. This means that either allocated sector
numbers were compacted, and the sector number was marked as allocated in order to reduce size of the allocated
sectors bitfield, or that the sector was precommitted, but the precommit has expired.


Perms: read
Expand Down
10 changes: 4 additions & 6 deletions node/impl/full/state.go
Original file line number Diff line number Diff line change
Expand Up @@ -880,20 +880,18 @@ func (a *StateAPI) StateMinerSectorCount(ctx context.Context, addr address.Addre
return api.MinerSectors{Live: liveCount, Active: activeCount, Faulty: faultyCount}, nil
}

func (a *StateAPI) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (minertypes.SectorPreCommitOnChainInfo, error) {
func (a *StateAPI) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*minertypes.SectorPreCommitOnChainInfo, error) {
ts, err := a.Chain.GetTipSetFromKey(ctx, tsk)
if err != nil {
return minertypes.SectorPreCommitOnChainInfo{}, xerrors.Errorf("loading tipset %s: %w", tsk, err)
return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err)
}

pci, err := stmgr.PreCommitInfo(ctx, a.StateManager, maddr, n, ts)
if err != nil {
return minertypes.SectorPreCommitOnChainInfo{}, err
} else if pci == nil {
return minertypes.SectorPreCommitOnChainInfo{}, xerrors.Errorf("precommit info is not exists")
return nil, err
}

return *pci, err
return pci, err
}

func (m *StateModule) StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error) {
Expand Down
34 changes: 1 addition & 33 deletions storage/adapter_storage_miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"

"github.com/ipfs/go-cid"
"golang.org/x/xerrors"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
Expand All @@ -15,9 +14,7 @@ import (
"github.com/filecoin-project/go-state-types/network"

"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
pipeline "github.com/filecoin-project/lotus/storage/pipeline"
)
Expand Down Expand Up @@ -118,36 +115,7 @@ func (s SealingAPIAdapter) StateSectorPartition(ctx context.Context, maddr addre
}

func (s SealingAPIAdapter) StateSectorPreCommitInfo(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tsk types.TipSetKey) (*minertypes.SectorPreCommitOnChainInfo, error) {

act, err := s.delegate.StateGetActor(ctx, maddr, tsk)
if err != nil {
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: %+v", sectorNumber, err)
}

stor := store.ActorStore(ctx, blockstore.NewAPIBlockstore(s.delegate))

state, err := miner.Load(stor, act)
if err != nil {
return nil, xerrors.Errorf("handleSealFailed(%d): temp error: loading miner state: %+v", sectorNumber, err)
}

pci, err := state.GetPrecommittedSector(sectorNumber)
if err != nil {
return nil, err
}
if pci == nil {
set, err := state.IsAllocated(sectorNumber)
if err != nil {
return nil, xerrors.Errorf("checking if sector is allocated: %w", err)
}
if set {
return nil, pipeline.ErrSectorAllocated
}

return nil, nil
}

return pci, nil
return s.delegate.StateSectorPreCommitInfo(ctx, maddr, sectorNumber, tsk)
}

func (s SealingAPIAdapter) SendMsg(ctx context.Context, from, to address.Address, method abi.MethodNum, value, maxFee abi.TokenAmount, params []byte) (cid.Cid, error) {
Expand Down
2 changes: 1 addition & 1 deletion storage/miner.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ type fullNodeFilteredAPI interface {
// Call a read only method on actors (no interaction with the chain required)
StateCall(context.Context, *types.Message, types.TipSetKey) (*api.InvocResult, error)
StateMinerSectors(context.Context, address.Address, *bitfield.BitField, types.TipSetKey) ([]*miner.SectorOnChainInfo, error)
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (miner.SectorPreCommitOnChainInfo, error)
StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorPreCommitOnChainInfo, error)
StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error)
StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*lminer.SectorLocation, error)
StateMinerInfo(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error)
Expand Down
38 changes: 24 additions & 14 deletions storage/pipeline/checks.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, t

pci, err := api.StateSectorPreCommitInfo(ctx, maddr, si.SectorNumber, tok)
if err != nil {
if err == ErrSectorAllocated {
//committed P2 message but commit C2 message too late, pci should be null in this case
return &ErrSectorNumberAllocated{err}
}
return &ErrApi{xerrors.Errorf("getting precommit info: %w", err)}
}

Expand All @@ -122,6 +118,15 @@ func checkPrecommit(ctx context.Context, maddr address.Address, si SectorInfo, t
return &ErrPrecommitOnChain{xerrors.Errorf("precommit already on chain")}
}

alloc, err := api.StateMinerSectorAllocated(ctx, maddr, si.SectorNumber, tok)
if err != nil {
return xerrors.Errorf("checking if sector is allocated: %w", err)
}
if alloc {
//committed P2 message but commit C2 message too late, pci should be null in this case
return &ErrSectorNumberAllocated{xerrors.Errorf("sector %d is allocated, but PreCommit info wasn't found on chain", si.SectorNumber)}
}

//never commit P2 message before, check ticket expiration
ticketEarliest := height - policy.MaxPreCommitRandomnessLookback

Expand All @@ -137,21 +142,26 @@ func (m *Sealing) checkCommit(ctx context.Context, si SectorInfo, proof []byte,
}

pci, err := m.Api.StateSectorPreCommitInfo(ctx, m.maddr, si.SectorNumber, tok)
if err == ErrSectorAllocated {
// not much more we can check here, basically try to wait for commit,
// and hope that this will work

if si.CommitMessage != nil {
return &ErrCommitWaitFailed{err}
}

return err
}
if err != nil {
return xerrors.Errorf("getting precommit info: %w", err)
}

if pci == nil {
alloc, err := m.Api.StateMinerSectorAllocated(ctx, m.maddr, si.SectorNumber, tok)
if err != nil {
return xerrors.Errorf("checking if sector is allocated: %w", err)
}
if alloc {
// not much more we can check here, basically try to wait for commit,
// and hope that this will work

if si.CommitMessage != nil {
return &ErrCommitWaitFailed{err}
}

return xerrors.Errorf("sector %d is allocated, but PreCommit info wasn't found on chain", si.SectorNumber)
}

return &ErrNoPrecommit{xerrors.Errorf("precommit info not found on-chain")}
}

Expand Down
21 changes: 4 additions & 17 deletions storage/pipeline/mocks/api.go

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

6 changes: 4 additions & 2 deletions storage/pipeline/mocks/mock_commit_batcher.go

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

6 changes: 4 additions & 2 deletions storage/pipeline/mocks/mock_precommit_batcher.go

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

Loading

0 comments on commit 9c4d10e

Please sign in to comment.