From 2277729bad01c1a8311b6907266be481a9fde3f0 Mon Sep 17 00:00:00 2001 From: Arnaud Date: Sun, 2 Nov 2025 16:30:26 +0100 Subject: [PATCH] Add exists in lib --- examples/golang/codex.go | 44 ++++++++++++++++++- .../requests/node_storage_request.nim | 22 +++++++++- library/libcodex.h | 6 +++ library/libcodex.nim | 14 ++++++ 4 files changed, 84 insertions(+), 2 deletions(-) diff --git a/examples/golang/codex.go b/examples/golang/codex.go index 14fc2d6e..cf6f9aa3 100644 --- a/examples/golang/codex.go +++ b/examples/golang/codex.go @@ -109,6 +109,10 @@ package main static int cGoCodexLogLevel(void* codexCtx, char* logLevel, void* resp) { return codex_log_level(codexCtx, logLevel, (CodexCallback) callback, resp); } + + static int cGoCodexExists(void* codexCtx, char* cid, void* resp) { + return codex_storage_exists(codexCtx, cid, (CodexCallback) callback, resp); + } */ import "C" import ( @@ -794,14 +798,33 @@ func (node CodexNode) UpdateLogLevel(logLevel string) error { return err } +func (node CodexNode) Exists(cid string) (bool, error) { + bridge := newBridgeCtx() + defer bridge.free() + + var cCid = C.CString(cid) + defer C.free(unsafe.Pointer(cCid)) + + if C.cGoCodexExists(node.ctx, cCid, bridge.resp) != C.RET_OK { + return false, bridge.callError("cGoCodexUploadCancel") + } + + result, err := bridge.wait() + return result == "true", err +} + func main() { + dataDir := os.TempDir() + "/data-dir" + node, err := New(Config{ BlockRetries: 5, LogLevel: "WARN", + DataDir: dataDir, }) if err != nil { log.Fatalf("Failed to create Codex node: %v", err) } + defer os.RemoveAll(dataDir) if err := node.Start(); err != nil { log.Fatalf("Failed to start Codex node: %v", err) @@ -819,14 +842,33 @@ func main() { log.Fatalf("Failed to update log level: %v", err) } + cid := "zDvZRwzmAkhzDRPH5EW242gJBNZ2T7aoH2v1fVH66FxXL4kSbvyM" + exists, err := node.Exists(cid) + if err != nil { + log.Fatalf("Failed to check data existence: %v", err) + } + + if exists { + log.Fatalf("The data should not exist") + } + buf := bytes.NewBuffer([]byte("Hello World!")) len := buf.Len() - cid, err := node.UploadReader(UploadOptions{Filepath: "hello.txt"}, buf) + cid, err = node.UploadReader(UploadOptions{Filepath: "hello.txt"}, buf) if err != nil { log.Fatalf("Failed to upload data: %v", err) } log.Printf("Uploaded data with CID: %s (size: %d bytes)", cid, len) + exists, err = node.Exists(cid) + if err != nil { + log.Fatalf("Failed to check data existence: %v", err) + } + + if !exists { + log.Fatalf("The data should exist") + } + // Wait for a SIGINT or SIGTERM signal ch := make(chan os.Signal, 1) signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM) diff --git a/library/codex_thread_requests/requests/node_storage_request.nim b/library/codex_thread_requests/requests/node_storage_request.nim index 74d05c4f..d6dafc87 100644 --- a/library/codex_thread_requests/requests/node_storage_request.nim +++ b/library/codex_thread_requests/requests/node_storage_request.nim @@ -19,7 +19,7 @@ import ../../../codex/stores/repostore from ../../../codex/codex import CodexServer, node, repoStore from ../../../codex/node import - iterateManifests, fetchManifest, fetchDatasetAsyncTask, delete + iterateManifests, fetchManifest, fetchDatasetAsyncTask, delete, hasLocalBlock from libp2p import Cid, init, `$` logScope: @@ -30,6 +30,7 @@ type NodeStorageMsgType* = enum DELETE FETCH SPACE + EXISTS type NodeStorageRequest* = object operation: NodeStorageMsgType @@ -125,6 +126,20 @@ proc space( ) return ok(serde.toJson(space)) +proc exists( + codex: ptr CodexServer, cCid: cstring +): Future[Result[string, string]] {.async: (raises: []).} = + let cid = Cid.init($cCid) + if cid.isErr: + return err("Failed to check the data existence: cannot parse cid: " & $cCid) + + try: + let node = codex[].node + let exists = await node.hasLocalBlock(cid.get()) + return ok($exists) + except CancelledError: + return err("Failed to check the data existence: operation cancelled.") + proc process*( self: ptr NodeStorageRequest, codex: ptr CodexServer ): Future[Result[string, string]] {.async: (raises: []).} = @@ -155,4 +170,9 @@ proc process*( if res.isErr: error "Failed to SPACE.", error = res.error return err($res.error) + of NodeStorageMsgType.EXISTS: + let res = (await exists(codex, self.cid)) + if res.isErr: + error "Failed to EXISTS.", error = res.error + return err($res.error) return res diff --git a/library/libcodex.h b/library/libcodex.h index e63c2ad1..bade4c95 100644 --- a/library/libcodex.h +++ b/library/libcodex.h @@ -172,6 +172,12 @@ int codex_storage_fetch( CodexCallback callback, void* userData); +int codex_storage_exists( + void* ctx, + const char* cid, + CodexCallback callback, + void* userData); + int codex_start(void* ctx, CodexCallback callback, void* userData); diff --git a/library/libcodex.nim b/library/libcodex.nim index 6619afeb..d1c7e052 100644 --- a/library/libcodex.nim +++ b/library/libcodex.nim @@ -515,6 +515,20 @@ proc codex_storage_fetch( return callback.okOrError(res, userData) +proc codex_storage_exists( + ctx: ptr CodexContext, cid: cstring, callback: CodexCallback, userData: pointer +): cint {.dynlib, exportc.} = + initializeLibrary() + checkLibcodexParams(ctx, callback, userData) + + let req = NodeStorageRequest.createShared(NodeStorageMsgType.EXISTS, cid = cid) + + let res = codex_context.sendRequestToCodexThread( + ctx, RequestType.STORAGE, req, callback, userData + ) + + return callback.okOrError(res, userData) + proc codex_start( ctx: ptr CodexContext, callback: CodexCallback, userData: pointer ): cint {.dynlib, exportc.} =