From e96bf2925dcfcf4cd3b95e0198803d7bb0d5a69f Mon Sep 17 00:00:00 2001 From: TippyFlits Date: Fri, 14 Aug 2026 15:23:51 +0000 Subject: [PATCH] pdp: serve long-term parked pieces with no deal or pdp ref from the cached reader Migration aggregates are parked long_term with no pdp ref until claimed; the cached reader returned ErrNoDeal for them, 404ing retrievals of complete parked pieces. Fall back to parked_pieces (long_term AND complete) via the piece park reader when no market deal and no pdp ref exists. ErrNoDeal behaviour is unchanged when the fallback finds nothing. --- lib/cachedreader/cachedreader.go | 34 +++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/lib/cachedreader/cachedreader.go b/lib/cachedreader/cachedreader.go index 2cbddbcf7..bb8975307 100644 --- a/lib/cachedreader/cachedreader.go +++ b/lib/cachedreader/cachedreader.go @@ -234,7 +234,11 @@ func (cpr *CachedPieceReader) getPieceReaderFromMarketPieceDeal(ctx context.Cont return nil, 0, fmt.Errorf("failed to query pdp_piecerefs for piece cid %s: %w", pieceCid, err) } if !isPDP { - return nil, 0, fmt.Errorf("piece cid %s: %w", pieceCid, ErrNoDeal) + reader, rawSize, err := cpr.getPieceReaderFromLongTermPark(ctx, pieceCid) + if err != nil { + return nil, 0, fmt.Errorf("piece cid %s: %w", pieceCid, ErrNoDeal) + } + return reader, rawSize, nil } } reader, rawSize, err := cpr.getPieceReaderFromPiecePark(ctx, nil, &pieceCid, &pieceSize) @@ -355,6 +359,34 @@ func (cpr *CachedPieceReader) getPieceReaderFromPiecePark(ctx context.Context, p return reader, uint64(pd[0].PieceRawSize), nil } +func (cpr *CachedPieceReader) getPieceReaderFromLongTermPark(ctx context.Context, pieceCid cid.Cid) (storiface.Reader, uint64, error) { + var pd []struct { + ID int64 `db:"id"` + PieceCid string `db:"piece_cid"` + PieceRawSize int64 `db:"piece_raw_size"` + } + + err := cpr.db.Select(ctx, &pd, `SELECT + id, + piece_cid, + piece_raw_size + FROM parked_pieces WHERE piece_cid = $1 AND long_term = TRUE AND complete = TRUE;`, pieceCid.String()) + if err != nil { + return nil, 0, fmt.Errorf("failed to query parked_pieces for piece cid %s: %w", pieceCid, err) + } + + if len(pd) == 0 { + return nil, 0, fmt.Errorf("failed to find long-term complete piece in parked_pieces for piece cid %s", pieceCid) + } + + reader, err := cpr.pieceParkReader.ReadPiece(ctx, storiface.PieceNumber(pd[0].ID), pd[0].PieceRawSize, pieceCid) + if err != nil { + return nil, 0, fmt.Errorf("failed to read piece from piece park: %w", err) + } + + return reader, uint64(pd[0].PieceRawSize), nil +} + type SubPieceReader struct { sr *io.SectionReader r io.Closer