feat(delegate): add list_secrets key enumeration to secret-storage API#80
Merged
Merged
Conversation
The delegate secret-storage hostcall API (get_secret/set_secret/ has_secret/remove_secret) was opaque key->value with no way to enumerate stored keys. Apps storing an open-ended key family (e.g. River's room:<owner_vk>) could not rediscover what they had stored, which strands dynamic key families across a delegate-WASM rebuild (new delegate key = empty storage, migration could only probe a hardcoded key set). River hit this in freenet/river#345 and had to build app-level ListRequest/ListResponse. Add a first-class enumerate operation to the hostcall surface: - two new `freenet_delegate_secrets` imports, `__frnt__delegate__list_secrets_len` / `__frnt__delegate__list_secrets`, following the existing len-then-fill two-call pattern used by get_secret so a variable-length result crosses the WASM boundary without a fixed cap on the guest side; - `DelegateCtx::list_secrets(prefix)` returning the raw keys (optionally prefix-scoped; empty prefix lists all); - a single authoritative wire codec (`encode_secret_key_list` / `decode_secret_key_list`, length-prefixed records) shared by the host emitter, the guest decoder, and the round-trip tests so the two sides cannot drift. Additive only: no existing import signatures or enum variants change, so deployed delegate WASM is unaffected. Claude-Session: https://claude.ai/code/session_01JZGPSEa8g1Z8Nomv528c8g
The branch adds new public symbols (encode/decode_secret_key_list, the
two __frnt__delegate__list_secrets{,_len} hostcalls, and
DelegateCtx::list_secrets) but kept version = 0.8.1, which is ALREADY
published to crates.io. crates.io refuses to re-publish an existing
version, so the publish that is meant to unblock the freenet-core PR
(#4355) would itself fail.
Bump to 0.8.2: the additions are wire-format-additive (the touched enums
are #[non_exhaustive] and no existing tag numbers move), so this is a
backward-compatible patch release. Verified the wire-format pin tests
(*_wire_format_is_stable) and the new secret_key_list_codec round-trip
tests still pass at 0.8.2.
Stdlib-first: this must merge and publish to crates.io BEFORE the
freenet-core PR (which now depends on "0.8.2") opens for review.
Claude-Session: https://claude.ai/code/session_01JZGPSEa8g1Z8Nomv528c8g
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The delegate secret-storage API (
get_secret/set_secret/has_secret/remove_secret) is opaque key→value with no way to enumerate keys. An app that stores an open-ended family of keys (one per entity, e.g. River'sroom:<owner_vk>) cannot discover what it has stored. This bites hardest during migration: delegate keys areBLAKE3(code_hash || params), so any delegate-WASM change produces a new delegate with empty storage that must migrate the old data — but with no enumeration, migration can only probe a fixed, hardcoded key set, silently stranding dynamic key families. River hit exactly this in freenet/river#345.Solution
Add a first-class
list_secrets(optionally prefix-scoped) operation to the delegate secret-storage API:DelegateCtx::list_secrets,encode/decode_secret_key_listcodec.freenet_delegate_secretsimport module.The new variants are additive on the
#[non_exhaustive]wire-boundary enums — existing bincode discriminants are unchanged, no existing variant is reordered, and deployed delegate WASM compiled against earlier 0.x stdlib continues to deserialize existing variants unmodified.Version bumped 0.8.1 → 0.8.2 so freenet-core can depend on the published release (stdlib-first policy — this PR merges + publishes before the freenet-core consumer PR opens for review).
Testing
Wire-format pin tests (4/4) confirm existing variant tags are unchanged; codec round-trip tests (4/4) cover the new list encode/decode incl. empty and prefix cases. clippy/fmt clean.
Fixes
Part of freenet/freenet-core#4355 (stdlib half). The freenet-core host-side handler lands in a follow-up PR once this publishes to crates.io.