diff --git a/solutions/LP-0003.md b/solutions/LP-0003.md new file mode 100644 index 00000000..38a6bb3c --- /dev/null +++ b/solutions/LP-0003.md @@ -0,0 +1,196 @@ +# Solution: LP-0003 - Commons / Private allowlist registration + +**Submitted by:** Rithik Kumar S ([@NotRithik](https://github.com/NotRithik)) + +**Draft status:** the implementation and deployment evidence are supplied. The builder-narrated video is pending, and consumed-CU reporting remains qualified below. + +## Summary + +Commons lets eligible members register once without publishing which address they hold in the committed list. The reference integration is a private allowlist gate, not a token payout. Two testnet distributions have twenty accepted claims between them. + +Fresh public reads at **block 4744** show **10 unique claims in each of two distributions**: + +- `03dd452cdaad00ae8be856d601415439eb3e69fbca9ce49974fe68c46dc2cd40` +- `c19bcad81fb89d3c95b3ac5c7e1ce006fa61bb28a5e15282bd79f8f7c0ab0231` + +Diana's separate three-member UI list is `204c317672d276829d91f07634d5705d9ad64f1d0b79c883281c511eec09ec3a`. Her private claim confirmed at block 4430. It is additional GUI evidence, not one of the two twenty-claim reference distributions. + +## Repository + +- **Repo:** https://github.com/NotRithik/commons-for-logos +- **Submission source:** [`10a61ea`](https://github.com/NotRithik/commons-for-logos/tree/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb), including the checked demo entrypoint and metadata aliases. +- **Release:** [v0.2.0-rc.2](https://github.com/NotRithik/commons-for-logos/releases/tag/v0.2.0-rc.2), including the Basecamp LGX, native CLI, three compiled programs, SPEL interfaces and SHA256SUMS. +- **Compiled-source release:** [b81a902](https://github.com/NotRithik/commons-for-logos/tree/b81a902b15b9260bb8b544a4c90e8a5cc01a9452). The submission entrypoint, metadata aliases and documentation do not change those program or application binaries. +- **Licenses:** [MIT](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/LICENSE-MIT) and [Apache-2.0](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/LICENSE-APACHE), at the user's option. +- **Program ID:** `87899fa9d54866a7d1c7dbe71e68506f970fe53cc7f6ca724f0150c83fd5c7d3`. The LEZ word-array representation and binary checksum are in [release/manifest.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/release/manifest.json). +- **Video:** pending. [docs/RECORDING-LP-0003.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/RECORDING-LP-0003.md) describes the required recording. + +LP-0002 and LP-0003 share a native UI and SDK but have different on-chain programs, separate deployment evidence and separate solution PRs. Kite / LP-0008 is not part of this package. + +## Approach + +Commons commits to eligible members using scoped Merkle leaves and derives per-action nullifiers from the authorized private account, not a caller-selected arbitrary secret. Witness-bearing actions use LEZ private transactions and local RISC0 proofs. Public account ownership, context and state invariants are checked separately from UI labels. + +A public Merkle-proof claim would reveal the member leaf and link an eligible address to the claim. A centralized eligibility server would add an operator that could identify and selectively deny claimants. Commons instead keeps the inclusion witness inside the local private proof while the on-chain program enforces one accepted nullifier per eligible member and distribution. The distributor still knows the enrollments it collected; the set size, commitment, accepted-claim count and timing remain public. + +The reference integration is the allowlist-registration branch of the prize, not a token payout. A registration proves eligibility and records one accepted participation. No balance-based token-holding check, minted asset or transferred allocation is claimed. The native interface separates local list preparation, reviewed on-chain publication, invitation import and the actual private registration. Its typed CLI boundary accepts fixed operations and bounded JSON, not arbitrary shell commands. + +The shared repository also contains a distinct threshold-governance program for LP-0002. That program and its governed-setting consumer are not used as evidence of an LP-0003 claim. LP-0003 uses the separately identified allowlist program, its own SPEL interface and its two reference distributions. + +LEZ supplies shielded authorization and independently enforced state transitions; RISC0 supplies local proof execution. A centralized substitute would reintroduce a trusted operator for eligibility, duplicate prevention and acceptance. Logos Basecamp supplies a native modular interface. Messaging and Storage are not claimed dependencies for this standalone primitive. + +### Reproduce + +Install the prerequisites in [docs/LOCAL-DEMO.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/LOCAL-DEMO.md), then run: + +```sh +git clone https://github.com/NotRithik/commons-for-logos.git +cd commons-for-logos +/bin/sh scripts/prepare-local.sh fetch +/bin/sh scripts/prepare-local.sh build +./demo.sh --mode allowlist-smoke +``` + +The local runner starts its own standalone sequencer and uses real local proofs with `RISC0_DEV_MODE=0`. It refuses an occupied port rather than stopping another service. `./demo.sh --help` only lists options. + +`allowlist-smoke` makes one real claim in each of two local distributions. It is a smaller CI check; the twenty-claim requirement is demonstrated separately on the public testnet. + +For read-only inspection of the existing public deployment, run: + +```sh +python3 scripts/check-public-state.py --require LP-0003 +``` + +This loads no wallet and sends no transaction. [docs/GUI.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/GUI.md) covers the native app and typed CLI; [docs/NATIVE-BUILD.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/NATIVE-BUILD.md) covers installation. + +## Success Criteria Checklist + +- [x] **A distributor can commit to an eligibility set on-chain without revealing individual addresses.** + + The distributor publishes a context-bound Merkle root and set size; individual enrollments remain off chain. + +- [x] **An eligible recipient can claim their allocation without revealing which address in the set they hold.** + + The allocation is a membership registration, not a token payout. Diana's shielded claim confirmed at block 4430 without placing her address in public application state. [evidence/ui-membership-4430.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/ui-membership-4430.json) + +- [x] **A recipient cannot claim more than once (double-claim prevention via nullifiers or equivalent).** + + Per-distribution nullifiers prevent reuse. Diana's repeated registration was refused and the list stayed at one accepted claim. [evidence/ui-manual-observations-20260911.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/ui-manual-observations-20260911.json) + +- [x] **An on-chain observer cannot link a completed claim to any specific address in the eligibility set.** + + The private LEZ transaction hides the eligibility witness and member account under the stated cryptographic assumptions. Traffic correlation and knowledge of private keys are outside the guarantee. + +- [x] **The submission documents its full privacy model: what on-chain observers learn, what the distributor learns, at which points in the claim flow identity information is revealed or withheld, and where trade-offs or residual leakage remain. Claims of privacy must be precise — "unlinkable" must be defined relative to a stated threat model.** + + [docs/PRIVACY.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/PRIVACY.md) describes public state, organizer enrollment knowledge, client secrets, centrally controlled demo keys and residual metadata leakage. + +- [x] **A reference integration is delivered: a working demo of a private airdrop or allowlist gate on LEZ testnet.** + + The reference integration is private allowlist registration through Basecamp. It records eligible participation; it does not transfer tokens or check a token balance. + +- [x] **At least 2 distinct distributions are deployed on LEZ testnet, with a combined total of at least 20 unique claims completed across them; the distributions must be reproducible and evidence must be provided.** + + The two separately owned distribution accounts each contain ten distinct accepted nullifiers: twenty claims total, freshly read at block 4744. [evidence/submission-public-state-20260912.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/submission-public-state-20260912.json) + +- [x] **Full documentation and a clean public repository are delivered.** + + The public repository includes the SDK, CLI, native module, protocol, privacy, errors, deployment and build documentation. + +- [x] **Provide a module/SDK that can be used to build Logos modules for interacting with the program.** + + The Rust SDK and typed native client support list preparation, state reads and private claims. Governance and its consumer are separate LP-0002 programs. + +- [x] **Provide a Logos Basecamp app GUI with local build instructions, downloadable assets, and loadable in Logos app (Basecamp).** + + The RC2 LGX and client assets are published. A fresh Package Manager install and a wallet-free on-chain read passed. [evidence/clean-install-20260911.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/clean-install-20260911.json) + +- [x] **Provide an IDL for the LEZ program, using the [SPEL framework](https://github.com/logos-co/spel).** + + SPEL-generated interfaces are supplied in idl/generated, including .idl.json aliases matching the generated JSON byte-for-byte. [idl/generated/wire-format.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/idl/generated/wire-format.json) + +- [x] **The system handles proof generation failures gracefully and surfaces a clear error to the claimant.** + + The missing-proof-engine check returned LOCAL_PROVER_UNAVAILABLE before submission and left the wallet unchanged. Native controls expose failures instead of reporting a successful claim or approval. [evidence/ui-manual-observations-20260911.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/ui-manual-observations-20260911.json) + +- [x] **A failed or rejected claim does not mark the claimant as having claimed, allowing a retry.** + + Invalid witnesses leave application state unchanged. Missing-engine and invalid-invitation refusals happen before submission; the duplicate-registration check preserves the existing count. An ambiguous post-submission failure requires reconciliation, not blind retry. [docs/PROTOCOL.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/PROTOCOL.md) + +- [x] **The verifier program returns deterministic, documented error codes for all invalid-proof and double-claim scenarios.** + + The verifier uses documented deterministic errors for invalid state, identity, witnesses and duplicate use. [docs/ERRORS.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/ERRORS.md) + +- [ ] **Document the compute unit (CU) cost of each on-chain operation on LEZ devnet/testnet. Note: LEZ's per-transaction compute budget may change during testnet.** + + Measured guest cycles and proof/confirmation times are in [docs/PERFORMANCE.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/PERFORMANCE.md). The pinned API has no consumed-CU receipt; this criterion remains qualified. [Upstream issue 840](https://github.com/logos-blockchain/logos-execution-zone/issues/840) is open. + +- [x] **The program is deployed and tested on LEZ devnet/testnet.** + + The deployed program owner IDs and current application state were rechecked at block 4744 without loading wallets or sending transactions. [evidence/submission-public-state-20260912.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/submission-public-state-20260912.json) + +- [x] **End-to-end integration tests run against a LEZ sequencer (standalone mode) and are included in CI.** + + The real standalone [run 34309398475](https://github.com/NotRithik/commons-for-logos/actions/runs/34309398475) passed both threshold and allowlist-smoke jobs with RISC0_DEV_MODE=0. It ran an earlier commit whose executed primitive/runner sources match RC2; later UI and consumer checks are separate. [evidence/real-proof-source-correspondence.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/real-proof-source-correspondence.json) + +- [x] **CI must be green on the default branch.** + + Release-source tooling [run 34622435353](https://github.com/NotRithik/commons-for-logos/actions/runs/34622435353) and portable/native [run 34622435250](https://github.com/NotRithik/commons-for-logos/actions/runs/34622435250) passed on b81a902b15b9260bb8b544a4c90e8a5cc01a9452. Submission additions are the shell entrypoint, metadata aliases, documentation and fresh read-only evidence; their local checks are recorded separately. + +- [x] **A README documents end-to-end usage: deployment steps, program addresses, and step-by-step instructions for interacting with the program via CLI and Basecamp app.** + + The [README.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/README.md) links step-by-step CLI/Basecamp use, build prerequisites, deployed addresses and [docs/QUICK-START.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/QUICK-START.md). + +- [x] **A reproducible end-to-end demo script is provided and works against a real local sequencer with `RISC0_DEV_MODE=0`.** + + The executable demo.sh delegates to the same real-sequencer Python runner used by the successful CI. Local launcher and metadata checks passed before publication. [evidence/submission-entrypoint-checks-20260912.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/submission-entrypoint-checks-20260912.json) + +- [ ] **A recorded video demo of the end-to-end flow is included in the submission; the recording must show terminal output (including proof generation) to confirm `RISC0_DEV_MODE=0` was active.** + + Builder-narrated video is pending. The required recording must show the complete prize-specific flow and actual proof-generation terminal output with RISC0_DEV_MODE=0. CI logs and JSON receipts are linked evidence, not a replacement video. + +## FURPS Self-Assessment + +### Functionality + +The allowlist program commits a fixed eligible set and accepts one private registration per eligible member. Two separate testnet distributions have ten unique accepted claims each; the newer three-member native-UI example is additional evidence. The program does not distribute tokens, check token balances, or change eligibility after publication. LP-0002 governance is a separate program and submission. + +### Usability + +Users select named identities and workspaces, exchange enrollment/invitations without sharing keys, review the exact action, and see confirmed results or actionable errors. The supplied launcher prepares an isolated key-free first-use profile. The UI distinguishes proving, confirmation and errors. + +### Reliability + +Duplicate registration and invalid membership invitations are rejected. A local validation or missing-engine failure before broadcast does not consume a claim. An unknown result after private submission requires reconciliation; some upstream private-call failure windows are not durably checkpointed before broadcast, so this is not a promise of automatic exactly-once retry. Testnet resets are diagnosed rather than hidden by replaying old wallets. + +### Performance + +Real guest-cycle measurements and proof-plus-confirmation times are separate. The pinned sequencer's missing billed-CU field is a stated upstream limitation, not a fabricated gas estimate. Proof duration depends on local hardware and network conditions. + +### Supportability + +Pinned source/dependencies, local build scripts, generated interfaces, deterministic errors, public receipts and separate portable/real-sequencer CI are supplied. The successful standalone run and both final default-branch jobs are linked below, with the older real-proof commit distinguished from the current GUI and adapter evidence. Host fixtures do not count as a real-chain proof. + +## Known limitations + +The organizer receives member enrollments but not signing keys. A compromised machine, disclosed private wallet, or known off-chain action/person correspondence defeats the corresponding anonymity claim. Small sets, timing, network identifiers, eligibility-set size and accepted-claim counts remain observable. Demo identities on one laptop are independent keys, not independent humans. The upstream wallet stores plaintext JSON protected by filesystem permissions, not encrypted custody. + +The application uses the pinned LEZ v0.2.4 API. Some private proving/submission failure windows do not yield a durable returned hash, so a timeout must be investigated before another attempt. [docs/PROTOCOL.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/PROTOCOL.md) states that boundary. + +The consumed-CU counter is unavailable through the pinned RPC. [docs/PERFORMANCE.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/PERFORMANCE.md) reports guest cycles, elapsed times and byte sizes separately. [LEZ issue 840](https://github.com/logos-blockchain/logos-execution-zone/issues/840) remains open without clarification; no conversion to network CUs is asserted. + +## Supporting Materials + +- [evidence/submission-public-state-20260912.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/submission-public-state-20260912.json) +- [evidence/submission-entrypoint-checks-20260912.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/submission-entrypoint-checks-20260912.json) +- [evidence/ui-manual-observations-20260911.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/ui-manual-observations-20260911.json) +- [evidence/clean-install-20260911.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/clean-install-20260911.json) +- [evidence/ui-membership-4430.json](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/evidence/ui-membership-4430.json) +- [docs/PRIVACY.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/PRIVACY.md) +- Release-source CI: [run 34622435353](https://github.com/NotRithik/commons-for-logos/actions/runs/34622435353) and [run 34622435250](https://github.com/NotRithik/commons-for-logos/actions/runs/34622435250). +- Real standalone proofs: [run 34309398475](https://github.com/NotRithik/commons-for-logos/actions/runs/34309398475). +- [docs/PROTOCOL.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/PROTOCOL.md), [docs/PERFORMANCE.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/PERFORMANCE.md) and [docs/ERRORS.md](https://github.com/NotRithik/commons-for-logos/blob/10a61ea96a411ca89dc209771c6db8b0aa0d2bfb/docs/ERRORS.md). + +## Terms & Conditions + +By submitting this solution, I confirm that I have read and agree to the [Terms & Conditions](https://github.com/logos-co/lambda-prize/blob/master/TERMS.md).