2019-07-24 01:13:56 +00:00
|
|
|
package impl
|
2019-07-24 00:58:31 +00:00
|
|
|
|
|
|
|
import (
|
2019-07-27 01:54:03 +00:00
|
|
|
"context"
|
2019-11-21 14:10:51 +00:00
|
|
|
"encoding/json"
|
2019-12-05 04:43:54 +00:00
|
|
|
"net/http"
|
|
|
|
"os"
|
2020-01-24 20:19:52 +00:00
|
|
|
"strconv"
|
2020-07-06 18:39:26 +00:00
|
|
|
"time"
|
2020-02-27 21:45:31 +00:00
|
|
|
|
2020-10-18 10:35:44 +00:00
|
|
|
"github.com/google/uuid"
|
2020-07-27 17:59:30 +00:00
|
|
|
"github.com/ipfs/go-cid"
|
2020-08-20 08:18:05 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/host"
|
2020-10-22 20:40:26 +00:00
|
|
|
"github.com/libp2p/go-libp2p-core/peer"
|
2020-07-27 17:59:30 +00:00
|
|
|
"golang.org/x/xerrors"
|
|
|
|
|
2019-12-19 20:13:17 +00:00
|
|
|
"github.com/filecoin-project/go-address"
|
2020-10-01 11:58:26 +00:00
|
|
|
datatransfer "github.com/filecoin-project/go-data-transfer"
|
2020-07-27 17:59:30 +00:00
|
|
|
"github.com/filecoin-project/go-fil-markets/piecestore"
|
2020-07-28 21:35:23 +00:00
|
|
|
retrievalmarket "github.com/filecoin-project/go-fil-markets/retrievalmarket"
|
2020-02-08 00:18:14 +00:00
|
|
|
storagemarket "github.com/filecoin-project/go-fil-markets/storagemarket"
|
2020-05-20 18:23:51 +00:00
|
|
|
"github.com/filecoin-project/go-jsonrpc/auth"
|
2020-09-07 03:49:10 +00:00
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
2020-10-01 11:58:26 +00:00
|
|
|
"github.com/filecoin-project/go-state-types/big"
|
2020-02-04 06:17:18 +00:00
|
|
|
|
2020-08-17 13:39:33 +00:00
|
|
|
sectorstorage "github.com/filecoin-project/lotus/extern/sector-storage"
|
2020-08-17 13:26:18 +00:00
|
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/fsutil"
|
|
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/stores"
|
|
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
2020-08-17 13:39:33 +00:00
|
|
|
sealing "github.com/filecoin-project/lotus/extern/storage-sealing"
|
2020-08-17 13:26:18 +00:00
|
|
|
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/api"
|
2020-01-28 23:08:02 +00:00
|
|
|
"github.com/filecoin-project/lotus/api/apistruct"
|
2020-03-04 05:37:11 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
2021-02-05 17:58:55 +00:00
|
|
|
"github.com/filecoin-project/lotus/markets/storageadapter"
|
2019-11-25 04:45:13 +00:00
|
|
|
"github.com/filecoin-project/lotus/miner"
|
2020-03-19 02:31:53 +00:00
|
|
|
"github.com/filecoin-project/lotus/node/impl/common"
|
2020-06-11 19:59:50 +00:00
|
|
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
2019-10-18 04:47:41 +00:00
|
|
|
"github.com/filecoin-project/lotus/storage"
|
|
|
|
"github.com/filecoin-project/lotus/storage/sectorblocks"
|
2020-11-26 07:02:43 +00:00
|
|
|
sto "github.com/filecoin-project/specs-storage/storage"
|
2019-07-24 00:58:31 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type StorageMinerAPI struct {
|
2020-03-19 02:31:53 +00:00
|
|
|
common.CommonAPI
|
2019-07-27 00:45:27 +00:00
|
|
|
|
2020-03-05 19:21:06 +00:00
|
|
|
SectorBlocks *sectorblocks.SectorBlocks
|
2019-07-30 00:46:56 +00:00
|
|
|
|
2020-07-28 21:35:23 +00:00
|
|
|
PieceStore dtypes.ProviderPieceStore
|
|
|
|
StorageProvider storagemarket.StorageProvider
|
|
|
|
RetrievalProvider retrievalmarket.RetrievalProvider
|
|
|
|
Miner *storage.Miner
|
|
|
|
BlockMiner *miner.Miner
|
|
|
|
Full api.FullNode
|
2020-08-17 13:26:18 +00:00
|
|
|
StorageMgr *sectorstorage.Manager `optional:"true"`
|
|
|
|
IStorageMgr sectorstorage.SectorManager
|
2020-03-13 16:54:55 +00:00
|
|
|
*stores.Index
|
2020-09-07 14:12:46 +00:00
|
|
|
storiface.WorkerReturn
|
2021-02-05 17:58:55 +00:00
|
|
|
DataTransfer dtypes.ProviderDataTransfer
|
|
|
|
Host host.Host
|
|
|
|
AddrSel *storage.AddressSelector
|
|
|
|
DealPublisher *storageadapter.DealPublisher
|
2020-06-11 19:59:50 +00:00
|
|
|
|
2020-10-01 15:14:08 +00:00
|
|
|
DS dtypes.MetadataDS
|
2020-10-01 11:58:26 +00:00
|
|
|
|
2020-12-02 06:21:29 +00:00
|
|
|
ConsiderOnlineStorageDealsConfigFunc dtypes.ConsiderOnlineStorageDealsConfigFunc
|
|
|
|
SetConsiderOnlineStorageDealsConfigFunc dtypes.SetConsiderOnlineStorageDealsConfigFunc
|
|
|
|
ConsiderOnlineRetrievalDealsConfigFunc dtypes.ConsiderOnlineRetrievalDealsConfigFunc
|
|
|
|
SetConsiderOnlineRetrievalDealsConfigFunc dtypes.SetConsiderOnlineRetrievalDealsConfigFunc
|
|
|
|
StorageDealPieceCidBlocklistConfigFunc dtypes.StorageDealPieceCidBlocklistConfigFunc
|
|
|
|
SetStorageDealPieceCidBlocklistConfigFunc dtypes.SetStorageDealPieceCidBlocklistConfigFunc
|
|
|
|
ConsiderOfflineStorageDealsConfigFunc dtypes.ConsiderOfflineStorageDealsConfigFunc
|
|
|
|
SetConsiderOfflineStorageDealsConfigFunc dtypes.SetConsiderOfflineStorageDealsConfigFunc
|
|
|
|
ConsiderOfflineRetrievalDealsConfigFunc dtypes.ConsiderOfflineRetrievalDealsConfigFunc
|
|
|
|
SetConsiderOfflineRetrievalDealsConfigFunc dtypes.SetConsiderOfflineRetrievalDealsConfigFunc
|
|
|
|
ConsiderVerifiedStorageDealsConfigFunc dtypes.ConsiderVerifiedStorageDealsConfigFunc
|
|
|
|
SetConsiderVerifiedStorageDealsConfigFunc dtypes.SetConsiderVerifiedStorageDealsConfigFunc
|
|
|
|
ConsiderUnverifiedStorageDealsConfigFunc dtypes.ConsiderUnverifiedStorageDealsConfigFunc
|
|
|
|
SetConsiderUnverifiedStorageDealsConfigFunc dtypes.SetConsiderUnverifiedStorageDealsConfigFunc
|
|
|
|
SetSealingConfigFunc dtypes.SetSealingConfigFunc
|
|
|
|
GetSealingConfigFunc dtypes.GetSealingConfigFunc
|
|
|
|
GetExpectedSealDurationFunc dtypes.GetExpectedSealDurationFunc
|
|
|
|
SetExpectedSealDurationFunc dtypes.SetExpectedSealDurationFunc
|
2019-07-24 00:58:31 +00:00
|
|
|
}
|
|
|
|
|
2019-11-21 14:10:51 +00:00
|
|
|
func (sm *StorageMinerAPI) ServeRemote(w http.ResponseWriter, r *http.Request) {
|
2020-05-20 18:23:51 +00:00
|
|
|
if !auth.HasPerm(r.Context(), nil, apistruct.PermAdmin) {
|
2019-11-21 14:10:51 +00:00
|
|
|
w.WriteHeader(401)
|
2020-06-02 14:29:39 +00:00
|
|
|
_ = json.NewEncoder(w).Encode(struct{ Error string }{"unauthorized: missing write permission"})
|
2019-11-21 14:10:51 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2020-03-11 05:49:17 +00:00
|
|
|
sm.StorageMgr.ServeHTTP(w, r)
|
2019-11-21 14:10:51 +00:00
|
|
|
}
|
2020-03-05 19:21:06 +00:00
|
|
|
|
2020-10-18 10:35:44 +00:00
|
|
|
func (sm *StorageMinerAPI) WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error) {
|
2020-03-23 14:56:22 +00:00
|
|
|
return sm.StorageMgr.WorkerStats(), nil
|
|
|
|
}
|
2019-11-08 18:15:13 +00:00
|
|
|
|
2020-10-18 10:35:44 +00:00
|
|
|
func (sm *StorageMinerAPI) WorkerJobs(ctx context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) {
|
2020-07-21 18:07:49 +00:00
|
|
|
return sm.StorageMgr.WorkerJobs(), nil
|
|
|
|
}
|
|
|
|
|
2019-10-14 02:32:32 +00:00
|
|
|
func (sm *StorageMinerAPI) ActorAddress(context.Context) (address.Address, error) {
|
2020-03-17 20:19:52 +00:00
|
|
|
return sm.Miner.Address(), nil
|
2019-08-10 01:54:45 +00:00
|
|
|
}
|
|
|
|
|
2020-04-23 21:12:42 +00:00
|
|
|
func (sm *StorageMinerAPI) MiningBase(ctx context.Context) (*types.TipSet, error) {
|
|
|
|
mb, err := sm.BlockMiner.GetBestMiningCandidate(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return mb.TipSet, nil
|
|
|
|
}
|
|
|
|
|
2020-02-09 06:06:32 +00:00
|
|
|
func (sm *StorageMinerAPI) ActorSectorSize(ctx context.Context, addr address.Address) (abi.SectorSize, error) {
|
2020-04-16 17:36:36 +00:00
|
|
|
mi, err := sm.Full.StateMinerInfo(ctx, addr, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return mi.SectorSize, nil
|
2019-11-21 14:10:51 +00:00
|
|
|
}
|
|
|
|
|
2021-02-16 18:16:35 +00:00
|
|
|
func (sm *StorageMinerAPI) PledgeSector(ctx context.Context) (abi.SectorID, error) {
|
2021-02-16 16:41:29 +00:00
|
|
|
sr, err := sm.Miner.PledgeSector(ctx)
|
|
|
|
if err != nil {
|
2021-02-16 18:16:35 +00:00
|
|
|
return abi.SectorID{}, err
|
2021-02-16 16:41:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// wait for the sector to enter the Packing state
|
|
|
|
// TODO: instead of polling implement some pubsub-type thing in storagefsm
|
|
|
|
for {
|
|
|
|
info, err := sm.Miner.GetSectorInfo(sr.ID.Number)
|
|
|
|
if err != nil {
|
2021-02-16 18:16:35 +00:00
|
|
|
return abi.SectorID{}, xerrors.Errorf("getting pledged sector info: %w", err)
|
2021-02-16 16:41:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if info.State != sealing.UndefinedSectorState {
|
2021-02-16 18:16:35 +00:00
|
|
|
return sr.ID, nil
|
2021-02-16 16:41:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
select {
|
|
|
|
case <-time.After(10 * time.Millisecond):
|
|
|
|
case <-ctx.Done():
|
2021-02-16 18:16:35 +00:00
|
|
|
return abi.SectorID{}, ctx.Err()
|
2021-02-16 16:41:29 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-27 01:54:03 +00:00
|
|
|
}
|
|
|
|
|
2020-07-24 08:04:04 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorsStatus(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (api.SectorInfo, error) {
|
2019-11-08 18:15:13 +00:00
|
|
|
info, err := sm.Miner.GetSectorInfo(sid)
|
|
|
|
if err != nil {
|
|
|
|
return api.SectorInfo{}, err
|
|
|
|
}
|
|
|
|
|
2020-02-09 06:06:32 +00:00
|
|
|
deals := make([]abi.DealID, len(info.Pieces))
|
2019-11-08 18:15:13 +00:00
|
|
|
for i, piece := range info.Pieces {
|
2020-04-07 22:34:30 +00:00
|
|
|
if piece.DealInfo == nil {
|
2020-02-23 00:47:47 +00:00
|
|
|
continue
|
|
|
|
}
|
2020-04-07 22:34:30 +00:00
|
|
|
deals[i] = piece.DealInfo.DealID
|
2019-11-08 18:15:13 +00:00
|
|
|
}
|
|
|
|
|
2020-01-23 14:18:05 +00:00
|
|
|
log := make([]api.SectorLog, len(info.Log))
|
|
|
|
for i, l := range info.Log {
|
|
|
|
log[i] = api.SectorLog{
|
|
|
|
Kind: l.Kind,
|
|
|
|
Timestamp: l.Timestamp,
|
|
|
|
Trace: l.Trace,
|
|
|
|
Message: l.Message,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-24 08:04:04 +00:00
|
|
|
sInfo := api.SectorInfo{
|
2019-11-08 18:15:13 +00:00
|
|
|
SectorID: sid,
|
2020-04-23 22:33:59 +00:00
|
|
|
State: api.SectorState(info.State),
|
2019-11-08 18:15:13 +00:00
|
|
|
CommD: info.CommD,
|
|
|
|
CommR: info.CommR,
|
|
|
|
Proof: info.Proof,
|
|
|
|
Deals: deals,
|
2020-04-06 18:07:26 +00:00
|
|
|
Ticket: api.SealTicket{
|
|
|
|
Value: info.TicketValue,
|
|
|
|
Epoch: info.TicketEpoch,
|
|
|
|
},
|
|
|
|
Seed: api.SealSeed{
|
|
|
|
Value: info.SeedValue,
|
|
|
|
Epoch: info.SeedEpoch,
|
|
|
|
},
|
2020-08-27 10:40:19 +00:00
|
|
|
PreCommitMsg: info.PreCommitMessage,
|
2020-08-27 10:41:24 +00:00
|
|
|
CommitMsg: info.CommitMessage,
|
|
|
|
Retries: info.InvalidProofs,
|
|
|
|
ToUpgrade: sm.Miner.IsMarkedForUpgrade(sid),
|
2019-12-04 00:44:29 +00:00
|
|
|
|
|
|
|
LastErr: info.LastErr,
|
2020-01-23 14:18:05 +00:00
|
|
|
Log: log,
|
2020-07-24 08:04:04 +00:00
|
|
|
// on chain info
|
2020-07-27 23:22:41 +00:00
|
|
|
SealProof: 0,
|
|
|
|
Activation: 0,
|
|
|
|
Expiration: 0,
|
|
|
|
DealWeight: big.Zero(),
|
2020-07-24 08:04:04 +00:00
|
|
|
VerifiedDealWeight: big.Zero(),
|
2020-07-27 23:22:41 +00:00
|
|
|
InitialPledge: big.Zero(),
|
|
|
|
OnTime: 0,
|
|
|
|
Early: 0,
|
2020-07-24 08:04:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if !showOnChainInfo {
|
|
|
|
return sInfo, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
onChainInfo, err := sm.Full.StateSectorGetInfo(ctx, sm.Miner.Address(), sid, types.EmptyTSK)
|
|
|
|
if err != nil {
|
2020-08-27 11:51:13 +00:00
|
|
|
return sInfo, err
|
|
|
|
}
|
|
|
|
if onChainInfo == nil {
|
2020-07-24 08:04:04 +00:00
|
|
|
return sInfo, nil
|
|
|
|
}
|
|
|
|
sInfo.SealProof = onChainInfo.SealProof
|
|
|
|
sInfo.Activation = onChainInfo.Activation
|
|
|
|
sInfo.Expiration = onChainInfo.Expiration
|
|
|
|
sInfo.DealWeight = onChainInfo.DealWeight
|
|
|
|
sInfo.VerifiedDealWeight = onChainInfo.VerifiedDealWeight
|
|
|
|
sInfo.InitialPledge = onChainInfo.InitialPledge
|
|
|
|
|
|
|
|
ex, err := sm.Full.StateSectorExpiration(ctx, sm.Miner.Address(), sid, types.EmptyTSK)
|
|
|
|
if err != nil {
|
|
|
|
return sInfo, nil
|
|
|
|
}
|
|
|
|
sInfo.OnTime = ex.OnTime
|
|
|
|
sInfo.Early = ex.Early
|
|
|
|
|
|
|
|
return sInfo, nil
|
2019-07-27 21:08:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// List all staged sectors
|
2020-02-09 06:06:32 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorsList(context.Context) ([]abi.SectorNumber, error) {
|
2019-11-08 18:15:13 +00:00
|
|
|
sectors, err := sm.Miner.ListSectors()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2020-02-09 06:06:32 +00:00
|
|
|
out := make([]abi.SectorNumber, len(sectors))
|
2019-11-08 18:15:13 +00:00
|
|
|
for i, sector := range sectors {
|
2021-02-16 16:34:06 +00:00
|
|
|
if sector.State == sealing.UndefinedSectorState {
|
|
|
|
continue // sector ID not set yet
|
|
|
|
}
|
|
|
|
|
2020-04-06 22:31:33 +00:00
|
|
|
out[i] = sector.SectorNumber
|
2019-11-08 18:15:13 +00:00
|
|
|
}
|
|
|
|
return out, nil
|
2019-07-27 21:08:10 +00:00
|
|
|
}
|
|
|
|
|
2020-12-06 00:51:48 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorsListInStates(ctx context.Context, states []api.SectorState) ([]abi.SectorNumber, error) {
|
|
|
|
filterStates := make(map[sealing.SectorState]struct{})
|
|
|
|
for _, state := range states {
|
|
|
|
st := sealing.SectorState(state)
|
|
|
|
if _, ok := sealing.ExistSectorStateList[st]; !ok {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
filterStates[st] = struct{}{}
|
|
|
|
}
|
|
|
|
|
|
|
|
var sns []abi.SectorNumber
|
|
|
|
if len(filterStates) == 0 {
|
|
|
|
return sns, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
sectors, err := sm.Miner.ListSectors()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for i := range sectors {
|
|
|
|
if _, ok := filterStates[sectors[i].State]; ok {
|
|
|
|
sns = append(sns, sectors[i].SectorNumber)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return sns, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) SectorsSummary(ctx context.Context) (map[api.SectorState]int, error) {
|
|
|
|
sectors, err := sm.Miner.ListSectors()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
out := make(map[api.SectorState]int)
|
|
|
|
for i := range sectors {
|
|
|
|
state := api.SectorState(sectors[i].State)
|
2020-12-10 18:36:02 +00:00
|
|
|
out[state]++
|
2020-12-06 00:51:48 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
2020-03-19 19:51:33 +00:00
|
|
|
func (sm *StorageMinerAPI) StorageLocal(ctx context.Context) (map[stores.ID]string, error) {
|
|
|
|
return sm.StorageMgr.StorageLocal(ctx)
|
|
|
|
}
|
|
|
|
|
2019-08-26 10:04:57 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorsRefs(context.Context) (map[string][]api.SealedRef, error) {
|
|
|
|
// json can't handle cids as map keys
|
|
|
|
out := map[string][]api.SealedRef{}
|
|
|
|
|
|
|
|
refs, err := sm.SectorBlocks.List()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
for k, v := range refs {
|
2020-01-24 20:19:52 +00:00
|
|
|
out[strconv.FormatUint(k, 10)] = v
|
2019-08-26 10:04:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
2020-07-08 15:23:27 +00:00
|
|
|
func (sm *StorageMinerAPI) StorageStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) {
|
2020-03-23 22:43:38 +00:00
|
|
|
return sm.StorageMgr.FsStat(ctx, id)
|
|
|
|
}
|
|
|
|
|
2020-06-26 15:28:05 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorStartSealing(ctx context.Context, number abi.SectorNumber) error {
|
|
|
|
return sm.Miner.StartPackingSector(number)
|
|
|
|
}
|
|
|
|
|
2020-07-06 18:39:26 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorSetSealDelay(ctx context.Context, delay time.Duration) error {
|
2020-08-18 14:20:31 +00:00
|
|
|
cfg, err := sm.GetSealingConfigFunc()
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("get config: %w", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
cfg.WaitDealsDelay = delay
|
|
|
|
|
|
|
|
return sm.SetSealingConfigFunc(cfg)
|
2020-07-06 18:39:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) SectorGetSealDelay(ctx context.Context) (time.Duration, error) {
|
2020-08-18 14:20:31 +00:00
|
|
|
cfg, err := sm.GetSealingConfigFunc()
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
|
|
}
|
|
|
|
return cfg.WaitDealsDelay, nil
|
2020-07-06 18:39:26 +00:00
|
|
|
}
|
|
|
|
|
2020-07-12 17:54:53 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorSetExpectedSealDuration(ctx context.Context, delay time.Duration) error {
|
|
|
|
return sm.SetExpectedSealDurationFunc(delay)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) SectorGetExpectedSealDuration(ctx context.Context) (time.Duration, error) {
|
|
|
|
return sm.GetExpectedSealDurationFunc()
|
|
|
|
}
|
|
|
|
|
2020-04-23 22:33:59 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorsUpdate(ctx context.Context, id abi.SectorNumber, state api.SectorState) error {
|
|
|
|
return sm.Miner.ForceSectorState(ctx, id, sealing.SectorState(state))
|
2019-12-05 04:43:54 +00:00
|
|
|
}
|
2020-03-05 19:21:06 +00:00
|
|
|
|
2020-06-22 17:35:14 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorRemove(ctx context.Context, id abi.SectorNumber) error {
|
|
|
|
return sm.Miner.RemoveSector(ctx, id)
|
|
|
|
}
|
|
|
|
|
2021-01-12 23:42:01 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorTerminate(ctx context.Context, id abi.SectorNumber) error {
|
|
|
|
return sm.Miner.TerminateSector(ctx, id)
|
|
|
|
}
|
|
|
|
|
2021-01-13 22:32:04 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorTerminateFlush(ctx context.Context) (*cid.Cid, error) {
|
|
|
|
return sm.Miner.TerminateFlush(ctx)
|
|
|
|
}
|
|
|
|
|
2021-01-14 11:37:23 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorTerminatePending(ctx context.Context) ([]abi.SectorID, error) {
|
|
|
|
return sm.Miner.TerminatePending(ctx)
|
|
|
|
}
|
|
|
|
|
2020-07-01 14:49:17 +00:00
|
|
|
func (sm *StorageMinerAPI) SectorMarkForUpgrade(ctx context.Context, id abi.SectorNumber) error {
|
|
|
|
return sm.Miner.MarkForUpgrade(id)
|
|
|
|
}
|
|
|
|
|
2020-03-11 01:57:52 +00:00
|
|
|
func (sm *StorageMinerAPI) WorkerConnect(ctx context.Context, url string) error {
|
2020-03-27 20:08:06 +00:00
|
|
|
w, err := connectRemoteWorker(ctx, sm, url)
|
2020-03-11 01:57:52 +00:00
|
|
|
if err != nil {
|
2020-03-18 23:23:28 +00:00
|
|
|
return xerrors.Errorf("connecting remote storage failed: %w", err)
|
2020-03-11 01:57:52 +00:00
|
|
|
}
|
|
|
|
|
2020-03-18 23:23:28 +00:00
|
|
|
log.Infof("Connected to a remote worker at %s", url)
|
|
|
|
|
2020-03-20 22:30:17 +00:00
|
|
|
return sm.StorageMgr.AddWorker(ctx, w)
|
2020-03-11 01:57:52 +00:00
|
|
|
}
|
|
|
|
|
2020-10-30 10:07:35 +00:00
|
|
|
func (sm *StorageMinerAPI) SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error) {
|
|
|
|
return sm.StorageMgr.SchedDiag(ctx, doSched)
|
2020-07-27 11:23:43 +00:00
|
|
|
}
|
|
|
|
|
2020-11-11 16:39:12 +00:00
|
|
|
func (sm *StorageMinerAPI) SealingAbort(ctx context.Context, call storiface.CallID) error {
|
|
|
|
return sm.StorageMgr.Abort(ctx, call)
|
|
|
|
}
|
|
|
|
|
2020-02-08 00:18:14 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketImportDealData(ctx context.Context, propCid cid.Cid, path string) error {
|
|
|
|
fi, err := os.Open(path)
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("failed to open file: %w", err)
|
|
|
|
}
|
2020-06-02 14:29:39 +00:00
|
|
|
defer fi.Close() //nolint:errcheck
|
2020-02-08 00:18:14 +00:00
|
|
|
|
|
|
|
return sm.StorageProvider.ImportDataForDeal(ctx, propCid, fi)
|
|
|
|
}
|
|
|
|
|
2020-09-17 07:32:10 +00:00
|
|
|
func (sm *StorageMinerAPI) listDeals(ctx context.Context) ([]api.MarketDeal, error) {
|
|
|
|
ts, err := sm.Full.ChainHead(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
tsk := ts.Key()
|
|
|
|
allDeals, err := sm.Full.StateMarketDeals(ctx, tsk)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var out []api.MarketDeal
|
|
|
|
|
|
|
|
for _, deal := range allDeals {
|
|
|
|
if deal.Proposal.Provider == sm.Miner.Address() {
|
|
|
|
out = append(out, deal)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) MarketListDeals(ctx context.Context) ([]api.MarketDeal, error) {
|
2020-09-17 08:17:14 +00:00
|
|
|
return sm.listDeals(ctx)
|
2020-02-08 00:18:14 +00:00
|
|
|
}
|
|
|
|
|
2020-08-04 23:40:29 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketListRetrievalDeals(ctx context.Context) ([]retrievalmarket.ProviderDealState, error) {
|
|
|
|
var out []retrievalmarket.ProviderDealState
|
|
|
|
deals := sm.RetrievalProvider.ListDeals()
|
|
|
|
|
|
|
|
for _, deal := range deals {
|
|
|
|
out = append(out, deal)
|
|
|
|
}
|
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
2020-09-02 17:58:44 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketGetDealUpdates(ctx context.Context) (<-chan storagemarket.MinerDeal, error) {
|
2020-08-06 20:16:55 +00:00
|
|
|
results := make(chan storagemarket.MinerDeal)
|
|
|
|
unsub := sm.StorageProvider.SubscribeToEvents(func(evt storagemarket.ProviderEvent, deal storagemarket.MinerDeal) {
|
2020-09-02 17:58:44 +00:00
|
|
|
select {
|
|
|
|
case results <- deal:
|
|
|
|
case <-ctx.Done():
|
2020-08-06 20:16:55 +00:00
|
|
|
}
|
|
|
|
})
|
|
|
|
go func() {
|
|
|
|
<-ctx.Done()
|
|
|
|
unsub()
|
|
|
|
close(results)
|
|
|
|
}()
|
|
|
|
return results, nil
|
|
|
|
}
|
|
|
|
|
2020-02-08 00:18:14 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketListIncompleteDeals(ctx context.Context) ([]storagemarket.MinerDeal, error) {
|
2020-04-07 02:17:02 +00:00
|
|
|
return sm.StorageProvider.ListLocalDeals()
|
2020-02-08 00:18:14 +00:00
|
|
|
}
|
|
|
|
|
2020-07-31 19:14:48 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketSetAsk(ctx context.Context, price types.BigInt, verifiedPrice types.BigInt, duration abi.ChainEpoch, minPieceSize abi.PaddedPieceSize, maxPieceSize abi.PaddedPieceSize) error {
|
2020-06-16 22:38:48 +00:00
|
|
|
options := []storagemarket.StorageAskOption{
|
|
|
|
storagemarket.MinPieceSize(minPieceSize),
|
|
|
|
storagemarket.MaxPieceSize(maxPieceSize),
|
|
|
|
}
|
|
|
|
|
2020-07-31 19:14:48 +00:00
|
|
|
return sm.StorageProvider.SetAsk(price, verifiedPrice, duration, options...)
|
2020-02-08 00:18:14 +00:00
|
|
|
}
|
|
|
|
|
2020-06-17 00:18:54 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketGetAsk(ctx context.Context) (*storagemarket.SignedStorageAsk, error) {
|
|
|
|
return sm.StorageProvider.GetAsk(), nil
|
|
|
|
}
|
|
|
|
|
2020-07-28 21:35:23 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketSetRetrievalAsk(ctx context.Context, rask *retrievalmarket.Ask) error {
|
|
|
|
sm.RetrievalProvider.SetAsk(rask)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) MarketGetRetrievalAsk(ctx context.Context) (*retrievalmarket.Ask, error) {
|
|
|
|
return sm.RetrievalProvider.GetAsk(), nil
|
|
|
|
}
|
|
|
|
|
2020-08-20 08:18:05 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketListDataTransfers(ctx context.Context) ([]api.DataTransferChannel, error) {
|
|
|
|
inProgressChannels, err := sm.DataTransfer.InProgressChannels(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
apiChannels := make([]api.DataTransferChannel, 0, len(inProgressChannels))
|
|
|
|
for _, channelState := range inProgressChannels {
|
|
|
|
apiChannels = append(apiChannels, api.NewDataTransferChannel(sm.Host.ID(), channelState))
|
|
|
|
}
|
|
|
|
|
|
|
|
return apiChannels, nil
|
|
|
|
}
|
|
|
|
|
2020-10-22 20:40:26 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketRestartDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
|
|
|
|
selfPeer := sm.Host.ID()
|
|
|
|
if isInitiator {
|
|
|
|
return sm.DataTransfer.RestartDataTransferChannel(ctx, datatransfer.ChannelID{Initiator: selfPeer, Responder: otherPeer, ID: transferID})
|
|
|
|
}
|
|
|
|
return sm.DataTransfer.RestartDataTransferChannel(ctx, datatransfer.ChannelID{Initiator: otherPeer, Responder: selfPeer, ID: transferID})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) MarketCancelDataTransfer(ctx context.Context, transferID datatransfer.TransferID, otherPeer peer.ID, isInitiator bool) error {
|
|
|
|
selfPeer := sm.Host.ID()
|
|
|
|
if isInitiator {
|
|
|
|
return sm.DataTransfer.CloseDataTransferChannel(ctx, datatransfer.ChannelID{Initiator: selfPeer, Responder: otherPeer, ID: transferID})
|
|
|
|
}
|
|
|
|
return sm.DataTransfer.CloseDataTransferChannel(ctx, datatransfer.ChannelID{Initiator: otherPeer, Responder: selfPeer, ID: transferID})
|
|
|
|
}
|
|
|
|
|
2020-08-20 08:18:05 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketDataTransferUpdates(ctx context.Context) (<-chan api.DataTransferChannel, error) {
|
|
|
|
channels := make(chan api.DataTransferChannel)
|
|
|
|
|
|
|
|
unsub := sm.DataTransfer.SubscribeToEvents(func(evt datatransfer.Event, channelState datatransfer.ChannelState) {
|
|
|
|
channel := api.NewDataTransferChannel(sm.Host.ID(), channelState)
|
|
|
|
select {
|
|
|
|
case <-ctx.Done():
|
|
|
|
case channels <- channel:
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
defer unsub()
|
|
|
|
<-ctx.Done()
|
|
|
|
}()
|
|
|
|
|
|
|
|
return channels, nil
|
|
|
|
}
|
|
|
|
|
2021-02-05 17:58:55 +00:00
|
|
|
func (sm *StorageMinerAPI) MarketPendingDeals(ctx context.Context) (api.PendingDealInfo, error) {
|
|
|
|
return sm.DealPublisher.PendingDeals(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) MarketPublishPendingDeals(ctx context.Context) error {
|
|
|
|
sm.DealPublisher.ForcePublishPendingDeals()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-09-17 07:32:10 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsList(ctx context.Context) ([]api.MarketDeal, error) {
|
|
|
|
return sm.listDeals(ctx)
|
2020-03-04 02:49:00 +00:00
|
|
|
}
|
|
|
|
|
2020-08-04 23:40:29 +00:00
|
|
|
func (sm *StorageMinerAPI) RetrievalDealsList(ctx context.Context) (map[retrievalmarket.ProviderDealIdentifier]retrievalmarket.ProviderDealState, error) {
|
|
|
|
return sm.RetrievalProvider.ListDeals(), nil
|
|
|
|
}
|
|
|
|
|
2020-06-26 17:50:54 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsConsiderOnlineStorageDeals(ctx context.Context) (bool, error) {
|
|
|
|
return sm.ConsiderOnlineStorageDealsConfigFunc()
|
2020-06-11 19:59:50 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 17:50:54 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsSetConsiderOnlineStorageDeals(ctx context.Context, b bool) error {
|
|
|
|
return sm.SetConsiderOnlineStorageDealsConfigFunc(b)
|
2020-06-11 19:59:50 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 17:50:54 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsConsiderOnlineRetrievalDeals(ctx context.Context) (bool, error) {
|
|
|
|
return sm.ConsiderOnlineRetrievalDealsConfigFunc()
|
2020-06-26 17:33:06 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 17:50:54 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsSetConsiderOnlineRetrievalDeals(ctx context.Context, b bool) error {
|
|
|
|
return sm.SetConsiderOnlineRetrievalDealsConfigFunc(b)
|
2020-06-23 17:17:31 +00:00
|
|
|
}
|
|
|
|
|
2020-06-26 19:27:41 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsConsiderOfflineStorageDeals(ctx context.Context) (bool, error) {
|
|
|
|
return sm.ConsiderOfflineStorageDealsConfigFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) DealsSetConsiderOfflineStorageDeals(ctx context.Context, b bool) error {
|
|
|
|
return sm.SetConsiderOfflineStorageDealsConfigFunc(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) DealsConsiderOfflineRetrievalDeals(ctx context.Context) (bool, error) {
|
|
|
|
return sm.ConsiderOfflineRetrievalDealsConfigFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) DealsSetConsiderOfflineRetrievalDeals(ctx context.Context, b bool) error {
|
|
|
|
return sm.SetConsiderOfflineRetrievalDealsConfigFunc(b)
|
2020-06-23 17:17:31 +00:00
|
|
|
}
|
|
|
|
|
2020-12-02 06:21:29 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsConsiderVerifiedStorageDeals(ctx context.Context) (bool, error) {
|
|
|
|
return sm.ConsiderVerifiedStorageDealsConfigFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) DealsSetConsiderVerifiedStorageDeals(ctx context.Context, b bool) error {
|
|
|
|
return sm.SetConsiderVerifiedStorageDealsConfigFunc(b)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) DealsConsiderUnverifiedStorageDeals(ctx context.Context) (bool, error) {
|
|
|
|
return sm.ConsiderUnverifiedStorageDealsConfigFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) DealsSetConsiderUnverifiedStorageDeals(ctx context.Context, b bool) error {
|
|
|
|
return sm.SetConsiderUnverifiedStorageDealsConfigFunc(b)
|
|
|
|
}
|
|
|
|
|
2020-07-12 17:54:53 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsGetExpectedSealDurationFunc(ctx context.Context) (time.Duration, error) {
|
|
|
|
return sm.GetExpectedSealDurationFunc()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) DealsSetExpectedSealDurationFunc(ctx context.Context, d time.Duration) error {
|
|
|
|
return sm.SetExpectedSealDurationFunc(d)
|
|
|
|
}
|
|
|
|
|
2020-03-04 02:49:00 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsImportData(ctx context.Context, deal cid.Cid, fname string) error {
|
|
|
|
fi, err := os.Open(fname)
|
|
|
|
if err != nil {
|
|
|
|
return xerrors.Errorf("failed to open given file: %w", err)
|
|
|
|
}
|
2020-06-02 14:29:39 +00:00
|
|
|
defer fi.Close() //nolint:errcheck
|
2020-03-04 02:49:00 +00:00
|
|
|
|
|
|
|
return sm.StorageProvider.ImportDataForDeal(ctx, deal, fi)
|
|
|
|
}
|
|
|
|
|
2020-06-18 22:42:24 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsPieceCidBlocklist(ctx context.Context) ([]cid.Cid, error) {
|
|
|
|
return sm.StorageDealPieceCidBlocklistConfigFunc()
|
2020-06-18 20:15:18 +00:00
|
|
|
}
|
|
|
|
|
2020-06-18 22:42:24 +00:00
|
|
|
func (sm *StorageMinerAPI) DealsSetPieceCidBlocklist(ctx context.Context, cids []cid.Cid) error {
|
|
|
|
return sm.SetStorageDealPieceCidBlocklistConfigFunc(cids)
|
2020-06-18 20:15:18 +00:00
|
|
|
}
|
|
|
|
|
2020-03-05 22:02:01 +00:00
|
|
|
func (sm *StorageMinerAPI) StorageAddLocal(ctx context.Context, path string) error {
|
|
|
|
if sm.StorageMgr == nil {
|
|
|
|
return xerrors.Errorf("no storage manager")
|
|
|
|
}
|
|
|
|
|
2020-03-19 15:10:19 +00:00
|
|
|
return sm.StorageMgr.AddLocalStorage(ctx, path)
|
2020-03-05 22:02:01 +00:00
|
|
|
}
|
|
|
|
|
2020-07-27 17:59:30 +00:00
|
|
|
func (sm *StorageMinerAPI) PiecesListPieces(ctx context.Context) ([]cid.Cid, error) {
|
2020-07-28 21:35:23 +00:00
|
|
|
return sm.PieceStore.ListPieceInfoKeys()
|
2020-07-27 17:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) PiecesListCidInfos(ctx context.Context) ([]cid.Cid, error) {
|
2020-07-28 21:35:23 +00:00
|
|
|
return sm.PieceStore.ListCidInfoKeys()
|
2020-07-27 17:59:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) PiecesGetPieceInfo(ctx context.Context, pieceCid cid.Cid) (*piecestore.PieceInfo, error) {
|
|
|
|
pi, err := sm.PieceStore.GetPieceInfo(pieceCid)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
return &pi, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (sm *StorageMinerAPI) PiecesGetCIDInfo(ctx context.Context, payloadCid cid.Cid) (*piecestore.CIDInfo, error) {
|
|
|
|
ci, err := sm.PieceStore.GetCIDInfo(payloadCid)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return &ci, nil
|
|
|
|
}
|
|
|
|
|
2020-10-01 11:58:26 +00:00
|
|
|
func (sm *StorageMinerAPI) CreateBackup(ctx context.Context, fpath string) error {
|
2020-10-01 15:14:08 +00:00
|
|
|
return backup(sm.DS, fpath)
|
2020-10-01 11:58:26 +00:00
|
|
|
}
|
|
|
|
|
2020-12-01 23:32:01 +00:00
|
|
|
func (sm *StorageMinerAPI) CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []sto.SectorRef, expensive bool) (map[abi.SectorNumber]string, error) {
|
2020-12-01 23:35:55 +00:00
|
|
|
var rg storiface.RGetter
|
2020-12-01 23:32:01 +00:00
|
|
|
if expensive {
|
|
|
|
rg = func(ctx context.Context, id abi.SectorID) (cid.Cid, error) {
|
|
|
|
si, err := sm.Miner.GetSectorInfo(id.Number)
|
|
|
|
if err != nil {
|
|
|
|
return cid.Undef, err
|
|
|
|
}
|
|
|
|
if si.CommR == nil {
|
|
|
|
return cid.Undef, xerrors.Errorf("commr is nil")
|
|
|
|
}
|
|
|
|
|
|
|
|
return *si.CommR, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bad, err := sm.StorageMgr.CheckProvable(ctx, pp, sectors, rg)
|
2020-11-26 07:02:43 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var out = make(map[abi.SectorNumber]string)
|
|
|
|
for sid, err := range bad {
|
|
|
|
out[sid.Number] = err
|
|
|
|
}
|
|
|
|
|
|
|
|
return out, nil
|
|
|
|
}
|
|
|
|
|
2020-12-02 19:46:07 +00:00
|
|
|
func (sm *StorageMinerAPI) ActorAddressConfig(ctx context.Context) (api.AddressConfig, error) {
|
|
|
|
return sm.AddrSel.AddressConfig, nil
|
|
|
|
}
|
|
|
|
|
2019-07-24 00:58:31 +00:00
|
|
|
var _ api.StorageMiner = &StorageMinerAPI{}
|