feat: DISABLE_RLN builds the library without zerokit (#4138)

* feat: let Nimble dependents build liblogosdelivery

Nimble installs only a package's namesake directory, so a dependent got
logos_delivery/ alone: enough to compile Nim against this package, not
enough to build the C library, whose entry point and headers live in
library/. installDirs ships that, and migrations/, which the postgres
driver reaches by relative import.

The build recipe moves into library/build_lib.nims so it ships too, and a
dependent builds the library the same way we do instead of copying a flag
list. buildLibrary now delegates to it.

The move is behaviour-preserving: buildLibrary's `params` was never
referenced by either exec string, so the chronicles and warning flags the
platform tasks pass have always been discarded, and they still are.
Making them honest would move shipped artifacts from INFO to TRACE
logging, which is a separate decision.

cBindingsDir is derived from the library directory rather than the cwd,
so the generated header lands beside the liblogosdelivery.h that includes
it wherever the package is checked out.

Needed by status-go, which consumes logos-delivery through Nimble
(status-im/status-app#19907, logos-messaging/pm#380).

* feat: let Nimble dependents build liblogosdelivery

Nimble installs only a package's namesake directory, so a dependent
received logos_delivery/ alone: enough to compile Nim against this
package, not enough to build the C library, whose entry point and headers
live in library/. tools/ is needed too, because logos_delivery imports
tools/confutils.

The single host-platform task saves every consumer dispatching on the OS
itself; the per-platform tasks stay for callers that want a specific one.

* feat: DISABLE_RLN builds the library without zerokit

RLN was not optional: 41 foreign functions are declared with importc and
no dynlib, so they must resolve at link time even where RLN is never
used, dragging in zerokit, cargo and the submodule.

Guarding the twenty modules that reach for rln with `when` would leave
one side uncompiled and rotting. This compiles link-time stand-ins for
exactly those 41 symbols instead: one conditional file, both
configurations building the same Nim.

A config that enables RLN on such a build is rejected by setupProtocols
through the normal constructor error path, so the stubs are unreachable
tripwires rather than the failure mode. Without that check a documented
preset — twn sets rlnRelay: true — reached them and aborted the host
process with no error callback.

config.nims stops force-linking rln.lib on Windows, where the switch was
unconditional and handed the linker a library that was never built.

The define is scoped to the liblogosdelivery target, so
`make DISABLE_RLN=true all` cannot compile the stubs into wakunode2,
which still links the real librln.

Verified on linux: no librln in ldd, all 41 symbols defined by the stubs
and none left undefined, the 16 logosdelivery_* and 37 waku_* entry
points intact, and no cargo invocation. status-go links and starts a node
against it, and a twn (RLN-enabled) config fails with
"the configuration enables RLN relay, but this build has -d:disable_rln".
This commit is contained in:
Igor Sirotin
2026-08-23 16:38:08 +01:00
committed by GitHub
parent 4a45d22e9e
commit 65efb24fa9
5 changed files with 81 additions and 2 deletions
+13 -1
View File
@@ -454,7 +454,19 @@ endif
# Windows: build with nim directly (see wakunode2) — `nimble <task>` re-clones
# git deps every build and they intermittently hang on the MSYS2 runner. Flags
# mirror logos_delivery.nimble's dynamic-windows task.
liblogosdelivery: | build-deps librln
# DISABLE_RLN=true links liblogosdelivery without zerokit: no librln, no Rust,
# no submodule. A node whose config enables RLN then fails to start.
DISABLE_RLN ?= false
ifeq ($(DISABLE_RLN),true)
LIBLOGOSDELIVERY_RLN_DEP :=
# Target-specific, so `make DISABLE_RLN=true all` cannot compile the stubs
# into wakunode2, which still links the real librln.
liblogosdelivery: NIM_PARAMS += -d:disable_rln
else
LIBLOGOSDELIVERY_RLN_DEP := librln
endif
liblogosdelivery: | build-deps $(LIBLOGOSDELIVERY_RLN_DEP)
ifeq ($(detected_OS),Windows)
nim c --out:build/liblogosdelivery.dll --threads:on --app:lib --opt:speed --noMain --mm:refc --header -d:metrics --nimMainPrefix:liblogosdelivery --skipParentCfg:off -d:discv5_protocol_id=d5waku --cpu:amd64 $(NIM_PARAMS) library/liblogosdelivery.nim
else
+2 -1
View File
@@ -6,7 +6,8 @@ else:
switch("nimcache", "nimcache/debug/$projectName")
if defined(windows):
switch("passL", "rln.lib")
if not defined(disable_rln):
switch("passL", "rln.lib")
switch("define", "postgres=false")
# disable timestamps in Windows PE headers - https://wiki.debian.org/ReproducibleBuilds/TimestampsInPEBinaries
@@ -324,6 +324,10 @@ proc setupProtocols(
return err("failed to mount libp2p ping protocol: " & getCurrentExceptionMsg())
if conf.rlnRelayConf.isSome():
when defined(disable_rln):
return
err("the configuration enables RLN relay, but this build has -d:disable_rln")
let rlnRelayConf = conf.rlnRelayConf.get()
let rlnConf = WakuRlnConfig(
dynamic: rlnRelayConf.dynamic,
@@ -18,6 +18,10 @@
import results, ../protocol_types
when defined(disable_rln):
# Only for nodes that never enable RLN: the stubs abort if called.
{.compile: "rln_stubs.c".}
{.push raises: [], gcsafe.}
# --- Types ------------------------------------------------------------------
+58
View File
@@ -0,0 +1,58 @@
// Link-time stand-ins for zerokit's RLN FFI, compiled instead of librln when
// the build defines `disable_rln`. The Nim side declares these with `importc`
// and no `dynlib`, so they must resolve at link time even where RLN is unused.
//
// Generated from the `importc` names in rln_interface.nim.
#include <stdio.h>
#include <stdlib.h>
static void logosdelivery_rln_disabled(const char *symbol) {
fprintf(stderr,
"liblogosdelivery: %s called, but this build has -d:disable_rln and "
"no RLN implementation.\n",
symbol);
abort();
}
void ffi_bytes_le_to_cfr(void) { logosdelivery_rln_disabled("ffi_bytes_le_to_cfr"); }
void ffi_bytes_le_to_rln_partial_proof(void) { logosdelivery_rln_disabled("ffi_bytes_le_to_rln_partial_proof"); }
void ffi_bytes_le_to_rln_proof(void) { logosdelivery_rln_disabled("ffi_bytes_le_to_rln_proof"); }
void ffi_c_string_free(void) { logosdelivery_rln_disabled("ffi_c_string_free"); }
void ffi_cfr_free(void) { logosdelivery_rln_disabled("ffi_cfr_free"); }
void ffi_cfr_to_bytes_le(void) { logosdelivery_rln_disabled("ffi_cfr_to_bytes_le"); }
void ffi_cfr_zero(void) { logosdelivery_rln_disabled("ffi_cfr_zero"); }
void ffi_compute_id_secret(void) { logosdelivery_rln_disabled("ffi_compute_id_secret"); }
void ffi_extended_key_gen(void) { logosdelivery_rln_disabled("ffi_extended_key_gen"); }
void ffi_finish_rln_proof(void) { logosdelivery_rln_disabled("ffi_finish_rln_proof"); }
void ffi_generate_partial_zk_proof(void) { logosdelivery_rln_disabled("ffi_generate_partial_zk_proof"); }
void ffi_generate_rln_proof(void) { logosdelivery_rln_disabled("ffi_generate_rln_proof"); }
void ffi_hash_to_field_le(void) { logosdelivery_rln_disabled("ffi_hash_to_field_le"); }
void ffi_poseidon_hash_pair(void) { logosdelivery_rln_disabled("ffi_poseidon_hash_pair"); }
void ffi_rln_free(void) { logosdelivery_rln_disabled("ffi_rln_free"); }
void ffi_rln_new(void) { logosdelivery_rln_disabled("ffi_rln_new"); }
void ffi_rln_new_with_params(void) { logosdelivery_rln_disabled("ffi_rln_new_with_params"); }
void ffi_rln_partial_proof_free(void) { logosdelivery_rln_disabled("ffi_rln_partial_proof_free"); }
void ffi_rln_partial_proof_to_bytes_le(void) { logosdelivery_rln_disabled("ffi_rln_partial_proof_to_bytes_le"); }
void ffi_rln_partial_witness_input_free(void) { logosdelivery_rln_disabled("ffi_rln_partial_witness_input_free"); }
void ffi_rln_partial_witness_input_new(void) { logosdelivery_rln_disabled("ffi_rln_partial_witness_input_new"); }
void ffi_rln_proof_free(void) { logosdelivery_rln_disabled("ffi_rln_proof_free"); }
void ffi_rln_proof_get_values(void) { logosdelivery_rln_disabled("ffi_rln_proof_get_values"); }
void ffi_rln_proof_new(void) { logosdelivery_rln_disabled("ffi_rln_proof_new"); }
void ffi_rln_proof_to_bytes_le(void) { logosdelivery_rln_disabled("ffi_rln_proof_to_bytes_le"); }
void ffi_rln_proof_values_free(void) { logosdelivery_rln_disabled("ffi_rln_proof_values_free"); }
void ffi_rln_proof_values_get_external_nullifier(void) { logosdelivery_rln_disabled("ffi_rln_proof_values_get_external_nullifier"); }
void ffi_rln_proof_values_get_nullifier(void) { logosdelivery_rln_disabled("ffi_rln_proof_values_get_nullifier"); }
void ffi_rln_proof_values_get_root(void) { logosdelivery_rln_disabled("ffi_rln_proof_values_get_root"); }
void ffi_rln_proof_values_get_x(void) { logosdelivery_rln_disabled("ffi_rln_proof_values_get_x"); }
void ffi_rln_proof_values_get_y(void) { logosdelivery_rln_disabled("ffi_rln_proof_values_get_y"); }
void ffi_rln_witness_input_free(void) { logosdelivery_rln_disabled("ffi_rln_witness_input_free"); }
void ffi_rln_witness_input_new(void) { logosdelivery_rln_disabled("ffi_rln_witness_input_new"); }
void ffi_seeded_extended_key_gen(void) { logosdelivery_rln_disabled("ffi_seeded_extended_key_gen"); }
void ffi_vec_cfr_free(void) { logosdelivery_rln_disabled("ffi_vec_cfr_free"); }
void ffi_vec_cfr_get(void) { logosdelivery_rln_disabled("ffi_vec_cfr_get"); }
void ffi_vec_cfr_len(void) { logosdelivery_rln_disabled("ffi_vec_cfr_len"); }
void ffi_vec_cfr_new(void) { logosdelivery_rln_disabled("ffi_vec_cfr_new"); }
void ffi_vec_cfr_push(void) { logosdelivery_rln_disabled("ffi_vec_cfr_push"); }
void ffi_vec_u8_free(void) { logosdelivery_rln_disabled("ffi_vec_u8_free"); }
void ffi_verify_with_roots(void) { logosdelivery_rln_disabled("ffi_verify_with_roots"); }