logos-delivery/library/liblogosdelivery_kernel.h
Ivan FB 7080a629da
feat: migrate the FFI layer to nim-ffi 0.2.0
nim-ffi 0.2.0 reshapes the authoring model: `.ffi.` procs take the
library value plus typed params instead of threading (ctx, callback,
userData) by hand, the macro validates the context itself, and payloads
ride the wire as CBOR rather than ad-hoc JSON strings. The old idiom no
longer compiles against it, so the whole surface moves at once.

Proc names are camelCase chosen so the generated snake_case export
matches the previous C symbol exactly (wakuRelayPublish ->
waku_relay_publish), keeping the ABI names stable.

Node lifecycle now uses the dedicated pragmas: `.ffiCtor.` for
create_node (LogosDelivery.new already returns the Future[Result[...]]
the contract wants) and `.ffiDtor.` for destroy. Contexts come from the
macro-emitted FFIContextPool, which caps live contexts at 32.

Events become typed `.ffiEvent.` procs over `.ffi.` payload objects. The
payloads carry wire-friendly scalars rather than the domain types, which
are not serialisable; byte fields stay base64. This is what makes the
generated bindings emit typed listeners instead of leaving consumers to
register by name and parse JSON themselves.

The payload fields are deliberately unexported. genBindings copies field
names verbatim, so an export marker leaks into the generated Rust as
`pub payload*: String` and the file does not parse -- a nim-ffi bug (it
strips the marker from type names but not fields, so its single-file
examples never hit it). Construction therefore lives behind the emit*
procs in declare_lib, which also keeps event emission in one place and
collapses each listener body to a single call.

`requireInitializedNode` is gone: the macro rejects a null/invalid ctx
before the handler runs, so all 14 call sites were redundant.

Relay and filter push handlers are declared `raises: [Defect]`, so the
emit call is wrapped explicitly -- the dispatch path no longer guards
the body for us.

genBindings() emits the C/C++/Rust bindings and must stay last in the
compilation root; it is a no-op without -d:ffiGenBindings. The Rust
output is checked in so consumers can vendor it directly.

Known gaps, tracked separately: the hand-written liblogosdelivery.h /
_kernel.h still declare the pre-CBOR signatures and need generating or
dropping, and nimble resolves cbor_serialization 0.4.0 while the lock
and nim-ffi both pin 0.3.0.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-16 00:55:59 +02:00

242 lines
9.1 KiB
C

// liblogosdelivery_kernel.h — Kernel / advanced API (low-level, per-protocol).
//
// ⚠️ USE AT YOUR OWN RISK — UNSUPPORTED, UNSTABLE SURFACE.
//
// These `waku_*` functions are the low-level kernel API. They are NOT part of
// the stable, supported Messaging / Reliable Channels surface declared in
// liblogosdelivery.h. They expose per-protocol internals (relay, filter,
// lightpush, store, discovery, peer management) and may change or be removed
// at ANY time, without notice or a deprecation cycle.
//
// Including this header is a deliberate opt-in into the advanced tier. If you
// only need messaging, include liblogosdelivery.h and nothing here.
//
// See https://github.com/logos-messaging/logos-delivery/issues/3851 for the
// tiering rationale.
#pragma once
#ifndef __liblogosdelivery_kernel__
#define __liblogosdelivery_kernel__
// Shared FFICallBack typedef and RET_* return codes live in the stable header.
#include "liblogosdelivery.h"
#ifdef __cplusplus
extern "C"
{
#endif
// NOTE: node lifecycle (create / start / stop / destroy) is unified and lives
// only in the stable header. Use logosdelivery_create_node,
// logosdelivery_start_node, logosdelivery_stop_node and logosdelivery_destroy
// (declared in liblogosdelivery.h, included above) regardless of whether you
// drive the node through the messaging surface or this kernel API.
int waku_version(void *ctx,
FFICallBack callback,
void *userData);
// NOTE: event listeners are registered via logosdelivery_add_event_listener
// (declared above) which the waku_* API shares.
int waku_content_topic(void *ctx,
FFICallBack callback,
void *userData,
const char *appName,
unsigned int appVersion,
const char *contentTopicName,
const char *encoding);
int waku_pubsub_topic(void *ctx,
FFICallBack callback,
void *userData,
const char *topicName);
int waku_default_pubsub_topic(void *ctx,
FFICallBack callback,
void *userData);
int waku_relay_publish(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic,
const char *jsonWakuMessage,
unsigned int timeoutMs);
int waku_lightpush_publish(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic,
const char *jsonWakuMessage);
int waku_relay_subscribe(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic);
int waku_relay_add_protected_shard(void *ctx,
FFICallBack callback,
void *userData,
int clusterId,
int shardId,
char *publicKey);
int waku_relay_unsubscribe(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic);
int waku_filter_subscribe(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic,
const char *contentTopics);
int waku_filter_unsubscribe(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic,
const char *contentTopics);
int waku_filter_unsubscribe_all(void *ctx,
FFICallBack callback,
void *userData);
int waku_relay_get_num_connected_peers(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic);
int waku_relay_get_connected_peers(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic);
int waku_relay_get_num_peers_in_mesh(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic);
int waku_relay_get_peers_in_mesh(void *ctx,
FFICallBack callback,
void *userData,
const char *pubSubTopic);
int waku_store_query(void *ctx,
FFICallBack callback,
void *userData,
const char *jsonQuery,
const char *peerAddr,
int timeoutMs);
int waku_connect(void *ctx,
FFICallBack callback,
void *userData,
const char *peerMultiAddr,
unsigned int timeoutMs);
int waku_disconnect_peer_by_id(void *ctx,
FFICallBack callback,
void *userData,
const char *peerId);
int waku_disconnect_all_peers(void *ctx,
FFICallBack callback,
void *userData);
int waku_dial_peer(void *ctx,
FFICallBack callback,
void *userData,
const char *peerMultiAddr,
const char *protocol,
int timeoutMs);
int waku_dial_peer_by_id(void *ctx,
FFICallBack callback,
void *userData,
const char *peerId,
const char *protocol,
int timeoutMs);
int waku_get_peerids_from_peerstore(void *ctx,
FFICallBack callback,
void *userData);
int waku_get_connected_peers_info(void *ctx,
FFICallBack callback,
void *userData);
int waku_get_peerids_by_protocol(void *ctx,
FFICallBack callback,
void *userData,
const char *protocol);
int waku_listen_addresses(void *ctx,
FFICallBack callback,
void *userData);
int waku_get_connected_peers(void *ctx,
FFICallBack callback,
void *userData);
// Returns a list of multiaddress given a url to a DNS discoverable ENR tree
// Parameters
// char* entTreeUrl: URL containing a discoverable ENR tree
// char* nameDnsServer: The nameserver to resolve the ENR tree url.
// int timeoutMs: Timeout value in milliseconds to execute the call.
int waku_dns_discovery(void *ctx,
FFICallBack callback,
void *userData,
const char *entTreeUrl,
const char *nameDnsServer,
int timeoutMs);
// Updates the bootnode list used for discovering new peers via DiscoveryV5
// bootnodes - JSON array containing the bootnode ENRs i.e. `["enr:...", "enr:..."]`
int waku_discv5_update_bootnodes(void *ctx,
FFICallBack callback,
void *userData,
char *bootnodes);
int waku_start_discv5(void *ctx,
FFICallBack callback,
void *userData);
int waku_stop_discv5(void *ctx,
FFICallBack callback,
void *userData);
// Retrieves the ENR information
int waku_get_my_enr(void *ctx,
FFICallBack callback,
void *userData);
int waku_get_my_peerid(void *ctx,
FFICallBack callback,
void *userData);
int waku_get_metrics(void *ctx,
FFICallBack callback,
void *userData);
int waku_peer_exchange_request(void *ctx,
FFICallBack callback,
void *userData,
int numPeers);
int waku_ping_peer(void *ctx,
FFICallBack callback,
void *userData,
const char *peerAddr,
int timeoutMs);
int waku_is_online(void *ctx,
FFICallBack callback,
void *userData);
#ifdef __cplusplus
}
#endif
#endif /* __liblogosdelivery_kernel__ */