13 Commits

Author SHA1 Message Date
Prem Chaitanya Prathi
d8bbef0c5b
feat(mix): bump libp2p stack to v2.0.0 + adopt stateless RLN spam protection
Combines five dep-and-build changes that all flow from the libp2p v2.0.0
upgrade and the move to the extracted libp2p_mix / mix-rln plugin stack:

waku.nimble:
  * libp2p: ff8d51857 -> c43199378 (release/v2.0.0 tip; sha-pinned until
    vacp2p cuts a v2.0.0 tag).
  * Drop the bare `zlib < 0.2` cap — no longer needed by the upgraded
    libp2p.
  * websock: bare ">= 0.4.0" — replaces the d4cd68b URL+SHA workaround
    that pinned through a libp2p commit-specific websock SHA.
  * nim-json-rpc: switch to chaitanyaprem/nim-json-rpc#f05fad25 — relaxes
    websock cap to allow >=0.4.0. TODO: revert to status-im/nim-json-rpc
    once status-im/nim-json-rpc#277 merges and a tag is cut.
  * lsquic: bare ">= 0.4.1" (drops URL form).
  * Add mix-rln-spam-protection-plugin pin (23b278b4) and nim-libp2p-mix
    pin (50c4ab4f — PR #14 HEAD); the plugin pins the same libp2p_mix
    SHA so the diamond dep collapses to a single source.

waku/factory/waku.nim:
  * Explicit HPService.setup(switch) / AutonatService.setup(switch)
    calls. libp2p v2.0.0's Service lifecycle refactor (libp2p#2462)
    removed switch.start's auto-setup loop, so any caller that assigns
    directly to switch.services (we do) is responsible for calling
    setup() themselves. Without it, AutonatService.addressMapper stays
    nil and peerInfo.expandAddrs SIGSEGVs during start(). Wrapped in
    try/except for ServiceSetupError so a setup failure surfaces as a
    logged error rather than a crash.

Build / scripts:
  * scripts/build_rln_mix.sh removed and Makefile simplified — librln
    is now a single shared archive built from zerokit's `stateless`
    features (no separate librln_mix archive).
  * simulations/mixnet/build_setup.sh + setup_credentials.nim updated
    to use librln_v2.0.2.a directly and run RLN keystore setup before
    nodes start.

Validated:
  * Cold local-cache nimble setup --localdeps -y.
  * wakunode2 and chat2mix link cleanly.
  * Mixnet roundtrip sim: [PASS] bob received message from alice.
  * RLN proof generation + verification on every in-path mix node:
    5 gen_called == 5 verified, 0 SPAM_PROOF_* errors.
2026-06-04 16:54:44 +05:30
Prem Chaitanya Prathi
d8e6dcef22
feat(mix): integrate mix protocol with extended kademlia + RLN spam protection
Rebased poc/mix-spam-protection onto origin/master. Bundles:

- Extended kademlia discovery integration for mix node pool
  (waku/discovery/waku_kademlia.nim, tools/confutils/cli_args.nim)
- RLN spam protection plugin (vacp2p/mix-rln-spam-protection) wired in:
  WakuMix gains mixRlnSpamProtection + publishMessage callback,
  per-hop proof generation / verification, membership coordination
  via /mix/rln/metadata/v1 content topic
- chat2mix sim app: filter-subscribes to spam-protection coordination
  topic, defers publishing until mix node pool is populated
- Makefile: automated librln_mix_v2.0.0.a build via
  scripts/build_rln_mix.sh and mix-librln target
- simulations/mixnet: 5-node mixnet sim infrastructure
  (config1-4.toml, run_*.sh, build_setup.sh, setup_credentials.nim,
  README, roundtrip_check.sh automated round-trip verification)

Rebase fixes:
- Plugin previously vendored as submodule; now a nimble requires entry
  pinned to logos-co/mix-rln-spam-protection-plugin@037f8e10
- waku.nimble: zlib < 0.2 pin to keep nimble lock resolution stable
  (upstream zlib HEAD bumped to 0.2.0)
- apps/chat2mix/config_chat2mix.nim: replace
  `defaultValue: parseIpAddress("...")` with IpAddress literal,
  works around confutils macro generating
  `defaultValueHelpName(): string {.raises: [].}` that violates the
  raises pragma when stringifying a parseIpAddress call
- config.nims: nimble setup --noNimblePath reordering

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-04 16:53:05 +05:30
NagyZoltanPeter
42e0aa43d1
feat: persistency (#3880)
* persistency: per-job SQLite-backed storage layer (singleton, brokered)

Adds a backend-neutral CRUD library at waku/persistency/, plus the
nim-brokers dependency swap that enables it.

Architecture (ports-and-adapters):
  * Persistency: process-wide singleton, one root directory.
  * Job: one tenant, one DB file, one worker thread, one BrokerContext.
  * Backend: SQLite via waku/common/databases/db_sqlite. Uniform schema
    kv(category BLOB, key BLOB, payload BLOB) PRIMARY KEY (category, key)
    WITHOUT ROWID, WAL mode.
  * Writes are fire-and-forget via EventBroker(mt) PersistEvent.
  * Reads are async via five RequestBroker(mt) shapes (KvGet, KvExists,
    KvScan, KvCount, KvDelete). Reads return Result[T, PersistencyError].
  * One storage thread per job; tenants isolated by BrokerContext.

Public surface (waku/persistency/persistency.nim):
  Persistency.instance(rootDir) / Persistency.instance() / Persistency.reset()
  p.openJob(id) / p.closeJob(id) / p.dropJob(id) / p.close()
  p.job(id) / p[id] / p.hasJob(id)
  Writes (Job form & string-id form, fire-and-forget):
    persist / persistPut / persistDelete / persistEncoded
  Reads (Job form & string-id form, async Result):
    get / exists / scan / scanPrefix / count / deleteAcked

Key & payload encoding (keys.nim, payload.nim):
  * encodePart family + variadic key(...) / payload(...) macros +
    single-value toKey / toPayload.
  * Primitives: string and openArray[byte] are 2-byte BE length + bytes;
    int{8..64} are sign-flipped 8-byte BE; uint{16..64} are 8-byte BE;
    bool/byte/char are 1 byte; enums are int64(ord(v)).
  * Generic encodePart[T: tuple | object] recurses through fields() so
    any composite Nim type is encodable without ceremony.
  * Stable across Nim/C compiler upgrades: no sizeof, no memcpy, no
    cast on pointers, no host-endianness dependency.
  * `rawKey(bytes)` + `persistPut(..., openArray[byte])` let callers
    bypass the built-in encoder with their own format (CBOR, protobuf...).

Lifecycle:
  * Persistency.new is private; Persistency.instance is the only public
    constructor. Same rootDir is idempotent; conflicting rootDir is
    peInvalidArgument. Persistency.reset for test/restart paths.
  * openJob opens-or-creates the per-job SQLite file; an existing file
    is reused with its data preserved.
  * Teardown integration: Persistency.instance registers a Teardown
    MultiRequestBroker provider that closes all jobs and clears the
    singleton slot when Waku.stop() issues Teardown.request.

Internal layering:
  types.nim          pure value types (Key, KeyRange, KvRow, TxOp,
                     PersistencyError)
  keys.nim           encodePart primitives + key(...) macro
  payload.nim        toPayload + payload(...) macro
  schema.nim         CREATE TABLE + connection pragmas + user_version
  backend_sqlite.nim KvBackend, applyOps (single source of write SQL),
                     getOne/existsOne/deleteOne, scanRange (asc/desc,
                     half-open ranges, open-ended stop), countRange
  backend_comm.nim   EventBroker(mt) PersistEvent + 5 RequestBroker(mt)
                     declarations; encodeErr/decodeErr boundary helpers
  backend_thread.nim startStorageThread / stopStorageThread (shared
                     allocShared0 arg, cstring dbPath, atomic
                     ready/shutdown flags); per-thread provider
                     registration
  persistency.nim    Persistency + Job types, singleton state, public
                     facade
  ../requests/lifecycle_requests.nim
                     Teardown MultiRequestBroker

Tests (69 cases, all passing):
  test_keys.nim          sort-order invariants (length-prefix strings,
                         sign-flipped ints, composite tuples, prefix
                         range)
  test_backend.nim       round-trip / replace / delete-return-value /
                         batched atomicity / asc-desc-half-open-open-
                         ended scans / category isolation / batch
                         txDelete
  test_lifecycle.nim     open-or-create rootDir / non-dir collision /
                         reopen across sessions / idempotent openJob /
                         two-tenant parallel isolation / closeJob joins
                         worker / dropJob removes file / acked delete
  test_facade.nim        put-then-get / atomic batch / scanPrefix
                         asc/desc / deleteAcked hit-miss /
                         fire-and-forget delete / two-tenant facade
                         isolation
  test_encoding.nim      tuple/named-tuple/object keys, embedded Key,
                         enum encoding, field-major composite sort,
                         payload struct encoding, end-to-end struct
                         round-trip through SQLite
  test_string_lookup.nim peJobNotFound semantics / hasJob / subscript /
                         persistPut+get via id / reads short-circuit /
                         writes drop+warn / persistEncoded via id /
                         scan parity Job-ref vs id
  test_singleton.nim     idempotent same-rootDir / different-rootDir
                         rejection / no-arg instance lifecycle / reset
                         retargets / reset idempotence / Teardown.request
                         end-to-end

Prerequisite delivered in the same series: replace the in-tree broker
implementation with the external nim-brokers package; update all
broker call-sites (waku_filter_v2, waku_relay, waku_rln_relay,
delivery_service, peer_manager, requests/*, factory/*, api tests, etc.)
to the new package API; chat2 made to compile again.

Note: SDS adapter (Phase 5 of the design) is deferred -- nim-sds is
still developed side-by-side and the persistency layer is intentionally
SDS-agnostic.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* persistency: pin nim-brokers by URL+commit (workaround for stale registry)

The bare `brokers >= 2.0.1` form cannot resolve on machines where the
local nimble SAT solver enumerates only the registry-recorded 0.1.0 for
brokers. The nim-lang/packages entry for `brokers` carries no per-tag
metadata (only the URL), so until that registry entry is refreshed the
SAT solver clamps the available-versions list to 0.1.0 and rejects the
>= 2.0.1 constraint -- even though pkgs2 and pkgcache both have v2.0.1
cloned locally.

Pinning by URL+commit bypasses the registry path entirely. Inline
comment in waku.nimble documents the situation and the path back to
the bare form once nim-lang/packages is updated.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* persistency: nph format pass

Run `nph` on all 57 Nim files touched by this PR. Pure formatting:
17 files re-styled, no semantic change. Suite still 69/69.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* Fix build, add local-storage-path config, lazy init of Persistency from Waku start

* fix: fix nix deps

* fixes for nix build, regenerate deps

* reverting accidental dependency changes

* Fixing deps

* Apply suggestions from code review

Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com>

* persistency tests: migrate to suite / asyncTest / await

Match the in-tree test convention (procSuite -> suite, sync test +
waitFor -> asyncTest + await):

- procSuite "X": -> suite "X":
- For tests doing async work: test -> asyncTest, waitFor -> await.
- Poll helpers (proc waitFor(t: Job, ...) in test_lifecycle.nim,
  proc waitUntilExists(...) in test_facade.nim and
  test_string_lookup.nim) -> Future[bool] {.async.}, internal
  `waitFor X` -> `await X`, internal `sleep(N)` ->
  `await sleepAsync(chronos.milliseconds(N))`.
- Renamed test_lifecycle.nim's helper proc from `waitFor(t: Job, ...)`
  -> `pollExists(t: Job, ...)`; the previous name shadowed
  chronos.waitFor in the chronos macro expansion.
- `chronos.milliseconds(N)` explicitly qualified because `std/times`
  also exports `milliseconds` (returning TimeInterval, not Duration).
- `check await x` -> `let okN = await x; check okN` to dodge chronos's
  "yield in expr not lowered" with await-as-macro-argument.
- `(await x).foo()` -> `let awN = await x; ... awN.foo() ...` for the
  same reason.

waku/persistency/persistency.nim: nph also pulled the proc signatures
across multiple lines; restored explicit `Future[void] {.async.}`
return types after the colon (an intermediate nph pass had elided them).

Suite: 71 / 71 OK against the new async write surface.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* use idiomatic valueOr instead of ifs

* Reworked persistency shutdown, remove not necessary teardown mechanism

* Use const for DefaultStoragePath

* format to follow coding guidelines - no use of result and explicit returns - no functional change

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com>
2026-05-16 00:09:07 +02:00
Fabiana Cecin
bb8a7e8782
Fix redundant start/stop calls (#3817)
* remove redundant proto start/stop calls from node start/stop
* fix WakuRelay start/stop not overriding GossipSub start/stop
* replace startRelay with reconnectRelayPeers
2026-04-22 09:52:57 -03:00
Ivan FB
0623c10635
completely remove storev2 (#3781) 2026-03-30 00:08:08 +02:00
Ivan Folgueira Bande
d1ac84a80f
Merge branch 'master' into merge-v037-branch-into-master 2026-03-20 11:26:35 +01:00
Ivan FB
11461aed44
allow union of several retention policies (#3766)
* refactor retention policy to allow union of several retention policies
* bug fix time retention policy
* add removal of orphan partitions if any
* use nim-http-utils 0.4.1
2026-03-19 21:37:04 +01:00
Fabiana Cecin
51ec09c39d
Implement stateful SubscriptionService for Core mode (#3732)
* SubscriptionManager tracks shard and content topic interest
* RecvService emits MessageReceivedEvent on subscribed content topics
* Route MAPI through old Kernel API relay unique-handler infra to avoid code duplication
* Encode current gen-zero network policy: on Core node boot, subscribe to all pubsub topics (all shards)
* Add test_api_subscriptions.nim (basic relay/core testing only)
* Removed any MAPI Edge sub/unsub/receive support code that was there (will add in next PR)
* Hook MessageSeenEvent to Kernel API bus
* Fix MAPI vs Kernel API unique relay handler support
* RecvService delegating topic subs to SubscriptionManager
* RecvService emits MessageReceivedEvent (fully filtered)
* Rename old SubscriptionManager to LegacySubscriptionManager
2026-03-02 14:52:36 -03:00
NagyZoltanPeter
1fd25355e0
feat: waku api send (#3669)
* Introduce api/send
Added events and requests for support.
Reworked delivery_monitor into a featured devlivery_service, that
- supports relay publish and lightpush depending on configuration but with fallback options
- if available and configured it utilizes store api to confirm message delivery
- emits message delivery events accordingly

prepare for use in api_example

* Fix edge mode config and test added
* Fix some import issues, start and stop waku shall not throw exception but return with result properly
* Utlize sync RequestBroker, adapt to non-async broker usage and gcsafe where appropriate, removed leftover
* add api_example app to examples2
* Adapt after merge from master
* Adapt code for using broker context
* Fix brokerCtx settings for all usedbrokers, cover locked node init
* Various fixes upon test failures. Added initial of subscribe API and auto-subscribe for send api
* More test added
* Fix multi propagate event emit, fix fail send test case
* Fix rebase
* Fix PushMessageHandlers in tests
* adapt libwaku to api changes
* Fix relay test by adapting publish return error in case NoPeersToPublish
* Addressing all remaining review findings. Removed leftovers. Fixed loggings and typos
* Fix rln relay broker, missed brokerCtx
* Fix rest relay test failed, due to publish will fail if no peer avail
* ignore anvil test state file
* Make terst_wakunode_rln_relay broker context aware to fix
* Fix waku rln tests by having them broker context aware
* fix typo in test_app.nim
2026-01-30 01:06:00 +01:00
Sergei Tikhomirov
7d1c6abaac
chore: do not mount lightpush without relay (fixes #2808) (#3540)
* chore: do not mount lightpush without relay (fixes #2808)

- Change mountLightPush signature to return Result[void, string]
- Return error when relay is not mounted
- Update all call sites to handle Result return type
- Add test verifying mounting fails without relay
- Only advertise lightpush capability when relay is enabled

* chore: don't mount legacy lightpush without relay
2025-12-11 10:51:47 +01:00
Sergei Tikhomirov
1e73213a36
chore: Lightpush minor refactor (#3538)
* chore: refactor Lightpush (more DRY)

* chore: apply review suggestions

Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com>

---------

Co-authored-by: Ivan FB <128452529+Ivansete-status@users.noreply.github.com>
2025-11-28 10:41:20 +01:00
Prem Chaitanya Prathi
088e3108c8
use exit==dest approach for mix (#3642) 2025-11-22 08:11:05 +05:30
NagyZoltanPeter
1762548741
chore: clarify api folders (#3637)
* Rename waku_api to rest_api and underlying rest to endpoint for clearity
* Rename node/api to node/kernel_api to suggest that it is an internal accessor to node interface + make everything compile after renaming
* make waku api a top level import
* fix use of relative path imports and use default to root rather in case of waku and tools modules
2025-11-15 23:31:09 +01:00