diff --git a/pkg/hold/pds/xrpc.go b/pkg/hold/pds/xrpc.go index d441720..ceeb8b9 100644 --- a/pkg/hold/pds/xrpc.go +++ b/pkg/hold/pds/xrpc.go @@ -7,6 +7,8 @@ import ( "net/http" "strings" + "github.com/bluesky-social/indigo/repo" + "github.com/bluesky-social/indigo/util" "github.com/ipfs/go-cid" "github.com/ipld/go-car" carutil "github.com/ipld/go-car/util" @@ -273,21 +275,50 @@ func (h *XRPCHandler) HandleSyncGetRecord(w http.ResponseWriter, r *http.Request return } - // Get the record CID and raw bytes - recordCID, _, err := h.pds.GetCrewMember(r.Context(), rkey) + // Get the current repo head + repoHead, err := h.pds.carstore.GetUserRepoHead(r.Context(), h.pds.uid) + if err != nil { + http.Error(w, fmt.Sprintf("failed to get repo head: %v", err), http.StatusInternalServerError) + return + } + + // Create a new delta session with logging blockstore + tempSession, err := h.pds.carstore.NewDeltaSession(r.Context(), h.pds.uid, nil) + if err != nil { + http.Error(w, fmt.Sprintf("failed to create temp session: %v", err), http.StatusInternalServerError) + return + } + + // Wrap the session's blockstore with a logging blockstore + loggingBS := util.NewLoggingBstore(tempSession) + + // Open the repo with the logging blockstore + tempRepo, err := repo.OpenRepo(r.Context(), loggingBS, repoHead) + if err != nil { + http.Error(w, fmt.Sprintf("failed to open repo: %v", err), http.StatusInternalServerError) + return + } + + // Get the record path + path := fmt.Sprintf("%s/%s", collection, rkey) + + // Get the record (this will log all accessed blocks in the MST path) + recordCID, _, err := tempRepo.GetRecordBytes(r.Context(), path) if err != nil { http.Error(w, fmt.Sprintf("failed to get record: %v", err), http.StatusNotFound) return } - // Get the raw block from the blockstore - blk, err := h.pds.repo.Blockstore().Get(r.Context(), recordCID) - if err != nil { - http.Error(w, fmt.Sprintf("failed to get record block: %v", err), http.StatusInternalServerError) - return + // Get all blocks that were accessed during record retrieval + blocks := loggingBS.GetLoggedBlocks() + + // Log block count for debugging + fmt.Printf("sync.getRecord: Retrieved %d blocks for record at %s/%s\n", len(blocks), collection, rkey) + for i, blk := range blocks { + fmt.Printf(" Block %d: CID=%s, size=%d bytes\n", i+1, blk.Cid().String(), len(blk.RawData())) } - // Write CAR file with the single record + // Write CAR file with all accessed blocks w.Header().Set("Content-Type", "application/vnd.ipld.car") // Create a buffer to write the CAR data @@ -305,10 +336,12 @@ func (h *XRPCHandler) HandleSyncGetRecord(w http.ResponseWriter, r *http.Request return } - // Write the block using LdWrite - if err := carutil.LdWrite(&buf, recordCID.Bytes(), blk.RawData()); err != nil { - http.Error(w, fmt.Sprintf("failed to write block to CAR: %v", err), http.StatusInternalServerError) - return + // Write all logged blocks to the CAR file + for _, blk := range blocks { + if err := carutil.LdWrite(&buf, blk.Cid().Bytes(), blk.RawData()); err != nil { + http.Error(w, fmt.Sprintf("failed to write block to CAR: %v", err), http.StatusInternalServerError) + return + } } // Write the CAR data to the response