Skip to content

chore: stop committing nimble.lock; treat as build artefact - #14

Merged
marcinczenko merged 6 commits into
chore/bump-libp2p-v2.0.0from
experiment/drop-nimble-lock
Jun 5, 2026
Merged

chore: stop committing nimble.lock; treat as build artefact#14
marcinczenko merged 6 commits into
chore/bump-libp2p-v2.0.0from
experiment/drop-nimble-lock

Conversation

@chaitanyaprem

@chaitanyaprem chaitanyaprem commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Stops committing nimble.lock. Treat it as a build artefact: regenerated on demand by make deps as input to ./tools/gen-deps.sh, never checked in. The committed long-lived pinning artefact for nix consumers becomes nix/deps.nix alone.

Why

nimble.lock was added in #8 and has caused all CI to fail since merge (CI run 25846185300, Examples 25846185331) with the same Nim source-tree checksum mismatch:

Error: Downloaded package checksum does not correspond to that in the lock file:
  Package: nim@v.2.2.4@r.911e0dbb1f76de61fa0215ab1bb85af5334cc9a8
  Checksum:          a092a045d3a427d127a5334a6e59c76faff54686
  Expected checksum: 68bb85cbfb1832ce4db43943911b046c3af3caab

Root cause: nimble 0.22.3 (used by waku to generate the lockfile) hashes the Nim source tree one way; the newer nimble shipped by jiro4989/setup-nim-action@v2 hashes it another way. Same SHA, different bytes. Waku works around this by pinning nimble to 0.22.3 in CI — but that hardcodes a load-bearing dependency on an undocumented nimble hashing contract.

For a leaf library like libp2p_mix, the simpler answer is: don't commit the lockfile. Library consumers (waku) already pin libp2p_mix by URL+SHA in their own .nimble, so they don't need ours. Bit-exact reproducibility for nix builds is preserved via the committed nix/deps.nix, which carries the same pinned transitive SHAs in the form nix actually consumes.

This matches what nim-libp2p (our direct upstream) has done since their #848 in 2023.

What lands here

Commit What
04bcd21 experiment: drop nimble.lock to test no-lockfile install path — removes nimble.lock, adds it to .gitignore with pointer to #13, rewrites CI install step (nimble setup --localdeps -y in place of nimble install -dy).
50c4ab4 chore: document nimble.lock as a build artefact — Makefile + README doc pass: nimble.lock is regenerated on demand; nix/deps.nix is the long-lived snapshot; downstream consumers pin libp2p_mix by URL+SHA.
66f9adf Build/add missing nix inputs (#15) — merged from @marcinczenko's PR #15. Refreshes nix/deps.nix to current libp2p v2.0.0 tip (adds npeg + protobuf_serialization transitive entries; bumps boringssl / lsquic / websock / libp2p revs). Adds git, jq, nix-prefetch-git to flake.nix nativeBuildInputs so make deps works inside nix develop. Drops --noNimblePath from config.nims (handled automatically by nimble setup -l). README workflow updates.
71ee1b0 docs(makefile): clarify ./tools/gen-deps.sh path in comment — Copilot review nit.
7b86ec5 ci: matrix to Nim 2.2.4 + 2.2.10 — replaces the single 2.2.6 entry with 2.2.4 (libp2p v2.0.0 floor; what this PR was validated against locally) and 2.2.10 (current; ships nimble 0.22.3 — the version most contributors run on their host machines). Same job count (6), broader nimble coverage — closes the exact gap that produced the original lockfile checksum mismatch.
87a8131 ci: add nix-build job (paths-filtered + weekly cron) — new ci-nix.yml that runs only when nix-relevant files change, on push to master, weekly on Mondays at 06:00 UTC, and on manual dispatch. Validates that nix/deps.nix is in sync with libp2p_mix.nimble (drift check via git diff --exit-code) and that nix build resolves.

Diff overview

9 files / +157 / −405 vs the base PR's tip:

.github/workflows/ci-nix.yml   (+71, new)     ← path-filtered nix build job
.github/workflows/ci.yml       (+9)           ← Nim matrix bump + install recipe
.gitignore                     (+3)           ← ignore nimble.lock
Makefile                       (+12)          ← document artefact-not-source role
README.md                      (+57 net)      ← Nix workflow + setup updates
config.nims                    (−1)           ← --noNimblePath now from nimble setup -l
flake.nix                      (+3)           ← git, jq, nix-prefetch-git in dev shell
nimble.lock                    (−376)         ← deleted
nix/deps.nix                   (+30 net)      ← refresh against libp2p v2.0.0 tip

CI additions in detail

Matrix change (.github/workflows/ci.yml)

- nim:
-   - { ref: '2.2.6', mm: refc }
+ nim:
+   - { ref: '2.2.4',  mm: refc }   # libp2p v2.0.0 floor; validated locally
+   - { ref: '2.2.10', mm: refc }   # current; ships nimble 0.22.3

New nix-build workflow (.github/workflows/ci-nix.yml)

Triggers:

  • pull_request with paths filter on libp2p_mix.nimble, nix/**, flake.nix, flake.lock, Makefile, tools/gen-deps.sh, .github/workflows/ci-nix.yml. Pure *.nim PRs don't trigger this job — zero per-PR tax for code-only changes.
  • push to master — post-merge smoke test.
  • schedule: cron '0 6 * * 1' — weekly drift check for external moves (nimble release, nixpkgs bump, upstream rev moves).
  • workflow_dispatch — manual trigger for ad-hoc validation.

Steps:

  1. Install Nix via DeterminateSystems/nix-installer-action + magic cache.
  2. Run make deps inside nix develop, then git diff --exit-code nix/deps.nix — fails the job if the committed snapshot drifted from what libp2p_mix.nimble resolves to.
  3. nix build -L.

How to test

# Direct nim path (matches CI matrix)
nimble setup -l --solver:legacy
nimble test
nimble testComponent

# Nix path (matches new ci-nix.yml)
nix develop --command bash -c "make deps && git diff --exit-code nix/deps.nix"
nix build -L

Out of scope (deliberately)

  • Touching nix/default.nix, nix/deps.nix, or flake.nix — now covered by the merged PR Build/add missing nix inputs #15 content.
  • Removing tools/gen-deps.sh — still used by make deps.
  • Updating pkgs.nim-2_2 / pkgs.nimble in flake.nix to a newer Nim. nixpkgs ships Nim 2.2.4 + Nimble 0.18.2; getting 2.2.10 + 0.22.3 inside nix develop requires either a nim overlay or adopting nimbus-build-system — both heavier than this PR's scope. Tracking as a follow-up.

Tracking

Closes #13.

@chaitanyaprem chaitanyaprem changed the title [experiment] drop nimble.lock — validate Option B from #13 chore: stop committing nimble.lock; treat as build artefact Jun 4, 2026
@chaitanyaprem
chaitanyaprem marked this pull request as ready for review June 4, 2026 07:26
@chaitanyaprem
chaitanyaprem requested a review from Copilot June 4, 2026 07:34

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Removes nimble.lock from version control and documents the new workflow where nimble.lock is treated as an intermediate build artifact used only to regenerate the committed Nix pinset (nix/deps.nix). This aligns the repo’s CI/developer experience with the stated goal of avoiding nimble lockfile checksum mismatches across nimble versions.

Changes:

  • Delete nimble.lock from the repository and add it to .gitignore.
  • Update the Makefile/README to clarify that make deps regenerates the committed nix/deps.nix, using an ephemeral nimble.lock internally.
  • Document downstream guidance: consumers should pin libp2p_mix by URL+SHA in their own .nimble if they need exact dependency sets.

Reviewed changes

Copilot reviewed 2 out of 4 changed files in this pull request and generated 1 comment.

File Description
README.md Updates Nix workflow documentation to treat nimble.lock as ephemeral and nix/deps.nix as the committed pinning artifact.
nimble.lock Removes the lockfile from the repo (no longer checked in).
Makefile Clarifies lockfile role and keeps a target to regenerate it as input for tools/gen-deps.sh.
.gitignore Ignores nimble.lock with an explanatory comment referencing the rationale.

Comment thread Makefile Outdated
See #13 — isolating the hypothesis that removing the
lockfile alone fixes the Nim source-tree checksum mismatch that's been
failing CI since #8 (most recently on chore/bump-libp2p-v2.0.0).

Without `nimble.lock`, `nimble setup --localdeps -y` resolves directly from
`libp2p_mix.nimble`'s `requires` clauses — no Nim source-tree sha1 to
re-validate against a lockfile entry written by a different nimble version.

If CI goes green, this validates Option B in #13 and we can land it on the
bump branch (and cascade to master + the nix/doc cleanups).
Follow-up to the lockfile deletion: add `nimble.lock` to `.gitignore`,
explain the lockfile/nix/deps.nix relationship in the Makefile target
comment, and rewrite the README "Nix" section so devs understand the
new flow:

  libp2p_mix.nimble  →  nimble.lock (gitignored, ephemeral)
                    →  nix/deps.nix (committed, long-lived pin)

CI is not affected — it never consumed nimble.lock once we switched to
`nimble setup --localdeps -y`. Only the maintainer flow for refreshing
nix/deps.nix touches nimble.lock now, and `make deps` regenerates it on
demand from libp2p_mix.nimble.

Closes #13
@chaitanyaprem
chaitanyaprem force-pushed the experiment/drop-nimble-lock branch from 3bfe610 to 50c4ab4 Compare June 4, 2026 10:12
chaitanyaprem added a commit to logos-co/mix-rln-spam-protection-plugin that referenced this pull request Jun 4, 2026
Brings in the move-semantics propagation + lockfile-as-build-artefact
cleanup. Pinned to the PR HEAD (50c4ab4) until logos-co/nim-libp2p-mix#14
and #12 merge to master.

waku.nimble pins the same SHA to keep the diamond dep collapsed to a
single libp2p_mix source.

@marcinczenko marcinczenko left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current deps.nix is outdated, which makes nix build failing. To fix it, one needs to run:

nix develop
make clean
rm -rf nimbledeps nimble.paths
nimble setup -l --solver:legacy
make deps
nix build

I suggest to use -l with nimble setup to keep nim dependencies local - it also takes care for adding --noNimblePath to the genrated nimble.paths.

But while in the Nix shell, make deps will fail, because it is missing nix-prefetch-git and probably other packages. I suggest adding this to the flake.nix:

pkgs.git
pkgs.jq
pkgs.nix-prefetch-git

Then everything works.

Maybe we should also update README a bit.

I included all those fixes (as a suggested change, but feel free to correct if something does not make sense to you) on top of your branch in #15.

Perhaps the intention of using nix in this project is only type-checking, but (not feeling very competent about Nix myself) I really do not like that we fall back to nim v2.2.4 and nimble v0.18.2 while in the native shell pretty much everyone will have 2.2.10 and 0.22.3 respecitvely. Also logos-storage in their nix config uses those recent versions I suppose (although the Nix config in logos-storage is much more sophisticated). status-go (which is also quite complex) uses 2.2.4 and 0.22.2. I give it quick shot with GPT in https://github.com/logos-co/nim-libp2p-mix/tree/build/nim-2.2.10-in-nix-shell, but I am not sure how portable it is. In logos-storage, nimbus-build-system takes care for Nim, but I feel it would be to heavy to use it here. So, I am not sure what would be the best way to land on a recent nim/nimbus version in Nix Shell here. But, in its current form, I would not use it for any development, so what's the point of having it then...

marcinczenko and others added 4 commits June 5, 2026 18:45
* build: adds missing nix build inputs

* chore: updates deps.nix

* chore: updates README
Addresses Copilot review nit on PR #14 — the comment referenced
`gen-deps.sh` while the actual invoked path is `./tools/gen-deps.sh`.
Replaces the single 2.2.6 entry with two: 2.2.4 (the libp2p v2.0.0
transitive floor; what this PR was validated against locally) and 2.2.10
(current 2.2.x, ships nimble 0.22.3 which is what most contributors
have on their host machines).

Net job count unchanged (3 platforms × 2 nim versions = 6), but
coverage now spans both the floor and the nimble-0.22 line — which is
precisely the gap that produced the original `nimble.lock` checksum
mismatch in #13.
Adds `.github/workflows/ci-nix.yml` to validate the nix build path
without taxing every code-only PR.

Triggers:
- pull_request, but only when nix-relevant files change
  (libp2p_mix.nimble, nix/**, flake.nix, flake.lock, Makefile,
  tools/gen-deps.sh, this workflow itself);
- push to master as a post-merge smoke test;
- weekly cron (Mon 06:00 UTC) to surface external drift (nimble
  releases, nixpkgs bumps, upstream rev moves) that no in-repo
  change would otherwise reveal;
- workflow_dispatch for ad-hoc validation after libp2p pin bumps.

Steps:
1. Install Nix via DeterminateSystems installer + magic cache.
2. Run `make deps` inside `nix develop`, then `git diff --exit-code
   nix/deps.nix` — fails the job if the committed snapshot is stale
   (catches a libp2p_mix.nimble bump that forgot to refresh deps.nix).
3. `nix build -L` to validate the snapshot actually resolves.

Net per-PR cost: ~0 min for typical *.nim PRs (path filter skips
the job entirely), ~5 min for the rare PR touching nix infra.
@marcinczenko
marcinczenko merged commit 011e40a into chore/bump-libp2p-v2.0.0 Jun 5, 2026
11 checks passed
@marcinczenko
marcinczenko deleted the experiment/drop-nimble-lock branch June 5, 2026 14:01
chaitanyaprem added a commit that referenced this pull request Jun 9, 2026
Three categories of fixes:

1. README typo + grammar (3 spots):
   - "setup the project" → "set up the project" (verb form)
   - "genrated" → "generated" (typo)
   - "If this does not work … and need to start fresh" — add missing
     subject "you"

2. Stale rationale comments in CI workflows:
   - ci.yml / examples.yml: the comment about "tolerant of platform drift
     in the lockfile's nim checksum" no longer applies — nimble.lock isn't
     committed (PR #14). Replace with a clearer description of what
     `nimble setup --localdeps -y` does and why it's the right bootstrap
     without a committed lock.
   - Makefile: the header comment said "CI does not consume nimble.lock
     directly", but the `ci / nix` job *does* regenerate it on the fly via
     `make deps`. Clarify which CI jobs are affected.

3. Cache `nimbledeps/` alongside `~/.nimble`:
   - `nimble setup --localdeps -y` installs into the project-local
     `nimbledeps/`, but the cache step was only restoring `~/.nimble`. Add
     `nimbledeps` to the cache path so subsequent CI runs actually benefit
     from the cache (was effectively cold every run).
   - Applies to both `ci.yml` (matrix jobs) and `examples.yml`.
jm-clius pushed a commit that referenced this pull request Jun 12, 2026
* chore: bump nim-libp2p pin to master HEAD

Bumps the nim-libp2p pin from `#d4cd68b91` to master HEAD
`#069a05bde492d717fce26e7df8b5b0c4221664f0` so downstream consumers
(waku) can pick up the service-discovery propagation fixes (PR #2434
table insertion check, PR #2502 build advert once byte-identical, plus
the empty service-rtable fallback) that landed after the prior pin.

libp2p_mix itself does not need any of those fixes — the bump exists to
let downstreams have a single consistent libp2p version across waku +
libp2p_mix + mix-rln-spam-protection-plugin.

* Revert "chore: bump nim-libp2p pin to master HEAD"

This reverts commit a173abe.

* chore: bump nim-libp2p to release/v2.0.0 tip + adapt to v2.0 API

- libp2p_mix.nimble: pin libp2p to release/v2.0.0 tip (c43199378).
  vacp2p/nim-libp2p has not yet published a v2.0.0 git tag, so we
  SHA-pin to the release branch tip (3 patch commits past the v2.0.0
  bump commit). Bump nim minimum to >= 2.2.4 to match v2.0.0's
  transitive requirement.
- libp2p_mix/{entry,exit,reply}_connection.nim: method write* override
  parameter switched to `sink seq[byte]` to match libp2p v2.0.0's
  LPStream base method signature.
- libp2p_mix/pool.nim: write peer addresses with AddressConfidence.Infinite.
  libp2p v2.0.0 introduced AddressBook auto-prune (Medium TTL = 1h, the
  default for legacy [] = assignment) which would silently evict our
  curated mix-pool addresses after 1h.
- .github/workflows/{ci,examples}.yml: drop --solver:legacy. vnext SAT
  now resolves cleanly with v2.0.0's URL+range transitive deps.
- nimble.lock: regenerated against v2.0.0; jwt entry removed (libp2p
  v2.0.0 replaces nim-jwt with an internal JWS signer); websock bumped
  to a clean v0.4.0+ commit (no longer URL+SHA-pinned by libp2p).

* ci: align install recipe with logos-delivery + drop incompatible Nim 2.0.16

`nimble install -dy` strictly re-validates every lockfile entry, which trips
on the `nim` package's source-tarball checksum drifting between the machine
that ran `nimble lock` and CI runners. Switch to `nimble setup --localdeps
-y`, the recipe used by logos-delivery (waku) — it provisions into a
project-local nimbledeps/ and is tolerant of that drift.

Also drop the Nim 2.0.16 matrix row: libp2p v2.0.0 transitively requires
nim >= 2.2.4, so 2.0.16 jobs can no longer resolve.

See #13 for the broader nimble.lock decision.

* fix: align with new move semantics for libp2p write

Propagate `sink seq[byte]` + `move()` through the mix send path so the
hot loop avoids a copy on every message. Without this, the libp2p
v2.0.0 `Connection.write*` method takes `sink seq[byte]` at the override
boundary, but every internal proc the body forwards to (`MixDialer`,
`mixDialer` lambda, `prepareMsgWithSurbs`, `buildMessage`, `MixMessage.
init`, `anonymizeLocalProtocolSend`, `MixReplyDialer`) still takes a
plain `seq[byte]`, forcing Nim to copy the message back into copyable
storage at the very next call.

Files touched:
- entry_connection.nim — `MixDialer` proc type, `write` call, `mixDialer`
  lambda + its call into `anonymizeLocalProtocolSend`
- exit_layer.nim — `replyDialerCbFactory` lambda's `msg` param
- mix_message.nim — add sink-taking `init` overload alongside the
  existing openArray one
- mix_protocol.nim — `prepareMsgWithSurbs`, `buildMessage` (incl. the
  `MixMessage.init` call), `anonymizeLocalProtocolSend`, and the
  `msgWithSurbs`/`buildMessage` call sites (`let` → `var` so the
  `move()` is well-formed)
- reply_connection.nim — `MixReplyDialer` proc type, `write` call

Validated by rebuilding wakunode2 + chat2mix against the patched mix
under logos-delivery's `nimbledeps/`. Both link cleanly.

Mirrors the move-semantics portion of #11's commit fb2c675, with the
readSpec-feature changes from cf38f48/853e80d intentionally left out
(those belong to a separate feature PR).

* experiment: drop nimble.lock to test no-lockfile install path

See #13 — isolating the hypothesis that removing the
lockfile alone fixes the Nim source-tree checksum mismatch that's been
failing CI since #8 (most recently on chore/bump-libp2p-v2.0.0).

Without `nimble.lock`, `nimble setup --localdeps -y` resolves directly from
`libp2p_mix.nimble`'s `requires` clauses — no Nim source-tree sha1 to
re-validate against a lockfile entry written by a different nimble version.

If CI goes green, this validates Option B in #13 and we can land it on the
bump branch (and cascade to master + the nix/doc cleanups).

* chore: document nimble.lock as a build artefact

Follow-up to the lockfile deletion: add `nimble.lock` to `.gitignore`,
explain the lockfile/nix/deps.nix relationship in the Makefile target
comment, and rewrite the README "Nix" section so devs understand the
new flow:

  libp2p_mix.nimble  →  nimble.lock (gitignored, ephemeral)
                    →  nix/deps.nix (committed, long-lived pin)

CI is not affected — it never consumed nimble.lock once we switched to
`nimble setup --localdeps -y`. Only the maintainer flow for refreshing
nix/deps.nix touches nimble.lock now, and `make deps` regenerates it on
demand from libp2p_mix.nimble.

Closes #13

* Build/add missing nix inputs (#15)

* build: adds missing nix build inputs

* chore: updates deps.nix

* chore: updates README

* docs(makefile): clarify ./tools/gen-deps.sh path in comment

Addresses Copilot review nit on PR #14 — the comment referenced
`gen-deps.sh` while the actual invoked path is `./tools/gen-deps.sh`.

* ci: matrix to Nim 2.2.4 + 2.2.10

Replaces the single 2.2.6 entry with two: 2.2.4 (the libp2p v2.0.0
transitive floor; what this PR was validated against locally) and 2.2.10
(current 2.2.x, ships nimble 0.22.3 which is what most contributors
have on their host machines).

Net job count unchanged (3 platforms × 2 nim versions = 6), but
coverage now spans both the floor and the nimble-0.22 line — which is
precisely the gap that produced the original `nimble.lock` checksum
mismatch in #13.

* ci: add nix-build job (paths-filtered + weekly cron)

Adds `.github/workflows/ci-nix.yml` to validate the nix build path
without taxing every code-only PR.

Triggers:
- pull_request, but only when nix-relevant files change
  (libp2p_mix.nimble, nix/**, flake.nix, flake.lock, Makefile,
  tools/gen-deps.sh, this workflow itself);
- push to master as a post-merge smoke test;
- weekly cron (Mon 06:00 UTC) to surface external drift (nimble
  releases, nixpkgs bumps, upstream rev moves) that no in-repo
  change would otherwise reveal;
- workflow_dispatch for ad-hoc validation after libp2p pin bumps.

Steps:
1. Install Nix via DeterminateSystems installer + magic cache.
2. Run `make deps` inside `nix develop`, then `git diff --exit-code
   nix/deps.nix` — fails the job if the committed snapshot is stale
   (catches a libp2p_mix.nimble bump that forgot to refresh deps.nix).
3. `nix build -L` to validate the snapshot actually resolves.

Net per-PR cost: ~0 min for typical *.nim PRs (path filter skips
the job entirely), ~5 min for the rare PR touching nix infra.

* chore: pin libp2p v2.0.0 + review fixes

---------

Co-authored-by: Marcin Czenko <marcin.czenko@pm.me>
chaitanyaprem added a commit to logos-co/mix-rln-spam-protection-plugin that referenced this pull request Jul 9, 2026
* feat(rln): replace pmtree backend with Nim IMT for stateless zerokit

Move Merkle tree state from zerokit's pmtree-ft to a pure-Nim
IncrementalMerkleTree (depth-20 Poseidon).  Lets the plugin build
against zerokit --features stateless and share a single archive with
relay -- eliminates the dual-archive symbol collision after zerokit's
v0.9->v2.0 FFI rename.

Architecture matches zerokit's documented stateless pattern
("stateless RLN and separate Merkle tree", rln-cli/README.md).
Byte-parity with pmtree locked down by a 61-op fixture captured from
the default-features build, plus delete/sparse-setLeaf/idempotency/
out-of-capacity coverage.

* chore(nimble): bump nim-libp2p to d4cd68b91b

Aligns with nim-libp2p-mix's libp2p pin so the diamond dependency
(waku -> {libp2p, nim-libp2p-mix -> libp2p}) resolves to a single
libp2p source.  d4cd68b91b is 14 commits past b16873f07, which means
the boringssl URL+range form is in place -- nimble vnext SAT can
solve without --solver:legacy.

No code changes; plugin only uses libp2p/protobuf/minprotobuf and
libp2p/varint, neither of which changed in the e1bbda4f6..d4cd68b91b
window.  All 29 plugin tests still green.

* chore(nimble): bump nim-libp2p-mix pin to 99d2ca0

nim-libp2p-mix#f24cd25a (its master tip) still pins libp2p#7e72c0d6,
which uses the pre-fix URL+tag form for boringssl and triggers the
nimble vnext SAT bug at any downstream consumer that also requires
modern libp2p (URL+range form).

99d2ca0 (chore/bump-libp2p-master tip on origin) bumps that pin to
libp2p#d4cd68b91b -- same as our pin in the prior commit -- so the
constraint graph is consistent end-to-end.  Carries PR #10's
Rng-type migration; does not affect this plugin (only
libp2p_mix/spam_protection is imported and its API surface is
unchanged).

All 29 plugin tests green against the new pin.

* chore(stateless-rln): drop pmtree-parity scaffolding, keep IMT regression test

capture_golden.nim and the pmtree-derived golden fixture served as the
one-time migration acceptance criterion; capture_golden.nim only compiled
against non-stateless zerokit and is now uncompilable in the plugin's build.
The IMT is internal-only, so pmtree parity is no longer a load-bearing
invariant — what we need is regression protection for the Nim IMT itself,
which the renamed test still provides.

* chore(nimble): bump libp2p to release/v2.0.0 tip + libp2p-mix to v2.0 bump

- libp2p pin: d4cd68b91b → c43199378 (release/v2.0.0 tip; 3 patch commits
  past the v2.0.0 bump). SHA-pinned because vacp2p/nim-libp2p has not yet
  published a v2.0.0 git tag.
- libp2p-mix pin: 99d2ca07 → a32af1a4 (chore/bump-libp2p-v2.0.0 tip after
  the v2.0.0 adaptation commit).
- nim minimum: 2.0.0 → 2.2.4 to match v2.0.0's transitive requirement.

Zero plugin code changes needed: libp2p v2.0.0's API churn (LPProtocol stream
limits, Switch service lifecycle, sink changes, etc.) does not affect the
plugin (no LPProtocol subclassing, no Service subclassing, no Connection
subclassing). Verified compile-link against the new libp2p-mix.

* chore(nimble): bump libp2p_mix pin to PR #14 HEAD

Brings in the move-semantics propagation + lockfile-as-build-artefact
cleanup. Pinned to the PR HEAD (50c4ab4) until logos-co/nim-libp2p-mix#14
and #12 merge to master.

waku.nimble pins the same SHA to keep the diamond dep collapsed to a
single libp2p_mix source.

* fix(nimble): correct libp2p_mix SHA to actual PR #14 tip

Previous commit (78995fc) pinned a fabricated SHA suffix
(50c4ab43904baa3...) that doesn't exist on the remote. The actual tip of
experiment/drop-nimble-lock is 50c4ab4fa788a33eb12a0a2cecaa708873352b58.
Both `git ls-remote origin experiment/drop-nimble-lock` and the cold-cache
build failure confirmed this.

waku.nimble pin will mirror this corrected SHA.

* refactor: rename newMixRlnSpamProtection to MixRlnSpamProtection.new

* feat: make PublishCallback return Result and track broadcast futures (#11)

Previously PublishCallback returned Future[void], so publish errors were
silently dropped, and the proof-metadata broadcast in the synchronous
verifyProof method was fired via an untracked asyncSpawn.

- PublishCallback now returns Future[Result[void, string]] so callers can
  handle publish failures.
- group_manager membership broadcasts handle the returned error (warn).
- verifyProof is a sync method (overrides a sync base), so it cannot await;
  its proof-metadata broadcast now runs as a tracked background future
  (pruned when finished, cancelled in stop()) instead of asyncSpawn.
- update createLoggingPublishCallback and doc examples accordingly.

Addresses review feedback on logos-delivery#3931.
chaitanyaprem added a commit to logos-co/mix-rln-spam-protection-plugin that referenced this pull request Jul 9, 2026
* feat: migrate to zerokit v2.0.2

Bumps zerokit FFI from v2.0.0 to v2.0.2, matching the version pinned by
logos-delivery#3868.

v2.0.1 dropped the Result wrapper from hash/keygen FFIs — update the four
affected signatures (ffi_hash_to_field_le, ffi_poseidon_hash_pair,
ffi_extended_key_gen, ffi_seeded_extended_key_gen) and their callers.
Removes the now-unused CResultVecCFrVecU8 and the duplicated credential
parsing.

v2.0.2 adds ffi_rln_proof_new — verifyRlnProof now uses it to build the
FFI_RLNProof directly from field elements, replacing the manual 290-byte
wire-format assembly (drops buildProofBytesLe + SingleVersionByte).

Unlike logos-delivery, this plugin keeps an offchain Merkle tree, so
zerokit must be built with default features (NOT --features stateless);
ffi_set_next_leaf / ffi_get_root / ffi_get_merkle_proof remain in use.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* refactor(rln-ffi): tighten ffi wrapper after v2.0.2 migration

- verifyRlnProof now requires validRoots (both call sites already passed
  it). Drops the dead ffi_verify_rln_proof fallback and its FFI import.
- Add ffi_rln_free and a close*(instance) proc so long-running embedders
  can tear down the zerokit box explicitly.
- Hoist gcsafe into the file-level {.push.}; drop per-proc annotations.
- Extract buildWitnessFromPath: both buildWitness overloads now share the
  scalar-witness setup. The fresh-path overload keeps zero-conversion
  semantics (zerokit-owned Vec_CFr passed straight through); the cached
  overload still reconstructs from bytes (FFI_MerkleProof handle does
  not survive across partial-proof cache calls).
- Drop now-unused ffi_bytes_le_to_rln_proof import.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* feat: use stateless rln (#9)

* feat(rln): replace pmtree backend with Nim IMT for stateless zerokit

Move Merkle tree state from zerokit's pmtree-ft to a pure-Nim
IncrementalMerkleTree (depth-20 Poseidon).  Lets the plugin build
against zerokit --features stateless and share a single archive with
relay -- eliminates the dual-archive symbol collision after zerokit's
v0.9->v2.0 FFI rename.

Architecture matches zerokit's documented stateless pattern
("stateless RLN and separate Merkle tree", rln-cli/README.md).
Byte-parity with pmtree locked down by a 61-op fixture captured from
the default-features build, plus delete/sparse-setLeaf/idempotency/
out-of-capacity coverage.

* chore(nimble): bump nim-libp2p to d4cd68b91b

Aligns with nim-libp2p-mix's libp2p pin so the diamond dependency
(waku -> {libp2p, nim-libp2p-mix -> libp2p}) resolves to a single
libp2p source.  d4cd68b91b is 14 commits past b16873f07, which means
the boringssl URL+range form is in place -- nimble vnext SAT can
solve without --solver:legacy.

No code changes; plugin only uses libp2p/protobuf/minprotobuf and
libp2p/varint, neither of which changed in the e1bbda4f6..d4cd68b91b
window.  All 29 plugin tests still green.

* chore(nimble): bump nim-libp2p-mix pin to 99d2ca0

nim-libp2p-mix#f24cd25a (its master tip) still pins libp2p#7e72c0d6,
which uses the pre-fix URL+tag form for boringssl and triggers the
nimble vnext SAT bug at any downstream consumer that also requires
modern libp2p (URL+range form).

99d2ca0 (chore/bump-libp2p-master tip on origin) bumps that pin to
libp2p#d4cd68b91b -- same as our pin in the prior commit -- so the
constraint graph is consistent end-to-end.  Carries PR #10's
Rng-type migration; does not affect this plugin (only
libp2p_mix/spam_protection is imported and its API surface is
unchanged).

All 29 plugin tests green against the new pin.

* chore(stateless-rln): drop pmtree-parity scaffolding, keep IMT regression test

capture_golden.nim and the pmtree-derived golden fixture served as the
one-time migration acceptance criterion; capture_golden.nim only compiled
against non-stateless zerokit and is now uncompilable in the plugin's build.
The IMT is internal-only, so pmtree parity is no longer a load-bearing
invariant — what we need is regression protection for the Nim IMT itself,
which the renamed test still provides.

* chore(nimble): bump libp2p to release/v2.0.0 tip + libp2p-mix to v2.0 bump

- libp2p pin: d4cd68b91b → c43199378 (release/v2.0.0 tip; 3 patch commits
  past the v2.0.0 bump). SHA-pinned because vacp2p/nim-libp2p has not yet
  published a v2.0.0 git tag.
- libp2p-mix pin: 99d2ca07 → a32af1a4 (chore/bump-libp2p-v2.0.0 tip after
  the v2.0.0 adaptation commit).
- nim minimum: 2.0.0 → 2.2.4 to match v2.0.0's transitive requirement.

Zero plugin code changes needed: libp2p v2.0.0's API churn (LPProtocol stream
limits, Switch service lifecycle, sink changes, etc.) does not affect the
plugin (no LPProtocol subclassing, no Service subclassing, no Connection
subclassing). Verified compile-link against the new libp2p-mix.

* chore(nimble): bump libp2p_mix pin to PR #14 HEAD

Brings in the move-semantics propagation + lockfile-as-build-artefact
cleanup. Pinned to the PR HEAD (50c4ab4) until logos-co/nim-libp2p-mix#14
and #12 merge to master.

waku.nimble pins the same SHA to keep the diamond dep collapsed to a
single libp2p_mix source.

* fix(nimble): correct libp2p_mix SHA to actual PR #14 tip

Previous commit (78995fc) pinned a fabricated SHA suffix
(50c4ab43904baa3...) that doesn't exist on the remote. The actual tip of
experiment/drop-nimble-lock is 50c4ab4fa788a33eb12a0a2cecaa708873352b58.
Both `git ls-remote origin experiment/drop-nimble-lock` and the cold-cache
build failure confirmed this.

waku.nimble pin will mirror this corrected SHA.

* refactor: rename newMixRlnSpamProtection to MixRlnSpamProtection.new

* feat: make PublishCallback return Result and track broadcast futures (#11)

Previously PublishCallback returned Future[void], so publish errors were
silently dropped, and the proof-metadata broadcast in the synchronous
verifyProof method was fired via an untracked asyncSpawn.

- PublishCallback now returns Future[Result[void, string]] so callers can
  handle publish failures.
- group_manager membership broadcasts handle the returned error (warn).
- verifyProof is a sync method (overrides a sync base), so it cannot await;
  its proof-metadata broadcast now runs as a tracked background future
  (pruned when finished, cancelled in stop()) instead of asyncSpawn.
- update createLoggingPublishCallback and doc examples accordingly.

Addresses review feedback on logos-delivery#3931.

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants