mirror of
https://github.com/logos-messaging/logos-messaging-go-bindings.git
synced 2026-08-26 10:21:12 +00:00
fix/kernel-wire-decoding
8
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
e42d217c59 |
refactor: kernel.Node owns the node, MessagingClient exposes it (#122)
* refactor: make kernel.Node the single owner of the node context The Kernel API and the Messaging API each built their own node and kept the FFI handle private, so a MessagingClient had no way to reach store queries, peers or metrics. The C library has one context serving both tiers, so this was only a Go ownership problem. kernel.Node now owns that context, and the kernel protocols hang off it as facades: Relay(), Store(), Peers(), Discovery(), plus Messaging() for the stable tier. MessagingClient drives a Node and hands it over with Node(), mirroring the Nim MessagingClient's public waku field. * refactor: address review on the Node facades Move the Messaging API back out of pkg/kernel: ffi.Handle becomes a defined type in the internal package, so kernel can hand the context to pkg/messaging through kernel.Handle without the kernel layer knowing the tier exists, and without the type being nameable outside this module. Split Discovery into DiscV5, PeerExchange and DNSDiscovery, group the node's identity and health under Debug(), and give every facade a pointer receiver. Drop the node name, the per-operation logging that duplicates what the library already writes, and GetFreePortIfNeeded — port 0 already means "let the OS pick". Heavy kernel tests now mark themselves with requiresNode and skip under -short, so the gate runs `go test -short ./...` instead of naming tests in a regexp. * refactor: keep the Messaging API where it was Restore messaging_client.go to its shape before this PR: Subscribe, Unsubscribe and Send go back on MessagingClient, and the package imports internal/ffi for the handle rather than reaching the calls through the kernel. The only change left is what owning a kernel.Node requires — the node holds the lifecycle and the listeners, and Node() exposes it. * fix: keep allocating test ports, and move that out of the library Removing GetFreePortIfNeeded also removed the allocation StartWakuNode did, and the library does not treat a zero DiscV5 UDP port as "pick one": every node tried the same default and all but the first failed to bind. StartWakuNode is test scaffolding, so it moves to the test helpers along with the port allocation. Neither is part of the package surface now. * chore: go mod tidy * refactor: let the library pick the ports, and address review TcpPort and Discv5UdpPort were `omitempty`, so a zero port was dropped from the JSON entirely and the library applied its own default of 9000 — every node bound the same port and all but the first failed. With the zero emitted, the library's auto-port retry picks a free one per node, which is what "port 0 means port 0" needs to work. The test-side port allocation is gone with it. Also: Handle moves to its own file with a Valid method and the reasoning for not aliasing unsafe.Pointer, logInfo is back alongside the other levels, and the single-field facade structs are spelled out. |
||
|
|
c2abe77f6b | ci: run the PR gate on stacked pull requests too | ||
|
|
e43988b44c |
fix: decode the kernel wire shapes the library actually sends
Three bugs the kernel suite never caught, because CI only compiles it. A peer's addresses were comma-joined into one argument, but the library inits that argument as a single multiaddress, so StoreQuery and PingPeer failed against any peer advertising more than one address. StoreQueryResponse could decode neither the Opt[T] wrapper objects the library renders results.Opt as, nor the integer arrays it renders seq[byte] as, so every store reply failed to unmarshal. Both shapes now decode, and the bare value still does. A context without a deadline sent timeoutMs=0, which chronos' withTimeout expires on immediately rather than treating as unbounded. StoreQuery with context.Background() could never have succeeded. |
||
|
|
f6a63576f4 |
feat: define the bindings as a Nimble package (#121)
Consumers resolve liblogosdelivery at the revision these bindings were written against, instead of pinning it themselves, and build it through the task here rather than reimplementing logos-delivery's flags. srcDir points at an empty directory, so nothing is contributed to a dependent's Nim path. |
||
|
|
7b138bf71f |
feat: Messaging API (MessagingClient) (#120)
* feat(messaging): object-oriented Go mirror of the Nim MessagingClient
Adds pkg/messaging: a high-level, idiomatic Go binding for the Messaging
API, mirroring logos-delivery's Nim MessagingClient. A MessagingClient owns
a node and carries the messaging surface as methods on it — New / Start /
Stop / Close, Subscribe / Unsubscribe, Send(ctx, Envelope) (RequestID,
error) — over internal/ffi rather than exposing the raw FFI.
Events arrive on a single Events() <-chan Event with a sealed Event
interface: MessageReceivedEvent, MessageSentEvent, MessagePropagatedEvent,
MessageErrorEvent and ConnectionStatusEvent. Delivery never blocks the
library's event thread; an event is dropped when a consumer falls behind.
Config marshals to the layered configuration JSON (mode / preset /
messagingOverrides / channelsOverrides), with every field omitempty so it
can never be mistaken for the legacy flat blob.
Migrating internal/ffi to the current C ABI comes with it, because the
generated surface has moved on since the bridge was written and no longer
compiles: nim-ffi now generates the header from the {.ffi.} annotations,
argument-taking calls pass a per-call <Name>Req struct and a typed
<Name>ReplyFn, no-argument calls take a raw scalar callback, destroy is
synchronous, and the single set_event_callback has been replaced by a
per-event listener registry. The bridge now also copies every callback
string while it is still borrowed, and ignores the non-terminal
STALE_WARN progress code instead of settling the call on it.
pkg/kernel follows the same listener change, registering the three kernel
events it already consumed.
Verified against a liblogosdelivery built from logos-delivery master:
build / vet / golangci-lint / go mod tidy clean, unit tests green, and the
tagged integration test does a full create-start-subscribe-send round trip
on logos.dev, observing the message back and its propagation confirmation.
Closes #119.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CnzdnSMtHM5aLHLtDGBGR9
* review: address feedback on the MessagingClient API
- Send takes contentTopic / payload / ephemeral directly instead of an
Envelope struct, which drops the Envelope type; ContentTopic and RequestID
move to types.go.
- messagingEvents becomes a function returning the slice, so the set cannot
be mutated by accident.
- Document what seals the Event interface and what that buys callers.
- Document why the received payload is decoded from a JSON integer array:
base64 is only used on the send path and by the channel events, not by the
messaging events.
* ci: stop golangci-lint's config verify from failing on a network timeout
golangci-lint-action runs `golangci-lint config verify` before linting, which
fetches the v2.4 JSON schema from golangci-lint.run on every run. That request
timed out on the runner and failed the gate with no lint finding behind it. An
invalid config still fails the lint run itself, so the pre-check only costs a
network dependency.
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
97b7601c41 |
refactor: build against the single liblogosdelivery library (#116)
* refactor: build against the single liblogosdelivery library logos-delivery#4012 unifies the node lifecycle on logosdelivery_* and ships the full API — Messaging, Reliable Channels, and the low-level Kernel (waku_*) tier — in one liblogosdelivery library, retiring the separate libwaku. Migrate the bindings onto it. - internal/ffi: collapse the two bridges into one internal/ffi/liblogosdelivery over the single library. The kernel wrappers keep calling waku_* (kernel header), the lifecycle now uses logosdelivery_create_node/start_node/ stop_node/destroy (waku_new/start/stop/destroy are gone), events use logosdelivery_set_event_callback. Include liblogosdelivery_kernel.h (which re-exports the stable header) and link -llogosdelivery. Remove internal/ffi/libwaku. - pkg/kernel: repoint at internal/ffi/liblogosdelivery; the Makefile links -llogosdelivery. - CI: build only `make liblogosdelivery`, headers from library/, single -llogosdelivery. Pinned to logos-delivery#4012 until it merges (see the TODO/LOGOS_DELIVERY_REF in pr.yml). The high-level MessagingClient (pkg/messaging) lands in a follow-up PR on top. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(kernel): drop removed config keys + add a runnable example Running against the single liblogosdelivery library surfaced a config drift: the consolidated WakuNodeConf strictly rejects unknown keys, and common.WakuConfig still emitted `legacyStore` (removed upstream, and sent unconditionally) and `host` (renamed to `listenAddress`). That failed node creation, so every kernel test that starts a node failed. Reconcile the config: - drop the LegacyStore field (and its two obsolete test references; the already-skipped TestCheckLegacyStore keeps compiling); - map Host to the `listenAddress` JSON key. Add examples/kernel: a small runnable check that drives the unified lifecycle (logosdelivery_create_node/start/stop/destroy) and a few kernel ops (version, listen addresses, is-online, relay subscribe/unsubscribe) over the single library. `go run ./examples/kernel` prints OK. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(kernel): correct RelayPublish wire format; verify send/receive RelayPublish marshalled the generated protobuf (content_topic), but the library requires the WakuMessage wire format (contentTopic) and rejected it with "Missing required field: contentTopic". Marshal the wire shape explicitly. Turn examples/kernel into an end-to-end send/receive check: two relay nodes on cluster 16 / shard 64, connected via the listen multiaddr, one publishes and the other receives it off MsgChan. Verified against a locally-built liblogosdelivery: prints "send/receive OK". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: build against logos-delivery master (unpin #4012) logos-delivery#4012 merged, so drop the LOGOS_DELIVERY_REF pin and clone the default branch; the cache key tracks master's HEAD again. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(ffi): flatten internal/ffi/liblogosdelivery into internal/ffi With a single library there is no bridge to choose between, so the extra subpackage adds nothing: move the bridge to internal/ffi (package ffi) and drop the umbrella doc. pkg/kernel now imports internal/ffi and calls ffi.*. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * test(kernel): add a two-node relay send/receive integration test TestRelaySendReceive connects two relay nodes, publishes a random payload from one and requires the other to receive it — end-to-end over the single library. Compiled by the PR gate; run under `make test` / locally against a built liblogosdelivery. (Replaces the former examples/kernel, removed alongside the ffi flatten.) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(ffi): keep two files in package ffi, one per header The single library still ships two headers — liblogosdelivery.h (stable Messaging/lifecycle) and liblogosdelivery_kernel.h (low-level waku_*). Mirror that with two files in one package instead of one merged ffi.go: keep the messaging bridge and all the shared plumbing (Handle/RetOK/lifecycle/callbacks/ call) in liblogosdelivery.go, and keep the kernel wrappers in libwaku.go, which reuses the shared call + logosGoCallback. This is the same two files we had, moved into package ffi — a much smaller diff than the merge. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Apply suggestions from code review Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com> |
||
|
|
5da314e0f7 |
feat: add liblogosdelivery cgo bridge (internal/ffi/liblogosdelivery) (#113)
Add internal/ffi/liblogosdelivery, the cgo bridge over liblogosdelivery (Messaging API), mirroring the libwaku subpackage from #114: synchronous request/response plumbing, a shared async event callback, and a handle->handler registry, exposing Go-typed primitives (New/Start/Stop/Destroy, Subscribe/Unsubscribe/Send, SetEventHandler, Handle, RetOK, EventHandler). It self-links liblogosdelivery via a #cgo directive. For symmetry — and so the two bridges never need a shared global -l flag — add the same #cgo LDFLAGS: -lwaku to the libwaku subpackage. Each subpackage now links exactly its own library; no binary links both (until logos-delivery#3851). Extend the PR gate to build liblogosdelivery, set CGO_CFLAGS for both headers with no -l (each package self-links), run the messaging unit tests, and compile the kernel tests. Part of #106. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
0a84f0fb7b |
ci: add PR-gate workflow + fix module path (#109)
* chore: rename module path to logos-delivery-go-bindings The module path still read `logos-messaging-go-bindings`, mismatching the repository name. Rename it to `github.com/logos-messaging/logos-delivery-go-bindings` and update all in-repo imports. gofmt re-sorts a few import blocks as a result (plus two files that were already unformatted on master). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: add PR-gate workflow and golangci-lint config The repo had no `on: pull_request` CI (only workflow_dispatch + nightly schedule), so nothing validated PRs. Add `.github/workflows/pr.yml` that builds libwaku and runs `go build`, `go vet`, golangci-lint, and a test-compile pass on every PR. Add a baseline `.golangci.yml` (standard linters + gofmt). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: scope golangci-lint to new code via new-from-merge-base Run the full `standard` linter set but only report findings introduced since the merge-base with master, so the legacy kernel wrapper's pre-existing issues (unchecked defer-Close, dead helpers) don't drown the gate while new code still gets full coverage. Fetch origin/master so the base ref is available in CI. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: clone logos-delivery outside vendor/ and build in module mode `go build` failed in CI because cloning logos-delivery into `vendor/` put Go into vendor mode against an inconsistent `vendor/modules.txt`. Clone the checkout into `.logos-delivery` instead and set `GOFLAGS=-mod=mod` so the gate always builds in module mode. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: use golangci-lint-action@v7 for golangci-lint v2 v6 of the action rejects golangci-lint v2 versions ("v2 is not supported by golangci-lint-action v6"). Bump to v7. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: cache libwaku, gate go mod tidy, rename LMN_DIR - Rename LMN_DIR -> LOGOS_DELIVERY_DIR across the PR-gate and nightly workflows, the waku Makefile, and the build docs. - Cache the built logos-delivery kernel keyed on its upstream HEAD SHA, skipping the clone + libwaku build while that commit is unchanged. - Add a "go mod tidy is clean" step that fails if go.mod/go.sum drift. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |