Skip to content

Commit a74ac84

Browse files
committed
Add codex library integration
1 parent 0c4d537 commit a74ac84

21 files changed

+420
-934
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,5 @@ coverage*.cov
2121

2222
# Logs
2323
*.log
24+
25+
libs

.vscode/settings.json

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
{
22
"go.testTags": "codex_integration",
33
"gopls": {
4-
"buildFlags": ["-tags=codex_integration"]
4+
"buildFlags": [
5+
"-tags=integration"
6+
]
7+
},
8+
"go.toolsEnvVars": {
9+
"CGO_ENABLED": "1",
10+
"CGO_CFLAGS": "-I${workspaceFolder}/libs",
11+
"CGO_LDFLAGS": "-L${workspaceFolder}/libs -lcodex -Wl,-rpath,${workspaceFolder}/libs"
512
}
6-
}
13+
}

Makefile

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Destination folder for the downloaded libraries
2+
LIBS_DIR := $(abspath ./libs)
3+
4+
# Flags for CGO to find the headers and the shared library
5+
UNAME_S := $(shell uname -s)
6+
CGO_CFLAGS := -I$(LIBS_DIR)
7+
CGO_LDFLAGS := -L$(LIBS_DIR) -lcodex -Wl,-rpath,$(LIBS_DIR)
8+
9+
ifeq ($(OS),Windows_NT)
10+
BIN_NAME := codex-go.exe
11+
else
12+
BIN_NAME := codex-go
13+
endif
14+
15+
# Configuration for fetching the right binary
16+
OS ?= "linux"
17+
ARCH ?= "amd64"
18+
VERSION ?= "v0.0.22"
19+
DOWNLOAD_URL := "https://github.com/codex-storage/codex-go-bindings/releases/download/$(VERSION)/codex-${OS}-${ARCH}.zip"
20+
21+
fetch:
22+
@echo "Fetching libcodex from GitHub Actions from: ${DOWNLOAD_URL}"
23+
curl -fSL --create-dirs -o $(LIBS_DIR)/codex-${OS}-${ARCH}.zip ${DOWNLOAD_URL}
24+
unzip -o -qq $(LIBS_DIR)/codex-${OS}-${ARCH}.zip -d $(LIBS_DIR)
25+
rm -f $(LIBS_DIR)/*.zip
26+
27+
build:
28+
CGO_ENABLED=1 CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" go build -o $(BIN_NAME) main.go
29+
30+
build-upload:
31+
CGO_ENABLED=1 CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" go build -o bin/codex-upload ./cmd/upload
32+
33+
build-download:
34+
CGO_ENABLED=1 CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" go build -o bin/codex-download ./cmd/download
35+
36+
test:
37+
@echo "Running unit tests..."
38+
CGO_ENABLED=1 CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" go test -v ./communities
39+
40+
test-integration:
41+
@echo "Running tests..."
42+
CGO_ENABLED=1 CGO_CFLAGS="$(CGO_CFLAGS)" CGO_LDFLAGS="$(CGO_LDFLAGS)" go test -v -tags=codex_integration ./communities -run Integration -timeout 15s
43+
44+
clean:
45+
rm -f $(BIN_NAME)
46+
rm -Rf $(LIBS_DIR)/*

README.md

Lines changed: 21 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,30 @@ A lightweight Go client utility for interacting with Codex client.
1010

1111
We will be running codex client, and then use a small testing utility to check if the low level abstraction - CodexClient - correctly uploads and downloads the content.
1212

13-
### Running CodexClient
13+
### Integration Codex library
1414

15-
I often remove some logging noise, by slightly changing the build
16-
params in `build.nims` (nim-codex):
15+
You need to download the library file by using:
1716

18-
```nim
19-
task codex, "build codex binary":
20-
buildBinary "codex",
21-
# params = "-d:chronicles_runtime_filtering -d:chronicles_log_level=TRACE"
22-
params =
23-
"-d:chronicles_runtime_filtering -d:chronicles_log_level=TRACE -d:chronicles_enabled_topics:restapi:TRACE,node:TRACE"
24-
```
25-
26-
You see a slightly more selective `params` in the `codex` task.
27-
28-
To run the client I use the following command:
29-
30-
```bash
31-
./build/codex --data-dir=./data-1 --listen-addrs=/ip4/127.0.0.1/tcp/8081 --api-port=8001 --nat=none --disc-port=8091 --log-level=TRACE
17+
```sh
18+
make fetch
3219
```
3320

3421
### Building codex-upload and codex-download utilities
3522

3623
Use the following command to build the `codex-upload` and `codex-download` utilities:
3724

3825
```bash
39-
go build -o bin/codex-upload ./cmd/upload
40-
go build -o bin/codex-download ./cmd/download
26+
make build-upload
27+
make build-download
4128
```
4229
### Uploading content to Codex
4330

4431
Now, using the `codex-upload` utility, we can upload the content to Codex as follows:
4532

4633
```bash
4734
~/code/local/go-codex-client
48-
❯ ./bin/codex-upload -file test-data.bin -host localhost -port 8001
49-
Uploading test-data.bin (43 bytes) to Codex at localhost:8001...
35+
❯ ./bin/codex-upload -file test-data.bin
36+
Uploading test-data.bin (43 bytes) to Codex
5037
✅ Upload successful!
5138
CID: zDvZRwzm8K7bcyPeBXcZzWD7AWc4VqNuseduDr3VsuYA1yXej49V
5239
```
@@ -57,8 +44,8 @@ Now, having the content uploaded to Codex - let's get it back using the `codex-d
5744

5845
```bash
5946
~/code/local/go-codex-client
60-
❯ ./bin/codex-download -cid zDvZRwzm8K7bcyPeBXcZzWD7AWc4VqNuseduDr3VsuYA1yXej49V -file output.bin -host localhost -port 8001
61-
Downloading CID zDvZRwzm8K7bcyPeBXcZzWD7AWc4VqNuseduDr3VsuYA1yXej49V from Codex at localhost:8001...
47+
❯ ./bin/codex-download -cid zDvZRwzm8K7bcyPeBXcZzWD7AWc4VqNuseduDr3VsuYA1yXej49V -file output.bin
48+
Downloading CID zDvZRwzm8K7bcyPeBXcZzWD7AWc4VqNuseduDr3VsuYA1yXej49V from Codex...
6249
✅ Download successful!
6350
Saved to: output.bin
6451
```
@@ -85,115 +72,23 @@ next section.
8572
To run all unit tests:
8673

8774
```bash
88-
❯ go test -v ./communities -count 1
89-
```
90-
91-
To be more selective, e.g. in order to run all the tests from
92-
`CodexArchiveDownloaderSuite`, run:
93-
94-
```bash
95-
go test -v ./communities -run CodexArchiveDownloader -count 1
96-
```
97-
98-
or for an individual test from that suite:
99-
100-
```bash
101-
go test -v ./communities -run TestCodexArchiveDownloaderSuite/TestCancellationDuringPolling -count 1
102-
```
103-
104-
You can also use `gotestsum` to run the tests (you may need to install it first, e.g. `go install gotest.tools/[email protected]`):
105-
106-
```bash
107-
gotestsum --packages="./communities" -f testname --rerun-fails -- -count 1
108-
```
109-
110-
For a more verbose output including logs use `-f standard-verbose`, e.g.:
111-
112-
```bash
113-
gotestsum --packages="./communities" -f standard-verbose --rerun-fails -- -v -count 1
114-
```
115-
116-
To be more selective, e.g. in order to run all the tests from
117-
`CodexArchiveDownloaderSuite`, run:
118-
119-
```bash
120-
gotestsum --packages="./communities" -f testname --rerun-fails -- -run CodexArchiveDownloader -count 1
121-
```
122-
123-
or for an individual test from that suite:
124-
125-
```bash
126-
gotestsum --packages="./communities" -f testname --rerun-fails -- -run TestCodexArchiveDownloaderSuite/TestCancellationDuringPolling -count 1
127-
```
128-
129-
Notice, that the `-run` flag accepts a regular expression that matches against the full test path, so you can be more concise in naming if necessary, e.g.:
130-
131-
```bash
132-
gotestsum --packages="./communities" -f testname --rerun-fails -- -run CodexArchiveDownloader/Cancellation -count 1
133-
```
134-
135-
This also applies to native `go test` command.
136-
137-
### Running integration tests
138-
139-
When building Codex client for testing like here, I often remove some logging noise, by slightly changing the build params in `build.nims`:
140-
141-
```nim
142-
task codex, "build codex binary":
143-
buildBinary "codex",
144-
# params = "-d:chronicles_runtime_filtering -d:chronicles_log_level=TRACE"
145-
params =
146-
"-d:chronicles_runtime_filtering -d:chronicles_log_level=TRACE -d:chronicles_enabled_topics:restapi:TRACE,node:TRACE"
147-
```
148-
149-
You see a slightly more selective `params` in the `codex` task.
150-
151-
To start Codex client, use e.g.:
152-
153-
```bash
154-
./build/codex --data-dir=./data-1 --listen-addrs=/ip4/127.0.0.1/tcp/8081 --api-port=8001 --nat=none --disc-port=8091 --log-level=TRACE
155-
```
156-
157-
To run the integration test, use `codex_integration` tag and narrow the scope using `-run Integration`:
158-
159-
```bash
160-
CODEX_API_PORT=8001 go test -v -tags=codex_integration ./communities -run Integration -timeout 15s
161-
```
162-
163-
This will run all integration tests, including CodexClient integration tests.
164-
165-
To make sure that the test is actually run and not cached, use `count` option:
166-
167-
```bash
168-
CODEX_API_PORT=8001 go test -v -tags=codex_integration ./communities -run Integration -timeout 15s -count 1
169-
```
170-
171-
To be more specific and only run the tests related to, e.g. index downloader or archive
172-
downloader you can use:
173-
174-
```bash
175-
CODEX_API_PORT=8001 go test -v -tags=codex_integration ./communities -run CodexIndexDownloaderIntegration -timeout 15s -count 1
176-
177-
CODEX_API_PORT=8001 go test -v -tags=codex_integration ./communities -run CodexArchiveDownloaderIntegration -timeout 15s -count 1
178-
```
179-
180-
and then, if you prefer to use `gotestsum`:
181-
182-
```bash
183-
CODEX_API_PORT=8001 gotestsum --packages="./communities" -f standard-verbose --rerun-fails -- -tags=codex_integration -run CodexIndexDownloaderIntegration -v -count 1
184-
185-
CODEX_API_PORT=8001 gotestsum --packages="./communities" -f standard-verbose --rerun-fails -- -tags=codex_integration -run CodexArchiveDownloaderIntegration -v -count 1
75+
❯ make test
76+
=== RUN TestUpload_Success
77+
--- PASS: TestUpload_Success (0.00s)
78+
=== RUN TestDownload_Success
79+
--- PASS: TestDownload_Success (0.00s)
80+
=== RUN TestDownloadWithContext_Cancel
81+
--- PASS: TestDownloadWithContext_Cancel (0.04s)
82+
PASS
83+
ok go-codex-client/communities 0.044s
18684
```
18785

188-
or to run all integration tests (including CodexClient integration tests):
86+
To run the integration test, use `test-integration`:
18987

19088
```bash
191-
CODEX_API_PORT=8001 gotestsum --packages="./communities" -f standard-verbose --rerun-fails -- -tags=codex_integration -v -count 1 -run Integration
89+
make test-integration
19290
```
19391

194-
I prefer to be more selective when running integration tests.
195-
196-
19792
### Regenerating artifacts
19893

19994
Everything you need comes included in the repo. But if you decide to change things,

cmd/download/main.go

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ import (
55
"fmt"
66
"log"
77
"os"
8+
"path"
89

910
"go-codex-client/communities" // Import the local communities package
11+
12+
"github.com/codex-storage/codex-go-bindings/codex"
1013
)
1114

1215
func main() {
1316
var (
14-
host = flag.String("host", "localhost", "Codex host")
15-
port = flag.String("port", "8080", "Codex port")
1617
cid = flag.String("cid", "", "CID of the file to download")
1718
file = flag.String("file", "downloaded-file.bin", "File to save the downloaded data")
1819
)
@@ -24,7 +25,20 @@ func main() {
2425
}
2526

2627
// Create Codex client
27-
client := communities.NewCodexClient(*host, *port)
28+
client, err := communities.NewCodexClient(codex.Config{
29+
LogFormat: codex.LogFormatNoColors,
30+
MetricsEnabled: false,
31+
BlockRetries: 5,
32+
LogLevel: "ERROR",
33+
DataDir: path.Join(os.TempDir(), "codex-client-data"),
34+
})
35+
if err != nil {
36+
log.Fatalf("Failed to create CodexClient: %v", err)
37+
}
38+
39+
if err := client.Start(); err != nil {
40+
log.Fatalf("Failed to start CodexClient: %v", err)
41+
}
2842

2943
// Create output file
3044
outputFile, err := os.Create(*file)
@@ -33,8 +47,6 @@ func main() {
3347
}
3448
defer outputFile.Close()
3549

36-
fmt.Printf("Downloading CID %s from Codex at %s:%s...\n", *cid, *host, *port)
37-
3850
// Download data - pass the io.Writer (outputFile), not the string
3951
err = client.Download(*cid, outputFile)
4052
if err != nil {
@@ -43,6 +55,13 @@ func main() {
4355
log.Fatalf("Download failed: %v", err)
4456
}
4557

58+
if err := client.Stop(); err != nil {
59+
log.Printf("Warning: Failed to stop CodexClient: %v", err)
60+
}
61+
if err := client.Destroy(); err != nil {
62+
log.Printf("Warning: Failed to stop CodexClient: %v", err)
63+
}
64+
4665
fmt.Printf("✅ Download successful!\n")
4766
fmt.Printf("Saved to: %s\n", *file)
4867
}

cmd/upload/main.go

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@ import (
66
"fmt"
77
"log"
88
"os"
9+
"path"
910

1011
"go-codex-client/communities" // Import the local communities package
12+
13+
"github.com/codex-storage/codex-go-bindings/codex"
1114
)
1215

1316
func main() {
1417
var (
15-
host = flag.String("host", "localhost", "Codex host")
16-
port = flag.String("port", "8080", "Codex port")
1718
file = flag.String("file", "test-data.bin", "File to upload")
1819
filename = flag.String("name", "", "Filename to use in upload (defaults to actual filename)")
1920
)
@@ -31,15 +32,35 @@ func main() {
3132
uploadName = *file
3233
}
3334

34-
fmt.Printf("Uploading %s (%d bytes) to Codex at %s:%s...\n", *file, len(data), *host, *port)
35+
fmt.Printf("Uploading %s (%d bytes) to Codex...\n", *file, len(data))
3536
// Create Codex client and upload
36-
client := communities.NewCodexClient(*host, *port)
37+
client, err := communities.NewCodexClient(codex.Config{
38+
LogFormat: codex.LogFormatNoColors,
39+
MetricsEnabled: false,
40+
BlockRetries: 5,
41+
LogLevel: "ERROR",
42+
DataDir: path.Join(os.TempDir(), "codex-client-data"),
43+
})
44+
if err != nil {
45+
log.Fatalf("Failed to create CodexClient: %v", err)
46+
}
47+
48+
if err := client.Start(); err != nil {
49+
log.Fatalf("Failed to start CodexClient: %v", err)
50+
}
3751

3852
cid, err := client.Upload(bytes.NewReader(data), uploadName)
3953
if err != nil {
4054
log.Fatalf("Upload failed: %v", err)
4155
}
4256

57+
if err := client.Stop(); err != nil {
58+
log.Printf("Warning: Failed to stop CodexClient: %v", err)
59+
}
60+
if err := client.Destroy(); err != nil {
61+
log.Printf("Warning: Failed to stop CodexClient: %v", err)
62+
}
63+
4364
fmt.Printf("✅ Upload successful!\n")
4465
fmt.Printf("CID: %s\n", cid)
4566
}

communities/codex_archive_downloader.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,8 @@ func (d *CodexArchiveDownloader) triggerSingleArchiveDownload(hash, cid string,
316316
return fmt.Errorf("failed to trigger archive download with CID %s: %w", cid, err)
317317
}
318318

319-
if manifest.CID != cid {
320-
return fmt.Errorf("unexpected manifest CID %s, expected %s", manifest.CID, cid)
319+
if manifest.Cid != cid {
320+
return fmt.Errorf("unexpected manifest CID %s, expected %s", manifest.Cid, cid)
321321
}
322322

323323
return nil

0 commit comments

Comments
 (0)