From 4b90fdd644d8dfdfba5a805a2af02b510c34028c Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Fri, 26 Apr 2024 17:06:24 +0400 Subject: [PATCH 01/17] multiple piece per sector, DDO deals --- cmd/curio/rpc/rpc.go | 20 +- curiosrc/market/deal_ingest.go | 408 +++++++++++++++++-- curiosrc/market/lmrpc/lmrpc.go | 446 ++++++++++++--------- curiosrc/seal/task_submit_precommit.go | 37 +- documentation/en/default-curio-config.toml | 23 +- node/config/def.go | 8 +- node/config/doc_gen.go | 23 +- node/config/types.go | 17 +- storage/pipeline/piece/piece_info.go | 9 + 9 files changed, 721 insertions(+), 270 deletions(-) diff --git a/cmd/curio/rpc/rpc.go b/cmd/curio/rpc/rpc.go index 1b2bb25e643..62a400f241f 100644 --- a/cmd/curio/rpc/rpc.go +++ b/cmd/curio/rpc/rpc.go @@ -37,6 +37,7 @@ import ( "github.com/filecoin-project/lotus/metrics/proxy" "github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/storage/paths" + "github.com/filecoin-project/lotus/storage/pipeline/piece" "github.com/filecoin-project/lotus/storage/sealer/fsutil" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -154,10 +155,23 @@ func (p *CurioAPI) StorageStat(ctx context.Context, id storiface.ID) (fsutil.FsS return p.Stor.FsStat(ctx, id) } -func (p *CurioAPI) AllocatePieceToSector(ctx context.Context, maddr address.Address, piece api.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) { - di := market.NewPieceIngester(p.Deps.DB, p.Deps.Full) +func (p *CurioAPI) AllocatePieceToSector(ctx context.Context, maddr address.Address, piece piece.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) { + di, err := market.NewPieceIngester(ctx, p.Deps.DB, p.Deps.Full, maddr, true, time.Minute) + if err != nil { + return api.SectorOffset{}, xerrors.Errorf("failed to create a piece ingestor") + } + + sector, err := di.AllocatePieceToSector(ctx, maddr, piece, rawSize, source, header) + if err != nil { + return api.SectorOffset{}, xerrors.Errorf("failed to add piece to a sector") + } + + err = di.Seal() + if err != nil { + return api.SectorOffset{}, xerrors.Errorf("failed to start sealing the sector %d for actor %s", sector.Sector, maddr) + } - return di.AllocatePieceToSector(ctx, maddr, piece, rawSize, source, header) + return sector, nil } // Trigger shutdown diff --git a/curiosrc/market/deal_ingest.go b/curiosrc/market/deal_ingest.go index f3125887d32..d660db40d0f 100644 --- a/curiosrc/market/deal_ingest.go +++ b/curiosrc/market/deal_ingest.go @@ -5,7 +5,10 @@ import ( "encoding/json" "net/http" "net/url" + "sync" + "time" + logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -19,81 +22,268 @@ import ( "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/curiosrc/seal" "github.com/filecoin-project/lotus/lib/harmony/harmonydb" + lpiece "github.com/filecoin-project/lotus/storage/pipeline/piece" ) +var log = logging.Logger("piece-ingestor") + +const loopFrequency = 10 * time.Second + type Ingester interface { AllocatePieceToSector(ctx context.Context, maddr address.Address, piece api.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) } type PieceIngesterApi interface { + ChainHead(context.Context) (*types.TipSet, error) StateMinerInfo(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) StateMinerAllocated(ctx context.Context, a address.Address, key types.TipSetKey) (*bitfield.BitField, error) StateNetworkVersion(ctx context.Context, key types.TipSetKey) (network.Version, error) } -type PieceIngester struct { - db *harmonydb.DB - api PieceIngesterApi +type openSector struct { + number abi.SectorNumber + currentSize abi.PaddedPieceSize + earliestEpoch abi.ChainEpoch + index uint64 + lk sync.Mutex + openedAt time.Time + sealNow bool } -func NewPieceIngester(db *harmonydb.DB, api PieceIngesterApi) *PieceIngester { - return &PieceIngester{db: db, api: api} +type PieceIngester struct { + ctx context.Context + db *harmonydb.DB + api PieceIngesterApi + miner address.Address + mid uint64 // miner ID + windowPoStProofType abi.RegisteredPoStProof + sectorSize abi.SectorSize + sealRightNow bool // Should be true only for CurioAPI AllocatePieceToSector method + maxWaitTime time.Duration + forceSeal chan struct{} + openSectors []*openSector + lk sync.Mutex } -func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address.Address, piece api.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) { - mi, err := p.api.StateMinerInfo(ctx, maddr, types.EmptyTSK) +func NewPieceIngester(ctx context.Context, db *harmonydb.DB, api PieceIngesterApi, maddr address.Address, sealRightNow bool, maxWaitTime time.Duration) (*PieceIngester, error) { + mi, err := api.StateMinerInfo(ctx, maddr, types.EmptyTSK) if err != nil { - return api.SectorOffset{}, err + return nil, err } - if piece.DealProposal.PieceSize != abi.PaddedPieceSize(mi.SectorSize) { - return api.SectorOffset{}, xerrors.Errorf("only full sector pieces supported for now") + mid, err := address.IDFromAddress(maddr) + if err != nil { + return nil, xerrors.Errorf("getting miner ID: %w", err) } - // check raw size - if piece.DealProposal.PieceSize != padreader.PaddedSize(uint64(rawSize)).Padded() { - return api.SectorOffset{}, xerrors.Errorf("raw size doesn't match padded piece size") + sm := map[abi.SectorNumber]*openSector{} + type details struct { + Sector abi.SectorNumber `db:"sector_number"` + Size abi.PaddedPieceSize `db:"piece_size"` + f05Epoch abi.ChainEpoch `db:"f05_deal_start_epoch"` + ddoEpoch abi.ChainEpoch `db:"direct_start_epoch"` + Index uint64 `db:"piece_index"` } + var pieces []details - // add initial piece + to a sector - nv, err := p.api.StateNetworkVersion(ctx, types.EmptyTSK) + // Get current open sector pieces from DB + err = db.Select(ctx, &pieces, ` + SELECT + ssip.sector_number, + ssip.piece_size, + ssip.piece_index, + ssip.f05_deal_start_epoch, + ssip.direct_start_epoch + FROM + curio.sectors_sdr_initial_pieces ssip + JOIN + (SELECT sector_number + FROM curio.sectors_sdr_initial_pieces sip + LEFT JOIN curio.sectors_sdr_pipeline sp ON sip.sp_id = sp.sp_id AND sip.sector_number = sp.sector_number + WHERE sp.sector_number IS NULL AND sip.sp_id = $1) as filtered ON ssip.sector_number = filtered.sector_number + WHERE + ssip.sp_id = $1 + ORDER BY + ssip.piece_index DESC;`, mid) if err != nil { - return api.SectorOffset{}, xerrors.Errorf("getting network version: %w", err) + return nil, xerrors.Errorf("getting open sectors from DB") } - synth := false // todo synthetic porep config - spt, err := miner.PreferredSealProofTypeFromWindowPoStType(nv, mi.WindowPoStProofType, synth) + for _, piece := range pieces { + var ep abi.ChainEpoch + if piece.ddoEpoch > 0 { + ep = piece.ddoEpoch + } else { + ep = piece.f05Epoch + } + s, ok := sm[piece.Sector] + if !ok { + s := &openSector{ + number: piece.Sector, + currentSize: piece.Size, + earliestEpoch: ep, + index: piece.Index, + openedAt: time.Now(), + } + sm[piece.Sector] = s + } + s.currentSize += piece.Size + s.earliestEpoch = ep + if s.index < piece.Index { + s.index = piece.Index + } + } + + var os []*openSector + for _, v := range sm { + os = append(os, v) + } + + pi := &PieceIngester{ + db: db, + api: api, + sealRightNow: sealRightNow, + miner: maddr, + maxWaitTime: maxWaitTime, + sectorSize: mi.SectorSize, + windowPoStProofType: mi.WindowPoStProofType, + openSectors: os, + mid: mid, + forceSeal: make(chan struct{}, 1), + } + + go pi.start() + + return pi, nil +} + +func (p *PieceIngester) start() { + ticker := time.NewTicker(loopFrequency) + defer ticker.Stop() + + for { + select { + case <-p.ctx.Done(): + return + case <-ticker.C: + err := p.Seal() + if err != nil { + log.Error(err) + } + } + } +} + +func (p *PieceIngester) Seal() error { + p.lk.Lock() + defer p.lk.Unlock() + + head, err := p.api.ChainHead(p.ctx) if err != nil { - return api.SectorOffset{}, xerrors.Errorf("getting seal proof type: %w", err) + return xerrors.Errorf("getting chain head: %w", err) } - mid, err := address.IDFromAddress(maddr) + nv, err := p.api.StateNetworkVersion(p.ctx, types.EmptyTSK) if err != nil { - return api.SectorOffset{}, xerrors.Errorf("getting miner ID: %w", err) + return xerrors.Errorf("getting network version: %w", err) } - num, err := seal.AllocateSectorNumbers(ctx, p.api, p.db, maddr, 1, func(tx *harmonydb.Tx, numbers []abi.SectorNumber) (bool, error) { - if len(numbers) != 1 { - return false, xerrors.Errorf("expected one sector number") + synth := false // todo synthetic porep config + + spt, err := miner.PreferredSealProofTypeFromWindowPoStType(nv, p.windowPoStProofType, synth) + if err != nil { + return xerrors.Errorf("getting seal proof type: %w", err) + } + + var os []*openSector + + for i := range p.openSectors { + // todo: When to start sealing + // Start sealing a sector if + // 1. If sector is full + // 2. We have been waiting for MaxWaitDuration + // 3. StartEpoch is less than 8 hours // todo: make this config? + // 4. If force seal is set //todo: create sealNOW command + if p.openSectors[i].sealNow || p.openSectors[i].currentSize == abi.PaddedPieceSize(p.sectorSize) || time.Since(p.openSectors[i].openedAt) >= p.maxWaitTime || p.openSectors[i].earliestEpoch > head.Height()+abi.ChainEpoch(960) { + // Start sealing the sector + p.openSectors[i].lk.Lock() + defer p.openSectors[i].lk.Unlock() + + cn, err := p.db.Exec(p.ctx, ` + INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, p.mid, p.openSectors[i].number, spt) + + if err != nil { + return xerrors.Errorf("adding sector to pipeline: %w", err) + } + + if cn != 1 { + return xerrors.Errorf("incorrect number of rows returned") + } } - n := numbers[0] + os = append(os, p.openSectors[i]) + } + + p.openSectors = os + + return nil +} + +func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address.Address, piece lpiece.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) { + if maddr != p.miner { + return api.SectorOffset{}, xerrors.Errorf("miner address doesn't match") + } - _, err := tx.Exec("INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3)", mid, n, spt) + if piece.DealProposal.PieceSize != abi.PaddedPieceSize(p.sectorSize) { + return api.SectorOffset{}, xerrors.Errorf("only full sector pieces supported for now") + } + + // check raw size + if piece.DealProposal.PieceSize != padreader.PaddedSize(uint64(rawSize)).Padded() { + return api.SectorOffset{}, xerrors.Errorf("raw size doesn't match padded piece size") + } + + var propJson []byte + + dataHdrJson, err := json.Marshal(header) + if err != nil { + return api.SectorOffset{}, xerrors.Errorf("json.Marshal(header): %w", err) + } + + if piece.DealProposal != nil { + propJson, err = json.Marshal(piece.DealProposal) if err != nil { - return false, xerrors.Errorf("inserting into sectors_sdr_pipeline: %w", err) + return api.SectorOffset{}, xerrors.Errorf("json.Marshal(piece.DealProposal): %w", err) } - - dataHdrJson, err := json.Marshal(header) + } else { + propJson, err = json.Marshal(piece.PieceActivationManifest) if err != nil { - return false, xerrors.Errorf("json.Marshal(header): %w", err) + return api.SectorOffset{}, xerrors.Errorf("json.Marshal(piece.PieceActivationManifest): %w", err) } + } - dealProposalJson, err := json.Marshal(piece.DealProposal) + p.lk.Lock() + defer p.lk.Unlock() + + if !p.sealRightNow { + // Try to allocate the piece to an open sector + allocated, ret, err := p.allocateToExisting(ctx, piece, rawSize, source, dataHdrJson, propJson) if err != nil { - return false, xerrors.Errorf("json.Marshal(piece.DealProposal): %w", err) + return api.SectorOffset{}, err + } + if allocated { + return ret, nil } + } - _, err = tx.Exec(`INSERT INTO sectors_sdr_initial_pieces (sp_id, + // Allocation to open sector failed, create a new sector and add the piece to it + num, err := seal.AllocateSectorNumbers(ctx, p.api, p.db, maddr, 1, func(tx *harmonydb.Tx, numbers []abi.SectorNumber) (bool, error) { + if len(numbers) != 1 { + return false, xerrors.Errorf("expected one sector number") + } + n := numbers[0] + + if piece.DealProposal != nil { + _, err = tx.Exec(`INSERT INTO sectors_sdr_initial_pieces (sp_id, sector_number, piece_index, @@ -110,15 +300,37 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address f05_deal_proposal, f05_deal_start_epoch, f05_deal_end_epoch) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, - mid, n, 0, - piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, - source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, - piece.PublishCid, piece.DealID, dealProposalJson, - piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch) - if err != nil { - return false, xerrors.Errorf("inserting into sectors_sdr_initial_pieces: %w", err) + p.mid, n, 0, + piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, + piece.PublishCid, piece.DealID, propJson, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch) + if err != nil { + return false, xerrors.Errorf("inserting into sectors_sdr_initial_pieces: %w", err) + } + } else { + _, err = tx.Exec(`INSERT INTO sectors_sdr_initial_pieces (sp_id, + sector_number, + piece_index, + + piece_cid, + piece_size, + + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + + direct_start_epoch, + direct_end_epoch, + direct_piece_activation_manifest) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, + p.mid, n, 0, + piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, + piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) + if err != nil { + return false, xerrors.Errorf("inserting into sectors_sdr_initial_pieces: %w", err) + } } - return true, nil }) if err != nil { @@ -129,10 +341,122 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address return api.SectorOffset{}, xerrors.Errorf("expected one sector number") } - // After we insert the piece/sector_pipeline entries, the lpseal/poller will take it from here + sec := &openSector{ + number: num[0], + currentSize: piece.DealProposal.PieceSize, + earliestEpoch: piece.DealProposal.StartEpoch, + index: 0, + openedAt: time.Now(), + } + + if p.sealRightNow { + sec.sealNow = true + } + + p.openSectors = append(p.openSectors, sec) return api.SectorOffset{ Sector: num[0], Offset: 0, }, nil } + +func (p *PieceIngester) allocateToExisting(ctx context.Context, piece lpiece.PieceDealInfo, rawSize int64, source url.URL, dataHdrJson, propJson []byte) (bool, api.SectorOffset, error) { + for i := range p.openSectors { + sec := p.openSectors[i] + sec.lk.Lock() + defer sec.lk.Unlock() + pieceSize := piece.Size() + if sec.currentSize+pieceSize < abi.PaddedPieceSize(p.sectorSize) { + + ret := api.SectorOffset{ + Sector: sec.number, + Offset: sec.currentSize + 1, // Current filled up size + 1 + } + + // Insert market deal to DB for the sector + if piece.DealProposal != nil { + cn, err := p.db.Exec(ctx, `INSERT INTO sectors_sdr_initial_pieces (sp_id, + sector_number, + piece_index, + + piece_cid, + piece_size, + + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + + f05_publish_cid, + f05_deal_id, + f05_deal_proposal, + f05_deal_start_epoch, + f05_deal_end_epoch) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, + p.mid, sec.number, sec.index+1, + piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, + piece.PublishCid, piece.DealID, propJson, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch) + + if err != nil { + return false, api.SectorOffset{}, xerrors.Errorf("adding deal to sector: %w", err) + } + + if cn != 1 { + return false, api.SectorOffset{}, xerrors.Errorf("expected one piece") + } + } else { // Insert DDO deal to DB for the sector + cn, err := p.db.Exec(ctx, `INSERT INTO sectors_sdr_initial_pieces (sp_id, + sector_number, + piece_index, + + piece_cid, + piece_size, + + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + + direct_start_epoch, + direct_end_epoch, + direct_piece_activation_manifest) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, + p.mid, sec.number, sec.index+1, + piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, + piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) + + if err != nil { + return false, api.SectorOffset{}, xerrors.Errorf("adding deal to sector: %w", err) + } + + if cn != 1 { + return false, api.SectorOffset{}, xerrors.Errorf("expected one piece") + } + } + sec.currentSize += pieceSize + startEpoch, _ := piece.StartEpoch() // ignoring error as method always returns nil + if sec.earliestEpoch > startEpoch { + sec.earliestEpoch = startEpoch + } + sec.index++ + return true, ret, nil + } + } + return false, api.SectorOffset{}, nil +} + +func (p *PieceIngester) SectorStartSealing(ctx context.Context, sector abi.SectorNumber) error { + p.lk.Lock() + defer p.lk.Unlock() + for _, s := range p.openSectors { + s := s + if s.number == sector { + s.lk.Lock() + s.sealNow = true + s.lk.Unlock() + return nil + } + } + return xerrors.Errorf("sector not found") +} diff --git a/curiosrc/market/lmrpc/lmrpc.go b/curiosrc/market/lmrpc/lmrpc.go index 33c0d34deb3..da4f5f75072 100644 --- a/curiosrc/market/lmrpc/lmrpc.go +++ b/curiosrc/market/lmrpc/lmrpc.go @@ -2,11 +2,13 @@ package lmrpc import ( "context" + "errors" "fmt" "io" "net" "net/http" "net/url" + "sort" "strconv" "strings" "sync" @@ -32,6 +34,7 @@ import ( "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/storage/paths" + "github.com/filecoin-project/lotus/storage/pipeline/piece" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -149,7 +152,10 @@ func forEachMarketRPC(cfg *config.CurioConfig, cb func(string, string) error) er func ServeCurioMarketRPC(db *harmonydb.DB, full api.FullNode, maddr address.Address, conf *config.CurioConfig, listen string) error { ctx := context.Background() - pin := cumarket.NewPieceIngester(db, full) + pin, err := cumarket.NewPieceIngester(ctx, db, full, maddr, false, time.Duration(conf.Ingest.MaxDealWaitTime)) + if err != nil { + return xerrors.Errorf("starting piece ingestor") + } si := paths.NewDBIndex(nil, db) @@ -188,8 +194,10 @@ func ServeCurioMarketRPC(db *harmonydb.DB, full api.FullNode, maddr address.Addr }, nil } - ast.CommonStruct.Internal.AuthNew = lp.AuthNew + pieceInfoLk := new(sync.Mutex) + pieceInfos := map[uuid.UUID][]pieceInfo{} + ast.CommonStruct.Internal.AuthNew = lp.AuthNew ast.Internal.ActorAddress = lp.ActorAddress ast.Internal.WorkerJobs = lp.WorkerJobs ast.Internal.SectorsStatus = lp.SectorsStatus @@ -198,164 +206,7 @@ func ServeCurioMarketRPC(db *harmonydb.DB, full api.FullNode, maddr address.Addr ast.Internal.SectorsListInStates = lp.SectorsListInStates ast.Internal.StorageRedeclareLocal = lp.StorageRedeclareLocal ast.Internal.ComputeDataCid = lp.ComputeDataCid - - type pieceInfo struct { - data storiface.Data - size abi.UnpaddedPieceSize - - done chan struct{} - } - - pieceInfoLk := new(sync.Mutex) - pieceInfos := map[uuid.UUID][]pieceInfo{} - - ast.Internal.SectorAddPieceToAny = func(ctx context.Context, pieceSize abi.UnpaddedPieceSize, pieceData storiface.Data, deal api.PieceDealInfo) (api.SectorOffset, error) { - origPieceData := pieceData - defer func() { - closer, ok := origPieceData.(io.Closer) - if !ok { - log.Warnf("DataCid: cannot close pieceData reader %T because it is not an io.Closer", origPieceData) - return - } - if err := closer.Close(); err != nil { - log.Warnw("closing pieceData in DataCid", "error", err) - } - }() - - pi := pieceInfo{ - data: pieceData, - size: pieceSize, - - done: make(chan struct{}), - } - - pieceUUID := uuid.New() - - //color.Blue("%s %s piece assign request with id %s", deal.DealProposal.PieceCID, deal.DealProposal.Provider, pieceUUID) - log.Infow("piece assign request", "piece_cid", deal.DealProposal.PieceCID, "provider", deal.DealProposal.Provider, "piece_uuid", pieceUUID) - - pieceInfoLk.Lock() - pieceInfos[pieceUUID] = append(pieceInfos[pieceUUID], pi) - pieceInfoLk.Unlock() - - // /piece?piece_cid=xxxx - dataUrl := rootUrl - dataUrl.Path = "/piece" - dataUrl.RawQuery = "piece_id=" + pieceUUID.String() - - // add piece entry - - var refID int64 - var pieceWasCreated bool - - for { - var backpressureWait bool - - comm, err := db.BeginTransaction(ctx, func(tx *harmonydb.Tx) (commit bool, err error) { - // BACKPRESSURE - wait, err := maybeApplyBackpressure(tx, conf.Ingest) - if err != nil { - return false, xerrors.Errorf("backpressure checks: %w", err) - } - if wait { - backpressureWait = true - return false, nil - } - - var pieceID int64 - // Attempt to select the piece ID first - err = tx.QueryRow(`SELECT id FROM parked_pieces WHERE piece_cid = $1`, deal.DealProposal.PieceCID.String()).Scan(&pieceID) - - if err != nil { - if err == pgx.ErrNoRows { - // Piece does not exist, attempt to insert - err = tx.QueryRow(` - INSERT INTO parked_pieces (piece_cid, piece_padded_size, piece_raw_size) - VALUES ($1, $2, $3) - ON CONFLICT (piece_cid) DO NOTHING - RETURNING id`, deal.DealProposal.PieceCID.String(), int64(pieceSize.Padded()), int64(pieceSize)).Scan(&pieceID) - if err != nil { - return false, xerrors.Errorf("inserting new parked piece and getting id: %w", err) - } - pieceWasCreated = true // New piece was created - } else { - // Some other error occurred during select - return false, xerrors.Errorf("checking existing parked piece: %w", err) - } - } else { - pieceWasCreated = false // Piece already exists, no new piece was created - } - - // Add parked_piece_ref - err = tx.QueryRow(`INSERT INTO parked_piece_refs (piece_id, data_url) - VALUES ($1, $2) RETURNING ref_id`, pieceID, dataUrl.String()).Scan(&refID) - if err != nil { - return false, xerrors.Errorf("inserting parked piece ref: %w", err) - } - - // If everything went well, commit the transaction - return true, nil // This will commit the transaction - }, harmonydb.OptionRetry()) - if err != nil { - return api.SectorOffset{}, xerrors.Errorf("inserting parked piece: %w", err) - } - if !comm { - if backpressureWait { - // Backpressure was applied, wait and try again - select { - case <-time.After(backpressureWaitTime): - case <-ctx.Done(): - return api.SectorOffset{}, xerrors.Errorf("context done while waiting for backpressure: %w", ctx.Err()) - } - continue - } - - return api.SectorOffset{}, xerrors.Errorf("piece tx didn't commit") - } - - break - } - - // wait for piece to be parked - if pieceWasCreated { - <-pi.done - } else { - // If the piece was not created, we need to close the done channel - close(pi.done) - - go func() { - // close the data reader (drain to eof if it's not a closer) - if closer, ok := pieceData.(io.Closer); ok { - if err := closer.Close(); err != nil { - log.Warnw("closing pieceData in DataCid", "error", err) - } - } else { - log.Warnw("pieceData is not an io.Closer", "type", fmt.Sprintf("%T", pieceData)) - - _, err := io.Copy(io.Discard, pieceData) - if err != nil { - log.Warnw("draining pieceData in DataCid", "error", err) - } - } - }() - } - - pieceIDUrl := url.URL{ - Scheme: "pieceref", - Opaque: fmt.Sprintf("%d", refID), - } - - // make a sector - so, err := pin.AllocatePieceToSector(ctx, maddr, deal, int64(pieceSize), pieceIDUrl, nil) - if err != nil { - return api.SectorOffset{}, err - } - - log.Infow("piece assigned to sector", "piece_cid", deal.DealProposal.PieceCID, "sector", so.Sector, "offset", so.Offset) - - return so, nil - } - + ast.Internal.SectorAddPieceToAny = sectorAddPieceToAnyOperation(maddr, rootUrl, conf, pieceInfoLk, pieceInfos, pin, db, mi.SectorSize) ast.Internal.StorageList = si.StorageList ast.Internal.StorageDetach = si.StorageDetach ast.Internal.StorageReportHealth = si.StorageReportHealth @@ -367,6 +218,7 @@ func ServeCurioMarketRPC(db *harmonydb.DB, full api.FullNode, maddr address.Addr ast.Internal.StorageLock = si.StorageLock ast.Internal.StorageTryLock = si.StorageTryLock ast.Internal.StorageGetLocks = si.StorageGetLocks + ast.Internal.SectorStartSealing = pin.SectorStartSealing var pieceHandler http.HandlerFunc = func(w http.ResponseWriter, r *http.Request) { // /piece?piece_id=xxxx @@ -435,7 +287,7 @@ func ServeCurioMarketRPC(db *harmonydb.DB, full api.FullNode, maddr address.Addr mux := http.NewServeMux() mux.Handle("/piece", pieceHandler) - mux.Handle("/", mh) + mux.Handle("/", mh) // todo: create a method for sealNow for sectors server := &http.Server{ Addr: listen, @@ -447,40 +299,224 @@ func ServeCurioMarketRPC(db *harmonydb.DB, full api.FullNode, maddr address.Addr return server.ListenAndServe() } -func maybeApplyBackpressure(tx *harmonydb.Tx, cfg config.CurioIngestConfig) (wait bool, err error) { - var bufferedSDR, bufferedTrees, bufferedPoRep int - err = tx.QueryRow(`WITH BufferedSDR AS ( - SELECT SUM(buffered_count) AS buffered_sdr_count - FROM ( - SELECT COUNT(p.task_id_sdr) - COUNT(t.owner_id) AS buffered_count - FROM sectors_sdr_pipeline p - LEFT JOIN harmony_task t ON p.task_id_sdr = t.id - WHERE p.after_sdr = false - UNION ALL - SELECT COUNT(1) AS buffered_count - FROM parked_pieces - WHERE complete = false - ) AS subquery -), - BufferedTrees AS ( - SELECT COUNT(p.task_id_tree_r) - COUNT(t.owner_id) AS buffered_trees_count - FROM sectors_sdr_pipeline p - LEFT JOIN harmony_task t ON p.task_id_tree_r = t.id - WHERE p.after_sdr = true AND p.after_tree_r = false - ), - BufferedPoRep AS ( - SELECT COUNT(p.task_id_porep) - COUNT(t.owner_id) AS buffered_porep_count - FROM sectors_sdr_pipeline p - LEFT JOIN harmony_task t ON p.task_id_porep = t.id - WHERE p.after_tree_r = true AND p.after_porep = false - ) -SELECT - (SELECT buffered_sdr_count FROM BufferedSDR) AS total_buffered, +type pieceInfo struct { + data storiface.Data + size abi.UnpaddedPieceSize + + done chan struct{} +} + +func sectorAddPieceToAnyOperation(maddr address.Address, rootUrl url.URL, conf *config.CurioConfig, pieceInfoLk *sync.Mutex, pieceInfos map[uuid.UUID][]pieceInfo, pin *cumarket.PieceIngester, db *harmonydb.DB, ssize abi.SectorSize) func(ctx context.Context, pieceSize abi.UnpaddedPieceSize, pieceData storiface.Data, deal api.PieceDealInfo) (api.SectorOffset, error) { + return func(ctx context.Context, pieceSize abi.UnpaddedPieceSize, pieceData storiface.Data, deal piece.PieceDealInfo) (api.SectorOffset, error) { + if (deal.PieceActivationManifest == nil && deal.DealProposal == nil) || (deal.PieceActivationManifest != nil && deal.DealProposal != nil) { + return api.SectorOffset{}, xerrors.Errorf("deal info must have either deal proposal or piece manifest") + } + + origPieceData := pieceData + defer func() { + closer, ok := origPieceData.(io.Closer) + if !ok { + log.Warnf("DataCid: cannot close pieceData reader %T because it is not an io.Closer", origPieceData) + return + } + if err := closer.Close(); err != nil { + log.Warnw("closing pieceData in DataCid", "error", err) + } + }() + + pi := pieceInfo{ + data: pieceData, + size: pieceSize, + + done: make(chan struct{}), + } + + pieceUUID := uuid.New() + + log.Infow("piece assign request", "piece_cid", deal.DealProposal.PieceCID, "provider", deal.DealProposal.Provider, "piece_uuid", pieceUUID) + + pieceInfoLk.Lock() + pieceInfos[pieceUUID] = append(pieceInfos[pieceUUID], pi) + pieceInfoLk.Unlock() + + // /piece?piece_cid=xxxx + dataUrl := rootUrl + dataUrl.Path = "/piece" + dataUrl.RawQuery = "piece_id=" + pieceUUID.String() + + // add piece entry + refID, pieceWasCreated, err := addPieceEntry(ctx, db, conf, deal, pieceSize, dataUrl, ssize) + if err != nil { + return api.SectorOffset{}, err + } + + // wait for piece to be parked + if pieceWasCreated { + <-pi.done + } else { + // If the piece was not created, we need to close the done channel + close(pi.done) + + closeDataReader(pieceData) + } + + pieceIDUrl := url.URL{ + Scheme: "pieceref", + Opaque: fmt.Sprintf("%d", refID), + } + + // make a sector + so, err := pin.AllocatePieceToSector(ctx, maddr, deal, int64(pieceSize), pieceIDUrl, nil) + if err != nil { + return api.SectorOffset{}, err + } + + log.Infow("piece assigned to sector", "piece_cid", deal.DealProposal.PieceCID, "sector", so.Sector, "offset", so.Offset) + + return so, nil + } +} + +func addPieceEntry(ctx context.Context, db *harmonydb.DB, conf *config.CurioConfig, deal api.PieceDealInfo, pieceSize abi.UnpaddedPieceSize, dataUrl url.URL, ssize abi.SectorSize) (int64, bool, error) { + var refID int64 + var pieceWasCreated bool + + for { + var backpressureWait bool + + comm, err := db.BeginTransaction(ctx, func(tx *harmonydb.Tx) (commit bool, err error) { + // BACKPRESSURE + wait, err := maybeApplyBackpressure(tx, conf.Ingest, ssize) + if err != nil { + return false, xerrors.Errorf("backpressure checks: %w", err) + } + if wait { + backpressureWait = true + return false, nil + } + + var pieceID int64 + // Attempt to select the piece ID first + err = tx.QueryRow(`SELECT id FROM parked_pieces WHERE piece_cid = $1`, deal.DealProposal.PieceCID.String()).Scan(&pieceID) + + if err != nil { + if errors.Is(err, pgx.ErrNoRows) { + // Piece does not exist, attempt to insert + err = tx.QueryRow(` + INSERT INTO parked_pieces (piece_cid, piece_padded_size, piece_raw_size) + VALUES ($1, $2, $3) + ON CONFLICT (piece_cid) DO NOTHING + RETURNING id`, deal.DealProposal.PieceCID.String(), int64(pieceSize.Padded()), int64(pieceSize)).Scan(&pieceID) + if err != nil { + return false, xerrors.Errorf("inserting new parked piece and getting id: %w", err) + } + pieceWasCreated = true // New piece was created + } else { + // Some other error occurred during select + return false, xerrors.Errorf("checking existing parked piece: %w", err) + } + } else { + pieceWasCreated = false // Piece already exists, no new piece was created + } + + // Add parked_piece_ref + err = tx.QueryRow(`INSERT INTO parked_piece_refs (piece_id, data_url) + VALUES ($1, $2) RETURNING ref_id`, pieceID, dataUrl.String()).Scan(&refID) + if err != nil { + return false, xerrors.Errorf("inserting parked piece ref: %w", err) + } + + // If everything went well, commit the transaction + return true, nil // This will commit the transaction + }, harmonydb.OptionRetry()) + if err != nil { + return refID, pieceWasCreated, xerrors.Errorf("inserting parked piece: %w", err) + } + if !comm { + if backpressureWait { + // Backpressure was applied, wait and try again + select { + case <-time.After(backpressureWaitTime): + case <-ctx.Done(): + return refID, pieceWasCreated, xerrors.Errorf("context done while waiting for backpressure: %w", ctx.Err()) + } + continue + } + + return refID, pieceWasCreated, xerrors.Errorf("piece tx didn't commit") + } + + break + } + return refID, pieceWasCreated, nil +} + +func closeDataReader(pieceData storiface.Data) { + go func() { + // close the data reader (drain to eof if it's not a closer) + if closer, ok := pieceData.(io.Closer); ok { + if err := closer.Close(); err != nil { + log.Warnw("closing pieceData in DataCid", "error", err) + } + } else { + log.Warnw("pieceData is not an io.Closer", "type", fmt.Sprintf("%T", pieceData)) + + _, err := io.Copy(io.Discard, pieceData) + if err != nil { + log.Warnw("draining pieceData in DataCid", "error", err) + } + } + }() +} + +func maybeApplyBackpressure(tx *harmonydb.Tx, cfg config.CurioIngestConfig, ssize abi.SectorSize) (wait bool, err error) { + var bufferedSDR, bufferedTrees, bufferedPoRep, waitDealSectors int + err = tx.QueryRow(` + WITH BufferedSDR AS ( + SELECT COUNT(p.task_id_sdr) - COUNT(t.owner_id) AS buffered_sdr_count + FROM sectors_sdr_pipeline p + LEFT JOIN harmony_task t ON p.task_id_sdr = t.id + WHERE p.after_sdr = false + ), + BufferedTrees AS ( + SELECT COUNT(p.task_id_tree_r) - COUNT(t.owner_id) AS buffered_trees_count + FROM sectors_sdr_pipeline p + LEFT JOIN harmony_task t ON p.task_id_tree_r = t.id + WHERE p.after_sdr = true AND p.after_tree_r = false + ), + BufferedPoRep AS ( + SELECT COUNT(p.task_id_porep) - COUNT(t.owner_id) AS buffered_porep_count + FROM sectors_sdr_pipeline p + LEFT JOIN harmony_task t ON p.task_id_porep = t.id + WHERE p.after_tree_r = true AND p.after_porep = false + ), + WaitDealSectors AS ( + SELECT COUNT(DISTINCT sip.sector_number) AS wait_deal_sectors_count + FROM sectors_sdr_initial_pieces sip + LEFT JOIN sectors_sdr_pipeline sp ON sip.sp_id = sp.sp_id AND sip.sector_number = sp.sector_number + WHERE sp.sector_number IS NULL + ) + SELECT + (SELECT buffered_sdr_count FROM BufferedSDR) AS total_buffered_sdr, (SELECT buffered_trees_count FROM BufferedTrees) AS buffered_trees_count, - (SELECT buffered_porep_count FROM BufferedPoRep) AS buffered_porep_count -`).Scan(&bufferedSDR, &bufferedTrees, &bufferedPoRep) + (SELECT buffered_porep_count FROM BufferedPoRep) AS buffered_porep_count, + (SELECT wait_deal_sectors_count FROM WaitDealSectors) AS wait_deal_sectors_count, +`).Scan(&bufferedSDR, &bufferedTrees, &bufferedPoRep, &waitDealSectors) + if err != nil { + return false, xerrors.Errorf("counting buffered sectors: %w", err) + } + + var pieceSizes []abi.PaddedPieceSize + + err = tx.Select(&pieceSizes, `SELECT piece_padded_size FROM curio.parked_pieces WHERE complete = false;`) if err != nil { - return false, xerrors.Errorf("counting parked pieces: %w", err) + return false, xerrors.Errorf("getting in-process pieces") + } + + sectors := sectorCount(pieceSizes, abi.PaddedPieceSize(ssize)) + if cfg.MaxQueueDealSector != 0 && waitDealSectors+sectors > cfg.MaxQueueDealSector { + log.Debugw("backpressure", "reason", "too many wait deal sectors", "wait_deal_sectors", waitDealSectors, "max", cfg.MaxQueueDealSector) + return true, nil } if cfg.MaxQueueSDR != 0 && bufferedSDR > cfg.MaxQueueSDR { @@ -498,3 +534,27 @@ SELECT return false, nil } + +func sectorCount(sizes []abi.PaddedPieceSize, targetSize abi.PaddedPieceSize) int { + sort.Slice(sizes, func(i, j int) bool { + return sizes[i] > sizes[j] + }) + + sectors := make([]abi.PaddedPieceSize, 0) + + for _, size := range sizes { + placed := false + for i := range sectors { + if sectors[i]+size <= targetSize { + sectors[i] += size + placed = true + break + } + } + if !placed { + sectors = append(sectors, size) + } + } + + return len(sectors) +} diff --git a/curiosrc/seal/task_submit_precommit.go b/curiosrc/seal/task_submit_precommit.go index d42bcbe0d6c..063aa425269 100644 --- a/curiosrc/seal/task_submit_precommit.go +++ b/curiosrc/seal/task_submit_precommit.go @@ -127,37 +127,42 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo F05DealID int64 `db:"f05_deal_id"` F05DealEndEpoch int64 `db:"f05_deal_end_epoch"` F05DealStartEpoch int64 `db:"f05_deal_start_epoch"` + + DDODealStartEpoch int64 `db:"direct_start_epoch"` + DDODealEndEpoch int64 `db:"direct_end_epoch"` } err = s.db.Select(ctx, &pieces, ` - SELECT piece_index, piece_cid, piece_size, f05_deal_id, f05_deal_end_epoch, f05_deal_start_epoch + SELECT piece_index, piece_cid, piece_size, f05_deal_id, f05_deal_end_epoch, f05_deal_start_epoch, direct_start_epoch, direct_end_epoch FROM sectors_sdr_initial_pieces WHERE sp_id = $1 AND sector_number = $2 ORDER BY piece_index ASC`, sectorParams.SpID, sectorParams.SectorNumber) if err != nil { return false, xerrors.Errorf("getting pieces: %w", err) } - if len(pieces) > 1 { - return false, xerrors.Errorf("too many pieces") // todo support multiple pieces - } - if len(pieces) > 0 { params.Sectors[0].UnsealedCid = &unsealedCID - params.Sectors[0].Expiration = abi.ChainEpoch(pieces[0].F05DealEndEpoch) - if abi.ChainEpoch(pieces[0].F05DealStartEpoch) < head.Height() { - // deal start epoch is in the past, can't precommit this sector anymore - _, perr := s.db.Exec(ctx, `UPDATE sectors_sdr_pipeline + for _, p := range pieces { + if (p.DDODealStartEpoch > 0 && abi.ChainEpoch(p.DDODealStartEpoch) < head.Height()) || (p.F05DealEndEpoch > 0 && abi.ChainEpoch(p.F05DealStartEpoch) < head.Height()) { + // deal start epoch is in the past, can't precommit this sector anymore + _, perr := s.db.Exec(ctx, `UPDATE sectors_sdr_pipeline SET failed = TRUE, failed_at = NOW(), failed_reason = 'past-start-epoch', failed_reason_msg = 'precommit: start epoch is in the past' WHERE task_id_precommit_msg = $1`, taskID) - if perr != nil { - return false, xerrors.Errorf("persisting precommit start epoch expiry: %w", perr) + if perr != nil { + return false, xerrors.Errorf("persisting precommit start epoch expiry: %w", perr) + } + return true, xerrors.Errorf("deal start epoch is in the past") + } + if p.F05DealID > 0 { + params.Sectors[0].DealIDs = append(params.Sectors[0].DealIDs, abi.DealID(p.F05DealID)) + } + if p.F05DealEndEpoch > 0 && abi.ChainEpoch(p.F05DealEndEpoch) > params.Sectors[0].Expiration { + params.Sectors[0].Expiration = abi.ChainEpoch(p.F05DealEndEpoch) + } + if p.DDODealEndEpoch > 0 && abi.ChainEpoch(p.DDODealEndEpoch) > params.Sectors[0].Expiration { + params.Sectors[0].Expiration = abi.ChainEpoch(p.DDODealEndEpoch) } - return true, xerrors.Errorf("deal start epoch is in the past") - } - - for _, p := range pieces { - params.Sectors[0].DealIDs = append(params.Sectors[0].DealIDs, abi.DealID(p.F05DealID)) } } } diff --git a/documentation/en/default-curio-config.toml b/documentation/en/default-curio-config.toml index 7bf34d3567e..09abe85015a 100644 --- a/documentation/en/default-curio-config.toml +++ b/documentation/en/default-curio-config.toml @@ -319,16 +319,24 @@ [Ingest] + # Maximum number of sectors that can be queued waiting for deals to start processing. + # 0 = unlimited + # Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. + # The DealSector queue includes deals which are ready to enter the sealing pipeline but are not yet part of it - + # size of this queue will also impact the maximum number of ParkPiece tasks which can run concurrently. + # DealSector queue is the first queue in the sealing pipeline, meaning that it should be used as the primary backpressure mechanism. + # + # type: int + #MaxQueueDealSector = 8 + # Maximum number of sectors that can be queued waiting for SDR to start processing. # 0 = unlimited # Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. - # The SDR queue includes deals which are in the process of entering the sealing pipeline - size of this queue - # will also impact the maximum number of ParkPiece tasks which can run concurrently. - # - # SDR queue is the first queue in the sealing pipeline, meaning that it should be used as the primary backpressure mechanism. + # The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the trees tasks it is + # possible that this queue grows more than this limit, the backpressure is only applied to sectors entering the pipeline. # # type: int - #MaxQueueSDR = 8 + #MaxQueueSDR = 0 # Maximum number of sectors that can be queued waiting for SDRTrees to start processing. # 0 = unlimited @@ -348,6 +356,11 @@ # type: int #MaxQueuePoRep = 0 + # Maximum time an open deal sector should wait for more deal before it starts sealing + # + # type: Duration + #MaxDealWaitTime = "1h0m0s" + [Journal] # Events of the form: "system1:event1,system1:event2[,...]" diff --git a/node/config/def.go b/node/config/def.go index 2dd4b77eb2f..b6b66758287 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -364,9 +364,11 @@ func DefaultCurioConfig() *CurioConfig { SingleCheckTimeout: Duration(10 * time.Minute), }, Ingest: CurioIngestConfig{ - MaxQueueSDR: 8, // default to 8 sectors before sdr - MaxQueueTrees: 0, // default don't use this limit - MaxQueuePoRep: 0, // default don't use this limit + MaxQueueDealSector: 8, // default to 8 sectors open(or in process of opening) for deals + MaxQueueSDR: 0, // default don't use this limit + MaxQueueTrees: 0, // default don't use this limit + MaxQueuePoRep: 0, // default don't use this limit + MaxDealWaitTime: Duration(1 * time.Hour), }, } } diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index 17bc0febffa..b646040094e 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -278,6 +278,17 @@ over the worker address if this flag is set.`, }, }, "CurioIngestConfig": { + { + Name: "MaxQueueDealSector", + Type: "int", + + Comment: `Maximum number of sectors that can be queued waiting for deals to start processing. +0 = unlimited +Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. +The DealSector queue includes deals which are ready to enter the sealing pipeline but are not yet part of it - +size of this queue will also impact the maximum number of ParkPiece tasks which can run concurrently. +DealSector queue is the first queue in the sealing pipeline, meaning that it should be used as the primary backpressure mechanism.`, + }, { Name: "MaxQueueSDR", Type: "int", @@ -285,10 +296,8 @@ over the worker address if this flag is set.`, Comment: `Maximum number of sectors that can be queued waiting for SDR to start processing. 0 = unlimited Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. -The SDR queue includes deals which are in the process of entering the sealing pipeline - size of this queue -will also impact the maximum number of ParkPiece tasks which can run concurrently. - -SDR queue is the first queue in the sealing pipeline, meaning that it should be used as the primary backpressure mechanism.`, +The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the trees tasks it is +possible that this queue grows more than this limit, the backpressure is only applied to sectors entering the pipeline.`, }, { Name: "MaxQueueTrees", @@ -310,6 +319,12 @@ Note: This mechanism will delay taking deal data from markets, providing backpre Like with the trees tasks, it is possible that this queue grows more than this limit, the backpressure is only applied to sectors entering the pipeline.`, }, + { + Name: "MaxDealWaitTime", + Type: "Duration", + + Comment: `Maximum time an open deal sector should wait for more deal before it starts sealing`, + }, }, "CurioProvingConfig": { { diff --git a/node/config/types.go b/node/config/types.go index 031bdf9088f..f09ee4a603b 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -828,13 +828,19 @@ type CurioProvingConfig struct { } type CurioIngestConfig struct { + // Maximum number of sectors that can be queued waiting for deals to start processing. + // 0 = unlimited + // Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. + // The DealSector queue includes deals which are ready to enter the sealing pipeline but are not yet part of it - + // size of this queue will also impact the maximum number of ParkPiece tasks which can run concurrently. + // DealSector queue is the first queue in the sealing pipeline, meaning that it should be used as the primary backpressure mechanism. + MaxQueueDealSector int + // Maximum number of sectors that can be queued waiting for SDR to start processing. // 0 = unlimited // Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. - // The SDR queue includes deals which are in the process of entering the sealing pipeline - size of this queue - // will also impact the maximum number of ParkPiece tasks which can run concurrently. - // - // SDR queue is the first queue in the sealing pipeline, meaning that it should be used as the primary backpressure mechanism. + // The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the trees tasks it is + // possible that this queue grows more than this limit, the backpressure is only applied to sectors entering the pipeline. MaxQueueSDR int // Maximum number of sectors that can be queued waiting for SDRTrees to start processing. @@ -850,6 +856,9 @@ type CurioIngestConfig struct { // Like with the trees tasks, it is possible that this queue grows more than this limit, the backpressure is only // applied to sectors entering the pipeline. MaxQueuePoRep int + + // Maximum time an open deal sector should wait for more deal before it starts sealing + MaxDealWaitTime Duration } // API contains configs for API endpoint diff --git a/storage/pipeline/piece/piece_info.go b/storage/pipeline/piece/piece_info.go index 48e15751ad0..7c34e94e7ca 100644 --- a/storage/pipeline/piece/piece_info.go +++ b/storage/pipeline/piece/piece_info.go @@ -170,6 +170,15 @@ func (ds *PieceDealInfo) String() string { } } +func (ds *PieceDealInfo) Size() abi.PaddedPieceSize { + switch { + case ds.isBuiltinMarketDeal(): + return ds.DealProposal.PieceSize + default: + return ds.PieceActivationManifest.Size + } +} + func (ds *PieceDealInfo) KeepUnsealedRequested() bool { return ds.KeepUnsealed } From 78e26310e35144e4a45588dabd62fbf162679770 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 30 Apr 2024 19:17:16 +0530 Subject: [PATCH 02/17] in memory to DB --- api/api_curio.go | 3 +- api/proxy_gen.go | 7 +- build/openrpc/full.json | 486 ++++++++-------- build/openrpc/gateway.json | 192 +++---- build/openrpc/miner.json | 260 ++++----- build/openrpc/worker.json | 74 +-- curiosrc/market/deal_ingest.go | 517 ++++++++++-------- curiosrc/market/fakelm/lmimpl.go | 3 +- go.mod | 1 + .../harmonydb/sql/20231217-sdr-pipeline.sql | 3 + .../sql/20240430-init-piece-createdat.sql | 114 ++++ 11 files changed, 911 insertions(+), 749 deletions(-) create mode 100644 lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql diff --git a/api/api_curio.go b/api/api_curio.go index 0eceb484fdb..8a6f428e076 100644 --- a/api/api_curio.go +++ b/api/api_curio.go @@ -8,6 +8,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" + lpiece "github.com/filecoin-project/lotus/storage/pipeline/piece" "github.com/filecoin-project/lotus/storage/sealer/fsutil" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -15,7 +16,7 @@ import ( type Curio interface { Version(context.Context) (Version, error) //perm:admin - AllocatePieceToSector(ctx context.Context, maddr address.Address, piece PieceDealInfo, rawSize int64, source url.URL, header http.Header) (SectorOffset, error) //perm:write + AllocatePieceToSector(ctx context.Context, maddr address.Address, piece lpiece.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (SectorOffset, error) //perm:write StorageInit(ctx context.Context, path string, opts storiface.LocalStorageMeta) error //perm:admin StorageAddLocal(ctx context.Context, path string) error //perm:admin diff --git a/api/proxy_gen.go b/api/proxy_gen.go index f9e7866151b..b34ff780f89 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -44,6 +44,7 @@ import ( "github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/repo/imports" "github.com/filecoin-project/lotus/storage/pipeline/piece" + lpiece "github.com/filecoin-project/lotus/storage/pipeline/piece" "github.com/filecoin-project/lotus/storage/pipeline/sealiface" "github.com/filecoin-project/lotus/storage/sealer/fsutil" "github.com/filecoin-project/lotus/storage/sealer/sealtasks" @@ -120,7 +121,7 @@ type CurioStruct struct { } type CurioMethods struct { - AllocatePieceToSector func(p0 context.Context, p1 address.Address, p2 PieceDealInfo, p3 int64, p4 url.URL, p5 http.Header) (SectorOffset, error) `perm:"write"` + AllocatePieceToSector func(p0 context.Context, p1 address.Address, p2 lpiece.PieceDealInfo, p3 int64, p4 url.URL, p5 http.Header) (SectorOffset, error) `perm:"write"` LogList func(p0 context.Context) ([]string, error) `perm:"read"` @@ -1494,14 +1495,14 @@ func (s *CommonStub) Version(p0 context.Context) (APIVersion, error) { return *new(APIVersion), ErrNotSupported } -func (s *CurioStruct) AllocatePieceToSector(p0 context.Context, p1 address.Address, p2 PieceDealInfo, p3 int64, p4 url.URL, p5 http.Header) (SectorOffset, error) { +func (s *CurioStruct) AllocatePieceToSector(p0 context.Context, p1 address.Address, p2 lpiece.PieceDealInfo, p3 int64, p4 url.URL, p5 http.Header) (SectorOffset, error) { if s.Internal.AllocatePieceToSector == nil { return *new(SectorOffset), ErrNotSupported } return s.Internal.AllocatePieceToSector(p0, p1, p2, p3, p4, p5) } -func (s *CurioStub) AllocatePieceToSector(p0 context.Context, p1 address.Address, p2 PieceDealInfo, p3 int64, p4 url.URL, p5 http.Header) (SectorOffset, error) { +func (s *CurioStub) AllocatePieceToSector(p0 context.Context, p1 address.Address, p2 lpiece.PieceDealInfo, p3 int64, p4 url.URL, p5 http.Header) (SectorOffset, error) { return *new(SectorOffset), ErrNotSupported } diff --git a/build/openrpc/full.json b/build/openrpc/full.json index 2fd01c3910c..b3c1a29b679 100644 --- a/build/openrpc/full.json +++ b/build/openrpc/full.json @@ -37,7 +37,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1651" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1652" } }, { @@ -60,7 +60,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1662" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1663" } }, { @@ -103,7 +103,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1673" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1674" } }, { @@ -214,7 +214,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1695" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1696" } }, { @@ -454,7 +454,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1706" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1707" } }, { @@ -685,7 +685,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1717" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1718" } }, { @@ -784,7 +784,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1728" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1729" } }, { @@ -816,7 +816,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1739" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1740" } }, { @@ -922,7 +922,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1750" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1751" } }, { @@ -1019,7 +1019,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1761" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1762" } }, { @@ -1078,7 +1078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1772" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1773" } }, { @@ -1171,7 +1171,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1783" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1784" } }, { @@ -1255,7 +1255,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1794" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1795" } }, { @@ -1355,7 +1355,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1805" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1806" } }, { @@ -1411,7 +1411,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1816" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1817" } }, { @@ -1484,7 +1484,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1827" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1828" } }, { @@ -1557,7 +1557,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1838" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1839" } }, { @@ -1604,7 +1604,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1849" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1850" } }, { @@ -1636,7 +1636,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1860" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1861" } }, { @@ -1691,7 +1691,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1871" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1872" } }, { @@ -1743,7 +1743,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1893" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1894" } }, { @@ -1780,7 +1780,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1904" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1905" } }, { @@ -1827,7 +1827,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1915" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1916" } }, { @@ -1874,7 +1874,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1926" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1927" } }, { @@ -1954,7 +1954,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1937" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1938" } }, { @@ -2006,7 +2006,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1948" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1949" } }, { @@ -2065,7 +2065,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1959" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1960" } }, { @@ -2136,7 +2136,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1970" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1971" } }, { @@ -2177,7 +2177,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1981" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L1982" } }, { @@ -2245,7 +2245,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2003" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2004" } }, { @@ -2306,7 +2306,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2014" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2015" } }, { @@ -2413,7 +2413,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2025" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2026" } }, { @@ -2569,7 +2569,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2036" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2037" } }, { @@ -2635,7 +2635,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2047" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2048" } }, { @@ -2976,7 +2976,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2058" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2059" } }, { @@ -3021,7 +3021,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2069" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2070" } }, { @@ -3068,7 +3068,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2102" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2103" } }, { @@ -3139,7 +3139,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2113" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2114" } }, { @@ -3282,7 +3282,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2124" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2125" } }, { @@ -3612,7 +3612,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2135" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2136" } }, { @@ -3680,7 +3680,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2146" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2147" } }, { @@ -3914,7 +3914,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2157" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2158" } }, { @@ -4077,7 +4077,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2168" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2169" } }, { @@ -4160,7 +4160,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2179" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2180" } }, { @@ -4201,7 +4201,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2190" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2191" } }, { @@ -4272,7 +4272,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2201" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2202" } }, { @@ -4416,7 +4416,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2212" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2213" } }, { @@ -4456,7 +4456,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2223" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2224" } }, { @@ -4497,7 +4497,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2234" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2235" } }, { @@ -4622,7 +4622,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2245" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2246" } }, { @@ -4747,7 +4747,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2256" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2257" } }, { @@ -4786,7 +4786,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2267" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2268" } }, { @@ -4833,7 +4833,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2278" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2279" } }, { @@ -4888,7 +4888,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2289" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2290" } }, { @@ -4917,7 +4917,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2300" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2301" } }, { @@ -5054,7 +5054,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2311" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2312" } }, { @@ -5083,7 +5083,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2322" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2323" } }, { @@ -5137,7 +5137,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2333" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2334" } }, { @@ -5228,7 +5228,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2344" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2345" } }, { @@ -5256,7 +5256,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2355" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2356" } }, { @@ -5346,7 +5346,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2366" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2367" } }, { @@ -5602,7 +5602,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2377" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2378" } }, { @@ -5847,7 +5847,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2388" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2389" } }, { @@ -5903,7 +5903,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2399" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2400" } }, { @@ -5950,7 +5950,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2410" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2411" } }, { @@ -6048,7 +6048,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2421" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2422" } }, { @@ -6114,7 +6114,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2432" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2433" } }, { @@ -6180,7 +6180,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2443" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2444" } }, { @@ -6289,7 +6289,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2454" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2455" } }, { @@ -6347,7 +6347,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2465" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2466" } }, { @@ -6469,7 +6469,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2476" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2477" } }, { @@ -6673,7 +6673,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2487" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2488" } }, { @@ -6868,7 +6868,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2498" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2499" } }, { @@ -7055,7 +7055,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2509" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2510" } }, { @@ -7259,7 +7259,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2520" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2521" } }, { @@ -7350,7 +7350,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2531" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2532" } }, { @@ -7408,7 +7408,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2542" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2543" } }, { @@ -7666,7 +7666,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2553" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2554" } }, { @@ -7941,7 +7941,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2564" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2565" } }, { @@ -7969,7 +7969,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2575" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2576" } }, { @@ -8007,7 +8007,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2586" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2587" } }, { @@ -8115,7 +8115,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2597" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2598" } }, { @@ -8153,7 +8153,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2608" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2609" } }, { @@ -8182,7 +8182,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2619" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2620" } }, { @@ -8245,7 +8245,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2630" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2631" } }, { @@ -8308,7 +8308,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2641" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2642" } }, { @@ -8353,7 +8353,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2652" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2653" } }, { @@ -8475,7 +8475,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2663" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2664" } }, { @@ -8630,7 +8630,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2674" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2675" } }, { @@ -8684,7 +8684,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2685" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2686" } }, { @@ -8738,7 +8738,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2696" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2697" } }, { @@ -8793,7 +8793,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2707" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2708" } }, { @@ -8936,7 +8936,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2718" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2719" } }, { @@ -9063,7 +9063,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2729" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2730" } }, { @@ -9165,7 +9165,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2740" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2741" } }, { @@ -9388,7 +9388,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2751" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2752" } }, { @@ -9571,7 +9571,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2762" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2763" } }, { @@ -9651,7 +9651,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2773" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2774" } }, { @@ -9696,7 +9696,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2784" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2785" } }, { @@ -9752,7 +9752,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2795" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2796" } }, { @@ -9832,7 +9832,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2806" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2807" } }, { @@ -9912,7 +9912,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2817" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2818" } }, { @@ -10397,7 +10397,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2828" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2829" } }, { @@ -10591,7 +10591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2839" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2840" } }, { @@ -10746,7 +10746,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2850" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2851" } }, { @@ -10995,7 +10995,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2861" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2862" } }, { @@ -11150,7 +11150,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2872" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2873" } }, { @@ -11327,7 +11327,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2883" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2884" } }, { @@ -11425,7 +11425,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2894" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2895" } }, { @@ -11590,7 +11590,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2905" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2906" } }, { @@ -11629,7 +11629,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2916" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2917" } }, { @@ -11694,7 +11694,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2927" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2928" } }, { @@ -11740,7 +11740,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2938" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2939" } }, { @@ -11890,7 +11890,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2949" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2950" } }, { @@ -12027,7 +12027,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2960" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2961" } }, { @@ -12258,7 +12258,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2971" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2972" } }, { @@ -12395,7 +12395,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2982" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2983" } }, { @@ -12560,7 +12560,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2993" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L2994" } }, { @@ -12637,7 +12637,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3004" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3005" } }, { @@ -12832,7 +12832,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3026" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3027" } }, { @@ -13011,7 +13011,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3037" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3038" } }, { @@ -13173,7 +13173,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3048" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3049" } }, { @@ -13321,7 +13321,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3059" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3060" } }, { @@ -13549,7 +13549,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3070" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3071" } }, { @@ -13697,7 +13697,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3081" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3082" } }, { @@ -13909,7 +13909,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3092" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3093" } }, { @@ -14115,7 +14115,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3103" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3104" } }, { @@ -14183,7 +14183,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3114" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3115" } }, { @@ -14300,7 +14300,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3125" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3126" } }, { @@ -14391,7 +14391,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3136" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3137" } }, { @@ -14477,7 +14477,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3147" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3148" } }, { @@ -14672,7 +14672,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3158" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3159" } }, { @@ -14834,7 +14834,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3169" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3170" } }, { @@ -15030,7 +15030,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3180" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3181" } }, { @@ -15210,7 +15210,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3191" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3192" } }, { @@ -15373,7 +15373,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3202" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3203" } }, { @@ -15400,7 +15400,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3213" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3214" } }, { @@ -15427,7 +15427,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3224" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3225" } }, { @@ -15526,7 +15526,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3235" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3236" } }, { @@ -15572,7 +15572,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3246" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3247" } }, { @@ -15672,7 +15672,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3257" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3258" } }, { @@ -15788,7 +15788,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3268" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3269" } }, { @@ -15836,7 +15836,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3279" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3280" } }, { @@ -15928,7 +15928,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3290" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3291" } }, { @@ -16043,7 +16043,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3301" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3302" } }, { @@ -16091,7 +16091,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3312" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3313" } }, { @@ -16128,7 +16128,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3323" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3324" } }, { @@ -16400,7 +16400,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3334" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3335" } }, { @@ -16448,7 +16448,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3345" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3346" } }, { @@ -16506,7 +16506,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3356" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3357" } }, { @@ -16711,7 +16711,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3367" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3368" } }, { @@ -16914,7 +16914,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3378" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3379" } }, { @@ -17083,7 +17083,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3389" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3390" } }, { @@ -17287,7 +17287,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3400" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3401" } }, { @@ -17454,7 +17454,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3411" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3412" } }, { @@ -17661,7 +17661,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3422" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3423" } }, { @@ -17729,7 +17729,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3433" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3434" } }, { @@ -17781,7 +17781,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3444" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3445" } }, { @@ -17830,7 +17830,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3455" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3456" } }, { @@ -17921,7 +17921,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3466" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3467" } }, { @@ -18427,7 +18427,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3477" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3478" } }, { @@ -18533,7 +18533,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3488" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3489" } }, { @@ -18585,7 +18585,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3499" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3500" } }, { @@ -19137,7 +19137,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3510" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3511" } }, { @@ -19251,7 +19251,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3521" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3522" } }, { @@ -19348,7 +19348,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3532" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3533" } }, { @@ -19448,7 +19448,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3543" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3544" } }, { @@ -19536,7 +19536,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3554" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3555" } }, { @@ -19636,7 +19636,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3565" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3566" } }, { @@ -19723,7 +19723,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3576" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3577" } }, { @@ -19814,7 +19814,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3587" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3588" } }, { @@ -19939,7 +19939,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3598" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3599" } }, { @@ -20048,7 +20048,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3609" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3610" } }, { @@ -20118,7 +20118,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3620" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3621" } }, { @@ -20221,7 +20221,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3631" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3632" } }, { @@ -20282,7 +20282,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3642" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3643" } }, { @@ -20412,7 +20412,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3653" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3654" } }, { @@ -20519,7 +20519,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3664" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3665" } }, { @@ -20733,7 +20733,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3675" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3676" } }, { @@ -20810,7 +20810,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3686" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3687" } }, { @@ -20887,7 +20887,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3697" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3698" } }, { @@ -20996,7 +20996,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3708" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3709" } }, { @@ -21105,7 +21105,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3719" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3720" } }, { @@ -21166,7 +21166,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3730" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3731" } }, { @@ -21276,7 +21276,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3741" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3742" } }, { @@ -21337,7 +21337,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3752" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3753" } }, { @@ -21405,7 +21405,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3763" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3764" } }, { @@ -21473,7 +21473,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3774" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3775" } }, { @@ -21554,7 +21554,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3785" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3786" } }, { @@ -21703,7 +21703,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3796" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3797" } }, { @@ -21775,7 +21775,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3807" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3808" } }, { @@ -21934,7 +21934,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3818" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3819" } }, { @@ -22099,7 +22099,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3829" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3830" } }, { @@ -22169,7 +22169,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3840" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3841" } }, { @@ -22237,7 +22237,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3851" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3852" } }, { @@ -22330,7 +22330,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3862" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3863" } }, { @@ -22401,7 +22401,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3873" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3874" } }, { @@ -22602,7 +22602,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3884" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3885" } }, { @@ -22734,7 +22734,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3895" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3896" } }, { @@ -22871,7 +22871,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3906" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3907" } }, { @@ -22982,7 +22982,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3917" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3918" } }, { @@ -23114,7 +23114,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3928" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3929" } }, { @@ -23245,7 +23245,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3939" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3940" } }, { @@ -23316,7 +23316,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3950" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3951" } }, { @@ -23400,7 +23400,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3961" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3962" } }, { @@ -23486,7 +23486,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3972" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3973" } }, { @@ -23669,7 +23669,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3983" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3984" } }, { @@ -23696,7 +23696,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3994" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L3995" } }, { @@ -23749,7 +23749,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4005" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4006" } }, { @@ -23837,7 +23837,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4016" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4017" } }, { @@ -24288,7 +24288,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4027" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4028" } }, { @@ -24455,7 +24455,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4038" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4039" } }, { @@ -24553,7 +24553,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4049" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4050" } }, { @@ -24726,7 +24726,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4060" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4061" } }, { @@ -24824,7 +24824,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4071" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4072" } }, { @@ -24975,7 +24975,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4082" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4083" } }, { @@ -25060,7 +25060,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4093" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4094" } }, { @@ -25128,7 +25128,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4104" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4105" } }, { @@ -25180,7 +25180,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4115" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4116" } }, { @@ -25248,7 +25248,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4126" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4127" } }, { @@ -25409,7 +25409,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4137" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4138" } }, { @@ -25456,7 +25456,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4159" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4160" } }, { @@ -25503,7 +25503,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4170" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4171" } }, { @@ -25546,7 +25546,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4192" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4193" } }, { @@ -25642,7 +25642,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4203" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4204" } }, { @@ -25908,7 +25908,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4214" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4215" } }, { @@ -25931,7 +25931,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4225" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4226" } }, { @@ -25974,7 +25974,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4236" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4237" } }, { @@ -26025,7 +26025,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4247" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4248" } }, { @@ -26070,7 +26070,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4258" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4259" } }, { @@ -26098,7 +26098,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4269" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4270" } }, { @@ -26138,7 +26138,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4280" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4281" } }, { @@ -26197,7 +26197,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4291" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4292" } }, { @@ -26241,7 +26241,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4302" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4303" } }, { @@ -26300,7 +26300,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4313" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4314" } }, { @@ -26337,7 +26337,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4324" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4325" } }, { @@ -26381,7 +26381,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4335" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4336" } }, { @@ -26421,7 +26421,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4346" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4347" } }, { @@ -26496,7 +26496,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4357" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4358" } }, { @@ -26704,7 +26704,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4368" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4369" } }, { @@ -26748,7 +26748,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4379" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4380" } }, { @@ -26838,7 +26838,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4390" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4391" } }, { @@ -26865,7 +26865,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4401" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4402" } } ] diff --git a/build/openrpc/gateway.json b/build/openrpc/gateway.json index 1e8dfbed647..407a5ec26c2 100644 --- a/build/openrpc/gateway.json +++ b/build/openrpc/gateway.json @@ -242,7 +242,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4412" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4413" } }, { @@ -473,7 +473,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4423" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4424" } }, { @@ -572,7 +572,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4434" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4435" } }, { @@ -604,7 +604,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4445" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4446" } }, { @@ -710,7 +710,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4456" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4457" } }, { @@ -803,7 +803,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4467" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4468" } }, { @@ -887,7 +887,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4478" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4479" } }, { @@ -987,7 +987,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4489" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4490" } }, { @@ -1043,7 +1043,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4500" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4501" } }, { @@ -1116,7 +1116,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4511" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4512" } }, { @@ -1189,7 +1189,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4522" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4523" } }, { @@ -1236,7 +1236,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4533" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4534" } }, { @@ -1268,7 +1268,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4544" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4545" } }, { @@ -1305,7 +1305,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4566" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4567" } }, { @@ -1352,7 +1352,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4577" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4578" } }, { @@ -1392,7 +1392,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4588" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4589" } }, { @@ -1439,7 +1439,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4599" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4600" } }, { @@ -1468,7 +1468,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4610" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4611" } }, { @@ -1605,7 +1605,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4621" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4622" } }, { @@ -1634,7 +1634,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4632" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4633" } }, { @@ -1688,7 +1688,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4643" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4644" } }, { @@ -1779,7 +1779,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4654" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4655" } }, { @@ -1807,7 +1807,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4665" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4666" } }, { @@ -1897,7 +1897,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4676" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4677" } }, { @@ -2153,7 +2153,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4687" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4688" } }, { @@ -2398,7 +2398,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4698" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4699" } }, { @@ -2454,7 +2454,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4709" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4710" } }, { @@ -2501,7 +2501,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4720" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4721" } }, { @@ -2599,7 +2599,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4731" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4732" } }, { @@ -2665,7 +2665,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4742" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4743" } }, { @@ -2731,7 +2731,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4753" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4754" } }, { @@ -2840,7 +2840,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4764" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4765" } }, { @@ -2898,7 +2898,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4775" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4776" } }, { @@ -3020,7 +3020,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4786" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4787" } }, { @@ -3207,7 +3207,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4797" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4798" } }, { @@ -3411,7 +3411,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4808" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4809" } }, { @@ -3502,7 +3502,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4819" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4820" } }, { @@ -3560,7 +3560,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4830" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4831" } }, { @@ -3818,7 +3818,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4841" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4842" } }, { @@ -4093,7 +4093,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4852" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4853" } }, { @@ -4121,7 +4121,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4863" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4864" } }, { @@ -4159,7 +4159,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4874" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4875" } }, { @@ -4267,7 +4267,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4885" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4886" } }, { @@ -4305,7 +4305,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4896" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4897" } }, { @@ -4334,7 +4334,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4907" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4908" } }, { @@ -4397,7 +4397,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4918" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4919" } }, { @@ -4460,7 +4460,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4929" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4930" } }, { @@ -4505,7 +4505,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4940" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4941" } }, { @@ -4627,7 +4627,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4951" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4952" } }, { @@ -4782,7 +4782,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4962" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4963" } }, { @@ -4836,7 +4836,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4973" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4974" } }, { @@ -4890,7 +4890,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4984" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4985" } }, { @@ -4992,7 +4992,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4995" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L4996" } }, { @@ -5215,7 +5215,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5006" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5007" } }, { @@ -5398,7 +5398,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5017" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5018" } }, { @@ -5592,7 +5592,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5028" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5029" } }, { @@ -5638,7 +5638,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5039" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5040" } }, { @@ -5788,7 +5788,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5050" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5051" } }, { @@ -5925,7 +5925,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5061" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5062" } }, { @@ -5993,7 +5993,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5072" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5073" } }, { @@ -6110,7 +6110,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5083" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5084" } }, { @@ -6201,7 +6201,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5094" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5095" } }, { @@ -6287,7 +6287,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5105" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5106" } }, { @@ -6314,7 +6314,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5116" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5117" } }, { @@ -6341,7 +6341,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5127" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5128" } }, { @@ -6409,7 +6409,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5138" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5139" } }, { @@ -6915,7 +6915,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5149" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5150" } }, { @@ -7012,7 +7012,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5160" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5161" } }, { @@ -7112,7 +7112,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5171" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5172" } }, { @@ -7212,7 +7212,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5182" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5183" } }, { @@ -7337,7 +7337,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5193" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5194" } }, { @@ -7446,7 +7446,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5204" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5205" } }, { @@ -7549,7 +7549,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5215" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5216" } }, { @@ -7679,7 +7679,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5226" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5227" } }, { @@ -7786,7 +7786,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5237" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5238" } }, { @@ -7847,7 +7847,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5248" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5249" } }, { @@ -7915,7 +7915,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5259" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5260" } }, { @@ -7996,7 +7996,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5270" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5271" } }, { @@ -8155,7 +8155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5281" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5282" } }, { @@ -8248,7 +8248,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5292" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5293" } }, { @@ -8449,7 +8449,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5303" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5304" } }, { @@ -8560,7 +8560,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5314" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5315" } }, { @@ -8691,7 +8691,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5325" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5326" } }, { @@ -8777,7 +8777,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5336" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5337" } }, { @@ -8804,7 +8804,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5347" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5348" } }, { @@ -8857,7 +8857,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5358" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5359" } }, { @@ -8945,7 +8945,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5369" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5370" } }, { @@ -9396,7 +9396,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5380" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5381" } }, { @@ -9563,7 +9563,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5391" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5392" } }, { @@ -9736,7 +9736,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5402" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5403" } }, { @@ -9804,7 +9804,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5413" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5414" } }, { @@ -9872,7 +9872,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5424" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5425" } }, { @@ -10033,7 +10033,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5435" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5436" } }, { @@ -10078,7 +10078,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5457" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5458" } }, { @@ -10123,7 +10123,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5468" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5469" } }, { @@ -10150,7 +10150,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5479" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5480" } } ] diff --git a/build/openrpc/miner.json b/build/openrpc/miner.json index 9e9d6e9c6bd..885a4e902d2 100644 --- a/build/openrpc/miner.json +++ b/build/openrpc/miner.json @@ -30,7 +30,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5765" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5766" } }, { @@ -109,7 +109,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5776" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5777" } }, { @@ -155,7 +155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5787" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5788" } }, { @@ -203,7 +203,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5798" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5799" } }, { @@ -251,7 +251,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5809" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5810" } }, { @@ -354,7 +354,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5820" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5821" } }, { @@ -428,7 +428,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5831" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5832" } }, { @@ -591,7 +591,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5842" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5843" } }, { @@ -742,7 +742,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5853" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5854" } }, { @@ -781,7 +781,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5864" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5865" } }, { @@ -833,7 +833,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5875" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5876" } }, { @@ -872,7 +872,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5897" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5898" } }, { @@ -924,7 +924,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5908" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5909" } }, { @@ -996,7 +996,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5919" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5920" } }, { @@ -1035,7 +1035,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5930" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5931" } }, { @@ -1074,7 +1074,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5941" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5942" } }, { @@ -1101,7 +1101,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5952" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5953" } }, { @@ -1128,7 +1128,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5963" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5964" } }, { @@ -1155,7 +1155,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5974" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5975" } }, { @@ -1182,7 +1182,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5985" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5986" } }, { @@ -1209,7 +1209,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5996" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L5997" } }, { @@ -1236,7 +1236,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6007" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6008" } }, { @@ -1294,7 +1294,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6018" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6019" } }, { @@ -1421,7 +1421,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6029" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6030" } }, { @@ -1461,7 +1461,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6040" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6041" } }, { @@ -1500,7 +1500,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6051" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6052" } }, { @@ -1539,7 +1539,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6062" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6063" } }, { @@ -1578,7 +1578,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6073" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6074" } }, { @@ -1617,7 +1617,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6084" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6085" } }, { @@ -1656,7 +1656,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6095" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6096" } }, { @@ -1695,7 +1695,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6106" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6107" } }, { @@ -1747,7 +1747,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6117" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6118" } }, { @@ -1770,7 +1770,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6128" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6129" } }, { @@ -1813,7 +1813,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6139" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6140" } }, { @@ -1884,7 +1884,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6150" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6151" } }, { @@ -2265,7 +2265,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6161" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6162" } }, { @@ -2364,7 +2364,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6183" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6184" } }, { @@ -2415,7 +2415,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6205" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6206" } }, { @@ -2473,7 +2473,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6216" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6217" } }, { @@ -2616,7 +2616,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6227" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6228" } }, { @@ -2743,7 +2743,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6238" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6239" } }, { @@ -3007,7 +3007,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6249" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6250" } }, { @@ -3044,7 +3044,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6260" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6261" } }, { @@ -3182,7 +3182,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6271" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6272" } }, { @@ -3205,7 +3205,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6282" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6283" } }, { @@ -3276,7 +3276,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6293" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6294" } }, { @@ -3319,7 +3319,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6304" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6305" } }, { @@ -3426,7 +3426,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6315" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6316" } }, { @@ -3489,7 +3489,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6326" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6327" } }, { @@ -3521,7 +3521,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6337" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6338" } }, { @@ -3609,7 +3609,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6348" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6349" } }, { @@ -3700,7 +3700,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6359" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6360" } }, { @@ -3740,7 +3740,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6370" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6371" } }, { @@ -3780,7 +3780,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6381" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6382" } }, { @@ -3821,7 +3821,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6392" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6393" } }, { @@ -3889,7 +3889,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6403" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6404" } }, { @@ -4020,7 +4020,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6414" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6415" } }, { @@ -4151,7 +4151,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6425" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6426" } }, { @@ -4251,7 +4251,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6436" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6437" } }, { @@ -4351,7 +4351,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6447" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6448" } }, { @@ -4451,7 +4451,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6458" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6459" } }, { @@ -4551,7 +4551,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6469" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6470" } }, { @@ -4651,7 +4651,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6480" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6481" } }, { @@ -4751,7 +4751,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6491" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6492" } }, { @@ -4875,7 +4875,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6502" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6503" } }, { @@ -4999,7 +4999,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6513" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6514" } }, { @@ -5114,7 +5114,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6524" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6525" } }, { @@ -5214,7 +5214,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6535" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6536" } }, { @@ -5347,7 +5347,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6546" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6547" } }, { @@ -5471,7 +5471,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6557" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6558" } }, { @@ -5595,7 +5595,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6568" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6569" } }, { @@ -5719,7 +5719,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6579" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6580" } }, { @@ -5852,7 +5852,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6590" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6591" } }, { @@ -5952,7 +5952,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6601" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6602" } }, { @@ -5993,7 +5993,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6612" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6613" } }, { @@ -6065,7 +6065,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6623" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6624" } }, { @@ -6115,7 +6115,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6634" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6635" } }, { @@ -6159,7 +6159,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6645" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6646" } }, { @@ -6200,7 +6200,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6656" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6657" } }, { @@ -6444,7 +6444,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6667" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6668" } }, { @@ -6518,7 +6518,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6678" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6679" } }, { @@ -6568,7 +6568,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6689" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6690" } }, { @@ -6597,7 +6597,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6700" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6701" } }, { @@ -6626,7 +6626,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6711" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6712" } }, { @@ -6682,7 +6682,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6722" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6723" } }, { @@ -6705,7 +6705,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6733" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6734" } }, { @@ -6765,7 +6765,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6744" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6745" } }, { @@ -6804,7 +6804,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6755" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6756" } }, { @@ -6844,7 +6844,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6766" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6767" } }, { @@ -6917,7 +6917,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6777" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6778" } }, { @@ -6981,7 +6981,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6788" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6789" } }, { @@ -7044,7 +7044,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6799" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6800" } }, { @@ -7094,7 +7094,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6810" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6811" } }, { @@ -7653,7 +7653,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6821" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6822" } }, { @@ -7694,7 +7694,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6832" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6833" } }, { @@ -7735,7 +7735,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6843" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6844" } }, { @@ -7776,7 +7776,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6854" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6855" } }, { @@ -7817,7 +7817,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6865" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6866" } }, { @@ -7858,7 +7858,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6876" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6877" } }, { @@ -7889,7 +7889,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6887" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6888" } }, { @@ -7939,7 +7939,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6898" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6899" } }, { @@ -7980,7 +7980,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6909" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6910" } }, { @@ -8019,7 +8019,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6920" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6921" } }, { @@ -8083,7 +8083,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6931" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6932" } }, { @@ -8141,7 +8141,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6942" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6943" } }, { @@ -8588,7 +8588,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6953" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6954" } }, { @@ -8624,7 +8624,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6964" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6965" } }, { @@ -8767,7 +8767,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6975" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6976" } }, { @@ -8823,7 +8823,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6986" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6987" } }, { @@ -8862,7 +8862,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6997" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L6998" } }, { @@ -9039,7 +9039,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7008" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7009" } }, { @@ -9091,7 +9091,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7019" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7020" } }, { @@ -9283,7 +9283,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7030" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7031" } }, { @@ -9383,7 +9383,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7041" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7042" } }, { @@ -9437,7 +9437,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7052" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7053" } }, { @@ -9476,7 +9476,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7063" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7064" } }, { @@ -9561,7 +9561,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7074" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7075" } }, { @@ -9755,7 +9755,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7085" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7086" } }, { @@ -9853,7 +9853,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7096" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7097" } }, { @@ -9985,7 +9985,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7107" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7108" } }, { @@ -10039,7 +10039,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7118" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7119" } }, { @@ -10073,7 +10073,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7129" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7130" } }, { @@ -10160,7 +10160,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7140" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7141" } }, { @@ -10214,7 +10214,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7151" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7152" } }, { @@ -10314,7 +10314,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7162" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7163" } }, { @@ -10391,7 +10391,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7173" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7174" } }, { @@ -10482,7 +10482,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7184" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7185" } }, { @@ -10521,7 +10521,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7195" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7196" } }, { @@ -10637,7 +10637,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7206" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7207" } }, { @@ -12737,7 +12737,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7217" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7218" } } ] diff --git a/build/openrpc/worker.json b/build/openrpc/worker.json index 86bd7c0b159..7c6b380f4ea 100644 --- a/build/openrpc/worker.json +++ b/build/openrpc/worker.json @@ -161,7 +161,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7305" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7306" } }, { @@ -252,7 +252,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7316" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7317" } }, { @@ -420,7 +420,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7327" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7328" } }, { @@ -447,7 +447,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7338" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7339" } }, { @@ -597,7 +597,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7349" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7350" } }, { @@ -700,7 +700,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7360" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7361" } }, { @@ -803,7 +803,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7371" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7372" } }, { @@ -925,7 +925,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7382" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7383" } }, { @@ -1135,7 +1135,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7393" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7394" } }, { @@ -1306,7 +1306,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7404" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7405" } }, { @@ -3350,7 +3350,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7415" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7416" } }, { @@ -3470,7 +3470,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7426" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7427" } }, { @@ -3531,7 +3531,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7437" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7438" } }, { @@ -3569,7 +3569,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7448" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7449" } }, { @@ -3729,7 +3729,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7459" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7460" } }, { @@ -3913,7 +3913,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7470" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7471" } }, { @@ -4054,7 +4054,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7481" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7482" } }, { @@ -4107,7 +4107,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7492" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7493" } }, { @@ -4250,7 +4250,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7503" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7504" } }, { @@ -4474,7 +4474,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7514" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7515" } }, { @@ -4601,7 +4601,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7525" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7526" } }, { @@ -4768,7 +4768,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7536" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7537" } }, { @@ -4895,7 +4895,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7547" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7548" } }, { @@ -4933,7 +4933,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7558" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7559" } }, { @@ -4972,7 +4972,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7569" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7570" } }, { @@ -4995,7 +4995,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7580" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7581" } }, { @@ -5034,7 +5034,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7591" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7592" } }, { @@ -5057,7 +5057,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7602" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7603" } }, { @@ -5096,7 +5096,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7613" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7614" } }, { @@ -5130,7 +5130,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7624" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7625" } }, { @@ -5184,7 +5184,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7635" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7636" } }, { @@ -5223,7 +5223,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7646" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7647" } }, { @@ -5262,7 +5262,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7657" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7658" } }, { @@ -5297,7 +5297,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7668" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7669" } }, { @@ -5477,7 +5477,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7679" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7680" } }, { @@ -5506,7 +5506,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7690" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7691" } }, { @@ -5529,7 +5529,7 @@ "deprecated": false, "externalDocs": { "description": "Github remote link", - "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7701" + "url": "https://github.com/filecoin-project/lotus/blob/master/api/proxy_gen.go#L7702" } } ] diff --git a/curiosrc/market/deal_ingest.go b/curiosrc/market/deal_ingest.go index d660db40d0f..03cce5adcca 100644 --- a/curiosrc/market/deal_ingest.go +++ b/curiosrc/market/deal_ingest.go @@ -3,12 +3,14 @@ package market import ( "context" "encoding/json" + "errors" + "fmt" "net/http" "net/url" - "sync" "time" logging "github.com/ipfs/go-log/v2" + "github.com/lib/pq" // PostgreSQL driver for errors "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -30,7 +32,7 @@ var log = logging.Logger("piece-ingestor") const loopFrequency = 10 * time.Second type Ingester interface { - AllocatePieceToSector(ctx context.Context, maddr address.Address, piece api.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) + AllocatePieceToSector(ctx context.Context, maddr address.Address, piece lpiece.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) } type PieceIngesterApi interface { @@ -45,9 +47,7 @@ type openSector struct { currentSize abi.PaddedPieceSize earliestEpoch abi.ChainEpoch index uint64 - lk sync.Mutex - openedAt time.Time - sealNow bool + openedAt *time.Time } type PieceIngester struct { @@ -57,12 +57,19 @@ type PieceIngester struct { miner address.Address mid uint64 // miner ID windowPoStProofType abi.RegisteredPoStProof + synth bool sectorSize abi.SectorSize sealRightNow bool // Should be true only for CurioAPI AllocatePieceToSector method maxWaitTime time.Duration - forceSeal chan struct{} - openSectors []*openSector - lk sync.Mutex +} + +type pieceDetails struct { + Sector abi.SectorNumber `db:"sector_number"` + Size abi.PaddedPieceSize `db:"piece_size"` + f05Epoch abi.ChainEpoch `db:"f05_deal_start_epoch"` + ddoEpoch abi.ChainEpoch `db:"direct_start_epoch"` + Index uint64 `db:"piece_index"` + CreatedAt *time.Time `db:"created_at"` } func NewPieceIngester(ctx context.Context, db *harmonydb.DB, api PieceIngesterApi, maddr address.Address, sealRightNow bool, maxWaitTime time.Duration) (*PieceIngester, error) { @@ -76,69 +83,6 @@ func NewPieceIngester(ctx context.Context, db *harmonydb.DB, api PieceIngesterAp return nil, xerrors.Errorf("getting miner ID: %w", err) } - sm := map[abi.SectorNumber]*openSector{} - type details struct { - Sector abi.SectorNumber `db:"sector_number"` - Size abi.PaddedPieceSize `db:"piece_size"` - f05Epoch abi.ChainEpoch `db:"f05_deal_start_epoch"` - ddoEpoch abi.ChainEpoch `db:"direct_start_epoch"` - Index uint64 `db:"piece_index"` - } - var pieces []details - - // Get current open sector pieces from DB - err = db.Select(ctx, &pieces, ` - SELECT - ssip.sector_number, - ssip.piece_size, - ssip.piece_index, - ssip.f05_deal_start_epoch, - ssip.direct_start_epoch - FROM - curio.sectors_sdr_initial_pieces ssip - JOIN - (SELECT sector_number - FROM curio.sectors_sdr_initial_pieces sip - LEFT JOIN curio.sectors_sdr_pipeline sp ON sip.sp_id = sp.sp_id AND sip.sector_number = sp.sector_number - WHERE sp.sector_number IS NULL AND sip.sp_id = $1) as filtered ON ssip.sector_number = filtered.sector_number - WHERE - ssip.sp_id = $1 - ORDER BY - ssip.piece_index DESC;`, mid) - if err != nil { - return nil, xerrors.Errorf("getting open sectors from DB") - } - - for _, piece := range pieces { - var ep abi.ChainEpoch - if piece.ddoEpoch > 0 { - ep = piece.ddoEpoch - } else { - ep = piece.f05Epoch - } - s, ok := sm[piece.Sector] - if !ok { - s := &openSector{ - number: piece.Sector, - currentSize: piece.Size, - earliestEpoch: ep, - index: piece.Index, - openedAt: time.Now(), - } - sm[piece.Sector] = s - } - s.currentSize += piece.Size - s.earliestEpoch = ep - if s.index < piece.Index { - s.index = piece.Index - } - } - - var os []*openSector - for _, v := range sm { - os = append(os, v) - } - pi := &PieceIngester{ db: db, api: api, @@ -147,9 +91,8 @@ func NewPieceIngester(ctx context.Context, db *harmonydb.DB, api PieceIngesterAp maxWaitTime: maxWaitTime, sectorSize: mi.SectorSize, windowPoStProofType: mi.WindowPoStProofType, - openSectors: os, mid: mid, - forceSeal: make(chan struct{}, 1), + synth: false, // TODO: synthetic porep config } go pi.start() @@ -175,55 +118,53 @@ func (p *PieceIngester) start() { } func (p *PieceIngester) Seal() error { - p.lk.Lock() - defer p.lk.Unlock() - head, err := p.api.ChainHead(p.ctx) if err != nil { return xerrors.Errorf("getting chain head: %w", err) } - nv, err := p.api.StateNetworkVersion(p.ctx, types.EmptyTSK) - if err != nil { - return xerrors.Errorf("getting network version: %w", err) - } - - synth := false // todo synthetic porep config - - spt, err := miner.PreferredSealProofTypeFromWindowPoStType(nv, p.windowPoStProofType, synth) + spt, err := p.getSealProofType() if err != nil { return xerrors.Errorf("getting seal proof type: %w", err) } - var os []*openSector + comm, err := p.db.BeginTransaction(p.ctx, func(tx *harmonydb.Tx) (commit bool, err error) { - for i := range p.openSectors { - // todo: When to start sealing - // Start sealing a sector if - // 1. If sector is full - // 2. We have been waiting for MaxWaitDuration - // 3. StartEpoch is less than 8 hours // todo: make this config? - // 4. If force seal is set //todo: create sealNOW command - if p.openSectors[i].sealNow || p.openSectors[i].currentSize == abi.PaddedPieceSize(p.sectorSize) || time.Since(p.openSectors[i].openedAt) >= p.maxWaitTime || p.openSectors[i].earliestEpoch > head.Height()+abi.ChainEpoch(960) { - // Start sealing the sector - p.openSectors[i].lk.Lock() - defer p.openSectors[i].lk.Unlock() - - cn, err := p.db.Exec(p.ctx, ` - INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, p.mid, p.openSectors[i].number, spt) + openSectors, err := p.getOpenSectors(tx) + if err != nil { + return false, err + } - if err != nil { - return xerrors.Errorf("adding sector to pipeline: %w", err) - } + for _, sector := range openSectors { + sector := sector + // Start sealing a sector if + // 1. If sector is full + // 2. We have been waiting for MaxWaitDuration + // 3. StartEpoch is less than 8 hours // todo: make this config? + if sector.currentSize == abi.PaddedPieceSize(p.sectorSize) || time.Since(*sector.openedAt) >= p.maxWaitTime || sector.earliestEpoch > head.Height()+abi.ChainEpoch(960) { + // Start sealing the sector + cn, err := p.db.Exec(p.ctx, ` + INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, p.mid, sector.number, spt) - if cn != 1 { - return xerrors.Errorf("incorrect number of rows returned") + if err != nil { + return false, xerrors.Errorf("adding sector to pipeline: %w", err) + } + + if cn != 1 { + return false, xerrors.Errorf("incorrect number of rows returned") + } } } - os = append(os, p.openSectors[i]) + return true, nil + }, harmonydb.OptionRetry()) + + if err != nil { + return xerrors.Errorf("start sealing sector: %w", err) } - p.openSectors = os + if !comm { + return xerrors.Errorf("start sealing sector: commit failed") + } return nil } @@ -261,9 +202,6 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address } } - p.lk.Lock() - defer p.lk.Unlock() - if !p.sealRightNow { // Try to allocate the piece to an open sector allocated, ret, err := p.allocateToExisting(ctx, piece, rawSize, source, dataHdrJson, propJson) @@ -283,52 +221,22 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address n := numbers[0] if piece.DealProposal != nil { - _, err = tx.Exec(`INSERT INTO sectors_sdr_initial_pieces (sp_id, - sector_number, - piece_index, - - piece_cid, - piece_size, - - data_url, - data_headers, - data_raw_size, - data_delete_on_finalize, - - f05_publish_cid, - f05_deal_id, - f05_deal_proposal, - f05_deal_start_epoch, - f05_deal_end_epoch) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, + _, err = tx.Exec(`SELECT insert_sector_market_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, p.mid, n, 0, piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, piece.PublishCid, piece.DealID, propJson, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch) if err != nil { - return false, xerrors.Errorf("inserting into sectors_sdr_initial_pieces: %w", err) + return false, xerrors.Errorf("adding deal to sector: %w", err) } } else { - _, err = tx.Exec(`INSERT INTO sectors_sdr_initial_pieces (sp_id, - sector_number, - piece_index, - - piece_cid, - piece_size, - - data_url, - data_headers, - data_raw_size, - data_delete_on_finalize, - - direct_start_epoch, - direct_end_epoch, - direct_piece_activation_manifest) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, + _, err = tx.Exec(`SELECT insert_sector_ddo_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, p.mid, n, 0, piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) if err != nil { - return false, xerrors.Errorf("inserting into sectors_sdr_initial_pieces: %w", err) + return false, xerrors.Errorf("adding deal to sector: %w", err) } } return true, nil @@ -341,20 +249,13 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address return api.SectorOffset{}, xerrors.Errorf("expected one sector number") } - sec := &openSector{ - number: num[0], - currentSize: piece.DealProposal.PieceSize, - earliestEpoch: piece.DealProposal.StartEpoch, - index: 0, - openedAt: time.Now(), - } - if p.sealRightNow { - sec.sealNow = true + err = p.SectorStartSealing(ctx, num[0]) + if err != nil { + return api.SectorOffset{}, xerrors.Errorf("SectorStartSealing: %w", err) + } } - p.openSectors = append(p.openSectors, sec) - return api.SectorOffset{ Sector: num[0], Offset: 0, @@ -362,101 +263,241 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address } func (p *PieceIngester) allocateToExisting(ctx context.Context, piece lpiece.PieceDealInfo, rawSize int64, source url.URL, dataHdrJson, propJson []byte) (bool, api.SectorOffset, error) { - for i := range p.openSectors { - sec := p.openSectors[i] - sec.lk.Lock() - defer sec.lk.Unlock() - pieceSize := piece.Size() - if sec.currentSize+pieceSize < abi.PaddedPieceSize(p.sectorSize) { - ret := api.SectorOffset{ - Sector: sec.number, - Offset: sec.currentSize + 1, // Current filled up size + 1 - } + var ret api.SectorOffset + var allocated bool + var rerr error - // Insert market deal to DB for the sector - if piece.DealProposal != nil { - cn, err := p.db.Exec(ctx, `INSERT INTO sectors_sdr_initial_pieces (sp_id, - sector_number, - piece_index, - - piece_cid, - piece_size, - - data_url, - data_headers, - data_raw_size, - data_delete_on_finalize, - - f05_publish_cid, - f05_deal_id, - f05_deal_proposal, - f05_deal_start_epoch, - f05_deal_end_epoch) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, - p.mid, sec.number, sec.index+1, - piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, - source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, - piece.PublishCid, piece.DealID, propJson, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch) + comm, err := p.db.BeginTransaction(ctx, func(tx *harmonydb.Tx) (commit bool, err error) { + openSectors, err := p.getOpenSectors(tx) + if err != nil { + return false, err + } - if err != nil { - return false, api.SectorOffset{}, xerrors.Errorf("adding deal to sector: %w", err) + pieceSize := piece.Size() + for _, sec := range openSectors { + sec := sec + if sec.currentSize+pieceSize < abi.PaddedPieceSize(p.sectorSize) { + + ret.Sector = sec.number + ret.Offset = sec.currentSize + 1 // Current filled up size + 1 + + // Insert market deal to DB for the sector + if piece.DealProposal != nil { + for { + cn, err := tx.Exec(`SELECT insert_sector_market_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, + p.mid, sec.number, sec.index+1, + piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, + piece.PublishCid, piece.DealID, propJson, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch) + + if err != nil { + var pqErr *pq.Error + ok := errors.As(err, &pqErr) + if ok && pqErr.Code == "P0001" { + sec.index++ // Increase 'sec.index' if sql exception 'P0001' raised + continue // Retry the transaction + } + return false, fmt.Errorf("adding deal to sector: %v", err) + } + + if cn != 1 { + return false, xerrors.Errorf("expected one piece") + } + + break // Break loop on successful transaction + } + + } else { // Insert DDO deal to DB for the sector + for { + cn, err := tx.Exec(`SELECT insert_sector_ddo_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, + p.mid, sec.number, sec.index+1, + piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, + piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) + + if err != nil { + var pqErr *pq.Error + ok := errors.As(err, &pqErr) + if ok && pqErr.Code == "P0001" { + sec.index++ // Increase 'sec.index' if sql exception 'P0001' raised + continue // Retry the transaction + } + return false, fmt.Errorf("adding deal to sector: %v", err) + } + + if cn != 1 { + return false, xerrors.Errorf("expected one piece") + } + + break // Break loop on successful transaction + } } + allocated = true + break + } + } + return true, nil + }, harmonydb.OptionRetry()) - if cn != 1 { - return false, api.SectorOffset{}, xerrors.Errorf("expected one piece") - } - } else { // Insert DDO deal to DB for the sector - cn, err := p.db.Exec(ctx, `INSERT INTO sectors_sdr_initial_pieces (sp_id, - sector_number, - piece_index, - - piece_cid, - piece_size, - - data_url, - data_headers, - data_raw_size, - data_delete_on_finalize, - - direct_start_epoch, - direct_end_epoch, - direct_piece_activation_manifest) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, - p.mid, sec.number, sec.index+1, - piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, - source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, - piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) + if !comm { + rerr = xerrors.Errorf("allocating piece to a sector: commit failed") + } - if err != nil { - return false, api.SectorOffset{}, xerrors.Errorf("adding deal to sector: %w", err) - } + if err != nil { + rerr = xerrors.Errorf("allocating piece to a sector: %w", err) + } - if cn != 1 { - return false, api.SectorOffset{}, xerrors.Errorf("expected one piece") - } - } - sec.currentSize += pieceSize - startEpoch, _ := piece.StartEpoch() // ignoring error as method always returns nil - if sec.earliestEpoch > startEpoch { - sec.earliestEpoch = startEpoch - } - sec.index++ - return true, ret, nil + return allocated, ret, rerr + +} + +func (p *PieceIngester) SectorStartSealing(ctx context.Context, sector abi.SectorNumber) error { + + spt, err := p.getSealProofType() + if err != nil { + return xerrors.Errorf("getting seal proof type: %w", err) + } + + comm, err := p.db.BeginTransaction(ctx, func(tx *harmonydb.Tx) (commit bool, err error) { + // Get current open sector pieces from DB + var pieces []pieceDetails + err = tx.Select(&pieces, ` + SELECT + ssip.sector_number, + ssip.piece_size, + ssip.piece_index, + ssip.f05_deal_start_epoch, + ssip.direct_start_epoch, + ssip.created_at + FROM + sectors_sdr_initial_pieces ssip + JOIN + (SELECT sector_number + FROM sectors_sdr_initial_pieces sip + LEFT JOIN sectors_sdr_pipeline sp ON sip.sp_id = sp.sp_id AND sip.sector_number = sp.sector_number + WHERE sp.sector_number IS NULL AND sip.sp_id = $1) as filtered ON ssip.sector_number = filtered.sector_number + WHERE + ssip.sp_id = $1 AND ssip.sector_number = $2 + ORDER BY + ssip.piece_index DESC;`, p.mid, sector) + if err != nil { + return false, xerrors.Errorf("getting open sectors from DB") + } + + if len(pieces) < 1 { + return false, xerrors.Errorf("sector %d is not waiting to be sealed", sector) + } + + cn, err := p.db.Exec(p.ctx, ` + INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, p.mid, sector, spt) + + if err != nil { + return false, xerrors.Errorf("adding sector to pipeline: %w", err) } + + if cn != 1 { + return false, xerrors.Errorf("incorrect number of rows returned") + } + + return true, nil + + }, harmonydb.OptionRetry()) + + if err != nil { + return xerrors.Errorf("start sealing sector: %w", err) + } + + if !comm { + return xerrors.Errorf("start sealing sector: commit failed") } - return false, api.SectorOffset{}, nil + + return nil } -func (p *PieceIngester) SectorStartSealing(ctx context.Context, sector abi.SectorNumber) error { - p.lk.Lock() - defer p.lk.Unlock() - for _, s := range p.openSectors { - s := s - if s.number == sector { - s.lk.Lock() - s.sealNow = true - s.lk.Unlock() - return nil +func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) { + // Get current open sector pieces from DB + var pieces []pieceDetails + err := tx.Select(&pieces, ` + SELECT + ssip.sector_number, + ssip.piece_size, + ssip.piece_index, + ssip.f05_deal_start_epoch, + ssip.direct_start_epoch, + ssip.created_at + FROM + sectors_sdr_initial_pieces ssip + JOIN + (SELECT sector_number + FROM sectors_sdr_initial_pieces sip + LEFT JOIN sectors_sdr_pipeline sp ON sip.sp_id = sp.sp_id AND sip.sector_number = sp.sector_number + WHERE sp.sector_number IS NULL AND sip.sp_id = $1) as filtered ON ssip.sector_number = filtered.sector_number + WHERE + ssip.sp_id = $1 + ORDER BY + ssip.piece_index DESC;`, p.mid) + if err != nil { + return nil, xerrors.Errorf("getting open sectors from DB") + } + + getEpoch := func(piece pieceDetails, cur abi.ChainEpoch) abi.ChainEpoch { + var ret abi.ChainEpoch + if piece.ddoEpoch > 0 { + ret = piece.ddoEpoch + } else { + ret = piece.f05Epoch + } + if cur > 0 && cur < ret { + return cur + } + return ret + } + + getOpenedAt := func(piece pieceDetails, cur *time.Time) *time.Time { + if piece.CreatedAt.Before(*cur) { + return piece.CreatedAt + } + return cur + } + + sectorMap := map[abi.SectorNumber]*openSector{} + for _, pi := range pieces { + pi := pi + sector, ok := sectorMap[pi.Sector] + if !ok { + sectorMap[pi.Sector] = &openSector{ + number: pi.Sector, + currentSize: pi.Size, + earliestEpoch: getEpoch(pi, 0), + index: pi.Index, + openedAt: pi.CreatedAt, + } + sector = sectorMap[pi.Sector] + } + sector.currentSize += pi.Size + sector.earliestEpoch = getEpoch(pi, sector.earliestEpoch) + if sector.index < pi.Index { + sector.index = pi.Index } + sector.openedAt = getOpenedAt(pi, sector.openedAt) + } + + var os []*openSector + + for _, v := range sectorMap { + v := v + os = append(os, v) + } + + return os, nil +} + +func (p *PieceIngester) getSealProofType() (abi.RegisteredSealProof, error) { + nv, err := p.api.StateNetworkVersion(p.ctx, types.EmptyTSK) + if err != nil { + return 0, xerrors.Errorf("getting network version: %w", err) } - return xerrors.Errorf("sector not found") + + return miner.PreferredSealProofTypeFromWindowPoStType(nv, p.windowPoStProofType, p.synth) } diff --git a/curiosrc/market/fakelm/lmimpl.go b/curiosrc/market/fakelm/lmimpl.go index 9dc19e627d8..80db580e918 100644 --- a/curiosrc/market/fakelm/lmimpl.go +++ b/curiosrc/market/fakelm/lmimpl.go @@ -24,6 +24,7 @@ import ( "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/storage/paths" sealing "github.com/filecoin-project/lotus/storage/pipeline" + lpiece "github.com/filecoin-project/lotus/storage/pipeline/piece" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -324,7 +325,7 @@ func (l *LMRPCProvider) SectorAddPieceToAny(ctx context.Context, size abi.Unpadd return api.SectorOffset{}, xerrors.Errorf("not supported, use AllocatePieceToSector") } -func (l *LMRPCProvider) AllocatePieceToSector(ctx context.Context, maddr address.Address, piece api.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) { +func (l *LMRPCProvider) AllocatePieceToSector(ctx context.Context, maddr address.Address, piece lpiece.PieceDealInfo, rawSize int64, source url.URL, header http.Header) (api.SectorOffset, error) { return l.pi.AllocatePieceToSector(ctx, maddr, piece, rawSize, source, header) } diff --git a/go.mod b/go.mod index 55ca8aff3c7..ec7448a11cf 100644 --- a/go.mod +++ b/go.mod @@ -109,6 +109,7 @@ require ( github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa github.com/kelseyhightower/envconfig v1.4.0 github.com/koalacxr/quantile v0.0.1 + github.com/lib/pq v1.10.9 github.com/libp2p/go-buffer-pool v0.1.0 github.com/libp2p/go-libp2p v0.33.2 github.com/libp2p/go-libp2p-kad-dht v0.25.2 diff --git a/lib/harmony/harmonydb/sql/20231217-sdr-pipeline.sql b/lib/harmony/harmonydb/sql/20231217-sdr-pipeline.sql index 31f10313968..feb26226bae 100644 --- a/lib/harmony/harmonydb/sql/20231217-sdr-pipeline.sql +++ b/lib/harmony/harmonydb/sql/20231217-sdr-pipeline.sql @@ -121,6 +121,9 @@ create table sectors_sdr_initial_pieces ( -- direct_end_epoch bigint, -- direct_piece_activation_manifest jsonb, + -- created_at added in 20240430-init-piece-createdat.sql + -- created_at timestamp, + -- foreign key foreign key (sp_id, sector_number) references sectors_sdr_pipeline (sp_id, sector_number) on delete cascade, diff --git a/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql b/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql new file mode 100644 index 00000000000..c9230a2162e --- /dev/null +++ b/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql @@ -0,0 +1,114 @@ +ALTER TABLE sectors_sdr_initial_pieces + ADD COLUMN created_at TIMESTAMP; + +CREATE OR REPLACE FUNCTION insert_sector_market_piece( + v_sp_id bigint, + v_sector_number bigint, + v_piece_index bigint, + v_piece_cid text, + v_piece_size bigint, + v_data_url text, + v_data_headers jsonb, + v_data_raw_size bigint, + v_data_delete_on_finalize boolean, + v_f05_publish_cid text, + v_f05_deal_id bigint, + v_f05_deal_proposal jsonb, + v_f05_deal_start_epoch bigint, + v_f05_deal_end_epoch bigint + ) RETURNS void AS $$ + BEGIN + INSERT INTO sectors_sdr_initial_pieces ( + sp_id, + sector_number, + piece_index, + created_at, + piece_cid, + piece_size, + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + f05_publish_cid, + f05_deal_id, + f05_deal_proposal, + f05_deal_start_epoch, + f05_deal_end_epoch + ) VALUES ( + v_sp_id, + v_sector_number, + v_piece_index, + NOW(), + v_piece_cid, + v_piece_size, + v_data_url, + v_data_headers, + v_data_raw_size, + v_data_delete_on_finalize, + v_f05_publish_cid, + v_f05_deal_id, + v_f05_deal_proposal, + v_f05_deal_start_epoch, + v_f05_deal_end_epoch + ) + ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; + + IF NOT FOUND THEN + RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; + END IF; + END; + $$ LANGUAGE plpgsql; + + + +CREATE OR REPLACE FUNCTION insert_sector_ddo_piece( + v_sp_id bigint, + v_sector_number bigint, + v_piece_index bigint, + v_piece_cid text, + v_piece_size bigint, + v_data_url text, + v_data_headers jsonb, + v_data_raw_size bigint, + v_data_delete_on_finalize boolean, + v_direct_start_epoch bigint, + v_direct_end_epoch bigint, + v_direct_piece_activation_manifest jsonb + ) RETURNS void AS $$ + BEGIN + INSERT INTO sectors_sdr_initial_pieces ( + sp_id, + sector_number, + piece_index, + created_at, + piece_cid, + piece_size, + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + direct_start_epoch, + direct_end_epoch, + direct_piece_activation_manifest + ) VALUES ( + v_sp_id, + v_sector_number, + v_piece_index, + NOW(), + v_piece_cid, + v_piece_size, + v_data_url, + v_data_headers, + v_data_raw_size, + v_data_delete_on_finalize, + v_direct_start_epoch, + v_direct_end_epoch, + v_direct_piece_activation_manifest + ) + ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; + + IF NOT FOUND THEN + RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; + END IF; + END; + $$ LANGUAGE plpgsql; From 308c81c01e245f43706c914305d24dd0f1e0af89 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 30 Apr 2024 22:57:53 +0530 Subject: [PATCH 03/17] sql parser --- lib/harmony/harmonydb/harmonydb.go | 40 ++++- .../sql/20240430-init-piece-createdat.sql | 148 +++++++++--------- 2 files changed, 111 insertions(+), 77 deletions(-) diff --git a/lib/harmony/harmonydb/harmonydb.go b/lib/harmony/harmonydb/harmonydb.go index 56b5acdfee2..a3d25478517 100644 --- a/lib/harmony/harmonydb/harmonydb.go +++ b/lib/harmony/harmonydb/harmonydb.go @@ -278,7 +278,8 @@ func (db *DB) upgrade() error { logger.Error("weird embed file read err") return err } - for _, s := range strings.Split(string(file), ";") { // Implement the changes. + + for _, s := range parseSQLStatements(string(file)) { // Implement the changes. if len(strings.TrimSpace(s)) == 0 { continue } @@ -299,3 +300,40 @@ func (db *DB) upgrade() error { } return nil } + +func parseSQLStatements(sqlContent string) []string { + var statements []string + var currentStatement strings.Builder + + lines := strings.Split(sqlContent, "\n") + var inFunction bool + + for _, line := range lines { + trimmedLine := strings.TrimSpace(line) + if trimmedLine == "" || strings.HasPrefix(trimmedLine, "--") { + // Skip empty lines and comments. + continue + } + + // Detect function blocks starting or ending. + if strings.Contains(trimmedLine, "$$") { + inFunction = !inFunction + } + + // Add the line to the current statement. + currentStatement.WriteString(line + "\n") + + // If we're not in a function and the line ends with a semicolon, or we just closed a function block. + if (!inFunction && strings.HasSuffix(trimmedLine, ";")) || (strings.Contains(trimmedLine, "$$") && !inFunction) { + statements = append(statements, currentStatement.String()) + currentStatement.Reset() + } + } + + // Add any remaining statement not followed by a semicolon (should not happen in well-formed SQL but just in case). + if currentStatement.Len() > 0 { + statements = append(statements, currentStatement.String()) + } + + return statements +} diff --git a/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql b/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql index c9230a2162e..aa7f2d0e35e 100644 --- a/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql +++ b/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql @@ -16,48 +16,46 @@ CREATE OR REPLACE FUNCTION insert_sector_market_piece( v_f05_deal_proposal jsonb, v_f05_deal_start_epoch bigint, v_f05_deal_end_epoch bigint - ) RETURNS void AS $$ - BEGIN - INSERT INTO sectors_sdr_initial_pieces ( - sp_id, - sector_number, - piece_index, - created_at, - piece_cid, - piece_size, - data_url, - data_headers, - data_raw_size, - data_delete_on_finalize, - f05_publish_cid, - f05_deal_id, - f05_deal_proposal, - f05_deal_start_epoch, - f05_deal_end_epoch - ) VALUES ( - v_sp_id, - v_sector_number, - v_piece_index, - NOW(), - v_piece_cid, - v_piece_size, - v_data_url, - v_data_headers, - v_data_raw_size, - v_data_delete_on_finalize, - v_f05_publish_cid, - v_f05_deal_id, - v_f05_deal_proposal, - v_f05_deal_start_epoch, - v_f05_deal_end_epoch - ) - ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; - - IF NOT FOUND THEN - RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; - END IF; - END; - $$ LANGUAGE plpgsql; +) RETURNS void AS $$ +BEGIN + INSERT INTO sectors_sdr_initial_pieces ( + sp_id, + sector_number, + piece_index, + created_at, + piece_cid, + piece_size, + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + f05_publish_cid, + f05_deal_id, + f05_deal_proposal, + f05_deal_start_epoch, + f05_deal_end_epoch + ) VALUES ( + v_sp_id, + v_sector_number, + v_piece_index, + NOW(), + v_piece_cid, + v_piece_size, + v_data_url, + v_data_headers, + v_data_raw_size, + v_data_delete_on_finalize, + v_f05_publish_cid, + v_f05_deal_id, + v_f05_deal_proposal, + v_f05_deal_start_epoch, + v_f05_deal_end_epoch + ) ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; + IF NOT FOUND THEN + RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; + END IF; +END; +$$ LANGUAGE plpgsql; @@ -74,41 +72,39 @@ CREATE OR REPLACE FUNCTION insert_sector_ddo_piece( v_direct_start_epoch bigint, v_direct_end_epoch bigint, v_direct_piece_activation_manifest jsonb - ) RETURNS void AS $$ - BEGIN +) RETURNS void AS $$ +BEGIN INSERT INTO sectors_sdr_initial_pieces ( - sp_id, - sector_number, - piece_index, - created_at, - piece_cid, - piece_size, - data_url, - data_headers, - data_raw_size, - data_delete_on_finalize, - direct_start_epoch, - direct_end_epoch, - direct_piece_activation_manifest + sp_id, + sector_number, + piece_index, + created_at, + piece_cid, + piece_size, + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + direct_start_epoch, + direct_end_epoch, + direct_piece_activation_manifest ) VALUES ( - v_sp_id, - v_sector_number, - v_piece_index, - NOW(), - v_piece_cid, - v_piece_size, - v_data_url, - v_data_headers, - v_data_raw_size, - v_data_delete_on_finalize, - v_direct_start_epoch, - v_direct_end_epoch, - v_direct_piece_activation_manifest - ) - ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; - + v_sp_id, + v_sector_number, + v_piece_index, + NOW(), + v_piece_cid, + v_piece_size, + v_data_url, + v_data_headers, + v_data_raw_size, + v_data_delete_on_finalize, + v_direct_start_epoch, + v_direct_end_epoch, + v_direct_piece_activation_manifest + ) ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; IF NOT FOUND THEN - RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; + RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; END IF; - END; - $$ LANGUAGE plpgsql; +END; +$$ LANGUAGE plpgsql; From 2158613c164451a66bf00d67228badf6e90decd3 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Wed, 1 May 2024 00:55:13 +0530 Subject: [PATCH 04/17] add seal command --- cmd/curio/market.go | 85 +++++++++++++++++++++++++++++++++++ documentation/en/cli-curio.md | 15 +++++++ 2 files changed, 100 insertions(+) diff --git a/cmd/curio/market.go b/cmd/curio/market.go index cc562db932c..ab96489702f 100644 --- a/cmd/curio/market.go +++ b/cmd/curio/market.go @@ -2,11 +2,18 @@ package main import ( "fmt" + "net/http" "sort" + "strconv" "github.com/urfave/cli/v2" "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + + "github.com/filecoin-project/lotus/api/client" + cliutil "github.com/filecoin-project/lotus/cli/util" "github.com/filecoin-project/lotus/cmd/curio/deps" "github.com/filecoin-project/lotus/curiosrc/market/lmrpc" ) @@ -15,6 +22,7 @@ var marketCmd = &cli.Command{ Name: "market", Subcommands: []*cli.Command{ marketRPCInfoCmd, + marketSealCmd, }, } @@ -68,3 +76,80 @@ var marketRPCInfoCmd = &cli.Command{ }, Name: "rpc-info", } + +var marketSealCmd = &cli.Command{ + Name: "seal", + Usage: "start sealing a deal sector early", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "actor", + Usage: "Specify actor address to start sealing sectors for", + Required: true, + }, + &cli.StringSliceFlag{ + Name: "layers", + Usage: "list of layers to be interpreted (atop defaults). Default: base", + }, + }, + Action: func(cctx *cli.Context) error { + act, err := address.NewFromString(cctx.String("actor")) + if err != nil { + return xerrors.Errorf("parsing --actor: %w", err) + } + + if cctx.Args().Len() > 1 { + return xerrors.Errorf("specify only one sector") + } + + sec := cctx.Args().First() + + sector, err := strconv.ParseUint(sec, 10, 64) + if err != nil { + return xerrors.Errorf("failed to parse the sector number: %w", err) + } + + db, err := deps.MakeDB(cctx) + if err != nil { + return err + } + + cfg, err := deps.GetConfig(cctx, db) + if err != nil { + return xerrors.Errorf("get config: %w", err) + } + + ts, err := lmrpc.MakeTokens(cfg) + if err != nil { + return xerrors.Errorf("make tokens: %w", err) + } + + info, ok := ts[act] + if !ok { + return xerrors.Errorf("no market configuration found for actor %s in the specified config layers", act) + } + + ainfo := cliutil.ParseApiInfo(info) + addr, err := ainfo.DialArgs("0") + if err != nil { + return xerrors.Errorf("could not get DialArgs: %w", err) + } + + type httpHead struct { + addr string + header http.Header + } + + head := httpHead{ + addr: addr, + header: ainfo.AuthHeader(), + } + + market, closer, err := client.NewStorageMinerRPCV0(cctx.Context, head.addr, head.header) + if err != nil { + return xerrors.Errorf("failed to get market API: %w", err) + } + defer closer() + + return market.SectorStartSealing(cctx.Context, abi.SectorNumber(sector)) + }, +} diff --git a/documentation/en/cli-curio.md b/documentation/en/cli-curio.md index 10fdfdf8462..e13c0a337be 100644 --- a/documentation/en/cli-curio.md +++ b/documentation/en/cli-curio.md @@ -531,6 +531,7 @@ USAGE: COMMANDS: rpc-info + seal start sealing a deal sector early help, h Shows a list of commands or help for one command OPTIONS: @@ -550,6 +551,20 @@ OPTIONS: --help, -h show help ``` +### curio market seal +``` +NAME: + curio market seal - start sealing a deal sector early + +USAGE: + curio market seal [command options] [arguments...] + +OPTIONS: + --actor value Specify actor address to start sealing sectors for + --layers value [ --layers value ] list of layers to be interpreted (atop defaults). Default: base + --help, -h show help +``` + ## curio fetch-params ``` NAME: From f46b33d19ad6a8c7f525bee2245b9244fd6ef9f5 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Fri, 10 May 2024 00:59:13 +0530 Subject: [PATCH 05/17] multi piece TreeD --- cmd/curio/market.go | 2 +- cmd/lotus-shed/miner.go | 9 +- curiosrc/docker/curio/entrypoint.sh | 2 +- curiosrc/ffi/sdr_funcs.go | 2 +- curiosrc/market/deal_ingest.go | 111 +++++----- curiosrc/market/lmrpc/lmrpc.go | 2 +- curiosrc/piece/task_park_piece.go | 47 ++-- curiosrc/seal/task_porep.go | 42 ++-- curiosrc/seal/task_submit_precommit.go | 9 +- curiosrc/seal/task_treed.go | 44 +++- lib/filler/filler.go | 43 ++++ .../filler/filler_test.go | 4 +- .../harmonydb/sql/20231217-sdr-pipeline.sql | 5 +- .../sql/20240430-init-piece-createdat.sql | 110 ---------- .../sql/20240508-open-deal-sectors.sql | 206 ++++++++++++++++++ storage/pipeline/states_sealing.go | 3 +- storage/pipeline/utils.go | 37 ---- 17 files changed, 425 insertions(+), 253 deletions(-) create mode 100644 lib/filler/filler.go rename storage/pipeline/utils_test.go => lib/filler/filler_test.go (96%) delete mode 100644 lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql create mode 100644 lib/harmony/harmonydb/sql/20240508-open-deal-sectors.sql diff --git a/cmd/curio/market.go b/cmd/curio/market.go index ab96489702f..e354d1e68ce 100644 --- a/cmd/curio/market.go +++ b/cmd/curio/market.go @@ -129,7 +129,7 @@ var marketSealCmd = &cli.Command{ } ainfo := cliutil.ParseApiInfo(info) - addr, err := ainfo.DialArgs("0") + addr, err := ainfo.DialArgs("v0") if err != nil { return xerrors.Errorf("could not get DialArgs: %w", err) } diff --git a/cmd/lotus-shed/miner.go b/cmd/lotus-shed/miner.go index 2f9b4ecf103..827fbf41514 100644 --- a/cmd/lotus-shed/miner.go +++ b/cmd/lotus-shed/miner.go @@ -220,6 +220,13 @@ var minerCreateCmd = &cli.Command{ Name: "create", Usage: "sends a create miner message", ArgsUsage: "[sender] [owner] [worker] [sector size]", + Flags: []cli.Flag{ + &cli.IntFlag{ + Name: "confidence", + Usage: "number of block confirmations to wait for", + Value: int(build.MessageConfidence), + }, + }, Action: func(cctx *cli.Context) error { wapi, closer, err := lcli.GetFullNodeAPI(cctx) if err != nil { @@ -274,7 +281,7 @@ var minerCreateCmd = &cli.Command{ log.Infof("Initializing worker account %s, message: %s", worker, signed.Cid()) log.Infof("Waiting for confirmation") - mw, err := wapi.StateWaitMsg(ctx, signed.Cid(), build.MessageConfidence) + mw, err := wapi.StateWaitMsg(ctx, signed.Cid(), uint64(cctx.Int("confidence"))) if err != nil { return xerrors.Errorf("waiting for worker init: %w", err) } diff --git a/curiosrc/docker/curio/entrypoint.sh b/curiosrc/docker/curio/entrypoint.sh index 12410a39463..cbdde9fdb32 100755 --- a/curiosrc/docker/curio/entrypoint.sh +++ b/curiosrc/docker/curio/entrypoint.sh @@ -36,7 +36,7 @@ if [ ! -f $CURIO_REPO_PATH/.init.curio ]; then echo Initiating a new Curio cluster ... curio config new-cluster $newminer echo Enabling market ... - curio config get seal | sed -e $'$a\\\n BoostAdapters = ["'"$newminer"':'"$myip"':32100"]' | curio config set --title seal + curio config get seal | sed -e $'$a\\\n BoostAdapters = ["'"$newminer"':'"$myip"':32100"]\n EnableParkPiece = true' | curio config set --title seal touch $CURIO_REPO_PATH/.init.config fi diff --git a/curiosrc/ffi/sdr_funcs.go b/curiosrc/ffi/sdr_funcs.go index eff49578d98..6efcdd66402 100644 --- a/curiosrc/ffi/sdr_funcs.go +++ b/curiosrc/ffi/sdr_funcs.go @@ -648,7 +648,7 @@ func (sb *SealCalls) TreeD(ctx context.Context, sector storiface.SectorRef, unse } if treeDUnsealed != unsealed { - return xerrors.Errorf("tree-d cid mismatch with supplied unsealed cid") + return xerrors.Errorf("tree-d cid %s mismatch with supplied unsealed cid %s", treeDUnsealed, unsealed) } if err := sb.ensureOneCopy(ctx, sector.ID, pathIDs, storiface.FTCache); err != nil { diff --git a/curiosrc/market/deal_ingest.go b/curiosrc/market/deal_ingest.go index 03cce5adcca..ef506cdf9a7 100644 --- a/curiosrc/market/deal_ingest.go +++ b/curiosrc/market/deal_ingest.go @@ -66,8 +66,8 @@ type PieceIngester struct { type pieceDetails struct { Sector abi.SectorNumber `db:"sector_number"` Size abi.PaddedPieceSize `db:"piece_size"` - f05Epoch abi.ChainEpoch `db:"f05_deal_start_epoch"` - ddoEpoch abi.ChainEpoch `db:"direct_start_epoch"` + F05Epoch abi.ChainEpoch `db:"f05_deal_start_epoch"` + DdoEpoch abi.ChainEpoch `db:"direct_start_epoch"` Index uint64 `db:"piece_index"` CreatedAt *time.Time `db:"created_at"` } @@ -84,6 +84,7 @@ func NewPieceIngester(ctx context.Context, db *harmonydb.DB, api PieceIngesterAp } pi := &PieceIngester{ + ctx: ctx, db: db, api: api, sealRightNow: sealRightNow, @@ -128,6 +129,26 @@ func (p *PieceIngester) Seal() error { return xerrors.Errorf("getting seal proof type: %w", err) } + shouldSeal := func(sector *openSector) bool { + // Start sealing a sector if + // 1. If sector is full + // 2. We have been waiting for MaxWaitDuration + // 3. StartEpoch is less than 8 hours // todo: make this config? + if sector.currentSize == abi.PaddedPieceSize(p.sectorSize) { + log.Debugf("start sealing sector %d of miner %d: %s", sector.number, p.miner.String(), "sector full") + return true + } + if time.Since(*sector.openedAt) > p.maxWaitTime { + log.Debugf("start sealing sector %d of miner %d: %s", sector.number, p.miner.String(), "MaxWaitTime reached") + return true + } + if sector.earliestEpoch < head.Height()+abi.ChainEpoch(960) { + log.Debugf("start sealing sector %d of miner %d: %s", sector.number, p.miner.String(), "earliest start epoch") + return true + } + return false + } + comm, err := p.db.BeginTransaction(p.ctx, func(tx *harmonydb.Tx) (commit bool, err error) { openSectors, err := p.getOpenSectors(tx) @@ -137,23 +158,24 @@ func (p *PieceIngester) Seal() error { for _, sector := range openSectors { sector := sector - // Start sealing a sector if - // 1. If sector is full - // 2. We have been waiting for MaxWaitDuration - // 3. StartEpoch is less than 8 hours // todo: make this config? - if sector.currentSize == abi.PaddedPieceSize(p.sectorSize) || time.Since(*sector.openedAt) >= p.maxWaitTime || sector.earliestEpoch > head.Height()+abi.ChainEpoch(960) { + if shouldSeal(sector) { // Start sealing the sector - cn, err := p.db.Exec(p.ctx, ` - INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, p.mid, sector.number, spt) + cn, err := tx.Exec(`INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, p.mid, sector.number, spt) if err != nil { return false, xerrors.Errorf("adding sector to pipeline: %w", err) } if cn != 1 { - return false, xerrors.Errorf("incorrect number of rows returned") + return false, xerrors.Errorf("adding sector to pipeline: incorrect number of rows returned") + } + + _, err = tx.Exec("SELECT transfer_and_delete_open_piece($1, $2)", p.mid, sector.number) + if err != nil { + return false, xerrors.Errorf("adding sector to pipeline: %w", err) } } + } return true, nil }, harmonydb.OptionRetry()) @@ -174,10 +196,6 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address return api.SectorOffset{}, xerrors.Errorf("miner address doesn't match") } - if piece.DealProposal.PieceSize != abi.PaddedPieceSize(p.sectorSize) { - return api.SectorOffset{}, xerrors.Errorf("only full sector pieces supported for now") - } - // check raw size if piece.DealProposal.PieceSize != padreader.PaddedSize(uint64(rawSize)).Padded() { return api.SectorOffset{}, xerrors.Errorf("raw size doesn't match padded piece size") @@ -232,7 +250,7 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address } else { _, err = tx.Exec(`SELECT insert_sector_ddo_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, p.mid, n, 0, - piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + piece.PieceActivationManifest.CID, piece.PieceActivationManifest.Size, source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) if err != nil { @@ -312,7 +330,7 @@ func (p *PieceIngester) allocateToExisting(ctx context.Context, piece lpiece.Pie for { cn, err := tx.Exec(`SELECT insert_sector_ddo_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, p.mid, sec.number, sec.index+1, - piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + piece.PieceActivationManifest.CID, piece.PieceActivationManifest.Size, source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) @@ -364,23 +382,18 @@ func (p *PieceIngester) SectorStartSealing(ctx context.Context, sector abi.Secto var pieces []pieceDetails err = tx.Select(&pieces, ` SELECT - ssip.sector_number, - ssip.piece_size, - ssip.piece_index, - ssip.f05_deal_start_epoch, - ssip.direct_start_epoch, - ssip.created_at + sector_number, + piece_size, + piece_index, + COALESCE(f05_deal_start_epoch, 0) AS f05_deal_start_epoch, + COALESCE(direct_start_epoch, 0) AS direct_start_epoch, + created_at FROM - sectors_sdr_initial_pieces ssip - JOIN - (SELECT sector_number - FROM sectors_sdr_initial_pieces sip - LEFT JOIN sectors_sdr_pipeline sp ON sip.sp_id = sp.sp_id AND sip.sector_number = sp.sector_number - WHERE sp.sector_number IS NULL AND sip.sp_id = $1) as filtered ON ssip.sector_number = filtered.sector_number + open_sector_pieces WHERE - ssip.sp_id = $1 AND ssip.sector_number = $2 + sp_id = $1 AND sector_number = $2 ORDER BY - ssip.piece_index DESC;`, p.mid, sector) + piece_index DESC;`, p.mid, sector) if err != nil { return false, xerrors.Errorf("getting open sectors from DB") } @@ -389,8 +402,7 @@ func (p *PieceIngester) SectorStartSealing(ctx context.Context, sector abi.Secto return false, xerrors.Errorf("sector %d is not waiting to be sealed", sector) } - cn, err := p.db.Exec(p.ctx, ` - INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, p.mid, sector, spt) + cn, err := tx.Exec(`INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, p.mid, sector, spt) if err != nil { return false, xerrors.Errorf("adding sector to pipeline: %w", err) @@ -400,6 +412,11 @@ func (p *PieceIngester) SectorStartSealing(ctx context.Context, sector abi.Secto return false, xerrors.Errorf("incorrect number of rows returned") } + _, err = tx.Exec("SELECT transfer_and_delete_open_piece($1, $2)", p.mid, sector) + if err != nil { + return false, xerrors.Errorf("adding sector to pipeline: %w", err) + } + return true, nil }, harmonydb.OptionRetry()) @@ -420,33 +437,28 @@ func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) var pieces []pieceDetails err := tx.Select(&pieces, ` SELECT - ssip.sector_number, - ssip.piece_size, - ssip.piece_index, - ssip.f05_deal_start_epoch, - ssip.direct_start_epoch, - ssip.created_at + sector_number, + piece_size, + piece_index, + COALESCE(f05_deal_start_epoch, 0) AS f05_deal_start_epoch, + COALESCE(direct_start_epoch, 0) AS direct_start_epoch, + created_at FROM - sectors_sdr_initial_pieces ssip - JOIN - (SELECT sector_number - FROM sectors_sdr_initial_pieces sip - LEFT JOIN sectors_sdr_pipeline sp ON sip.sp_id = sp.sp_id AND sip.sector_number = sp.sector_number - WHERE sp.sector_number IS NULL AND sip.sp_id = $1) as filtered ON ssip.sector_number = filtered.sector_number + open_sector_pieces WHERE - ssip.sp_id = $1 + sp_id = $1 ORDER BY - ssip.piece_index DESC;`, p.mid) + piece_index DESC;`, p.mid) if err != nil { return nil, xerrors.Errorf("getting open sectors from DB") } getEpoch := func(piece pieceDetails, cur abi.ChainEpoch) abi.ChainEpoch { var ret abi.ChainEpoch - if piece.ddoEpoch > 0 { - ret = piece.ddoEpoch + if piece.DdoEpoch > 0 { + ret = piece.DdoEpoch } else { - ret = piece.f05Epoch + ret = piece.F05Epoch } if cur > 0 && cur < ret { return cur @@ -474,6 +486,7 @@ func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) openedAt: pi.CreatedAt, } sector = sectorMap[pi.Sector] + continue } sector.currentSize += pi.Size sector.earliestEpoch = getEpoch(pi, sector.earliestEpoch) diff --git a/curiosrc/market/lmrpc/lmrpc.go b/curiosrc/market/lmrpc/lmrpc.go index da4f5f75072..74d130f7005 100644 --- a/curiosrc/market/lmrpc/lmrpc.go +++ b/curiosrc/market/lmrpc/lmrpc.go @@ -500,7 +500,7 @@ func maybeApplyBackpressure(tx *harmonydb.Tx, cfg config.CurioIngestConfig, ssiz (SELECT buffered_sdr_count FROM BufferedSDR) AS total_buffered_sdr, (SELECT buffered_trees_count FROM BufferedTrees) AS buffered_trees_count, (SELECT buffered_porep_count FROM BufferedPoRep) AS buffered_porep_count, - (SELECT wait_deal_sectors_count FROM WaitDealSectors) AS wait_deal_sectors_count, + (SELECT wait_deal_sectors_count FROM WaitDealSectors) AS wait_deal_sectors_count `).Scan(&bufferedSDR, &bufferedTrees, &bufferedPoRep, &waitDealSectors) if err != nil { return false, xerrors.Errorf("counting buffered sectors: %w", err) diff --git a/curiosrc/piece/task_park_piece.go b/curiosrc/piece/task_park_piece.go index 18ebcdef849..d8b6d51a102 100644 --- a/curiosrc/piece/task_park_piece.go +++ b/curiosrc/piece/task_park_piece.go @@ -6,6 +6,7 @@ import ( "strconv" "time" + "github.com/hashicorp/go-multierror" logging "github.com/ipfs/go-log/v2" "golang.org/x/xerrors" @@ -126,9 +127,7 @@ func (p *ParkPieceTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (d err = p.db.Select(ctx, &refData, ` SELECT data_url, data_headers FROM parked_piece_refs - WHERE piece_id = $1 AND data_url IS NOT NULL - LIMIT 1 - `, pieceData.PieceID) + WHERE piece_id = $1 AND data_url IS NOT NULL`, pieceData.PieceID) if err != nil { return false, xerrors.Errorf("fetching reference data: %w", err) } @@ -143,28 +142,34 @@ func (p *ParkPieceTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (d return false, xerrors.Errorf("parsing piece raw size: %w", err) } - if refData[0].DataURL != "" { - upr := &seal.UrlPieceReader{ - Url: refData[0].DataURL, - RawSize: pieceRawSize, - } - defer func() { - _ = upr.Close() - }() + var merr error - pnum := storiface.PieceNumber(pieceData.PieceID) + for i := range refData { + if refData[i].DataURL != "" { + upr := &seal.UrlPieceReader{ + Url: refData[0].DataURL, + RawSize: pieceRawSize, + } + defer func() { + _ = upr.Close() + }() - if err := p.sc.WritePiece(ctx, &taskID, pnum, pieceRawSize, upr); err != nil { - return false, xerrors.Errorf("write piece: %w", err) - } + pnum := storiface.PieceNumber(pieceData.PieceID) - // Update the piece as complete after a successful write. - _, err = p.db.Exec(ctx, `UPDATE parked_pieces SET complete = TRUE WHERE id = $1`, pieceData.PieceID) - if err != nil { - return false, xerrors.Errorf("marking piece as complete: %w", err) - } + if err := p.sc.WritePiece(ctx, &taskID, pnum, pieceRawSize, upr); err != nil { + merr = multierror.Append(merr, xerrors.Errorf("write piece: %w", err)) + continue + } - return true, nil + // Update the piece as complete after a successful write. + _, err = p.db.Exec(ctx, `UPDATE parked_pieces SET complete = TRUE WHERE id = $1`, pieceData.PieceID) + if err != nil { + return false, xerrors.Errorf("marking piece as complete: %w", err) + } + + return true, nil + } + return false, merr } // If no URL is found, this indicates an issue since at least one URL is expected. diff --git a/curiosrc/seal/task_porep.go b/curiosrc/seal/task_porep.go index d4d744e4092..62894d55b5c 100644 --- a/curiosrc/seal/task_porep.go +++ b/curiosrc/seal/task_porep.go @@ -112,9 +112,9 @@ func (p *PoRepTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done proof, err := p.sc.PoRepSnark(ctx, sr, sealed, unsealed, sectorParams.TicketValue, abi.InteractiveSealRandomness(rand)) if err != nil { - end, err := p.recoverErrors(ctx, sectorParams.SpID, sectorParams.SectorNumber, err) - if err != nil { - return false, xerrors.Errorf("recover errors: %w", err) + end, rerr := p.recoverErrors(ctx, sectorParams.SpID, sectorParams.SectorNumber, err) + if rerr != nil { + return false, xerrors.Errorf("recover errors: %w", rerr) } if end { // done, but the error handling has stored a different than success state @@ -190,26 +190,17 @@ func (p *PoRepTask) recoverErrors(ctx context.Context, spid, snum int64, cerr er switch { case strings.Contains(cerr.Error(), errstrInvalidCommD): - fallthrough + log.Warnf("PoRep error recovery: PoRep failed with %s for sector %d of miner %d", errstrInvalidCommD, snum, spid) + return p.resetSector(ctx, spid, snum) case strings.Contains(cerr.Error(), errstrInvalidCommR): // todo: it might be more optimal to just retry the Trees compute first. // Invalid CommD/R likely indicates a problem with the data computed in that step // For now for simplicity just retry the whole thing - fallthrough + log.Warnf("PoRep error recovery: PoRep failed with %s for sector %d of miner %d", errstrInvalidCommR, snum, spid) + return p.resetSector(ctx, spid, snum) case strings.Contains(cerr.Error(), errstrInvalidEncoding): - n, err := p.db.Exec(ctx, `UPDATE sectors_sdr_pipeline - SET after_porep = FALSE, after_sdr = FALSE, after_tree_d = FALSE, - after_tree_r = FALSE, after_tree_c = FALSE - WHERE sp_id = $1 AND sector_number = $2`, - spid, snum) - if err != nil { - return false, xerrors.Errorf("store sdr success: updating pipeline: %w", err) - } - if n != 1 { - return false, xerrors.Errorf("store sdr success: updated %d rows", n) - } - - return true, nil + log.Warnf("PoRep error recovery: PoRep failed with %s for sector %d of miner %d", errstrInvalidEncoding, snum, spid) + return p.resetSector(ctx, spid, snum) default: // if end is false the original error will be returned by the caller @@ -217,4 +208,19 @@ func (p *PoRepTask) recoverErrors(ctx context.Context, spid, snum int64, cerr er } } +func (p *PoRepTask) resetSector(ctx context.Context, spid, snum int64) (bool, error) { + n, err := p.db.Exec(ctx, `UPDATE sectors_sdr_pipeline + SET after_porep = FALSE, after_sdr = FALSE, after_tree_d = FALSE, + after_tree_r = FALSE, after_tree_c = FALSE + WHERE sp_id = $1 AND sector_number = $2`, + spid, snum) + if err != nil { + return false, xerrors.Errorf("store sdr success: updating pipeline: %w", err) + } + if n != 1 { + return false, xerrors.Errorf("store sdr success: updated %d rows", n) + } + return true, nil +} + var _ harmonytask.TaskInterface = &PoRepTask{} diff --git a/curiosrc/seal/task_submit_precommit.go b/curiosrc/seal/task_submit_precommit.go index 063aa425269..108e51fb67e 100644 --- a/curiosrc/seal/task_submit_precommit.go +++ b/curiosrc/seal/task_submit_precommit.go @@ -133,7 +133,14 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo } err = s.db.Select(ctx, &pieces, ` - SELECT piece_index, piece_cid, piece_size, f05_deal_id, f05_deal_end_epoch, f05_deal_start_epoch, direct_start_epoch, direct_end_epoch + SELECT piece_index, + piece_cid, + piece_size, + f05_deal_id, + COALESCE(f05_deal_end_epoch, 0) AS f05_deal_end_epoch, + COALESCE(f05_deal_start_epoch, 0) AS f05_deal_start_epoch, + COALESCE(direct_start_epoch, 0) AS direct_start_epoch, + COALESCE(direct_end_epoch, 0) AS direct_end_epoch FROM sectors_sdr_initial_pieces WHERE sp_id = $1 AND sector_number = $2 ORDER BY piece_index ASC`, sectorParams.SpID, sectorParams.SectorNumber) if err != nil { diff --git a/curiosrc/seal/task_treed.go b/curiosrc/seal/task_treed.go index fda1d1f6558..c824bbcdc25 100644 --- a/curiosrc/seal/task_treed.go +++ b/curiosrc/seal/task_treed.go @@ -7,6 +7,7 @@ import ( "net/url" "strconv" + "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -164,20 +165,35 @@ func (t *TreeDTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done }() if len(pieces) > 0 { - pieceInfos := make([]abi.PieceInfo, len(pieces)) - pieceReaders := make([]io.Reader, len(pieces)) + var pieceInfos []abi.PieceInfo + var pieceReaders []io.Reader + var offset abi.UnpaddedPieceSize - for i, p := range pieces { + for _, p := range pieces { // make pieceInfo c, err := cid.Parse(p.PieceCID) if err != nil { return false, xerrors.Errorf("parsing piece cid: %w", err) } - pieceInfos[i] = abi.PieceInfo{ + pads, padLength := ffiwrapper.GetRequiredPadding(offset.Padded(), abi.PaddedPieceSize(p.PieceSize)) + offset += padLength.Unpadded() + + for _, pad := range pads { + padCid := zerocomm.ZeroPieceCommitment(pad.Unpadded()) + pieceInfos = append(pieceInfos, abi.PieceInfo{ + Size: pad, + PieceCID: padCid, + }) + pieceReaders = append(pieceReaders, nullreader.NewNullReader(pad.Unpadded())) + } + + pieceInfos = append(pieceInfos, abi.PieceInfo{ Size: abi.PaddedPieceSize(p.PieceSize), PieceCID: c, - } + }) + + offset += abi.PaddedPieceSize(p.PieceSize).Unpadded() // make pieceReader if p.DataUrl != nil { @@ -216,19 +232,31 @@ func (t *TreeDTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done closers = append(closers, pr) - pieceReaders[i], _ = padreader.New(pr, uint64(*p.DataRawSize)) + reader, _ := padreader.New(pr, uint64(*p.DataRawSize)) + pieceReaders = append(pieceReaders, reader) } else { - pieceReaders[i], _ = padreader.New(&UrlPieceReader{ + reader, _ := padreader.New(&UrlPieceReader{ Url: dataUrl, RawSize: *p.DataRawSize, }, uint64(*p.DataRawSize)) + pieceReaders = append(pieceReaders, reader) } } else { // padding piece (w/o fr32 padding, added in TreeD) - pieceReaders[i] = nullreader.NewNullReader(abi.PaddedPieceSize(p.PieceSize).Unpadded()) + pieceReaders = append(pieceReaders, nullreader.NewNullReader(abi.PaddedPieceSize(p.PieceSize).Unpadded())) } } + if offset.Padded() < abi.PaddedPieceSize(ssize) { + fillerSize := abi.PaddedPieceSize(ssize) - offset.Padded() + filler := nullreader.NewNullReader(fillerSize.Unpadded()) + pieceInfos = append(pieceInfos, abi.PieceInfo{ + Size: fillerSize, + PieceCID: zerocomm.ZeroPieceCommitment(fillerSize.Unpadded()), + }) + pieceReaders = append(pieceReaders, filler) + } + commd, err = nonffi.GenerateUnsealedCID(sectorParams.RegSealProof, pieceInfos) if err != nil { return false, xerrors.Errorf("computing CommD: %w", err) diff --git a/lib/filler/filler.go b/lib/filler/filler.go new file mode 100644 index 00000000000..42bb4fa99ab --- /dev/null +++ b/lib/filler/filler.go @@ -0,0 +1,43 @@ +package filler + +import ( + "math/bits" + + "github.com/filecoin-project/go-state-types/abi" +) + +func FillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) { + // Convert to in-sector bytes for easier math: + // + // Sector size to user bytes ratio is constant, e.g. for 1024B we have 1016B + // of user-usable data. + // + // (1024/1016 = 128/127) + // + // Given that we can get sector size by simply adding 1/127 of the user + // bytes + // + // (we convert to sector bytes as they are nice round binary numbers) + + toFill := uint64(in + (in / 127)) + + // We need to fill the sector with pieces that are powers of 2. Conveniently + // computers store numbers in binary, which means we can look at 1s to get + // all the piece sizes we need to fill the sector. It also means that number + // of pieces is the number of 1s in the number of remaining bytes to fill + out := make([]abi.UnpaddedPieceSize, bits.OnesCount64(toFill)) + for i := range out { + // Extract the next lowest non-zero bit + next := bits.TrailingZeros64(toFill) + psize := uint64(1) << next + // e.g: if the number is 0b010100, psize will be 0b000100 + + // set that bit to 0 by XORing it, so the next iteration looks at the + // next bit + toFill ^= psize + + // Add the piece size to the list of pieces we need to create + out[i] = abi.PaddedPieceSize(psize).Unpadded() + } + return out, nil +} diff --git a/storage/pipeline/utils_test.go b/lib/filler/filler_test.go similarity index 96% rename from storage/pipeline/utils_test.go rename to lib/filler/filler_test.go index fb9548a2832..a9b62da3066 100644 --- a/storage/pipeline/utils_test.go +++ b/lib/filler/filler_test.go @@ -1,4 +1,4 @@ -package sealing +package filler import ( "testing" @@ -9,7 +9,7 @@ import ( ) func testFill(t *testing.T, n abi.UnpaddedPieceSize, exp []abi.UnpaddedPieceSize) { - f, err := fillersFromRem(n) + f, err := FillersFromRem(n) assert.NoError(t, err) assert.Equal(t, exp, f) diff --git a/lib/harmony/harmonydb/sql/20231217-sdr-pipeline.sql b/lib/harmony/harmonydb/sql/20231217-sdr-pipeline.sql index feb26226bae..d8cf019eb01 100644 --- a/lib/harmony/harmonydb/sql/20231217-sdr-pipeline.sql +++ b/lib/harmony/harmonydb/sql/20231217-sdr-pipeline.sql @@ -121,9 +121,12 @@ create table sectors_sdr_initial_pieces ( -- direct_end_epoch bigint, -- direct_piece_activation_manifest jsonb, - -- created_at added in 20240430-init-piece-createdat.sql + -- created_at added in 20240508-open-deal-sectors.sql -- created_at timestamp, + -- open_sector_pieces table is a copy of this + -- all alters should happen on both tables except constraints + -- foreign key foreign key (sp_id, sector_number) references sectors_sdr_pipeline (sp_id, sector_number) on delete cascade, diff --git a/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql b/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql deleted file mode 100644 index aa7f2d0e35e..00000000000 --- a/lib/harmony/harmonydb/sql/20240430-init-piece-createdat.sql +++ /dev/null @@ -1,110 +0,0 @@ -ALTER TABLE sectors_sdr_initial_pieces - ADD COLUMN created_at TIMESTAMP; - -CREATE OR REPLACE FUNCTION insert_sector_market_piece( - v_sp_id bigint, - v_sector_number bigint, - v_piece_index bigint, - v_piece_cid text, - v_piece_size bigint, - v_data_url text, - v_data_headers jsonb, - v_data_raw_size bigint, - v_data_delete_on_finalize boolean, - v_f05_publish_cid text, - v_f05_deal_id bigint, - v_f05_deal_proposal jsonb, - v_f05_deal_start_epoch bigint, - v_f05_deal_end_epoch bigint -) RETURNS void AS $$ -BEGIN - INSERT INTO sectors_sdr_initial_pieces ( - sp_id, - sector_number, - piece_index, - created_at, - piece_cid, - piece_size, - data_url, - data_headers, - data_raw_size, - data_delete_on_finalize, - f05_publish_cid, - f05_deal_id, - f05_deal_proposal, - f05_deal_start_epoch, - f05_deal_end_epoch - ) VALUES ( - v_sp_id, - v_sector_number, - v_piece_index, - NOW(), - v_piece_cid, - v_piece_size, - v_data_url, - v_data_headers, - v_data_raw_size, - v_data_delete_on_finalize, - v_f05_publish_cid, - v_f05_deal_id, - v_f05_deal_proposal, - v_f05_deal_start_epoch, - v_f05_deal_end_epoch - ) ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; - IF NOT FOUND THEN - RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; - END IF; -END; -$$ LANGUAGE plpgsql; - - - -CREATE OR REPLACE FUNCTION insert_sector_ddo_piece( - v_sp_id bigint, - v_sector_number bigint, - v_piece_index bigint, - v_piece_cid text, - v_piece_size bigint, - v_data_url text, - v_data_headers jsonb, - v_data_raw_size bigint, - v_data_delete_on_finalize boolean, - v_direct_start_epoch bigint, - v_direct_end_epoch bigint, - v_direct_piece_activation_manifest jsonb -) RETURNS void AS $$ -BEGIN - INSERT INTO sectors_sdr_initial_pieces ( - sp_id, - sector_number, - piece_index, - created_at, - piece_cid, - piece_size, - data_url, - data_headers, - data_raw_size, - data_delete_on_finalize, - direct_start_epoch, - direct_end_epoch, - direct_piece_activation_manifest - ) VALUES ( - v_sp_id, - v_sector_number, - v_piece_index, - NOW(), - v_piece_cid, - v_piece_size, - v_data_url, - v_data_headers, - v_data_raw_size, - v_data_delete_on_finalize, - v_direct_start_epoch, - v_direct_end_epoch, - v_direct_piece_activation_manifest - ) ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; - IF NOT FOUND THEN - RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; - END IF; -END; -$$ LANGUAGE plpgsql; diff --git a/lib/harmony/harmonydb/sql/20240508-open-deal-sectors.sql b/lib/harmony/harmonydb/sql/20240508-open-deal-sectors.sql new file mode 100644 index 00000000000..88c439a19cd --- /dev/null +++ b/lib/harmony/harmonydb/sql/20240508-open-deal-sectors.sql @@ -0,0 +1,206 @@ +ALTER TABLE sectors_sdr_initial_pieces + ADD COLUMN created_at TIMESTAMP; + +create table open_sector_pieces ( + sp_id bigint not null, + sector_number bigint not null, + + piece_index bigint not null, + piece_cid text not null, + piece_size bigint not null, -- padded size + + -- data source + data_url text not null, + data_headers jsonb not null default '{}', + data_raw_size bigint not null, + data_delete_on_finalize bool not null, + + -- deal info + f05_publish_cid text, + f05_deal_id bigint, + f05_deal_proposal jsonb, + f05_deal_start_epoch bigint, + f05_deal_end_epoch bigint, + + -- ddo deal info + -- added in 20240402-sdr-pipeline-ddo-deal-info.sql + direct_start_epoch bigint, + direct_end_epoch bigint, + direct_piece_activation_manifest jsonb, + + -- created_at added in 20240508-open-deal-sectors.sql + created_at timestamp, + + -- sectors_sdr_initial_pieces table is a copy of this + -- all alters should happen on both tables except constraints + + primary key (sp_id, sector_number, piece_index) +); + + +CREATE OR REPLACE FUNCTION insert_sector_market_piece( + v_sp_id bigint, + v_sector_number bigint, + v_piece_index bigint, + v_piece_cid text, + v_piece_size bigint, + v_data_url text, + v_data_headers jsonb, + v_data_raw_size bigint, + v_data_delete_on_finalize boolean, + v_f05_publish_cid text, + v_f05_deal_id bigint, + v_f05_deal_proposal jsonb, + v_f05_deal_start_epoch bigint, + v_f05_deal_end_epoch bigint +) RETURNS void AS $$ +BEGIN +INSERT INTO open_sector_pieces ( + sp_id, + sector_number, + piece_index, + created_at, + piece_cid, + piece_size, + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + f05_publish_cid, + f05_deal_id, + f05_deal_proposal, + f05_deal_start_epoch, + f05_deal_end_epoch +) VALUES ( + v_sp_id, + v_sector_number, + v_piece_index, + NOW(), + v_piece_cid, + v_piece_size, + v_data_url, + v_data_headers, + v_data_raw_size, + v_data_delete_on_finalize, + v_f05_publish_cid, + v_f05_deal_id, + v_f05_deal_proposal, + v_f05_deal_start_epoch, + v_f05_deal_end_epoch + ) ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; +IF NOT FOUND THEN + RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; +END IF; +END; +$$ LANGUAGE plpgsql; + + + +CREATE OR REPLACE FUNCTION insert_sector_ddo_piece( + v_sp_id bigint, + v_sector_number bigint, + v_piece_index bigint, + v_piece_cid text, + v_piece_size bigint, + v_data_url text, + v_data_headers jsonb, + v_data_raw_size bigint, + v_data_delete_on_finalize boolean, + v_direct_start_epoch bigint, + v_direct_end_epoch bigint, + v_direct_piece_activation_manifest jsonb +) RETURNS void AS $$ +BEGIN +INSERT INTO open_sector_pieces ( + sp_id, + sector_number, + piece_index, + created_at, + piece_cid, + piece_size, + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + direct_start_epoch, + direct_end_epoch, + direct_piece_activation_manifest +) VALUES ( + v_sp_id, + v_sector_number, + v_piece_index, + NOW(), + v_piece_cid, + v_piece_size, + v_data_url, + v_data_headers, + v_data_raw_size, + v_data_delete_on_finalize, + v_direct_start_epoch, + v_direct_end_epoch, + v_direct_piece_activation_manifest + ) ON CONFLICT (sp_id, sector_number, piece_index) DO NOTHING; +IF NOT FOUND THEN + RAISE EXCEPTION 'Conflict detected for piece_index %', v_piece_index; +END IF; +END; +$$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION transfer_and_delete_open_piece(v_sp_id bigint, v_sector_number bigint) +RETURNS void AS $$ +BEGIN + -- Copy data from open_sector_pieces to sectors_sdr_initial_pieces +INSERT INTO sectors_sdr_initial_pieces ( + sp_id, + sector_number, + piece_index, + piece_cid, + piece_size, + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + f05_publish_cid, + f05_deal_id, + f05_deal_proposal, + f05_deal_start_epoch, + f05_deal_end_epoch, + direct_start_epoch, + direct_end_epoch, + direct_piece_activation_manifest, + created_at +) +SELECT + sp_id, + sector_number, + piece_index, + piece_cid, + piece_size, + data_url, + data_headers, + data_raw_size, + data_delete_on_finalize, + f05_publish_cid, + f05_deal_id, + f05_deal_proposal, + f05_deal_start_epoch, + f05_deal_end_epoch, + direct_start_epoch, + direct_end_epoch, + direct_piece_activation_manifest, + created_at +FROM + open_sector_pieces +WHERE + sp_id = v_sp_id AND + sector_number = v_sector_number; + +-- Check for successful insertion, then delete the corresponding row from open_sector_pieces +IF FOUND THEN +DELETE FROM open_sector_pieces +WHERE sp_id = v_sp_id AND sector_number = v_sector_number; +ELSE + RAISE EXCEPTION 'No data found to transfer for sp_id % and sector_number %', v_sp_id, v_sector_number; +END IF; +END; +$$ LANGUAGE plpgsql; diff --git a/storage/pipeline/states_sealing.go b/storage/pipeline/states_sealing.go index 81ee85853c0..793202206f3 100644 --- a/storage/pipeline/states_sealing.go +++ b/storage/pipeline/states_sealing.go @@ -9,6 +9,7 @@ import ( "net/http" "time" + "github.com/filecoin-project/lotus/lib/filler" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -88,7 +89,7 @@ func (m *Sealing) handlePacking(ctx statemachine.Context, sector SectorInfo) err return xerrors.Errorf("too much data in sector: %d > %d", allocated, ubytes) } - fillerSizes, err := fillersFromRem(ubytes - allocated) + fillerSizes, err := filler.FillersFromRem(ubytes - allocated) if err != nil { return err } diff --git a/storage/pipeline/utils.go b/storage/pipeline/utils.go index ac519b6acef..373859f6dd5 100644 --- a/storage/pipeline/utils.go +++ b/storage/pipeline/utils.go @@ -4,7 +4,6 @@ import ( "bytes" "context" "fmt" - "math/bits" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -18,42 +17,6 @@ import ( "github.com/filecoin-project/lotus/storage/pipeline/sealiface" ) -func fillersFromRem(in abi.UnpaddedPieceSize) ([]abi.UnpaddedPieceSize, error) { - // Convert to in-sector bytes for easier math: - // - // Sector size to user bytes ratio is constant, e.g. for 1024B we have 1016B - // of user-usable data. - // - // (1024/1016 = 128/127) - // - // Given that we can get sector size by simply adding 1/127 of the user - // bytes - // - // (we convert to sector bytes as they are nice round binary numbers) - - toFill := uint64(in + (in / 127)) - - // We need to fill the sector with pieces that are powers of 2. Conveniently - // computers store numbers in binary, which means we can look at 1s to get - // all the piece sizes we need to fill the sector. It also means that number - // of pieces is the number of 1s in the number of remaining bytes to fill - out := make([]abi.UnpaddedPieceSize, bits.OnesCount64(toFill)) - for i := range out { - // Extract the next lowest non-zero bit - next := bits.TrailingZeros64(toFill) - psize := uint64(1) << next - // e.g: if the number is 0b010100, psize will be 0b000100 - - // set that bit to 0 by XORing it, so the next iteration looks at the - // next bit - toFill ^= psize - - // Add the piece size to the list of pieces we need to create - out[i] = abi.PaddedPieceSize(psize).Unpadded() - } - return out, nil -} - func (m *Sealing) ListSectors() ([]SectorInfo, error) { var sectors []SectorInfo if err := m.sectors.List(§ors); err != nil { From 57b170ea9f15365477a52ab01584c386eeaaf601 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Fri, 10 May 2024 14:07:28 +0530 Subject: [PATCH 06/17] redo filler pieces --- curiosrc/market/deal_ingest.go | 2 +- curiosrc/seal/task_treed.go | 24 ++++++++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/curiosrc/market/deal_ingest.go b/curiosrc/market/deal_ingest.go index ef506cdf9a7..6ce61dc861d 100644 --- a/curiosrc/market/deal_ingest.go +++ b/curiosrc/market/deal_ingest.go @@ -298,7 +298,7 @@ func (p *PieceIngester) allocateToExisting(ctx context.Context, piece lpiece.Pie if sec.currentSize+pieceSize < abi.PaddedPieceSize(p.sectorSize) { ret.Sector = sec.number - ret.Offset = sec.currentSize + 1 // Current filled up size + 1 + ret.Offset = sec.currentSize // Insert market deal to DB for the sector if piece.DealProposal != nil { diff --git a/curiosrc/seal/task_treed.go b/curiosrc/seal/task_treed.go index 57881a726b5..97a62197d36 100644 --- a/curiosrc/seal/task_treed.go +++ b/curiosrc/seal/task_treed.go @@ -7,6 +7,7 @@ import ( "net/url" "strconv" + "github.com/filecoin-project/lotus/lib/filler" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -180,10 +181,9 @@ func (t *TreeDTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done offset += padLength.Unpadded() for _, pad := range pads { - padCid := zerocomm.ZeroPieceCommitment(pad.Unpadded()) pieceInfos = append(pieceInfos, abi.PieceInfo{ Size: pad, - PieceCID: padCid, + PieceCID: zerocomm.ZeroPieceCommitment(pad.Unpadded()), }) pieceReaders = append(pieceReaders, nullreader.NewNullReader(pad.Unpadded())) } @@ -193,7 +193,7 @@ func (t *TreeDTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done PieceCID: c, }) - offset += abi.PaddedPieceSize(p.PieceSize).Unpadded() + offset += abi.UnpaddedPieceSize(*p.DataRawSize) // make pieceReader if p.DataUrl != nil { @@ -248,13 +248,17 @@ func (t *TreeDTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done } if offset.Padded() < abi.PaddedPieceSize(ssize) { - fillerSize := abi.PaddedPieceSize(ssize) - offset.Padded() - filler := nullreader.NewNullReader(fillerSize.Unpadded()) - pieceInfos = append(pieceInfos, abi.PieceInfo{ - Size: fillerSize, - PieceCID: zerocomm.ZeroPieceCommitment(fillerSize.Unpadded()), - }) - pieceReaders = append(pieceReaders, filler) + fillerSize, err := filler.FillersFromRem(abi.PaddedPieceSize(ssize).Unpadded() - offset) + if err != nil { + return false, xerrors.Errorf("failed to calculate the final padding: %w", err) + } + for _, fil := range fillerSize { + pieceInfos = append(pieceInfos, abi.PieceInfo{ + Size: fil.Padded(), + PieceCID: zerocomm.ZeroPieceCommitment(fil), + }) + pieceReaders = append(pieceReaders, nullreader.NewNullReader(fil)) + } } commd, err = nonffi.GenerateUnsealedCID(sectorParams.RegSealProof, pieceInfos) From a71bc65e625db2da0b007163f085dff2f955f141 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Fri, 10 May 2024 19:35:04 +0530 Subject: [PATCH 07/17] remove psql exception handling --- curiosrc/market/deal_ingest.go | 92 +++++++++----------------- curiosrc/market/lmrpc/lmrpc.go | 7 +- curiosrc/seal/task_porep.go | 16 ++--- curiosrc/seal/task_submit_precommit.go | 23 +++---- curiosrc/seal/task_treed.go | 25 +++---- curiosrc/seal/task_treerc.go | 6 +- node/config/def.go | 2 +- 7 files changed, 71 insertions(+), 100 deletions(-) diff --git a/curiosrc/market/deal_ingest.go b/curiosrc/market/deal_ingest.go index 6ce61dc861d..0576e8bf5ab 100644 --- a/curiosrc/market/deal_ingest.go +++ b/curiosrc/market/deal_ingest.go @@ -3,14 +3,12 @@ package market import ( "context" "encoding/json" - "errors" "fmt" "net/http" "net/url" "time" logging "github.com/ipfs/go-log/v2" - "github.com/lib/pq" // PostgreSQL driver for errors "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -66,8 +64,7 @@ type PieceIngester struct { type pieceDetails struct { Sector abi.SectorNumber `db:"sector_number"` Size abi.PaddedPieceSize `db:"piece_size"` - F05Epoch abi.ChainEpoch `db:"f05_deal_start_epoch"` - DdoEpoch abi.ChainEpoch `db:"direct_start_epoch"` + Epoch abi.ChainEpoch `db:"deal_start_epoch"` Index uint64 `db:"piece_index"` CreatedAt *time.Time `db:"created_at"` } @@ -295,61 +292,42 @@ func (p *PieceIngester) allocateToExisting(ctx context.Context, piece lpiece.Pie pieceSize := piece.Size() for _, sec := range openSectors { sec := sec - if sec.currentSize+pieceSize < abi.PaddedPieceSize(p.sectorSize) { + if sec.currentSize+pieceSize <= abi.PaddedPieceSize(p.sectorSize) { ret.Sector = sec.number ret.Offset = sec.currentSize // Insert market deal to DB for the sector if piece.DealProposal != nil { - for { - cn, err := tx.Exec(`SELECT insert_sector_market_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, - p.mid, sec.number, sec.index+1, - piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, - source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, - piece.PublishCid, piece.DealID, propJson, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch) - - if err != nil { - var pqErr *pq.Error - ok := errors.As(err, &pqErr) - if ok && pqErr.Code == "P0001" { - sec.index++ // Increase 'sec.index' if sql exception 'P0001' raised - continue // Retry the transaction - } - return false, fmt.Errorf("adding deal to sector: %v", err) - } - - if cn != 1 { - return false, xerrors.Errorf("expected one piece") - } - - break // Break loop on successful transaction + cn, err := tx.Exec(`SELECT insert_sector_market_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14)`, + p.mid, sec.number, sec.index+1, + piece.DealProposal.PieceCID, piece.DealProposal.PieceSize, + source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, + piece.PublishCid, piece.DealID, propJson, piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch) + + if err != nil { + return false, fmt.Errorf("adding deal to sector: %v", err) + } + + if cn != 1 { + return false, xerrors.Errorf("expected one piece") } } else { // Insert DDO deal to DB for the sector - for { - cn, err := tx.Exec(`SELECT insert_sector_ddo_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, - p.mid, sec.number, sec.index+1, - piece.PieceActivationManifest.CID, piece.PieceActivationManifest.Size, - source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, - piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) - - if err != nil { - var pqErr *pq.Error - ok := errors.As(err, &pqErr) - if ok && pqErr.Code == "P0001" { - sec.index++ // Increase 'sec.index' if sql exception 'P0001' raised - continue // Retry the transaction - } - return false, fmt.Errorf("adding deal to sector: %v", err) - } - - if cn != 1 { - return false, xerrors.Errorf("expected one piece") - } - - break // Break loop on successful transaction + cn, err := tx.Exec(`SELECT insert_sector_ddo_piece($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12)`, + p.mid, sec.number, sec.index+1, + piece.PieceActivationManifest.CID, piece.PieceActivationManifest.Size, + source.String(), dataHdrJson, rawSize, !piece.KeepUnsealed, + piece.DealSchedule.StartEpoch, piece.DealSchedule.EndEpoch, propJson) + + if err != nil { + return false, fmt.Errorf("adding deal to sector: %v", err) + } + + if cn != 1 { + return false, xerrors.Errorf("expected one piece") } + } allocated = true break @@ -385,8 +363,7 @@ func (p *PieceIngester) SectorStartSealing(ctx context.Context, sector abi.Secto sector_number, piece_size, piece_index, - COALESCE(f05_deal_start_epoch, 0) AS f05_deal_start_epoch, - COALESCE(direct_start_epoch, 0) AS direct_start_epoch, + COALESCE(direct_start_epoch, f05_deal_start_epoch, 0) AS deal_start_epoch, created_at FROM open_sector_pieces @@ -440,8 +417,7 @@ func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) sector_number, piece_size, piece_index, - COALESCE(f05_deal_start_epoch, 0) AS f05_deal_start_epoch, - COALESCE(direct_start_epoch, 0) AS direct_start_epoch, + COALESCE(direct_start_epoch, f05_deal_start_epoch, 0) AS deal_start_epoch, created_at FROM open_sector_pieces @@ -454,16 +430,10 @@ func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) } getEpoch := func(piece pieceDetails, cur abi.ChainEpoch) abi.ChainEpoch { - var ret abi.ChainEpoch - if piece.DdoEpoch > 0 { - ret = piece.DdoEpoch - } else { - ret = piece.F05Epoch - } - if cur > 0 && cur < ret { + if cur > 0 && cur < piece.Epoch { return cur } - return ret + return piece.Epoch } getOpenedAt := func(piece pieceDetails, cur *time.Time) *time.Time { diff --git a/curiosrc/market/lmrpc/lmrpc.go b/curiosrc/market/lmrpc/lmrpc.go index b40ad02ccfc..3c6feb6f8a3 100644 --- a/curiosrc/market/lmrpc/lmrpc.go +++ b/curiosrc/market/lmrpc/lmrpc.go @@ -374,7 +374,10 @@ func sectorAddPieceToAnyOperation(maddr address.Address, rootUrl url.URL, conf * for { var taskID *int64 var complete bool - err := db.QueryRow(ctx, `SELECT task_id, complete FROM parked_pieces WHERE id = $1`, refID).Scan(&taskID, &complete) + err := db.QueryRow(ctx, `SELECT pp.task_id, pp.complete + FROM curio.parked_pieces pp + JOIN curio.parked_piece_refs ppr ON pp.id = ppr.piece_id + WHERE ppr.ref_id = $1;`, refID).Scan(&taskID, &complete) if err != nil { return api.SectorOffset{}, xerrors.Errorf("getting piece park status: %w", err) } @@ -575,7 +578,7 @@ func maybeApplyBackpressure(tx *harmonydb.Tx, cfg config.CurioIngestConfig, ssiz return true, nil } - if cfg.MaxQueueSDR != 0 && bufferedSDR > cfg.MaxQueueSDR { + if bufferedSDR > cfg.MaxQueueSDR { log.Debugw("backpressure", "reason", "too many SDR tasks", "buffered", bufferedSDR, "max", cfg.MaxQueueSDR) return true, nil } diff --git a/curiosrc/seal/task_porep.go b/curiosrc/seal/task_porep.go index 62894d55b5c..704d4673703 100644 --- a/curiosrc/seal/task_porep.go +++ b/curiosrc/seal/task_porep.go @@ -112,14 +112,14 @@ func (p *PoRepTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done proof, err := p.sc.PoRepSnark(ctx, sr, sealed, unsealed, sectorParams.TicketValue, abi.InteractiveSealRandomness(rand)) if err != nil { - end, rerr := p.recoverErrors(ctx, sectorParams.SpID, sectorParams.SectorNumber, err) - if rerr != nil { - return false, xerrors.Errorf("recover errors: %w", rerr) - } - if end { - // done, but the error handling has stored a different than success state - return true, nil - } + //end, rerr := p.recoverErrors(ctx, sectorParams.SpID, sectorParams.SectorNumber, err) + //if rerr != nil { + // return false, xerrors.Errorf("recover errors: %w", rerr) + //} + //if end { + // // done, but the error handling has stored a different than success state + // return true, nil + //} return false, xerrors.Errorf("failed to compute seal proof: %w", err) } diff --git a/curiosrc/seal/task_submit_precommit.go b/curiosrc/seal/task_submit_precommit.go index 108e51fb67e..e768f806a43 100644 --- a/curiosrc/seal/task_submit_precommit.go +++ b/curiosrc/seal/task_submit_precommit.go @@ -124,12 +124,10 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo PieceCID string `db:"piece_cid"` PieceSize int64 `db:"piece_size"` - F05DealID int64 `db:"f05_deal_id"` - F05DealEndEpoch int64 `db:"f05_deal_end_epoch"` - F05DealStartEpoch int64 `db:"f05_deal_start_epoch"` + F05DealID int64 `db:"f05_deal_id"` - DDODealStartEpoch int64 `db:"direct_start_epoch"` - DDODealEndEpoch int64 `db:"direct_end_epoch"` + DealStartEpoch int64 `db:"deal_start_epoch"` + DealEndEpoch int64 `db:"deal_end_epoch"` } err = s.db.Select(ctx, &pieces, ` @@ -137,10 +135,8 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo piece_cid, piece_size, f05_deal_id, - COALESCE(f05_deal_end_epoch, 0) AS f05_deal_end_epoch, - COALESCE(f05_deal_start_epoch, 0) AS f05_deal_start_epoch, - COALESCE(direct_start_epoch, 0) AS direct_start_epoch, - COALESCE(direct_end_epoch, 0) AS direct_end_epoch + COALESCE(f05_deal_end_epoch, direct_end_epoch, 0) AS deal_end_epoch, + COALESCE(f05_deal_start_epoch, direct_start_epoch, 0) AS deal_start_epoch FROM sectors_sdr_initial_pieces WHERE sp_id = $1 AND sector_number = $2 ORDER BY piece_index ASC`, sectorParams.SpID, sectorParams.SectorNumber) if err != nil { @@ -151,7 +147,7 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo params.Sectors[0].UnsealedCid = &unsealedCID for _, p := range pieces { - if (p.DDODealStartEpoch > 0 && abi.ChainEpoch(p.DDODealStartEpoch) < head.Height()) || (p.F05DealEndEpoch > 0 && abi.ChainEpoch(p.F05DealStartEpoch) < head.Height()) { + if p.DealStartEpoch > 0 && abi.ChainEpoch(p.DealStartEpoch) < head.Height() { // deal start epoch is in the past, can't precommit this sector anymore _, perr := s.db.Exec(ctx, `UPDATE sectors_sdr_pipeline SET failed = TRUE, failed_at = NOW(), failed_reason = 'past-start-epoch', failed_reason_msg = 'precommit: start epoch is in the past' @@ -164,11 +160,8 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo if p.F05DealID > 0 { params.Sectors[0].DealIDs = append(params.Sectors[0].DealIDs, abi.DealID(p.F05DealID)) } - if p.F05DealEndEpoch > 0 && abi.ChainEpoch(p.F05DealEndEpoch) > params.Sectors[0].Expiration { - params.Sectors[0].Expiration = abi.ChainEpoch(p.F05DealEndEpoch) - } - if p.DDODealEndEpoch > 0 && abi.ChainEpoch(p.DDODealEndEpoch) > params.Sectors[0].Expiration { - params.Sectors[0].Expiration = abi.ChainEpoch(p.DDODealEndEpoch) + if p.DealEndEpoch > 0 && abi.ChainEpoch(p.DealEndEpoch) > params.Sectors[0].Expiration { + params.Sectors[0].Expiration = abi.ChainEpoch(p.DealEndEpoch) } } } diff --git a/curiosrc/seal/task_treed.go b/curiosrc/seal/task_treed.go index 97a62197d36..296203c1050 100644 --- a/curiosrc/seal/task_treed.go +++ b/curiosrc/seal/task_treed.go @@ -169,6 +169,7 @@ func (t *TreeDTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done var pieceInfos []abi.PieceInfo var pieceReaders []io.Reader var offset abi.UnpaddedPieceSize + var allocated abi.UnpaddedPieceSize for _, p := range pieces { // make pieceInfo @@ -177,6 +178,8 @@ func (t *TreeDTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done return false, xerrors.Errorf("parsing piece cid: %w", err) } + allocated += abi.UnpaddedPieceSize(*p.DataRawSize) + pads, padLength := ffiwrapper.GetRequiredPadding(offset.Padded(), abi.PaddedPieceSize(p.PieceSize)) offset += padLength.Unpadded() @@ -247,18 +250,16 @@ func (t *TreeDTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done } } - if offset.Padded() < abi.PaddedPieceSize(ssize) { - fillerSize, err := filler.FillersFromRem(abi.PaddedPieceSize(ssize).Unpadded() - offset) - if err != nil { - return false, xerrors.Errorf("failed to calculate the final padding: %w", err) - } - for _, fil := range fillerSize { - pieceInfos = append(pieceInfos, abi.PieceInfo{ - Size: fil.Padded(), - PieceCID: zerocomm.ZeroPieceCommitment(fil), - }) - pieceReaders = append(pieceReaders, nullreader.NewNullReader(fil)) - } + fillerSize, err := filler.FillersFromRem(abi.PaddedPieceSize(ssize).Unpadded() - allocated) + if err != nil { + return false, xerrors.Errorf("failed to calculate the final padding: %w", err) + } + for _, fil := range fillerSize { + pieceInfos = append(pieceInfos, abi.PieceInfo{ + Size: fil.Padded(), + PieceCID: zerocomm.ZeroPieceCommitment(fil), + }) + pieceReaders = append(pieceReaders, nullreader.NewNullReader(fil)) } commd, err = nonffi.GenerateUnsealedCID(sectorParams.RegSealProof, pieceInfos) diff --git a/curiosrc/seal/task_treerc.go b/curiosrc/seal/task_treerc.go index 7584c47ac6b..384fb12edf9 100644 --- a/curiosrc/seal/task_treerc.go +++ b/curiosrc/seal/task_treerc.go @@ -71,11 +71,15 @@ func (t *TreeRCTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done } // R / C - sealed, _, err := t.sc.TreeRC(ctx, &taskID, sref, commd) + sealed, unsealed, err := t.sc.TreeRC(ctx, &taskID, sref, commd) if err != nil { return false, xerrors.Errorf("computing tree r and c: %w", err) } + if unsealed != commd { + return false, xerrors.Errorf("commd %s does match unsealed %s", commd.String(), unsealed.String()) + } + // todo synth porep // todo porep challenge check diff --git a/node/config/def.go b/node/config/def.go index c5eaa7eca2b..55fd7548f87 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -365,7 +365,7 @@ func DefaultCurioConfig() *CurioConfig { }, Ingest: CurioIngestConfig{ MaxQueueDealSector: 8, // default to 8 sectors open(or in process of opening) for deals - MaxQueueSDR: 0, // default don't use this limit + MaxQueueSDR: 8, // default to 8 (will cause backpressure even if deal sectors are 0) MaxQueueTrees: 0, // default don't use this limit MaxQueuePoRep: 0, // default don't use this limit MaxDealWaitTime: Duration(1 * time.Hour), From 936e86a77af764fda6de26dc0c027407397f6365 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Mon, 13 May 2024 13:19:12 +0530 Subject: [PATCH 08/17] fix deal sectors porep --- cmd/curio/tasks/tasks.go | 5 ++- curiosrc/piece/task_park_piece.go | 18 +++++++-- curiosrc/seal/task_sdr.go | 46 ++++++++++++++++++---- documentation/en/default-curio-config.toml | 2 +- go.mod | 1 - 5 files changed, 58 insertions(+), 14 deletions(-) diff --git a/cmd/curio/tasks/tasks.go b/cmd/curio/tasks/tasks.go index c59d792f209..909eb1a2452 100644 --- a/cmd/curio/tasks/tasks.go +++ b/cmd/curio/tasks/tasks.go @@ -85,7 +85,10 @@ func StartTasks(ctx context.Context, dependencies *deps.Deps) (*harmonytask.Task { // Piece handling if cfg.Subsystems.EnableParkPiece { - parkPieceTask := piece.NewParkPieceTask(db, must.One(slrLazy.Val()), cfg.Subsystems.ParkPieceMaxTasks) + parkPieceTask, err := piece.NewParkPieceTask(db, must.One(slrLazy.Val()), cfg.Subsystems.ParkPieceMaxTasks) + if err != nil { + return nil, err + } cleanupPieceTask := piece.NewCleanupPieceTask(db, must.One(slrLazy.Val()), 0) activeTasks = append(activeTasks, parkPieceTask, cleanupPieceTask) } diff --git a/curiosrc/piece/task_park_piece.go b/curiosrc/piece/task_park_piece.go index d8b6d51a102..e7f658584d4 100644 --- a/curiosrc/piece/task_park_piece.go +++ b/curiosrc/piece/task_park_piece.go @@ -34,7 +34,7 @@ type ParkPieceTask struct { max int } -func NewParkPieceTask(db *harmonydb.DB, sc *ffi.SealCalls, max int) *ParkPieceTask { +func NewParkPieceTask(db *harmonydb.DB, sc *ffi.SealCalls, max int) (*ParkPieceTask, error) { pt := &ParkPieceTask{ db: db, sc: sc, @@ -42,8 +42,20 @@ func NewParkPieceTask(db *harmonydb.DB, sc *ffi.SealCalls, max int) *ParkPieceTa max: max, } - go pt.pollPieceTasks(context.Background()) - return pt + ctx := context.Background() + + // We should delete all incomplete pieces before we start + // as we would have lost reader for these. The RPC caller will get an error + // when Curio shuts down before parking a piece. They can always retry. + // Leaving these pieces we utilise unnecessary resources in the form of ParkPieceTask + + _, err := db.Exec(ctx, `DELETE FROM parked_pieces WHERE complete = FALSE AND task_id IS NULL`) + if err != nil { + return nil, xerrors.Errorf("failed to delete incomplete parked pieces: %w", err) + } + + go pt.pollPieceTasks(ctx) + return pt, nil } func (p *ParkPieceTask) pollPieceTasks(ctx context.Context) { diff --git a/curiosrc/seal/task_sdr.go b/curiosrc/seal/task_sdr.go index 0a3aebcd4a4..7490f4a890e 100644 --- a/curiosrc/seal/task_sdr.go +++ b/curiosrc/seal/task_sdr.go @@ -4,6 +4,8 @@ import ( "bytes" "context" + "github.com/filecoin-project/lotus/lib/filler" + "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -74,13 +76,14 @@ func (s *SDRTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done bo sectorParams := sectorParamsArr[0] var pieces []struct { - PieceIndex int64 `db:"piece_index"` - PieceCID string `db:"piece_cid"` - PieceSize int64 `db:"piece_size"` + PieceIndex int64 `db:"piece_index"` + PieceCID string `db:"piece_cid"` + PieceSize int64 `db:"piece_size"` + DataRawSize *int64 `db:"data_raw_size"` } err = s.db.Select(ctx, &pieces, ` - SELECT piece_index, piece_cid, piece_size + SELECT piece_index, piece_cid, piece_size, data_raw_size FROM sectors_sdr_initial_pieces WHERE sp_id = $1 AND sector_number = $2 ORDER BY piece_index ASC`, sectorParams.SpID, sectorParams.SectorNumber) if err != nil { @@ -94,18 +97,45 @@ func (s *SDRTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) (done bo var commd cid.Cid + var offset abi.UnpaddedPieceSize + var allocated abi.UnpaddedPieceSize + var pieceInfos []abi.PieceInfo + if len(pieces) > 0 { - pieceInfos := make([]abi.PieceInfo, len(pieces)) - for i, p := range pieces { + for _, p := range pieces { c, err := cid.Parse(p.PieceCID) if err != nil { return false, xerrors.Errorf("parsing piece cid: %w", err) } - pieceInfos[i] = abi.PieceInfo{ + allocated += abi.UnpaddedPieceSize(*p.DataRawSize) + + pads, padLength := ffiwrapper.GetRequiredPadding(offset.Padded(), abi.PaddedPieceSize(p.PieceSize)) + offset += padLength.Unpadded() + + for _, pad := range pads { + pieceInfos = append(pieceInfos, abi.PieceInfo{ + Size: pad, + PieceCID: zerocomm.ZeroPieceCommitment(pad.Unpadded()), + }) + } + + pieceInfos = append(pieceInfos, abi.PieceInfo{ Size: abi.PaddedPieceSize(p.PieceSize), PieceCID: c, - } + }) + offset += abi.UnpaddedPieceSize(*p.DataRawSize) + } + + fillerSize, err := filler.FillersFromRem(abi.PaddedPieceSize(ssize).Unpadded() - allocated) + if err != nil { + return false, xerrors.Errorf("failed to calculate the final padding: %w", err) + } + for _, fil := range fillerSize { + pieceInfos = append(pieceInfos, abi.PieceInfo{ + Size: fil.Padded(), + PieceCID: zerocomm.ZeroPieceCommitment(fil), + }) } commd, err = nonffi.GenerateUnsealedCID(sectorParams.RegSealProof, pieceInfos) diff --git a/documentation/en/default-curio-config.toml b/documentation/en/default-curio-config.toml index 292b95cd133..69503ea51a4 100644 --- a/documentation/en/default-curio-config.toml +++ b/documentation/en/default-curio-config.toml @@ -336,7 +336,7 @@ # possible that this queue grows more than this limit, the backpressure is only applied to sectors entering the pipeline. # # type: int - #MaxQueueSDR = 0 + #MaxQueueSDR = 8 # Maximum number of sectors that can be queued waiting for SDRTrees to start processing. # 0 = unlimited diff --git a/go.mod b/go.mod index 81b69f7a215..18d75f81770 100644 --- a/go.mod +++ b/go.mod @@ -109,7 +109,6 @@ require ( github.com/jackc/pgerrcode v0.0.0-20220416144525-469b46aa5efa github.com/kelseyhightower/envconfig v1.4.0 github.com/koalacxr/quantile v0.0.1 - github.com/lib/pq v1.10.9 github.com/libp2p/go-buffer-pool v0.1.0 github.com/libp2p/go-libp2p v0.33.2 github.com/libp2p/go-libp2p-kad-dht v0.25.2 From 18af80221605bbf1e51e2b40fe690c9ed2b65255 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Mon, 13 May 2024 13:42:35 +0530 Subject: [PATCH 09/17] fix tests --- curiosrc/market/deal_ingest.go | 1 - curiosrc/market/lmrpc/lmrpc.go | 3 +-- curiosrc/seal/task_porep.go | 49 ---------------------------------- curiosrc/seal/task_sdr.go | 4 +-- curiosrc/seal/task_treed.go | 2 +- 5 files changed, 4 insertions(+), 55 deletions(-) diff --git a/curiosrc/market/deal_ingest.go b/curiosrc/market/deal_ingest.go index 0576e8bf5ab..c11d0b58ee3 100644 --- a/curiosrc/market/deal_ingest.go +++ b/curiosrc/market/deal_ingest.go @@ -455,7 +455,6 @@ func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) index: pi.Index, openedAt: pi.CreatedAt, } - sector = sectorMap[pi.Sector] continue } sector.currentSize += pi.Size diff --git a/curiosrc/market/lmrpc/lmrpc.go b/curiosrc/market/lmrpc/lmrpc.go index 3c6feb6f8a3..ac138fae2d1 100644 --- a/curiosrc/market/lmrpc/lmrpc.go +++ b/curiosrc/market/lmrpc/lmrpc.go @@ -413,9 +413,8 @@ func sectorAddPieceToAnyOperation(maddr address.Address, rootUrl url.URL, conf * } if !taskResult { return api.SectorOffset{}, xerrors.Errorf("park-piece task failed: %s", taskError) - } else { - return api.SectorOffset{}, xerrors.Errorf("park task succeeded but piece is not marked as complete") } + return api.SectorOffset{}, xerrors.Errorf("park task succeeded but piece is not marked as complete") } } diff --git a/curiosrc/seal/task_porep.go b/curiosrc/seal/task_porep.go index 704d4673703..f01b7d8e2aa 100644 --- a/curiosrc/seal/task_porep.go +++ b/curiosrc/seal/task_porep.go @@ -3,7 +3,6 @@ package seal import ( "bytes" "context" - "strings" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -175,52 +174,4 @@ func (p *PoRepTask) Adder(taskFunc harmonytask.AddTaskFunc) { p.sp.pollers[pollerPoRep].Set(taskFunc) } -func (p *PoRepTask) recoverErrors(ctx context.Context, spid, snum int64, cerr error) (end bool, err error) { - const ( - // rust-fil-proofs error strings - // https://github.com/filecoin-project/rust-fil-proofs/blob/3f018b51b6327b135830899d237a7ba181942d7e/storage-proofs-porep/src/stacked/vanilla/proof.rs#L454C1-L463 - errstrInvalidCommD = "Invalid comm_d detected at challenge_index" - errstrInvalidCommR = "Invalid comm_r detected at challenge_index" - errstrInvalidEncoding = "Invalid encoding proof generated at layer" - ) - - if cerr == nil { - return false, xerrors.Errorf("nil error") - } - - switch { - case strings.Contains(cerr.Error(), errstrInvalidCommD): - log.Warnf("PoRep error recovery: PoRep failed with %s for sector %d of miner %d", errstrInvalidCommD, snum, spid) - return p.resetSector(ctx, spid, snum) - case strings.Contains(cerr.Error(), errstrInvalidCommR): - // todo: it might be more optimal to just retry the Trees compute first. - // Invalid CommD/R likely indicates a problem with the data computed in that step - // For now for simplicity just retry the whole thing - log.Warnf("PoRep error recovery: PoRep failed with %s for sector %d of miner %d", errstrInvalidCommR, snum, spid) - return p.resetSector(ctx, spid, snum) - case strings.Contains(cerr.Error(), errstrInvalidEncoding): - log.Warnf("PoRep error recovery: PoRep failed with %s for sector %d of miner %d", errstrInvalidEncoding, snum, spid) - return p.resetSector(ctx, spid, snum) - - default: - // if end is false the original error will be returned by the caller - return false, nil - } -} - -func (p *PoRepTask) resetSector(ctx context.Context, spid, snum int64) (bool, error) { - n, err := p.db.Exec(ctx, `UPDATE sectors_sdr_pipeline - SET after_porep = FALSE, after_sdr = FALSE, after_tree_d = FALSE, - after_tree_r = FALSE, after_tree_c = FALSE - WHERE sp_id = $1 AND sector_number = $2`, - spid, snum) - if err != nil { - return false, xerrors.Errorf("store sdr success: updating pipeline: %w", err) - } - if n != 1 { - return false, xerrors.Errorf("store sdr success: updated %d rows", n) - } - return true, nil -} - var _ harmonytask.TaskInterface = &PoRepTask{} diff --git a/curiosrc/seal/task_sdr.go b/curiosrc/seal/task_sdr.go index 7490f4a890e..364957791fd 100644 --- a/curiosrc/seal/task_sdr.go +++ b/curiosrc/seal/task_sdr.go @@ -4,8 +4,6 @@ import ( "bytes" "context" - "github.com/filecoin-project/lotus/lib/filler" - "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -19,10 +17,12 @@ import ( "github.com/filecoin-project/lotus/chain/actors/policy" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/curiosrc/ffi" + "github.com/filecoin-project/lotus/lib/filler" "github.com/filecoin-project/lotus/lib/harmony/harmonydb" "github.com/filecoin-project/lotus/lib/harmony/harmonytask" "github.com/filecoin-project/lotus/lib/harmony/resources" "github.com/filecoin-project/lotus/storage/paths" + "github.com/filecoin-project/lotus/storage/sealer/ffiwrapper" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) diff --git a/curiosrc/seal/task_treed.go b/curiosrc/seal/task_treed.go index 296203c1050..0f37c75feff 100644 --- a/curiosrc/seal/task_treed.go +++ b/curiosrc/seal/task_treed.go @@ -7,7 +7,6 @@ import ( "net/url" "strconv" - "github.com/filecoin-project/lotus/lib/filler" "github.com/ipfs/go-cid" "golang.org/x/xerrors" @@ -17,6 +16,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/curiosrc/ffi" + "github.com/filecoin-project/lotus/lib/filler" "github.com/filecoin-project/lotus/lib/harmony/harmonydb" "github.com/filecoin-project/lotus/lib/harmony/harmonytask" "github.com/filecoin-project/lotus/lib/harmony/resources" From a9518443e8c7828dd109030d8d37242c6df6df5e Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 14 May 2024 16:04:09 +0530 Subject: [PATCH 10/17] ddo deals --- cmd/curio/config.go | 3 +- cmd/curio/deps/deps.go | 12 +- cmd/curio/market.go | 8 +- cmd/curio/tasks/tasks.go | 2 +- curiosrc/market/deal_ingest.go | 2 +- curiosrc/market/lmrpc/lmrpc.go | 18 +- curiosrc/seal/task_sdr.go | 8 + curiosrc/seal/task_submit_commit.go | 184 ++++++++++-- curiosrc/seal/task_submit_precommit.go | 18 +- curiosrc/web/api/sector/sector.go | 38 ++- documentation/en/default-curio-config.toml | 10 + itests/curio_test.go | 314 +++++++++++++++++++++ node/config/def.go | 6 +- node/config/doc_gen.go | 12 + node/config/types.go | 5 + 15 files changed, 565 insertions(+), 75 deletions(-) diff --git a/cmd/curio/config.go b/cmd/curio/config.go index 16b7d89c378..8148ea3cf56 100644 --- a/cmd/curio/config.go +++ b/cmd/curio/config.go @@ -220,7 +220,8 @@ var configViewCmd = &cli.Command{ if err != nil { return err } - curioConfig, err := deps.GetConfig(cctx, db) + layers := cctx.StringSlice("layers") + curioConfig, err := deps.GetConfig(cctx.Context, layers, db) if err != nil { return err } diff --git a/cmd/curio/deps/deps.go b/cmd/curio/deps/deps.go index df645684bc6..622be33e676 100644 --- a/cmd/curio/deps/deps.go +++ b/cmd/curio/deps/deps.go @@ -219,7 +219,7 @@ func (deps *Deps) PopulateRemainingDeps(ctx context.Context, cctx *cli.Context, if deps.Cfg == nil { // The config feeds into task runners & their helpers - deps.Cfg, err = GetConfig(cctx, deps.DB) + deps.Cfg, err = GetConfig(cctx.Context, cctx.StringSlice("layers"), deps.DB) if err != nil { return xerrors.Errorf("populate config: %w", err) } @@ -371,13 +371,13 @@ func LoadConfigWithUpgrades(text string, curioConfigWithDefaults *config.CurioCo } return meta, err } -func GetConfig(cctx *cli.Context, db *harmonydb.DB) (*config.CurioConfig, error) { +func GetConfig(ctx context.Context, layers []string, db *harmonydb.DB) (*config.CurioConfig, error) { curioConfig := config.DefaultCurioConfig() have := []string{} - layers := append([]string{"base"}, cctx.StringSlice("layers")...) // Always stack on top of "base" layer + layers = append([]string{"base"}, layers...) // Always stack on top of "base" layer for _, layer := range layers { text := "" - err := db.QueryRow(cctx.Context, `SELECT config FROM harmony_config WHERE title=$1`, layer).Scan(&text) + err := db.QueryRow(ctx, `SELECT config FROM harmony_config WHERE title=$1`, layer).Scan(&text) if err != nil { if strings.Contains(err.Error(), sql.ErrNoRows.Error()) { return nil, fmt.Errorf("missing layer '%s' ", layer) @@ -420,7 +420,9 @@ func GetDepsCLI(ctx context.Context, cctx *cli.Context) (*Deps, error) { return nil, err } - cfg, err := GetConfig(cctx, db) + layers := cctx.StringSlice("layers") + + cfg, err := GetConfig(cctx.Context, layers, db) if err != nil { return nil, err } diff --git a/cmd/curio/market.go b/cmd/curio/market.go index e354d1e68ce..b97388685cf 100644 --- a/cmd/curio/market.go +++ b/cmd/curio/market.go @@ -39,7 +39,9 @@ var marketRPCInfoCmd = &cli.Command{ return err } - cfg, err := deps.GetConfig(cctx, db) + layers := cctx.StringSlice("layers") + + cfg, err := deps.GetConfig(cctx.Context, layers, db) if err != nil { return xerrors.Errorf("get config: %w", err) } @@ -113,7 +115,9 @@ var marketSealCmd = &cli.Command{ return err } - cfg, err := deps.GetConfig(cctx, db) + layers := cctx.StringSlice("layers") + + cfg, err := deps.GetConfig(cctx.Context, layers, db) if err != nil { return xerrors.Errorf("get config: %w", err) } diff --git a/cmd/curio/tasks/tasks.go b/cmd/curio/tasks/tasks.go index 909eb1a2452..ce53b630539 100644 --- a/cmd/curio/tasks/tasks.go +++ b/cmd/curio/tasks/tasks.go @@ -137,7 +137,7 @@ func StartTasks(ctx context.Context, dependencies *deps.Deps) (*harmonytask.Task activeTasks = append(activeTasks, moveStorageTask) } if cfg.Subsystems.EnableSendCommitMsg { - commitTask := seal.NewSubmitCommitTask(sp, db, full, sender, as, cfg.Fees.MaxCommitGasFee) + commitTask := seal.NewSubmitCommitTask(sp, db, full, sender, as, cfg) activeTasks = append(activeTasks, commitTask) } } diff --git a/curiosrc/market/deal_ingest.go b/curiosrc/market/deal_ingest.go index c11d0b58ee3..543c8baf586 100644 --- a/curiosrc/market/deal_ingest.go +++ b/curiosrc/market/deal_ingest.go @@ -194,7 +194,7 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address } // check raw size - if piece.DealProposal.PieceSize != padreader.PaddedSize(uint64(rawSize)).Padded() { + if piece.Size() != padreader.PaddedSize(uint64(rawSize)).Padded() { return api.SectorOffset{}, xerrors.Errorf("raw size doesn't match padded piece size") } diff --git a/curiosrc/market/lmrpc/lmrpc.go b/curiosrc/market/lmrpc/lmrpc.go index ac138fae2d1..40ada11e9db 100644 --- a/curiosrc/market/lmrpc/lmrpc.go +++ b/curiosrc/market/lmrpc/lmrpc.go @@ -34,7 +34,7 @@ import ( "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/storage/paths" - "github.com/filecoin-project/lotus/storage/pipeline/piece" + lpiece "github.com/filecoin-project/lotus/storage/pipeline/piece" "github.com/filecoin-project/lotus/storage/sealer/storiface" ) @@ -306,8 +306,8 @@ type pieceInfo struct { done chan struct{} } -func sectorAddPieceToAnyOperation(maddr address.Address, rootUrl url.URL, conf *config.CurioConfig, pieceInfoLk *sync.Mutex, pieceInfos map[uuid.UUID][]pieceInfo, pin *cumarket.PieceIngester, db *harmonydb.DB, ssize abi.SectorSize) func(ctx context.Context, pieceSize abi.UnpaddedPieceSize, pieceData storiface.Data, deal api.PieceDealInfo) (api.SectorOffset, error) { - return func(ctx context.Context, pieceSize abi.UnpaddedPieceSize, pieceData storiface.Data, deal piece.PieceDealInfo) (api.SectorOffset, error) { +func sectorAddPieceToAnyOperation(maddr address.Address, rootUrl url.URL, conf *config.CurioConfig, pieceInfoLk *sync.Mutex, pieceInfos map[uuid.UUID][]pieceInfo, pin *cumarket.PieceIngester, db *harmonydb.DB, ssize abi.SectorSize) func(ctx context.Context, pieceSize abi.UnpaddedPieceSize, pieceData storiface.Data, deal lpiece.PieceDealInfo) (api.SectorOffset, error) { + return func(ctx context.Context, pieceSize abi.UnpaddedPieceSize, pieceData storiface.Data, deal lpiece.PieceDealInfo) (api.SectorOffset, error) { if (deal.PieceActivationManifest == nil && deal.DealProposal == nil) || (deal.PieceActivationManifest != nil && deal.DealProposal != nil) { return api.SectorOffset{}, xerrors.Errorf("deal info must have either deal proposal or piece manifest") } @@ -333,7 +333,9 @@ func sectorAddPieceToAnyOperation(maddr address.Address, rootUrl url.URL, conf * pieceUUID := uuid.New() - log.Infow("piece assign request", "piece_cid", deal.DealProposal.PieceCID, "provider", deal.DealProposal.Provider, "piece_uuid", pieceUUID) + if deal.DealProposal != nil { + log.Infow("piece assign request", "piece_cid", deal.PieceCID().String(), "provider", deal.DealProposal.Provider, "piece_uuid", pieceUUID) + } pieceInfoLk.Lock() pieceInfos[pieceUUID] = append(pieceInfos[pieceUUID], pi) @@ -429,13 +431,13 @@ func sectorAddPieceToAnyOperation(maddr address.Address, rootUrl url.URL, conf * return api.SectorOffset{}, err } - log.Infow("piece assigned to sector", "piece_cid", deal.DealProposal.PieceCID, "sector", so.Sector, "offset", so.Offset) + log.Infow("piece assigned to sector", "piece_cid", deal.PieceCID().String(), "sector", so.Sector, "offset", so.Offset) return so, nil } } -func addPieceEntry(ctx context.Context, db *harmonydb.DB, conf *config.CurioConfig, deal api.PieceDealInfo, pieceSize abi.UnpaddedPieceSize, dataUrl url.URL, ssize abi.SectorSize) (int64, bool, error) { +func addPieceEntry(ctx context.Context, db *harmonydb.DB, conf *config.CurioConfig, deal lpiece.PieceDealInfo, pieceSize abi.UnpaddedPieceSize, dataUrl url.URL, ssize abi.SectorSize) (int64, bool, error) { var refID int64 var pieceWasCreated bool @@ -455,7 +457,7 @@ func addPieceEntry(ctx context.Context, db *harmonydb.DB, conf *config.CurioConf var pieceID int64 // Attempt to select the piece ID first - err = tx.QueryRow(`SELECT id FROM parked_pieces WHERE piece_cid = $1`, deal.DealProposal.PieceCID.String()).Scan(&pieceID) + err = tx.QueryRow(`SELECT id FROM parked_pieces WHERE piece_cid = $1`, deal.PieceCID().String()).Scan(&pieceID) if err != nil { if errors.Is(err, pgx.ErrNoRows) { @@ -464,7 +466,7 @@ func addPieceEntry(ctx context.Context, db *harmonydb.DB, conf *config.CurioConf INSERT INTO parked_pieces (piece_cid, piece_padded_size, piece_raw_size) VALUES ($1, $2, $3) ON CONFLICT (piece_cid) DO NOTHING - RETURNING id`, deal.DealProposal.PieceCID.String(), int64(pieceSize.Padded()), int64(pieceSize)).Scan(&pieceID) + RETURNING id`, deal.PieceCID().String(), int64(pieceSize.Padded()), int64(pieceSize)).Scan(&pieceID) if err != nil { return false, xerrors.Errorf("inserting new parked piece and getting id: %w", err) } diff --git a/curiosrc/seal/task_sdr.go b/curiosrc/seal/task_sdr.go index 364957791fd..fd8f9794e07 100644 --- a/curiosrc/seal/task_sdr.go +++ b/curiosrc/seal/task_sdr.go @@ -28,6 +28,14 @@ import ( var isDevnet = build.BlockDelaySecs < 30 +func SetDevnet(value bool) { + isDevnet = value +} + +func GetDevnet() bool { + return isDevnet +} + type SDRAPI interface { ChainHead(context.Context) (*types.TipSet, error) StateGetRandomnessFromTickets(context.Context, crypto.DomainSeparationTag, abi.ChainEpoch, []byte, types.TipSetKey) (abi.Randomness, error) diff --git a/curiosrc/seal/task_submit_commit.go b/curiosrc/seal/task_submit_commit.go index 73d452e0e82..37c7c932f61 100644 --- a/curiosrc/seal/task_submit_commit.go +++ b/curiosrc/seal/task_submit_commit.go @@ -3,16 +3,22 @@ package seal import ( "bytes" "context" + "encoding/json" "fmt" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + cborutil "github.com/filecoin-project/go-cbor-util" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/builtin" + miner2 "github.com/filecoin-project/go-state-types/builtin/v13/miner" + verifreg13 "github.com/filecoin-project/go-state-types/builtin/v13/verifreg" + verifregtypes9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/chain/actors/builtin/market" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/curiosrc/message" @@ -20,6 +26,7 @@ import ( "github.com/filecoin-project/lotus/lib/harmony/harmonydb" "github.com/filecoin-project/lotus/lib/harmony/harmonytask" "github.com/filecoin-project/lotus/lib/harmony/resources" + "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/storage/ctladdr" ) @@ -28,9 +35,17 @@ type SubmitCommitAPI interface { StateMinerInfo(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (big.Int, error) StateSectorPreCommitInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorPreCommitOnChainInfo, error) + StateGetAllocation(ctx context.Context, clientAddr address.Address, allocationId verifregtypes9.AllocationId, tsk types.TipSetKey) (*verifregtypes9.Allocation, error) + StateGetAllocationIdForPendingDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (verifregtypes9.AllocationId, error) ctladdr.NodeApi } +type commitConfig struct { + maxFee types.FIL + RequireActivationSuccess bool + RequireNotificationSuccess bool +} + type SubmitCommitTask struct { sp *SealPoller db *harmonydb.DB @@ -38,19 +53,24 @@ type SubmitCommitTask struct { sender *message.Sender as *multictladdr.MultiAddressSelector - - maxFee types.FIL + cfg commitConfig } -func NewSubmitCommitTask(sp *SealPoller, db *harmonydb.DB, api SubmitCommitAPI, sender *message.Sender, as *multictladdr.MultiAddressSelector, maxFee types.FIL) *SubmitCommitTask { +func NewSubmitCommitTask(sp *SealPoller, db *harmonydb.DB, api SubmitCommitAPI, sender *message.Sender, as *multictladdr.MultiAddressSelector, cfg *config.CurioConfig) *SubmitCommitTask { + + cnfg := commitConfig{ + maxFee: cfg.Fees.MaxCommitGasFee, + RequireActivationSuccess: cfg.Subsystems.RequireActivationSuccess, + RequireNotificationSuccess: cfg.Subsystems.RequireNotificationSuccess, + } + return &SubmitCommitTask{ sp: sp, db: db, api: api, sender: sender, as: as, - - maxFee: maxFee, + cfg: cnfg, } } @@ -76,19 +96,31 @@ func (s *SubmitCommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) } sectorParams := sectorParamsArr[0] - maddr, err := address.NewIDAddress(uint64(sectorParams.SpID)) - if err != nil { - return false, xerrors.Errorf("getting miner address: %w", err) + var pieces []struct { + PieceIndex int64 `db:"piece_index"` + PieceCID string `db:"piece_cid"` + PieceSize int64 `db:"piece_size"` + Proposal json.RawMessage `db:"f05_deal_proposal"` + Manifest json.RawMessage `db:"direct_piece_activation_manifest"` + DealID abi.DealID `db:"f05_deal_id"` } - params := miner.ProveCommitSectorParams{ - SectorNumber: abi.SectorNumber(sectorParams.SectorNumber), - Proof: sectorParams.Proof, + err = s.db.Select(ctx, &pieces, ` + SELECT piece_index, + piece_cid, + piece_size, + f05_deal_proposal, + direct_piece_activation_manifest, + COALESCE(f05_deal_id, 0) AS f05_deal_id + FROM sectors_sdr_initial_pieces + WHERE sp_id = $1 AND sector_number = $2 ORDER BY piece_index ASC`, sectorParams.SpID, sectorParams.SectorNumber) + if err != nil { + return false, xerrors.Errorf("getting pieces: %w", err) } - enc := new(bytes.Buffer) - if err := params.MarshalCBOR(enc); err != nil { - return false, xerrors.Errorf("could not serialize commit params: %w", err) + maddr, err := address.NewIDAddress(uint64(sectorParams.SpID)) + if err != nil { + return false, xerrors.Errorf("getting miner address: %w", err) } ts, err := s.api.ChainHead(ctx) @@ -96,11 +128,6 @@ func (s *SubmitCommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) return false, xerrors.Errorf("getting chain head: %w", err) } - mi, err := s.api.StateMinerInfo(ctx, maddr, types.EmptyTSK) - if err != nil { - return false, xerrors.Errorf("getting miner info: %w", err) - } - pci, err := s.api.StateSectorPreCommitInfo(ctx, maddr, abi.SectorNumber(sectorParams.SectorNumber), ts.Key()) if err != nil { return false, xerrors.Errorf("getting precommit info: %w", err) @@ -109,6 +136,88 @@ func (s *SubmitCommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) return false, xerrors.Errorf("precommit info not found on chain") } + mi, err := s.api.StateMinerInfo(ctx, maddr, types.EmptyTSK) + if err != nil { + return false, xerrors.Errorf("getting miner info: %w", err) + } + + params := miner.ProveCommitSectors3Params{ + RequireActivationSuccess: s.cfg.RequireActivationSuccess, + RequireNotificationSuccess: s.cfg.RequireNotificationSuccess, + } + + var pams []miner.PieceActivationManifest + + for _, piece := range pieces { + if piece.Proposal != nil { + var prop *market.DealProposal + err = json.Unmarshal(piece.Proposal, &prop) + if err != nil { + return false, xerrors.Errorf("marshalling json to deal proposal: %w", err) + } + alloc, err := s.api.StateGetAllocationIdForPendingDeal(ctx, piece.DealID, types.EmptyTSK) + if err != nil { + return false, xerrors.Errorf("getting allocation for deal %d: %w", piece.DealID, err) + } + clid, err := s.api.StateLookupID(ctx, prop.Client, types.EmptyTSK) + if err != nil { + return false, xerrors.Errorf("getting client address for deal %d: %w", piece.DealID, err) + } + + clientId, err := address.IDFromAddress(clid) + if err != nil { + return false, xerrors.Errorf("getting client address for deal %d: %w", piece.DealID, err) + } + + var vac *miner2.VerifiedAllocationKey + if alloc != verifregtypes9.NoAllocationID { + vac = &miner2.VerifiedAllocationKey{ + Client: abi.ActorID(clientId), + ID: verifreg13.AllocationId(alloc), + } + } + + payload, err := cborutil.Dump(piece.DealID) + if err != nil { + return false, xerrors.Errorf("serializing deal id: %w", err) + } + + pams = append(pams, miner.PieceActivationManifest{ + CID: prop.PieceCID, + Size: prop.PieceSize, + VerifiedAllocationKey: vac, + Notify: []miner2.DataActivationNotification{ + { + Address: market.Address, + Payload: payload, + }, + }, + }) + } else { + var pam *miner.PieceActivationManifest + err = json.Unmarshal(piece.Manifest, &pam) + if err != nil { + return false, xerrors.Errorf("marshalling json to PieceManifest: %w", err) + } + err = s.allocationCheck(ctx, pam, pci, abi.ActorID(sectorParams.SpID), ts) + if err != nil { + return false, err + } + pams = append(pams, *pam) + } + } + + params.SectorActivations = append(params.SectorActivations, miner.SectorActivationManifest{ + SectorNumber: abi.SectorNumber(sectorParams.SectorNumber), + Pieces: pams, + }) + params.SectorProofs = append(params.SectorProofs, sectorParams.Proof) + + enc := new(bytes.Buffer) + if err := params.MarshalCBOR(enc); err != nil { + return false, xerrors.Errorf("could not serialize commit params: %w", err) + } + collateral, err := s.api.StateMinerInitialPledgeCollateral(ctx, maddr, pci.Info, ts.Key()) if err != nil { return false, xerrors.Errorf("getting initial pledge collateral: %w", err) @@ -127,13 +236,13 @@ func (s *SubmitCommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bool) msg := &types.Message{ To: maddr, From: a, - Method: builtin.MethodsMiner.ProveCommitSector, // todo ddo provecommit3 + Method: builtin.MethodsMiner.ProveCommitSectors3, Params: enc.Bytes(), Value: collateral, // todo config for pulling from miner balance!! } mss := &api.MessageSendSpec{ - MaxFee: abi.TokenAmount(s.maxFee), + MaxFee: abi.TokenAmount(s.cfg.maxFee), } mcid, err := s.sender.Send(ctx, msg, mss, "commit") @@ -278,4 +387,37 @@ func (s *SubmitCommitTask) Adder(taskFunc harmonytask.AddTaskFunc) { s.sp.pollers[pollerCommitMsg].Set(taskFunc) } +func (s *SubmitCommitTask) allocationCheck(ctx context.Context, piece *miner.PieceActivationManifest, precomitInfo *miner.SectorPreCommitOnChainInfo, miner abi.ActorID, ts *types.TipSet) error { + // skip pieces not claiming an allocation + if piece.VerifiedAllocationKey == nil { + return nil + } + addr, err := address.NewIDAddress(uint64(piece.VerifiedAllocationKey.Client)) + if err != nil { + return err + } + + alloc, err := s.api.StateGetAllocation(ctx, addr, verifregtypes9.AllocationId(piece.VerifiedAllocationKey.ID), ts.Key()) + if err != nil { + return err + } + if alloc == nil { + return xerrors.Errorf("no allocation found for piece %s with allocation ID %d", piece.CID.String(), piece.VerifiedAllocationKey.ID) + } + if alloc.Provider != miner { + return xerrors.Errorf("provider id mismatch for piece %s: expected %d and found %d", piece.CID.String(), miner, alloc.Provider) + } + if alloc.Size != piece.Size { + return xerrors.Errorf("size mismatch for piece %s: expected %d and found %d", piece.CID.String(), piece.Size, alloc.Size) + } + if precomitInfo.Info.Expiration < ts.Height()+alloc.TermMin { + return xerrors.Errorf("sector expiration %d is before than allocation TermMin %d for piece %s", precomitInfo.Info.Expiration, ts.Height()+alloc.TermMin, piece.CID.String()) + } + if precomitInfo.Info.Expiration > ts.Height()+alloc.TermMax { + return xerrors.Errorf("sector expiration %d is later than allocation TermMax %d for piece %s", precomitInfo.Info.Expiration, ts.Height()+alloc.TermMax, piece.CID.String()) + } + + return nil +} + var _ harmonytask.TaskInterface = &SubmitCommitTask{} diff --git a/curiosrc/seal/task_submit_precommit.go b/curiosrc/seal/task_submit_precommit.go index e768f806a43..4c79431b62e 100644 --- a/curiosrc/seal/task_submit_precommit.go +++ b/curiosrc/seal/task_submit_precommit.go @@ -120,21 +120,17 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo { var pieces []struct { - PieceIndex int64 `db:"piece_index"` - PieceCID string `db:"piece_cid"` - PieceSize int64 `db:"piece_size"` - - F05DealID int64 `db:"f05_deal_id"` - - DealStartEpoch int64 `db:"deal_start_epoch"` - DealEndEpoch int64 `db:"deal_end_epoch"` + PieceIndex int64 `db:"piece_index"` + PieceCID string `db:"piece_cid"` + PieceSize int64 `db:"piece_size"` + DealStartEpoch int64 `db:"deal_start_epoch"` + DealEndEpoch int64 `db:"deal_end_epoch"` } err = s.db.Select(ctx, &pieces, ` SELECT piece_index, piece_cid, piece_size, - f05_deal_id, COALESCE(f05_deal_end_epoch, direct_end_epoch, 0) AS deal_end_epoch, COALESCE(f05_deal_start_epoch, direct_start_epoch, 0) AS deal_start_epoch FROM sectors_sdr_initial_pieces @@ -145,7 +141,6 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo if len(pieces) > 0 { params.Sectors[0].UnsealedCid = &unsealedCID - for _, p := range pieces { if p.DealStartEpoch > 0 && abi.ChainEpoch(p.DealStartEpoch) < head.Height() { // deal start epoch is in the past, can't precommit this sector anymore @@ -157,9 +152,6 @@ func (s *SubmitPrecommitTask) Do(taskID harmonytask.TaskID, stillOwned func() bo } return true, xerrors.Errorf("deal start epoch is in the past") } - if p.F05DealID > 0 { - params.Sectors[0].DealIDs = append(params.Sectors[0].DealIDs, abi.DealID(p.F05DealID)) - } if p.DealEndEpoch > 0 && abi.ChainEpoch(p.DealEndEpoch) > params.Sectors[0].Expiration { params.Sectors[0].Expiration = abi.ChainEpoch(p.DealEndEpoch) } diff --git a/curiosrc/web/api/sector/sector.go b/curiosrc/web/api/sector/sector.go index e3b4b3c158d..5ec719fb57f 100644 --- a/curiosrc/web/api/sector/sector.go +++ b/curiosrc/web/api/sector/sector.go @@ -126,7 +126,12 @@ func (c *cfg) getSectors(w http.ResponseWriter, r *http.Request) { // Get all pieces apihelper.OrHTTPFail(w, c.DB.Select(r.Context(), &pieces, `SELECT - sp_id, sector_number, piece_size, f05_deal_id, f05_deal_proposal, direct_piece_activation_manifest + sp_id, + sector_number, + piece_size, + COALESCE(f05_deal_id, 0) AS f05_deal_id, + f05_deal_proposal, + direct_piece_activation_manifest FROM sectors_sdr_initial_pieces ORDER BY sp_id, sector_number`)) pieceIndex := map[sectorID][]int{} @@ -187,23 +192,14 @@ func (c *cfg) getSectors(w http.ResponseWriter, r *http.Request) { rdw := big.Add(st.DealWeight, st.VerifiedDealWeight) dw = float64(big.Div(rdw, big.NewInt(int64(st.Expiration-st.Activation))).Uint64()) vp = float64(big.Div(big.Mul(st.VerifiedDealWeight, big.NewInt(verifiedPowerGainMul)), big.NewInt(int64(st.Expiration-st.Activation))).Uint64()) - for _, deal := range st.DealIDs { - - if deal > 0 { - f05++ - } - } - // DDO info is not on chain - for _, piece := range pieces { - if piece.Manifest != nil { - //var pam *miner.PieceActivationManifest - //apihelper.OrHTTPFail(w, json.Unmarshal(piece.Manifest, pam)) - //dw += float64(pam.Size) - //if pam.VerifiedAllocationKey != nil { - // vp += float64(pam.Size) * verifiedPowerGainMul - //} + // DDO sectors don't have deal info on chain + for _, p := range pi { + if p.Manifest != nil { ddo++ } + if p.Proposal != nil { + f05++ + } } } sectors[i].DealWeight = "CC" @@ -254,19 +250,19 @@ func (c *cfg) getSectors(w http.ResponseWriter, r *http.Request) { } if len(pi) > 0 { - for _, piece := range pi { - if piece.Proposal != nil { + for _, p := range pi { + if p.Proposal != nil { var prop *market.DealProposal - apihelper.OrHTTPFail(w, json.Unmarshal(piece.Proposal, &prop)) + apihelper.OrHTTPFail(w, json.Unmarshal(p.Proposal, &prop)) dw += float64(prop.PieceSize) if prop.VerifiedDeal { vp += float64(prop.PieceSize) * verifiedPowerGainMul } f05++ } - if piece.Manifest != nil { + if p.Manifest != nil { var pam *miner.PieceActivationManifest - apihelper.OrHTTPFail(w, json.Unmarshal(piece.Manifest, &pam)) + apihelper.OrHTTPFail(w, json.Unmarshal(p.Manifest, &pam)) dw += float64(pam.Size) if pam.VerifiedAllocationKey != nil { vp += float64(pam.Size) * verifiedPowerGainMul diff --git a/documentation/en/default-curio-config.toml b/documentation/en/default-curio-config.toml index 69503ea51a4..14baa0a1939 100644 --- a/documentation/en/default-curio-config.toml +++ b/documentation/en/default-curio-config.toml @@ -123,6 +123,16 @@ # type: bool #EnableSendCommitMsg = false + # Whether to abort if any sector activation in a batch fails (newly sealed sectors, only with ProveCommitSectors3). + # + # type: bool + #RequireActivationSuccess = true + + # Whether to abort if any sector activation in a batch fails (updating sectors, only with ProveReplicaUpdates3). + # + # type: bool + #RequireNotificationSuccess = true + # EnableMoveStorage enables the move-into-long-term-storage task to run on this curio instance. # This tasks should only be enabled on nodes with long-term storage. # diff --git a/itests/curio_test.go b/itests/curio_test.go index 997352dd359..1f1338d08e2 100644 --- a/itests/curio_test.go +++ b/itests/curio_test.go @@ -2,19 +2,42 @@ package itests import ( "context" + "encoding/base64" + "flag" + "fmt" + "net" + "os" + "path" "testing" "time" "github.com/docker/go-units" + "github.com/gbrlsnchs/jwt/v3" + "github.com/google/uuid" + manet "github.com/multiformats/go-multiaddr/net" "github.com/stretchr/testify/require" + "github.com/urfave/cli/v2" + "golang.org/x/xerrors" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/api" + miner2 "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/cli/spcli" "github.com/filecoin-project/lotus/cmd/curio/deps" + "github.com/filecoin-project/lotus/cmd/curio/rpc" + "github.com/filecoin-project/lotus/cmd/curio/tasks" + "github.com/filecoin-project/lotus/curiosrc/market/lmrpc" + "github.com/filecoin-project/lotus/curiosrc/seal" "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/lib/harmony/harmonydb" + "github.com/filecoin-project/lotus/node" "github.com/filecoin-project/lotus/node/config" "github.com/filecoin-project/lotus/node/impl" + "github.com/filecoin-project/lotus/storage/sealer/storiface" ) func TestCurioNewActor(t *testing.T) { @@ -65,3 +88,294 @@ func TestCurioNewActor(t *testing.T) { require.Contains(t, baseCfg.Addresses[0].MinerAddresses, maddr.String()) } + +func TestCurioHappyPath(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + full, miner, esemble := kit.EnsembleMinimal(t, + kit.LatestActorsAt(-1), + kit.MockProofs(), + kit.WithSectorIndexDB(), + ) + + esemble.Start() + blockTime := 100 * time.Millisecond + esemble.BeginMining(blockTime) + + err := miner.LogSetLevel(ctx, "*", "ERROR") + require.NoError(t, err) + + err = full.LogSetLevel(ctx, "*", "ERROR") + require.NoError(t, err) + + db := miner.BaseAPI.(*impl.StorageMinerAPI).HarmonyDB + + token, err := full.AuthNew(ctx, api.AllPermissions) + require.NoError(t, err) + + fapi := fmt.Sprintf("%s:%s", string(token), full.ListenAddr) + + var titles []string + err = db.Select(ctx, &titles, `SELECT title FROM harmony_config WHERE LENGTH(config) > 0`) + require.NoError(t, err) + require.NotEmpty(t, titles) + require.NotContains(t, titles, "base") + + addr := miner.OwnerKey.Address + sectorSizeInt, err := units.RAMInBytes("8MiB") + require.NoError(t, err) + + maddr, err := spcli.CreateStorageMiner(ctx, full, addr, addr, addr, abi.SectorSize(sectorSizeInt), 0) + require.NoError(t, err) + + err = deps.CreateMinerConfig(ctx, full, db, []string{maddr.String()}, fapi) + require.NoError(t, err) + + err = db.Select(ctx, &titles, `SELECT title FROM harmony_config WHERE LENGTH(config) > 0`) + require.NoError(t, err) + require.Contains(t, titles, "base") + baseCfg := config.DefaultCurioConfig() + var baseText string + + err = db.QueryRow(ctx, "SELECT config FROM harmony_config WHERE title='base'").Scan(&baseText) + require.NoError(t, err) + _, err = deps.LoadConfigWithUpgrades(baseText, baseCfg) + require.NoError(t, err) + + storageSecret := baseCfg.Apis.StorageRPCSecret + + require.NotNil(t, baseCfg.Addresses) + require.GreaterOrEqual(t, len(baseCfg.Addresses), 1) + + require.Contains(t, baseCfg.Addresses[0].MinerAddresses, maddr.String()) + + temp := os.TempDir() + dir, err := os.MkdirTemp(temp, "curio") + require.NoError(t, err) + defer func() { + _ = os.Remove(dir) + }() + + cctx, err := createCliContext(dir) + require.NoError(t, err) + + shutdownChan := make(chan struct{}) + { + var ctxclose func() + ctx, ctxclose = context.WithCancel(ctx) + go func() { + <-shutdownChan + ctxclose() + }() + } + + dependencies := &deps.Deps{} + dependencies.DB = db + dependencies.Full = full + seal.SetDevnet(true) + err = os.Setenv("CURIO_REPO_PATH", dir) + require.NoError(t, err) + err = dependencies.PopulateRemainingDeps(ctx, cctx, false) + require.NoError(t, err) + + taskEngine, err := tasks.StartTasks(ctx, dependencies) + require.NoError(t, err) + + defer taskEngine.GracefullyTerminate() + + dependencies.Cfg.Subsystems.BoostAdapters = []string{fmt.Sprintf("%s:127.0.0.1:32000", maddr)} + err = lmrpc.ServeCurioMarketRPCFromConfig(dependencies.DB, dependencies.Full, dependencies.Cfg) + require.NoError(t, err) + + go func() { + err = rpc.ListenAndServe(ctx, dependencies, shutdownChan) // Monitor for shutdown. + require.NoError(t, err) + }() + + finishCh := node.MonitorShutdown(shutdownChan) + + mid, err := address.IDFromAddress(maddr) + require.NoError(t, err) + + mi, err := full.StateMinerInfo(ctx, maddr, types.EmptyTSK) + require.NoError(t, err) + + nv, err := full.StateNetworkVersion(ctx, types.EmptyTSK) + require.NoError(t, err) + + wpt := mi.WindowPoStProofType + spt, err := miner2.PreferredSealProofTypeFromWindowPoStType(nv, wpt, false) + require.NoError(t, err) + + var machines []string + err = db.Select(ctx, &machines, `select host_and_port from harmony_machines`) + require.NoError(t, err) + + require.Len(t, machines, 1) + laddr, err := net.ResolveTCPAddr("tcp", machines[0]) + require.NoError(t, err) + + ma, err := manet.FromNetAddr(laddr) + require.NoError(t, err) + + var apiToken []byte + { + type jwtPayload struct { + Allow []auth.Permission + } + + p := jwtPayload{ + Allow: api.AllPermissions, + } + + sk, err := base64.StdEncoding.DecodeString(storageSecret) + require.NoError(t, err) + + apiToken, err = jwt.Sign(&p, jwt.NewHS256(sk)) + require.NoError(t, err) + } + + ctoken := fmt.Sprintf("%s:%s", string(apiToken), ma) + err = os.Setenv("CURIO_API_INFO", ctoken) + require.NoError(t, err) + + capi, ccloser, err := rpc.GetCurioAPI(&cli.Context{}) + require.NoError(t, err) + defer ccloser() + + scfg := storiface.LocalStorageMeta{ + ID: storiface.ID(uuid.New().String()), + Weight: 10, + CanSeal: true, + CanStore: true, + MaxStorage: 0, + Groups: []string{}, + AllowTo: []string{}, + } + + err = capi.StorageInit(ctx, dir, scfg) + require.NoError(t, err) + + err = capi.StorageAddLocal(ctx, dir) + require.NoError(t, err) + + err = capi.LogSetLevel(ctx, "harmonytask", "DEBUG") + + num, err := seal.AllocateSectorNumbers(ctx, full, db, maddr, 1, func(tx *harmonydb.Tx, numbers []abi.SectorNumber) (bool, error) { + for _, n := range numbers { + _, err := tx.Exec("insert into sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) values ($1, $2, $3)", mid, n, spt) + if err != nil { + return false, xerrors.Errorf("inserting into sectors_sdr_pipeline: %w", err) + } + } + return true, nil + }) + require.Len(t, num, 1) + // TODO: add DDO deal, f05 deal 2 MiB each in the sector + + var sectorParamsArr []struct { + SpID int64 `db:"sp_id"` + SectorNumber int64 `db:"sector_number"` + } + + require.Eventuallyf(t, func() bool { + err = db.Select(ctx, §orParamsArr, ` + SELECT sp_id, sector_number + FROM sectors_sdr_pipeline + WHERE after_commit_msg_success = True`) + require.NoError(t, err) + return len(sectorParamsArr) == 1 + }, 5*time.Minute, 1*time.Second, "sector did not finish sealing in 5 minutes") + + require.Equal(t, sectorParamsArr[0].SectorNumber, int64(0)) + require.Equal(t, sectorParamsArr[0].SpID, int64(mid)) + + _ = capi.Shutdown(ctx) + + <-finishCh +} + +func createCliContext(dir string) (*cli.Context, error) { + // Define flags for the command + flags := []cli.Flag{ + &cli.StringFlag{ + Name: "listen", + Usage: "host address and port the worker api will listen on", + Value: "0.0.0.0:12300", + EnvVars: []string{"LOTUS_WORKER_LISTEN"}, + }, + &cli.BoolFlag{ + Name: "nosync", + Usage: "don't check full-node sync status", + }, + &cli.BoolFlag{ + Name: "halt-after-init", + Usage: "only run init, then return", + Hidden: true, + }, + &cli.BoolFlag{ + Name: "manage-fdlimit", + Usage: "manage open file limit", + Value: true, + }, + &cli.StringFlag{ + Name: "storage-json", + Usage: "path to json file containing storage config", + Value: "~/.curio/storage.json", + }, + &cli.StringFlag{ + Name: "journal", + Usage: "path to journal files", + Value: "~/.curio/", + }, + &cli.StringSliceFlag{ + Name: "layers", + Aliases: []string{"l", "layer"}, + Usage: "list of layers to be interpreted (atop defaults)", + }, + } + + // Set up the command with flags + command := &cli.Command{ + Name: "simulate", + Flags: flags, + Action: func(c *cli.Context) error { + fmt.Println("Listen address:", c.String("listen")) + fmt.Println("No-sync:", c.Bool("nosync")) + fmt.Println("Halt after init:", c.Bool("halt-after-init")) + fmt.Println("Manage file limit:", c.Bool("manage-fdlimit")) + fmt.Println("Storage config path:", c.String("storage-json")) + fmt.Println("Journal path:", c.String("journal")) + fmt.Println("Layers:", c.StringSlice("layers")) + return nil + }, + } + + // Create a FlagSet and populate it + set := flag.NewFlagSet("test", flag.ContinueOnError) + for _, f := range flags { + if err := f.Apply(set); err != nil { + return nil, xerrors.Errorf("Error applying flag: %s\n", err) + } + } + + curioDir := path.Join(dir, "curio") + cflag := fmt.Sprintf("--storage-json=%s", curioDir) + + storage := path.Join(dir, "storage.json") + sflag := fmt.Sprintf("--journal=%s", storage) + + // Parse the flags with test values + err := set.Parse([]string{"--listen=0.0.0.0:12345", "--nosync", "--manage-fdlimit", sflag, cflag, "--layers=seal", "--layers=post"}) + if err != nil { + return nil, xerrors.Errorf("Error setting flag: %s\n", err) + } + + // Create a cli.Context from the FlagSet + app := cli.NewApp() + ctx := cli.NewContext(app, set, nil) + ctx.Command = command + + return ctx, nil +} diff --git a/node/config/def.go b/node/config/def.go index 55fd7548f87..6b0ebc63267 100644 --- a/node/config/def.go +++ b/node/config/def.go @@ -331,8 +331,10 @@ const ( func DefaultCurioConfig() *CurioConfig { return &CurioConfig{ Subsystems: CurioSubsystemsConfig{ - GuiAddress: ":4701", - BoostAdapters: []string{}, + GuiAddress: ":4701", + BoostAdapters: []string{}, + RequireActivationSuccess: true, + RequireNotificationSuccess: true, }, Fees: CurioFees{ DefaultMaxFee: DefaultDefaultMaxFee(), diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index 63acdf7c823..c6dbff49dda 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -605,6 +605,18 @@ also be bounded by resources available on the machine.`, Comment: `EnableSendCommitMsg enables the sending of commit messages to the chain from this curio instance.`, }, + { + Name: "RequireActivationSuccess", + Type: "bool", + + Comment: `Whether to abort if any sector activation in a batch fails (newly sealed sectors, only with ProveCommitSectors3).`, + }, + { + Name: "RequireNotificationSuccess", + Type: "bool", + + Comment: `Whether to abort if any sector activation in a batch fails (updating sectors, only with ProveReplicaUpdates3).`, + }, { Name: "EnableMoveStorage", Type: "bool", diff --git a/node/config/types.go b/node/config/types.go index 3ddaa0c46d2..b0b690d5c35 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -190,6 +190,11 @@ type CurioSubsystemsConfig struct { // from this curio instance. EnableSendCommitMsg bool + // Whether to abort if any sector activation in a batch fails (newly sealed sectors, only with ProveCommitSectors3). + RequireActivationSuccess bool + // Whether to abort if any sector activation in a batch fails (updating sectors, only with ProveReplicaUpdates3). + RequireNotificationSuccess bool + // EnableMoveStorage enables the move-into-long-term-storage task to run on this curio instance. // This tasks should only be enabled on nodes with long-term storage. // From f7c5824fabd6762192f58d120265962e65042963 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 14 May 2024 18:06:45 +0530 Subject: [PATCH 11/17] lower SDR cpu for test --- curiosrc/seal/task_sdr.go | 1 + 1 file changed, 1 insertion(+) diff --git a/curiosrc/seal/task_sdr.go b/curiosrc/seal/task_sdr.go index fd8f9794e07..b531a4cbf94 100644 --- a/curiosrc/seal/task_sdr.go +++ b/curiosrc/seal/task_sdr.go @@ -251,6 +251,7 @@ func (s *SDRTask) TypeDetails() harmonytask.TaskTypeDetails { if isDevnet { res.Cost.Ram = 1 << 30 + res.Cost.Cpu = 1 } return res From ae9af6b67214e5dbe0593fcb4aec4e0a5d3ee24b Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 14 May 2024 20:34:28 +0530 Subject: [PATCH 12/17] devnet cpu 0 --- curiosrc/seal/task_sdr.go | 2 +- curiosrc/web/api/sector/sector.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/curiosrc/seal/task_sdr.go b/curiosrc/seal/task_sdr.go index b531a4cbf94..443c1b3cbd0 100644 --- a/curiosrc/seal/task_sdr.go +++ b/curiosrc/seal/task_sdr.go @@ -251,7 +251,7 @@ func (s *SDRTask) TypeDetails() harmonytask.TaskTypeDetails { if isDevnet { res.Cost.Ram = 1 << 30 - res.Cost.Cpu = 1 + res.Cost.Cpu = 0 } return res diff --git a/curiosrc/web/api/sector/sector.go b/curiosrc/web/api/sector/sector.go index 5ec719fb57f..2ab2139e1af 100644 --- a/curiosrc/web/api/sector/sector.go +++ b/curiosrc/web/api/sector/sector.go @@ -271,6 +271,7 @@ func (c *cfg) getSectors(w http.ResponseWriter, r *http.Request) { } } } + sectors[i].IsFilPlus = vp > dw if dw > 0 { sectors[i].DealWeight = fmt.Sprintf("%s", units.BytesSize(dw)) } else if vp > 0 { From f90e75b07422ab1c35daf72fbebc4ecd2b1d0d14 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 14 May 2024 21:35:32 +0530 Subject: [PATCH 13/17] get params for itest --- .circleci/config.yml | 1 + .github/workflows/test.yml | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 75d747c6979..9c235003c8c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -560,6 +560,7 @@ workflows: - build suite: itest-curio target: "./itests/curio_test.go" + get-params: true - test: name: test-itest-deadlines requires: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f63e4c42b82..1081a1a58c0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,6 +77,7 @@ jobs: "itest-sector_import_simple": ["self-hosted", "linux", "x64", "2xlarge"], "itest-wdpost": ["self-hosted", "linux", "x64", "2xlarge"], "unit-storage": ["self-hosted", "linux", "x64", "2xlarge"], + "itest-curio": ["self-hosted", "linux", "x64", "2xlarge"], "itest-batch_deal": ["self-hosted", "linux", "x64", "xlarge"], "itest-cli": ["self-hosted", "linux", "x64", "xlarge"], @@ -158,7 +159,8 @@ jobs: "itest-worker", "multicore-sdr", "unit-cli", - "unit-storage" + "unit-storage", + "itest-curio" ] run: | # Create a list of integration test groups From afe24cab4c2eef086692bd0c1b319d190edf6d43 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 14 May 2024 22:30:54 +0530 Subject: [PATCH 14/17] fix itest sector size --- .circleci/config.yml | 2 ++ .circleci/template.yml | 4 ++-- itests/curio_test.go | 3 +-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 9c235003c8c..583b9d402a0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -560,7 +560,9 @@ workflows: - build suite: itest-curio target: "./itests/curio_test.go" + resource_class: 2xlarge get-params: true + - test: name: test-itest-deadlines requires: diff --git a/.circleci/template.yml b/.circleci/template.yml index b7462b0275b..949c59d2425 100644 --- a/.circleci/template.yml +++ b/.circleci/template.yml @@ -545,10 +545,10 @@ workflows: - build suite: itest-[[ $name ]] target: "./itests/[[ $file ]]" - [[- if or (eq $name "worker") (eq $name "deals_concurrent") (eq $name "wdpost_worker_config") (eq $name "sector_pledge")]] + [[- if or (eq $name "worker") (eq $name "deals_concurrent") (eq $name "wdpost_worker_config") (eq $name "sector_pledge") (eq $name "curio")]] resource_class: 2xlarge [[- end]] - [[- if or (eq $name "wdpost") (eq $name "sector_pledge")]] + [[- if or (eq $name "wdpost") (eq $name "sector_pledge") (eq $name "curio")]] get-params: true [[end]] [[- end ]][[- end]] diff --git a/itests/curio_test.go b/itests/curio_test.go index 1f1338d08e2..2b082051bcb 100644 --- a/itests/curio_test.go +++ b/itests/curio_test.go @@ -95,7 +95,6 @@ func TestCurioHappyPath(t *testing.T) { full, miner, esemble := kit.EnsembleMinimal(t, kit.LatestActorsAt(-1), - kit.MockProofs(), kit.WithSectorIndexDB(), ) @@ -123,7 +122,7 @@ func TestCurioHappyPath(t *testing.T) { require.NotContains(t, titles, "base") addr := miner.OwnerKey.Address - sectorSizeInt, err := units.RAMInBytes("8MiB") + sectorSizeInt, err := units.RAMInBytes("2KiB") require.NoError(t, err) maddr, err := spcli.CreateStorageMiner(ctx, full, addr, addr, addr, abi.SectorSize(sectorSizeInt), 0) From 88fdfef7f17ade2396e624031203ac2a5f90e097 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 14 May 2024 22:41:15 +0530 Subject: [PATCH 15/17] revert sdr devnet cpu --- curiosrc/seal/task_sdr.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curiosrc/seal/task_sdr.go b/curiosrc/seal/task_sdr.go index 443c1b3cbd0..b531a4cbf94 100644 --- a/curiosrc/seal/task_sdr.go +++ b/curiosrc/seal/task_sdr.go @@ -251,7 +251,7 @@ func (s *SDRTask) TypeDetails() harmonytask.TaskTypeDetails { if isDevnet { res.Cost.Ram = 1 << 30 - res.Cost.Cpu = 0 + res.Cost.Cpu = 1 } return res From 1715beb7e43e7fa9ebaaa0b84770183378feba90 Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Thu, 16 May 2024 00:23:50 +0530 Subject: [PATCH 16/17] improve SectorStatus API --- curiosrc/market/fakelm/lmimpl.go | 166 ++++++++++++++++++------------- 1 file changed, 99 insertions(+), 67 deletions(-) diff --git a/curiosrc/market/fakelm/lmimpl.go b/curiosrc/market/fakelm/lmimpl.go index 80db580e918..04444939027 100644 --- a/curiosrc/market/fakelm/lmimpl.go +++ b/curiosrc/market/fakelm/lmimpl.go @@ -18,7 +18,6 @@ import ( "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/actors/builtin/miner" - "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/curiosrc/market" "github.com/filecoin-project/lotus/lib/harmony/harmonydb" "github.com/filecoin-project/lotus/node/config" @@ -65,17 +64,79 @@ func (l *LMRPCProvider) WorkerJobs(ctx context.Context) (map[uuid.UUID][]storifa } func (l *LMRPCProvider) SectorsStatus(ctx context.Context, sid abi.SectorNumber, showOnChainInfo bool) (api.SectorInfo, error) { - si, err := l.si.StorageFindSector(ctx, abi.SectorID{Miner: l.minerID, Number: sid}, storiface.FTSealed|storiface.FTCache, 0, false) - if err != nil { - return api.SectorInfo{}, err - } - var ssip []struct { PieceCID *string `db:"piece_cid"` DealID *int64 `db:"f05_deal_id"` + Complete bool `db:"after_commit_msg_success"` + Failed bool `db:"failed"` + SDR bool `db:"after_sdr"` + PoRep bool `db:"after_porep"` } - err = l.db.Select(ctx, &ssip, "SELECT ssip.piece_cid, ssip.f05_deal_id FROM sectors_sdr_pipeline p LEFT JOIN sectors_sdr_initial_pieces ssip ON p.sp_id = ssip.sp_id AND p.sector_number = ssip.sector_number WHERE p.sp_id = $1 AND p.sector_number = $2", l.minerID, sid) + err := l.db.Select(ctx, &ssip, ` + WITH CheckCommit AS ( + SELECT + sp_id, + sector_number, + after_commit_msg, + failed, + after_sdr, + after_porep, + after_commit_msg_success + FROM + sectors_sdr_pipeline + WHERE + sp_id = $1 AND sector_number = $2 + ), + MetaPieces AS ( + SELECT + mp.piece_cid, + mp.f05_deal_id, + cc.after_commit_msg_success, + cc.failed, + cc.after_sdr, + cc.after_porep + FROM + sectors_meta_pieces mp + INNER JOIN + CheckCommit cc ON mp.sp_id = cc.sp_id AND mp.sector_num = cc.sector_number + WHERE + cc.after_commit_msg IS TRUE + ), + InitialPieces AS ( + SELECT + ip.piece_cid, + ip.f05_deal_id, + cc.after_commit_msg_success, + cc.failed, + cc.after_sdr, + cc.after_porep + FROM + sectors_sdr_initial_pieces ip + INNER JOIN + CheckCommit cc ON ip.sp_id = cc.sp_id AND ip.sector_number = cc.sector_number + WHERE + cc.after_commit_msg IS FALSE + ), + FallbackPieces AS ( + SELECT + op.piece_cid, + op.f05_deal_id, + FALSE as after_commit_msg_success, + FALSE as failed, + FALSE as after_sdr, + FALSE as after_porep + FROM + open_sector_pieces op + WHERE + op.sp_id = $1 AND op.sector_number = $2 + AND NOT EXISTS (SELECT 1 FROM sectors_sdr_pipeline sp WHERE sp.sp_id = op.sp_id AND sp.sector_number = op.sector_number) + ) + SELECT * FROM MetaPieces + UNION ALL + SELECT * FROM InitialPieces + UNION ALL + SELECT * FROM FallbackPieces;`, l.minerID, sid) if err != nil { return api.SectorInfo{}, err } @@ -87,15 +148,6 @@ func (l *LMRPCProvider) SectorsStatus(ctx context.Context, sid abi.SectorNumber, deals = append(deals, abi.DealID(*d.DealID)) } } - } else { - osi, err := l.full.StateSectorGetInfo(ctx, l.maddr, sid, types.EmptyTSK) - if err != nil { - return api.SectorInfo{}, err - } - - if osi != nil { - deals = osi.DealIDs - } } spt, err := miner.SealProofTypeFromSectorSize(l.ssize, network.Version20, false) // good enough, just need this for ssize anyways @@ -103,49 +155,8 @@ func (l *LMRPCProvider) SectorsStatus(ctx context.Context, sid abi.SectorNumber, return api.SectorInfo{}, err } - if len(si) == 0 { - state := api.SectorState(sealing.UndefinedSectorState) - if len(ssip) > 0 { - state = api.SectorState(sealing.PreCommit1) - } - - return api.SectorInfo{ - SectorID: sid, - State: state, - CommD: nil, - CommR: nil, - Proof: nil, - Deals: deals, - Pieces: nil, - Ticket: api.SealTicket{}, - Seed: api.SealSeed{}, - PreCommitMsg: nil, - CommitMsg: nil, - Retries: 0, - ToUpgrade: false, - ReplicaUpdateMessage: nil, - LastErr: "", - Log: nil, - SealProof: spt, - Activation: 0, - Expiration: 0, - DealWeight: big.Zero(), - VerifiedDealWeight: big.Zero(), - InitialPledge: big.Zero(), - OnTime: 0, - Early: 0, - }, nil - } - - var state = api.SectorState(sealing.Proving) - if !si[0].CanStore { - state = api.SectorState(sealing.PreCommit2) - } - - // todo improve this with on-chain info - return api.SectorInfo{ + ret := api.SectorInfo{ SectorID: sid, - State: state, CommD: nil, CommR: nil, Proof: nil, @@ -160,16 +171,37 @@ func (l *LMRPCProvider) SectorsStatus(ctx context.Context, sid abi.SectorNumber, ReplicaUpdateMessage: nil, LastErr: "", Log: nil, + SealProof: spt, + Activation: 0, + Expiration: 0, + DealWeight: big.Zero(), + VerifiedDealWeight: big.Zero(), + InitialPledge: big.Zero(), + OnTime: 0, + Early: 0, + } - SealProof: spt, - Activation: 0, - Expiration: 0, - DealWeight: big.Zero(), - VerifiedDealWeight: big.Zero(), - InitialPledge: big.Zero(), - OnTime: 0, - Early: 0, - }, nil + // If no rows found i.e. sector doesn't exist in DB + //assign ssip[0] to a local variable for easier reading. + currentSSIP := ssip[0] + + switch { + case len(ssip) == 0: + ret.State = api.SectorState(sealing.UndefinedSectorState) + case currentSSIP.Failed: + ret.State = api.SectorState(sealing.FailedUnrecoverable) + case !currentSSIP.SDR: + ret.State = api.SectorState(sealing.WaitDeals) + case currentSSIP.SDR && !currentSSIP.PoRep: + ret.State = api.SectorState(sealing.PreCommit1) + case currentSSIP.SDR && currentSSIP.PoRep && !currentSSIP.Complete: + ret.State = api.SectorState(sealing.PreCommit2) + case currentSSIP.Complete: + ret.State = api.SectorState(sealing.Proving) + default: + return api.SectorInfo{}, nil + } + return ret, nil } func (l *LMRPCProvider) SectorsList(ctx context.Context) ([]abi.SectorNumber, error) { From b92c6193e4a37decbf6e4f84582bfe792f84e90b Mon Sep 17 00:00:00 2001 From: LexLuthr Date: Tue, 21 May 2024 15:56:17 +0530 Subject: [PATCH 17/17] account for verified constraints --- cli/spcli/actor.go | 5 + cmd/curio/market.go | 102 +++++++--- curiosrc/market/deal_ingest.go | 106 ++++++++-- curiosrc/market/lmrpc/lmrpc.go | 6 +- curiosrc/web/api/sector/sector.go | 6 +- documentation/en/cli-curio.md | 1 + documentation/en/cli-sptool.md | 1 + documentation/en/default-curio-config.toml | 5 +- itests/curio_test.go | 192 +++++++++--------- .../sql/20240508-open-deal-sectors.sql | 4 +- node/config/doc_gen.go | 5 +- node/config/types.go | 5 +- 12 files changed, 279 insertions(+), 159 deletions(-) diff --git a/cli/spcli/actor.go b/cli/spcli/actor.go index 33590de50b6..5db3f7e7dc2 100644 --- a/cli/spcli/actor.go +++ b/cli/spcli/actor.go @@ -1268,6 +1268,11 @@ var ActorNewMinerCmd = &cli.Command{ Name: "sector-size", Usage: "specify sector size to use for new miner initialisation", }, + &cli.IntFlag{ + Name: "confidence", + Usage: "number of block confirmations to wait for", + Value: int(build.MessageConfidence), + }, }, Action: func(cctx *cli.Context) error { ctx := cctx.Context diff --git a/cmd/curio/market.go b/cmd/curio/market.go index b97388685cf..4f546292894 100644 --- a/cmd/curio/market.go +++ b/cmd/curio/market.go @@ -2,7 +2,6 @@ package main import ( "fmt" - "net/http" "sort" "strconv" @@ -12,10 +11,12 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/lotus/api/client" - cliutil "github.com/filecoin-project/lotus/cli/util" + "github.com/filecoin-project/lotus/chain/actors/builtin/miner" + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/cmd/curio/deps" "github.com/filecoin-project/lotus/curiosrc/market/lmrpc" + "github.com/filecoin-project/lotus/lib/harmony/harmonydb" ) var marketCmd = &cli.Command{ @@ -92,6 +93,11 @@ var marketSealCmd = &cli.Command{ Name: "layers", Usage: "list of layers to be interpreted (atop defaults). Default: base", }, + &cli.BoolFlag{ + Name: "synthetic", + Usage: "Use synthetic PoRep", + Value: false, // todo implement synthetic + }, }, Action: func(cctx *cli.Context) error { act, err := address.NewFromString(cctx.String("actor")) @@ -110,50 +116,86 @@ var marketSealCmd = &cli.Command{ return xerrors.Errorf("failed to parse the sector number: %w", err) } - db, err := deps.MakeDB(cctx) + ctx := lcli.ReqContext(cctx) + dep, err := deps.GetDepsCLI(ctx, cctx) if err != nil { return err } - layers := cctx.StringSlice("layers") - - cfg, err := deps.GetConfig(cctx.Context, layers, db) + mid, err := address.IDFromAddress(act) if err != nil { - return xerrors.Errorf("get config: %w", err) + return xerrors.Errorf("getting miner id: %w", err) } - ts, err := lmrpc.MakeTokens(cfg) + mi, err := dep.Full.StateMinerInfo(ctx, act, types.EmptyTSK) if err != nil { - return xerrors.Errorf("make tokens: %w", err) + return xerrors.Errorf("getting miner info: %w", err) } - info, ok := ts[act] - if !ok { - return xerrors.Errorf("no market configuration found for actor %s in the specified config layers", act) - } - - ainfo := cliutil.ParseApiInfo(info) - addr, err := ainfo.DialArgs("v0") + nv, err := dep.Full.StateNetworkVersion(ctx, types.EmptyTSK) if err != nil { - return xerrors.Errorf("could not get DialArgs: %w", err) + return xerrors.Errorf("getting network version: %w", err) } - type httpHead struct { - addr string - header http.Header - } + wpt := mi.WindowPoStProofType + spt, err := miner.PreferredSealProofTypeFromWindowPoStType(nv, wpt, cctx.Bool("synthetic")) + if err != nil { + return xerrors.Errorf("getting seal proof type: %w", err) + } + + comm, err := dep.DB.BeginTransaction(ctx, func(tx *harmonydb.Tx) (commit bool, err error) { + // Get current open sector pieces from DB + var pieces []struct { + Sector abi.SectorNumber `db:"sector_number"` + Size abi.PaddedPieceSize `db:"piece_size"` + Index uint64 `db:"piece_index"` + } + err = tx.Select(&pieces, ` + SELECT + sector_number, + piece_size, + piece_index, + FROM + open_sector_pieces + WHERE + sp_id = $1 AND sector_number = $2 + ORDER BY + piece_index DESC;`, mid, sector) + if err != nil { + return false, xerrors.Errorf("getting open sectors from DB") + } + + if len(pieces) < 1 { + return false, xerrors.Errorf("sector %d is not waiting to be sealed", sector) + } + + cn, err := tx.Exec(`INSERT INTO sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) VALUES ($1, $2, $3);`, mid, sector, spt) + + if err != nil { + return false, xerrors.Errorf("adding sector to pipeline: %w", err) + } + + if cn != 1 { + return false, xerrors.Errorf("incorrect number of rows returned") + } + + _, err = tx.Exec("SELECT transfer_and_delete_open_piece($1, $2)", mid, sector) + if err != nil { + return false, xerrors.Errorf("adding sector to pipeline: %w", err) + } + + return true, nil + + }, harmonydb.OptionRetry()) - head := httpHead{ - addr: addr, - header: ainfo.AuthHeader(), + if err != nil { + return xerrors.Errorf("start sealing sector: %w", err) } - market, closer, err := client.NewStorageMinerRPCV0(cctx.Context, head.addr, head.header) - if err != nil { - return xerrors.Errorf("failed to get market API: %w", err) + if !comm { + return xerrors.Errorf("start sealing sector: commit failed") } - defer closer() - return market.SectorStartSealing(cctx.Context, abi.SectorNumber(sector)) + return nil }, } diff --git a/curiosrc/market/deal_ingest.go b/curiosrc/market/deal_ingest.go index 543c8baf586..8aa41811b36 100644 --- a/curiosrc/market/deal_ingest.go +++ b/curiosrc/market/deal_ingest.go @@ -15,6 +15,7 @@ import ( "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/go-padreader" "github.com/filecoin-project/go-state-types/abi" + verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" @@ -38,14 +39,17 @@ type PieceIngesterApi interface { StateMinerInfo(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) StateMinerAllocated(ctx context.Context, a address.Address, key types.TipSetKey) (*bitfield.BitField, error) StateNetworkVersion(ctx context.Context, key types.TipSetKey) (network.Version, error) + StateGetAllocation(ctx context.Context, clientAddr address.Address, allocationId verifregtypes.AllocationId, tsk types.TipSetKey) (*verifregtypes.Allocation, error) + StateGetAllocationForPendingDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*verifregtypes.Allocation, error) } type openSector struct { - number abi.SectorNumber - currentSize abi.PaddedPieceSize - earliestEpoch abi.ChainEpoch - index uint64 - openedAt *time.Time + number abi.SectorNumber + currentSize abi.PaddedPieceSize + earliestStartEpoch abi.ChainEpoch + index uint64 + openedAt *time.Time + latestEndEpoch abi.ChainEpoch } type PieceIngester struct { @@ -62,11 +66,18 @@ type PieceIngester struct { } type pieceDetails struct { - Sector abi.SectorNumber `db:"sector_number"` - Size abi.PaddedPieceSize `db:"piece_size"` - Epoch abi.ChainEpoch `db:"deal_start_epoch"` - Index uint64 `db:"piece_index"` - CreatedAt *time.Time `db:"created_at"` + Sector abi.SectorNumber `db:"sector_number"` + Size abi.PaddedPieceSize `db:"piece_size"` + StartEpoch abi.ChainEpoch `db:"deal_start_epoch"` + EndEpoch abi.ChainEpoch `db:"deal_end_epoch"` + Index uint64 `db:"piece_index"` + CreatedAt *time.Time `db:"created_at"` +} + +type verifiedDeal struct { + isVerified bool + tmin abi.ChainEpoch + tmax abi.ChainEpoch } func NewPieceIngester(ctx context.Context, db *harmonydb.DB, api PieceIngesterApi, maddr address.Address, sealRightNow bool, maxWaitTime time.Duration) (*PieceIngester, error) { @@ -139,7 +150,7 @@ func (p *PieceIngester) Seal() error { log.Debugf("start sealing sector %d of miner %d: %s", sector.number, p.miner.String(), "MaxWaitTime reached") return true } - if sector.earliestEpoch < head.Height()+abi.ChainEpoch(960) { + if sector.earliestStartEpoch < head.Height()+abi.ChainEpoch(960) { log.Debugf("start sealing sector %d of miner %d: %s", sector.number, p.miner.String(), "earliest start epoch") return true } @@ -205,12 +216,44 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address return api.SectorOffset{}, xerrors.Errorf("json.Marshal(header): %w", err) } + vd := verifiedDeal{ + isVerified: false, + } + if piece.DealProposal != nil { + vd.isVerified = piece.DealProposal.VerifiedDeal + if vd.isVerified { + alloc, err := p.api.StateGetAllocationForPendingDeal(ctx, piece.DealID, types.EmptyTSK) + if err != nil { + return api.SectorOffset{}, xerrors.Errorf("getting pending allocation for deal %d: %w", piece.DealID, err) + } + if alloc == nil { + return api.SectorOffset{}, xerrors.Errorf("no allocation found for deal %d: %w", piece.DealID, err) + } + vd.tmin = alloc.TermMin + vd.tmax = alloc.TermMax + } propJson, err = json.Marshal(piece.DealProposal) if err != nil { return api.SectorOffset{}, xerrors.Errorf("json.Marshal(piece.DealProposal): %w", err) } } else { + vd.isVerified = piece.PieceActivationManifest.VerifiedAllocationKey != nil + if vd.isVerified { + client, err := address.NewIDAddress(uint64(piece.PieceActivationManifest.VerifiedAllocationKey.Client)) + if err != nil { + return api.SectorOffset{}, xerrors.Errorf("getting client address from actor ID: %w", err) + } + alloc, err := p.api.StateGetAllocation(ctx, client, verifregtypes.AllocationId(piece.PieceActivationManifest.VerifiedAllocationKey.ID), types.EmptyTSK) + if err != nil { + return api.SectorOffset{}, xerrors.Errorf("getting allocation details for %d: %w", piece.PieceActivationManifest.VerifiedAllocationKey.ID, err) + } + if alloc == nil { + return api.SectorOffset{}, xerrors.Errorf("no allocation found for ID %d: %w", piece.PieceActivationManifest.VerifiedAllocationKey.ID, err) + } + vd.tmin = alloc.TermMin + vd.tmax = alloc.TermMax + } propJson, err = json.Marshal(piece.PieceActivationManifest) if err != nil { return api.SectorOffset{}, xerrors.Errorf("json.Marshal(piece.PieceActivationManifest): %w", err) @@ -219,7 +262,7 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address if !p.sealRightNow { // Try to allocate the piece to an open sector - allocated, ret, err := p.allocateToExisting(ctx, piece, rawSize, source, dataHdrJson, propJson) + allocated, ret, err := p.allocateToExisting(ctx, piece, rawSize, source, dataHdrJson, propJson, vd) if err != nil { return api.SectorOffset{}, err } @@ -277,7 +320,7 @@ func (p *PieceIngester) AllocatePieceToSector(ctx context.Context, maddr address }, nil } -func (p *PieceIngester) allocateToExisting(ctx context.Context, piece lpiece.PieceDealInfo, rawSize int64, source url.URL, dataHdrJson, propJson []byte) (bool, api.SectorOffset, error) { +func (p *PieceIngester) allocateToExisting(ctx context.Context, piece lpiece.PieceDealInfo, rawSize int64, source url.URL, dataHdrJson, propJson []byte, vd verifiedDeal) (bool, api.SectorOffset, error) { var ret api.SectorOffset var allocated bool @@ -293,6 +336,14 @@ func (p *PieceIngester) allocateToExisting(ctx context.Context, piece lpiece.Pie for _, sec := range openSectors { sec := sec if sec.currentSize+pieceSize <= abi.PaddedPieceSize(p.sectorSize) { + if vd.isVerified { + sectorLifeTime := sec.latestEndEpoch - sec.earliestStartEpoch + // Allocation's TMin must fit in sector and TMax should be at least sector lifetime or more + // Based on https://github.com/filecoin-project/builtin-actors/blob/a0e34d22665ac8c84f02fea8a099216f29ffaeeb/actors/verifreg/src/lib.rs#L1071-L1086 + if sectorLifeTime <= vd.tmin && sectorLifeTime >= vd.tmax { + continue + } + } ret.Sector = sec.number ret.Offset = sec.currentSize @@ -364,6 +415,7 @@ func (p *PieceIngester) SectorStartSealing(ctx context.Context, sector abi.Secto piece_size, piece_index, COALESCE(direct_start_epoch, f05_deal_start_epoch, 0) AS deal_start_epoch, + COALESCE(direct_end_epoch, f05_deal_end_epoch, 0) AS deal_end_epoch, created_at FROM open_sector_pieces @@ -418,6 +470,7 @@ func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) piece_size, piece_index, COALESCE(direct_start_epoch, f05_deal_start_epoch, 0) AS deal_start_epoch, + COALESCE(direct_end_epoch, f05_deal_end_epoch, 0) AS deal_end_epoch, created_at FROM open_sector_pieces @@ -429,11 +482,18 @@ func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) return nil, xerrors.Errorf("getting open sectors from DB") } - getEpoch := func(piece pieceDetails, cur abi.ChainEpoch) abi.ChainEpoch { - if cur > 0 && cur < piece.Epoch { + getStartEpoch := func(new abi.ChainEpoch, cur abi.ChainEpoch) abi.ChainEpoch { + if cur > 0 && cur < new { + return cur + } + return new + } + + getEndEpoch := func(new abi.ChainEpoch, cur abi.ChainEpoch) abi.ChainEpoch { + if cur > 0 && cur > new { return cur } - return piece.Epoch + return new } getOpenedAt := func(piece pieceDetails, cur *time.Time) *time.Time { @@ -449,16 +509,18 @@ func (p *PieceIngester) getOpenSectors(tx *harmonydb.Tx) ([]*openSector, error) sector, ok := sectorMap[pi.Sector] if !ok { sectorMap[pi.Sector] = &openSector{ - number: pi.Sector, - currentSize: pi.Size, - earliestEpoch: getEpoch(pi, 0), - index: pi.Index, - openedAt: pi.CreatedAt, + number: pi.Sector, + currentSize: pi.Size, + earliestStartEpoch: getStartEpoch(pi.StartEpoch, 0), + index: pi.Index, + openedAt: pi.CreatedAt, + latestEndEpoch: getEndEpoch(pi.EndEpoch, 0), } continue } sector.currentSize += pi.Size - sector.earliestEpoch = getEpoch(pi, sector.earliestEpoch) + sector.earliestStartEpoch = getStartEpoch(pi.StartEpoch, sector.earliestStartEpoch) + sector.latestEndEpoch = getEndEpoch(pi.EndEpoch, sector.earliestStartEpoch) if sector.index < pi.Index { sector.index = pi.Index } diff --git a/curiosrc/market/lmrpc/lmrpc.go b/curiosrc/market/lmrpc/lmrpc.go index 40ada11e9db..b111d515d10 100644 --- a/curiosrc/market/lmrpc/lmrpc.go +++ b/curiosrc/market/lmrpc/lmrpc.go @@ -377,8 +377,8 @@ func sectorAddPieceToAnyOperation(maddr address.Address, rootUrl url.URL, conf * var taskID *int64 var complete bool err := db.QueryRow(ctx, `SELECT pp.task_id, pp.complete - FROM curio.parked_pieces pp - JOIN curio.parked_piece_refs ppr ON pp.id = ppr.piece_id + FROM parked_pieces pp + JOIN parked_piece_refs ppr ON pp.id = ppr.piece_id WHERE ppr.ref_id = $1;`, refID).Scan(&taskID, &complete) if err != nil { return api.SectorOffset{}, xerrors.Errorf("getting piece park status: %w", err) @@ -568,7 +568,7 @@ func maybeApplyBackpressure(tx *harmonydb.Tx, cfg config.CurioIngestConfig, ssiz var pieceSizes []abi.PaddedPieceSize - err = tx.Select(&pieceSizes, `SELECT piece_padded_size FROM curio.parked_pieces WHERE complete = false;`) + err = tx.Select(&pieceSizes, `SELECT piece_padded_size FROM parked_pieces WHERE complete = false;`) if err != nil { return false, xerrors.Errorf("getting in-process pieces") } diff --git a/curiosrc/web/api/sector/sector.go b/curiosrc/web/api/sector/sector.go index 2ab2139e1af..31113fd4345 100644 --- a/curiosrc/web/api/sector/sector.go +++ b/curiosrc/web/api/sector/sector.go @@ -149,7 +149,7 @@ func (c *cfg) getSectors(w http.ResponseWriter, r *http.Request) { if i, ok := sectorIdx[sectorID{minerID, uint64(st.SectorNumber)}]; ok { sectors[i].IsOnChain = true sectors[i].ExpiresAt = st.Expiration - sectors[i].IsFilPlus = st.VerifiedDealWeight.GreaterThan(st.DealWeight) + sectors[i].IsFilPlus = st.VerifiedDealWeight.GreaterThan(big.NewInt(0)) if ss, err := st.SealProof.SectorSize(); err == nil { sectors[i].SealInfo = ss.ShortString() } @@ -217,7 +217,7 @@ func (c *cfg) getSectors(w http.ResponseWriter, r *http.Request) { SectorNum: int64(chainy.onChain.SectorNumber), IsOnChain: true, ExpiresAt: chainy.onChain.Expiration, - IsFilPlus: chainy.onChain.VerifiedDealWeight.GreaterThan(chainy.onChain.DealWeight), + IsFilPlus: chainy.onChain.VerifiedDealWeight.GreaterThan(big.NewInt(0)), Proving: chainy.active, Flag: true, // All such sectors should be flagged to be terminated } @@ -271,7 +271,7 @@ func (c *cfg) getSectors(w http.ResponseWriter, r *http.Request) { } } } - sectors[i].IsFilPlus = vp > dw + sectors[i].IsFilPlus = vp > 0 if dw > 0 { sectors[i].DealWeight = fmt.Sprintf("%s", units.BytesSize(dw)) } else if vp > 0 { diff --git a/documentation/en/cli-curio.md b/documentation/en/cli-curio.md index f0016c7bf30..97bbfeb068f 100644 --- a/documentation/en/cli-curio.md +++ b/documentation/en/cli-curio.md @@ -562,6 +562,7 @@ USAGE: OPTIONS: --actor value Specify actor address to start sealing sectors for --layers value [ --layers value ] list of layers to be interpreted (atop defaults). Default: base + --synthetic Use synthetic PoRep (default: false) --help, -h show help ``` diff --git a/documentation/en/cli-sptool.md b/documentation/en/cli-sptool.md index 6bf27b611cd..172b069f862 100644 --- a/documentation/en/cli-sptool.md +++ b/documentation/en/cli-sptool.md @@ -245,6 +245,7 @@ OPTIONS: --owner value, -o value owner key to use for new miner initialisation --from value, -f value address to send actor(miner) creation message from --sector-size value specify sector size to use for new miner initialisation + --confidence value number of block confirmations to wait for (default: 5) --help, -h show help ``` diff --git a/documentation/en/default-curio-config.toml b/documentation/en/default-curio-config.toml index 14baa0a1939..1e4dcfbd0cb 100644 --- a/documentation/en/default-curio-config.toml +++ b/documentation/en/default-curio-config.toml @@ -342,8 +342,9 @@ # Maximum number of sectors that can be queued waiting for SDR to start processing. # 0 = unlimited # Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. - # The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the trees tasks it is - # possible that this queue grows more than this limit, the backpressure is only applied to sectors entering the pipeline. + # The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the SDR tasks it is + # possible that this queue grows more than this limit(CC sectors), the backpressure is only applied to sectors + # entering the pipeline. # # type: int #MaxQueueSDR = 8 diff --git a/itests/curio_test.go b/itests/curio_test.go index 2b082051bcb..2abbfa03df4 100644 --- a/itests/curio_test.go +++ b/itests/curio_test.go @@ -20,10 +20,12 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-jsonrpc" "github.com/filecoin-project/go-jsonrpc/auth" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/api/v1api" miner2 "github.com/filecoin-project/lotus/chain/actors/builtin/miner" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/cli/spcli" @@ -142,8 +144,6 @@ func TestCurioHappyPath(t *testing.T) { _, err = deps.LoadConfigWithUpgrades(baseText, baseCfg) require.NoError(t, err) - storageSecret := baseCfg.Apis.StorageRPCSecret - require.NotNil(t, baseCfg.Addresses) require.GreaterOrEqual(t, len(baseCfg.Addresses), 1) @@ -156,43 +156,9 @@ func TestCurioHappyPath(t *testing.T) { _ = os.Remove(dir) }() - cctx, err := createCliContext(dir) - require.NoError(t, err) - - shutdownChan := make(chan struct{}) - { - var ctxclose func() - ctx, ctxclose = context.WithCancel(ctx) - go func() { - <-shutdownChan - ctxclose() - }() - } - - dependencies := &deps.Deps{} - dependencies.DB = db - dependencies.Full = full - seal.SetDevnet(true) - err = os.Setenv("CURIO_REPO_PATH", dir) - require.NoError(t, err) - err = dependencies.PopulateRemainingDeps(ctx, cctx, false) - require.NoError(t, err) - - taskEngine, err := tasks.StartTasks(ctx, dependencies) - require.NoError(t, err) - - defer taskEngine.GracefullyTerminate() - - dependencies.Cfg.Subsystems.BoostAdapters = []string{fmt.Sprintf("%s:127.0.0.1:32000", maddr)} - err = lmrpc.ServeCurioMarketRPCFromConfig(dependencies.DB, dependencies.Full, dependencies.Cfg) - require.NoError(t, err) - - go func() { - err = rpc.ListenAndServe(ctx, dependencies, shutdownChan) // Monitor for shutdown. - require.NoError(t, err) - }() - - finishCh := node.MonitorShutdown(shutdownChan) + capi, enginerTerm, closure, finishCh := ConstructCurioTest(ctx, t, dir, db, full, maddr, baseCfg) + defer enginerTerm() + defer closure() mid, err := address.IDFromAddress(maddr) require.NoError(t, err) @@ -207,60 +173,6 @@ func TestCurioHappyPath(t *testing.T) { spt, err := miner2.PreferredSealProofTypeFromWindowPoStType(nv, wpt, false) require.NoError(t, err) - var machines []string - err = db.Select(ctx, &machines, `select host_and_port from harmony_machines`) - require.NoError(t, err) - - require.Len(t, machines, 1) - laddr, err := net.ResolveTCPAddr("tcp", machines[0]) - require.NoError(t, err) - - ma, err := manet.FromNetAddr(laddr) - require.NoError(t, err) - - var apiToken []byte - { - type jwtPayload struct { - Allow []auth.Permission - } - - p := jwtPayload{ - Allow: api.AllPermissions, - } - - sk, err := base64.StdEncoding.DecodeString(storageSecret) - require.NoError(t, err) - - apiToken, err = jwt.Sign(&p, jwt.NewHS256(sk)) - require.NoError(t, err) - } - - ctoken := fmt.Sprintf("%s:%s", string(apiToken), ma) - err = os.Setenv("CURIO_API_INFO", ctoken) - require.NoError(t, err) - - capi, ccloser, err := rpc.GetCurioAPI(&cli.Context{}) - require.NoError(t, err) - defer ccloser() - - scfg := storiface.LocalStorageMeta{ - ID: storiface.ID(uuid.New().String()), - Weight: 10, - CanSeal: true, - CanStore: true, - MaxStorage: 0, - Groups: []string{}, - AllowTo: []string{}, - } - - err = capi.StorageInit(ctx, dir, scfg) - require.NoError(t, err) - - err = capi.StorageAddLocal(ctx, dir) - require.NoError(t, err) - - err = capi.LogSetLevel(ctx, "harmonytask", "DEBUG") - num, err := seal.AllocateSectorNumbers(ctx, full, db, maddr, 1, func(tx *harmonydb.Tx, numbers []abi.SectorNumber) (bool, error) { for _, n := range numbers { _, err := tx.Exec("insert into sectors_sdr_pipeline (sp_id, sector_number, reg_seal_proof) values ($1, $2, $3)", mid, n, spt) @@ -378,3 +290,97 @@ func createCliContext(dir string) (*cli.Context, error) { return ctx, nil } + +func ConstructCurioTest(ctx context.Context, t *testing.T, dir string, db *harmonydb.DB, full v1api.FullNode, maddr address.Address, cfg *config.CurioConfig) (api.Curio, func(), jsonrpc.ClientCloser, <-chan struct{}) { + cctx, err := createCliContext(dir) + require.NoError(t, err) + + shutdownChan := make(chan struct{}) + + { + var ctxclose func() + ctx, ctxclose = context.WithCancel(ctx) + go func() { + <-shutdownChan + ctxclose() + }() + } + + dependencies := &deps.Deps{} + dependencies.DB = db + dependencies.Full = full + seal.SetDevnet(true) + err = os.Setenv("CURIO_REPO_PATH", dir) + require.NoError(t, err) + err = dependencies.PopulateRemainingDeps(ctx, cctx, false) + require.NoError(t, err) + + taskEngine, err := tasks.StartTasks(ctx, dependencies) + require.NoError(t, err) + + dependencies.Cfg.Subsystems.BoostAdapters = []string{fmt.Sprintf("%s:127.0.0.1:32000", maddr)} + err = lmrpc.ServeCurioMarketRPCFromConfig(dependencies.DB, dependencies.Full, dependencies.Cfg) + require.NoError(t, err) + + go func() { + err = rpc.ListenAndServe(ctx, dependencies, shutdownChan) // Monitor for shutdown. + require.NoError(t, err) + }() + + finishCh := node.MonitorShutdown(shutdownChan) + + var machines []string + err = db.Select(ctx, &machines, `select host_and_port from harmony_machines`) + require.NoError(t, err) + + require.Len(t, machines, 1) + laddr, err := net.ResolveTCPAddr("tcp", machines[0]) + require.NoError(t, err) + + ma, err := manet.FromNetAddr(laddr) + require.NoError(t, err) + + var apiToken []byte + { + type jwtPayload struct { + Allow []auth.Permission + } + + p := jwtPayload{ + Allow: api.AllPermissions, + } + + sk, err := base64.StdEncoding.DecodeString(cfg.Apis.StorageRPCSecret) + require.NoError(t, err) + + apiToken, err = jwt.Sign(&p, jwt.NewHS256(sk)) + require.NoError(t, err) + } + + ctoken := fmt.Sprintf("%s:%s", string(apiToken), ma) + err = os.Setenv("CURIO_API_INFO", ctoken) + require.NoError(t, err) + + capi, ccloser, err := rpc.GetCurioAPI(&cli.Context{}) + require.NoError(t, err) + + scfg := storiface.LocalStorageMeta{ + ID: storiface.ID(uuid.New().String()), + Weight: 10, + CanSeal: true, + CanStore: true, + MaxStorage: 0, + Groups: []string{}, + AllowTo: []string{}, + } + + err = capi.StorageInit(ctx, dir, scfg) + require.NoError(t, err) + + err = capi.StorageAddLocal(ctx, dir) + require.NoError(t, err) + + err = capi.LogSetLevel(ctx, "harmonytask", "DEBUG") + + return capi, taskEngine.GracefullyTerminate, ccloser, finishCh +} diff --git a/lib/harmony/harmonydb/sql/20240508-open-deal-sectors.sql b/lib/harmony/harmonydb/sql/20240508-open-deal-sectors.sql index 88c439a19cd..2b1cd78809e 100644 --- a/lib/harmony/harmonydb/sql/20240508-open-deal-sectors.sql +++ b/lib/harmony/harmonydb/sql/20240508-open-deal-sectors.sql @@ -1,5 +1,5 @@ ALTER TABLE sectors_sdr_initial_pieces - ADD COLUMN created_at TIMESTAMP; + ADD COLUMN created_at TIMESTAMP NOT NULL DEFAULT current_timestamp; create table open_sector_pieces ( sp_id bigint not null, @@ -29,7 +29,7 @@ create table open_sector_pieces ( direct_piece_activation_manifest jsonb, -- created_at added in 20240508-open-deal-sectors.sql - created_at timestamp, + created_at timestamp NOT NULL DEFAULT current_timestamp, -- sectors_sdr_initial_pieces table is a copy of this -- all alters should happen on both tables except constraints diff --git a/node/config/doc_gen.go b/node/config/doc_gen.go index c6dbff49dda..7ad4400c6d1 100644 --- a/node/config/doc_gen.go +++ b/node/config/doc_gen.go @@ -326,8 +326,9 @@ DealSector queue is the first queue in the sealing pipeline, meaning that it sho Comment: `Maximum number of sectors that can be queued waiting for SDR to start processing. 0 = unlimited Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. -The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the trees tasks it is -possible that this queue grows more than this limit, the backpressure is only applied to sectors entering the pipeline.`, +The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the SDR tasks it is +possible that this queue grows more than this limit(CC sectors), the backpressure is only applied to sectors +entering the pipeline.`, }, { Name: "MaxQueueTrees", diff --git a/node/config/types.go b/node/config/types.go index b0b690d5c35..c1a569b1fd5 100644 --- a/node/config/types.go +++ b/node/config/types.go @@ -845,8 +845,9 @@ type CurioIngestConfig struct { // Maximum number of sectors that can be queued waiting for SDR to start processing. // 0 = unlimited // Note: This mechanism will delay taking deal data from markets, providing backpressure to the market subsystem. - // The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the trees tasks it is - // possible that this queue grows more than this limit, the backpressure is only applied to sectors entering the pipeline. + // The SDR queue includes deals which are in the process of entering the sealing pipeline. In case of the SDR tasks it is + // possible that this queue grows more than this limit(CC sectors), the backpressure is only applied to sectors + // entering the pipeline. MaxQueueSDR int // Maximum number of sectors that can be queued waiting for SDRTrees to start processing.