-
Notifications
You must be signed in to change notification settings - Fork 23
Solution: LP-0017 — Whistleblower #48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
92b8bb2
868236e
6d4d308
8e83abc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,141 @@ | ||
| # Solution: LP-0017 — Whistleblower | ||
|
|
||
| **Submitted by:** Thompsonmina | ||
|
|
||
| ## Summary | ||
|
|
||
| Whistleblower is a Logos Basecamp app for censorship-resistant document | ||
| publication. A user picks a file, attaches metadata, and submits; the | ||
| app uploads to Logos Storage, gets back a content identifier (CID), | ||
| broadcasts the CID + metadata over Logos Delivery, and either the | ||
| publisher or any permissionless third party anchors the CID on-chain via | ||
| the `chronicle-registry` SPEL program on LEZ. | ||
|
|
||
| The submission includes `logos-chronicle`, a standalone reusable | ||
| document-indexing module any Basecamp app can depend on, and | ||
| `batch-anchor`, a permissionless CLI that subscribes to the Chronicle | ||
| Delivery topic and batch-anchors accumulated CIDs (up to 50 per tx) | ||
| without coordination with the original publisher. | ||
|
|
||
| ## Repository | ||
|
|
||
| - **Repo:** https://github.com/Thompsonmina/WhistleBlower-Logos- | ||
| - **Demo video:** https://github.com/Thompsonmina/WhistleBlower-Logos-/releases/download/demo-v1/demo.mp4 | ||
|
|
||
| ## Approach | ||
|
|
||
| The pipeline splits cleanly into a **publish path** and an **anchor | ||
| path**, with one shared on-chain registry. | ||
|
|
||
| **Publish path — `logos-chronicle` (Basecamp module).** A Logos Core | ||
| module in C++/Qt exposing JSON-in / JSON-out methods. `publishFileJson` | ||
| chains: (1) upload to Logos Storage with exponential-backoff retries, | ||
| (2) build + sign a metadata envelope (`cid`, `title`, `description`, | ||
| `content_type`, `size_bytes`, `timestamp`, optional `tags`, | ||
| deterministic `metadata_hash`), (3) broadcast on the Chronicle Waku | ||
| topic `/chronicle/1/document-index/json`. Re-broadcasting the same CID | ||
| is deduped locally. Optional `anchorBatchJson` / | ||
| `anchorStatusJson` / `lookupAnchorJson` for publisher-initiated | ||
| on-chain anchoring, wired via a generated FFI cdylib. | ||
|
|
||
| **Anchor path — `chronicle-registry` (SPEL program) + `batch-anchor` | ||
| (CLI).** The registry is a permissionless PDA at | ||
| `[program_id, "registry"]` holding a Borsh `HashMap<CID, CidRecord>`. | ||
| Two instructions: `init_registry(anchorer)` and | ||
| `index_batch(anchorer, cids, metadata_hashes, anchor_timestamps)` up to | ||
| `MAX_BATCH = 50`. Idempotency is in-program (`contains_key`), which is | ||
| what lets the permissionless `batch-anchor` CLI replay any batch after | ||
| a restart without coordination. | ||
|
|
||
| `batch-anchor` is a tokio daemon that seeds an in-memory dedup set from | ||
| on-chain state at startup, catches up over Waku's store protocol for | ||
| messages broadcast while it was offline, subscribes to the live relay, | ||
| and flushes the buffer on either size (50) or time (30 s) — whichever | ||
| comes first. | ||
|
|
||
| **Why LEZ over zone-SDK.** The zone-SDK path "requires a single designated actor to perform consensus | ||
| inscription" concentrating anchor authority and undermining | ||
| the censorship-resistance premise of the problem. A SPEL program on LEZ is | ||
| permissionless — anyone with a wallet can submit `index_batch`, which | ||
| is exactly the property the `batch-anchor` CLI relies on. SPEL also | ||
| ships IDL generation, scaffolding, an auto-generated CLI, and the | ||
| `#[lez_program]` macro — strictly less code than rolling the inscription | ||
| format by hand. | ||
|
|
||
| ## Success Criteria Checklist | ||
|
|
||
| - [x] **Upload**: app uploads to Logos Storage and obtains a CID (chronicle module, `publishFileJson`). | ||
| - [x] **Broadcast**: chronicle publishes a versioned metadata envelope on `/chronicle/1/document-index/json` immediately after upload. | ||
| - [x] **On-chain anchoring (UI)**: chronicle exposes `anchorBatchJson` / `anchorStatusJson` / `lookupAnchorJson`; whistleblower UI wires a per-row "anchor" button. | ||
| - [x] **Batch anchor tool**: `batch-anchor` CLI subscribes to the topic, batches up to 50 CIDs per tx, permissionless, idempotent (in-program `contains_key` + on-chain dedup seed at startup). | ||
| - [x] **On-chain registry**: `chronicle-registry` SPEL program on LEZ stores `(CID, metadata_hash, anchor_timestamp)` keyed on CID; queryable via `batch-anchor lookup <cid>`; ≥10 CIDs per tx (50). | ||
| - [x] **Document-indexing module**: `logos-chronicle` is a standalone Logos Core module with documented JSON API; any Basecamp app can depend on it. | ||
| - [x] **Basecamp app GUI**: `logos-whistleblower` builds via the repo's nix flake and loads into Basecamp. | ||
| - [x] **Module SDK README**: `logos-chronicle/README.md` + `logos-chronicle/docs/api.md`. | ||
| - [x] **IDL for LEZ program**: `chronicle-registry-idl.json` at repo root; regenerated via `make idl`. | ||
| - [x] **Upload retries with exponential backoff**: chronicle storage layer, documented in `logos-chronicle/docs/api.md`. | ||
| - [x] **Broadcast dedup**: chronicle keeps a per-CID publish ledger; subscribers (incl. `batch-anchor`) skip duplicates. | ||
| - [x] **Batch tool resume after interruption**: seeded from chain at startup + Waku store-protocol catch-up over a configurable lookback window. | ||
| - [x] **CU benchmarks (1 + 50 CID)**: documented in `README_CHRONICLE_REGISTRY.md` § Compute units (cold n=1 = 2,240 cycles; cold n=50 = 178,646 cycles). | ||
| - [x] **Local LEZ deployment**: chronicle-registry deploys to a local LEZ devnet via `make deploy`; `scripts/setup.sh` does so end-to-end. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need to have it tested on the testnet/devnet as per criteria here have you tried?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. At the time I submitted i wasnt aware there was a publicly available devnet. I have just now deployed the registry and tested it on there The deploy transaction is a752b72b95ed607f9c7238a042d62639a3cad2d8a2772ec5b047a07e17d7cf11, and an n=50 index_batch ran in 0eddbf2e877430e073a59c6e27842da07b4f34e0b733e4d24643d7074d9cb6cc |
||
| - [ ] **E2E integration tests in CI**: IT contract sketched in `integration-test.toml`; chronicle smoke test on the IT topic; that runs against a real local sequencer; `RISC0_DEV_MODE` left unset so the prover runs in production mode CI runner that runs lez and logoscore environment pending. | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure on this step. Were you able to validate E2E?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To clarify what I meant by "E2E validated": the publish + anchor flows are both exercised by nix run .#smoke-publish # upload → broadcast → status → restart-persistence Both run against actual nwaku and (for anchor) an actual LEZ sequencer + on-chain The reason was scope: smoke-anchor needs the LEZ sequencer running, which is I'm pushing a commit now that should adds them to CI — it brings up nwaku via docker-compose, builds the modules via Nix, There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks, while manually everything must be working we still need to have tests and green CI (as per criteria in the link) |
||
| - [x] **Top-level README** with build, addresses, app, tool, query: `whistleblower/README.md`. | ||
| - [x] **Reproducible E2E demo script**: `scripts/run-app.sh` + . | ||
| - [x] **Narrated video demo**: linked above;. | ||
| - [x] **Dual licensed MIT + Apache-2.0**: `LICENSE-MIT`, `LICENSE-APACHE`. | ||
|
|
||
| ## FURPS Self-Assessment | ||
|
|
||
| ### Functionality | ||
|
|
||
| Upload → broadcast → optional publisher anchor → batch anchor → on-chain | ||
| lookup, end-to-end. Two independent anchor consumers | ||
| (`chronicle::anchorBatchJson` for publisher-initiated, `batch-anchor` | ||
| for permissionless third-party) sharing one registry program. Borsh | ||
| serialisation gives deterministic on-chain bytes (required for risc0 | ||
| proof determinism). Idempotency is enforced in-program so callers can | ||
| replay batches freely. | ||
|
|
||
| ### Usability | ||
|
|
||
| - Whistleblower Basecamp app: file picker + metadata fields + submit; per-row "anchor on-chain" action. | ||
| - One-shot evaluator path: `git clone && cd whistleblower && ./scripts/run-app.sh`. Idempotent. | ||
| - `logos-chronicle` module: JSON-in / JSON-out methods; SDK README + `docs/api.md`. | ||
| - IDL JSON for the LEZ program shipped at repo root. | ||
|
|
||
| ### Reliability | ||
|
|
||
| - Upload: exponential-backoff retry on transient storage failures, structured error after exhaust. | ||
| - Broadcast: chronicle keeps a per-CID publish ledger so re-broadcasts are silent no-ops to subscribers. | ||
| - Batch anchor: dedup set seeded from on-chain state on every startup (no local-state drift); Waku store-protocol catch-up recovers messages broadcast while the anchor was offline. | ||
|
|
||
| ### Performance | ||
|
|
||
| LP-17 R8 — CU costs instrumented via `risc0_zkvm::guest::env::cycle_count()` around each instruction body, logged to sequencer stdout. | ||
|
|
||
| | Instruction | n | Cycles | Cycles / CID | | ||
| |------------------|----|---------|--------------| | ||
| | `init_registry` | — | 414 | — | | ||
| | `index_batch` | 1 | 2,240 | 2,240 | | ||
| | `index_batch` | 50 | 178,646 | 3,573 | | ||
|
|
||
| Worst-case (n=50 near the 100 KiB account-data cap) is ~288k cycles — well under 1 Mi, ~3 % of the NSSA 32 Mi per-tx budget. | ||
|
|
||
| ### Supportability | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can't find in this document mentioning of
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What i had on CI, was tests for the anchor tool were green. But as referenced above i shall push the remaining e2e tests up. |
||
|
|
||
| - Top-level + per-component READMEs, with an LP-17 requirement → file map. | ||
| - `scripts/setup.sh` (idempotent bootstrap) and `scripts/run-app.sh` (one-shot launcher). | ||
| - Project-local `--user-dir` for basecamp means re-runs never touch the user's regular `~/.local/share/Logos`. | ||
| - Pending: CI config + automated E2E test in CI. | ||
|
|
||
| ## Supporting Materials | ||
|
|
||
| - Top-level README: https://github.com/Thompsonmina/WhistleBlower-Logos-/blob/master/README.md | ||
| - Chronicle-registry deep-dive: https://github.com/Thompsonmina/WhistleBlower-Logos-/blob/master/README_CHRONICLE_REGISTRY.md | ||
| - Chronicle module API: https://github.com/Thompsonmina/WhistleBlower-Logos-/blob/master/logos-chronicle/docs/api.md | ||
| - Demo script (off-camera reading copy): https://github.com/Thompsonmina/WhistleBlower-Logos-/blob/master/docs/demo-script.md | ||
| - Demo video: https://github.com/Thompsonmina/WhistleBlower-Logos-/releases/download/demo-v1/demo.mp4 | ||
|
|
||
| ## Terms & Conditions | ||
|
|
||
| By submitting this solution, I confirm that I have read and agree to the [Terms & Conditions](../TERMS.md). | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
overall, in this submission I see you are missing
GitHub issues filed for any problems encountered with Logos technologyhave you had no problems? was everything smooth?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is one of the requirements
https://github.com/logos-co/lambda-prize/blob/master/prizes/LP-0017.md#submission-requirements
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I shall add that to documentation, but the one issue in did encounter i made a pr for it
logos-co/spel#189
its just around serialisation of string vecs in spel cli
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please, add it
any other issues have you had?