register: quiet helper stdout; commit the shared-faucet testnet descriptor

deployments/shared-faucet is the post-2026-08-05-reset testnet deployment,
copied from logos-lez-rln — the testnet target's first committed profile.
docs/journeys/register.md: the narrated pass from the first local run
(devnet-up 15s / provision 350s; two consecutive fresh-devnet passes).
This commit is contained in:
Arseniy Klempner
2026-08-10 20:03:39 -06:00
parent 33383063de
commit 4685c2b4e2
4 changed files with 1674 additions and 2 deletions
+11
View File
@@ -0,0 +1,11 @@
{
"name": "shared-faucet",
"tree_id": "15f5520c1648358440b73a7b11f4a8cf8e44b63b7a0ae326609863e3e2f1b6ee",
"sequencer": "https://testnet.lez.logos.co/",
"registration_program_id": "65343a570616eec04387832a193b258ee48d445f1feb4d842db4f320feec3e7b",
"merkle_program_id": "ec8c814c6b2d0854c75a86a5e1c63f0df00598f23b27b3fc8f14e3eeeba0161d",
"config_account": "8Subd1uJZAQRxTnh3Y2KQEaoexpyFQHp28yWCzZcZB14",
"payment_account": "EMG8ax4F9nRyKPbAu87xctu25Ku6JAkk5fsKLTCkY6K7",
"supply_holding": "DJwWhGqfkFdxnu54umQXUiFzPPr6ADRC5n3Xm3CbECok",
"funding": "faucet"
}
File diff suppressed because it is too large Load Diff
+79
View File
@@ -0,0 +1,79 @@
# register — what a pass looks like
`./run.sh register --target local` on a darwin-arm64 laptop, nothing else
running, 2026-08-10. One command: boots a local sequencer, provisions a fresh
RLN tree, and drives a paid membership through the full module stack.
## The run, narrated
**Artifacts** (seconds, all from the flake pins):
```
== artifacts ==
e2e: pins consistent: lez-rln ff02e202cedb (rln-layouts + flake.lock)
e2e: bundles: logos-logos_execution_zone-module-lib.lgx, logos-liblogos_lez_rln_module-module-lib.lgx, logos-liblogos_rln_module-module-lib.lgx
```
The pin gate matters: if the rln-modules tree pinned `rln-layouts` at a
different lez-rln rev than the one deployed, chain-state decode skew would
present as phantom chain bugs. It fails loudly instead.
**Target** — a fresh chain and a fresh tree, every run:
```
e2e: timing: devnet-up 15s # dev.sh, sequencer build cached
e2e: timing: provision 350s # run_setup: programs + config + faucet PDA
e2e: timing: stage 0s
e2e: deployment: sequencer http://127.0.0.1:3040/, funding faucet
```
Provisioning dominates a cold run (~6 min); `E2E_DEVNET=external` plus
`E2E_DEPLOYMENT_DIR` skips both for the inner loop.
**The scenario** — registration is paid from a faucet claim (no gifter, no
pre-funded pool), and the price comes from the live bounds, not a constant:
```
== wallet ==
e2e: holding: 3d6d39a789a9866173c49a6b7b084cc487397a5402f8c5d7fd92b122f66026a6
e2e: claiming 2000000 RLNTOK from the faucet (rate 100 x price 10000 x2)
== registration ==
e2e: keystore unlocked
e2e: register(logos:local:98cee59d…, rate 100) via membership module
e2e: pending membership: 7a8217ad… (commitment 317ce6db326b77f0…)
e2e: state poll 3: active
e2e: ACTIVE at leaf 0
e2e: get_merkle_proof returned a rooted proof
e2e: cross-check: rln module sees the membership (active)
== rate-limit proofs ==
e2e: proof issued (message_id 0, epoch 29773555)
e2e: epoch quota: remaining 99/100 in epoch 29773555
e2e: verify_proof: valid
e2e: tampered signal correctly invalid
e2e: PASS — registered on logos:local:98cee59d028f02cf72606efcf1008aa5c032df6930114b5284a59b926cf0b5a9
```
The registry id is `logos:${E2E_TARGET}:<config-account-hex>` — the target is
a flag; the same file, unchanged, runs `--target testnet` with the testnet
poll budgets from the contract.
## What it proves
- The three-module stack (`logos_execution_zone`
`liblogos_lez_rln_module``liblogos_rln_module`) loads and speaks the
lidl wire in a logoscore daemon.
- The paid Register path end-to-end on chain: claim → register → active
leaf → merkle proof, cross-checked between the two RLN modules.
- Proof crypto against live chain state: generate → quota decrement →
verify valid → tampered-signal invalid.
- R2 (lp calls into a Rust module) and R4 (host-stamped persistence path)
hold — their failure modes have dedicated diagnostics in the scenario.
## Knobs
`E2E_KEEP=1` leaves the devnet + daemon up for inspection. `E2E_RATE_LIMIT`
changes the registered rate (claim scales with it). `E2E_DEVNET=external`
attaches to your own sequencer. Budgets: `docs/contract.md`.
+2 -2
View File
@@ -106,7 +106,7 @@ section "wallet"
wallet_open "$NODE" || die "wallet open failed"
CHAIN_HEAD=$(chain_head) || die "cannot probe chain head at $E2E_SEQUENCER"
say "syncing wallet to chain head $CHAIN_HEAD"
wallet_sync "$NODE" "$CHAIN_HEAD"
wallet_sync "$NODE" >/dev/null || die "wallet sync failed"
# ---------- faucet funding (Register-instruction path, no gifter) -----------
say "deriving a fresh holding account"
@@ -126,7 +126,7 @@ say "claiming $CLAIM RLNTOK from the faucet (rate $RATE_LIMIT x price $PRICE x2)
CLAIM_RES=$(node_call "$NODE" liblogos_lez_rln_module claim_tokens \
"$(argfile cfg2 "$E2E_CONFIG_ACCOUNT")" "$(argfile hold "$HOLDING")" "$CLAIM" | jres) || CLAIM_RES=""
[ -n "$CLAIM_RES" ] || die "claim_tokens failed"
wait_balance "$NODE" "$HOLDING" "$CLAIM" || die "faucet credit never landed (want $CLAIM)"
wait_balance "$NODE" "$HOLDING" "$CLAIM" >/dev/null || die "faucet credit never landed (want $CLAIM)"
# ---------- scope (the identity is generated INSIDE the module) --------------
# The consumer supplies only the scope (registry_id + rln_identifier) and the