remote-store: real Swarm backend via a Bee node#477
Conversation
Replace the four unsupported remote-store stubs with a Bee-backed backend behind the component seam: a shared RemoteStore handle built from the new [remote_store] engine table (API URL, postage batch, feed-signing key), threaded through Components and every module store. Uploads and feed updates are stamped with the configured batch; feed updates are signed host-side. Faults classify by failure: missing configuration is unsupported, malformed guest input invalid-input, a lookup miss unavailable, HTTP 429 rate-limited, 402/403 denied, and a transport timeout timeout. An absent table leaves every call unsupported so guests can probe-then-skip.
lgahdl
left a comment
There was a problem hiding this comment.
Solid work overall — verified feed-key handling never leaks into logs (no Debug derive on Backend, manual Debug impls redact it), the config redaction test is a real assertion (not a tautology), graceful degradation uses .ok_or(...)? everywhere with no unwrap-on-None, and HTTP status-to-Fault mapping is exhaustive except that RateLimited always drops any Retry-After header (minor, can't confirm without bee-rs source whether the header is even exposed).
One thing worth resolving before merge, flagged with appropriate uncertainty since it depends on bee-rs's internal behavior I couldn't fully confirm from its docs:
| let result = backend | ||
| .client | ||
| .file() | ||
| .update_feed(batch, key, &topic, &data) |
There was a problem hiding this comment.
write_feed passes data straight through to update_feed with no timestamp prefix visibly prepended in this code, but read_feed (line 177) unconditionally strips the first FEED_TIMESTAMP_LEN (8) bytes of whatever comes back. If bee-rs's update_feed does NOT prepend that prefix itself (i.e. the caller is symmetrically responsible for it on both read and write, matching how the read side's stripping is handled by this crate rather than the library), then every write-then-read round trip silently eats the first 8 bytes of the guest's own payload — silent data corruption on the primary write path of new infrastructure. I wasn't able to fully confirm from bee-rs's published docs whether the timestamp is applied library-side on write, so this may already be handled correctly — but regardless of which is true, there's no test that chains a real write_feed call into a read_feed call to prove the round trip is intact (write_feed_signs_the_next_update only checks the returned reference; read_feed_strips_the_timestamp_prefix hand-constructs a payload that already has the prefix, so the two paths are never exercised together). Worth adding that round-trip test before merge — it will immediately confirm or rule this out either way.
What
Implements the
nexum:host/remote-storeinterface against a real Swarm backend: aRemoteStorehandle (crates/nexum-runtime/src/host/remote_store_bee.rs) wrapping abee-rsHTTP client, wired throughComponentsBuilder/Components/HostStatealongside the existing chain/store/logs seams.upload/downloadhit Bee's/bytesAPI;read-feed/write-feedhit the single-owner feed API, stripping/prepending the canonical timestamp prefix and signing writes with the configured feed key. A new[remote_store]config table (api, optionalpostage_batch, optionalfeed_key) drives it; absent config or an absent batch/key degrades individual operations tounsupportedrather than failing boot.RemoteStoreErrorprojects ontoFaultby HTTP status (429 to rate-limited, 402/403 to denied, timeout to timeout, 404/malformed to not-found/internal).Why
All four
remote-storefunctions were stubs returningUnsupported. Content-addressed module and adapter distribution (doc 03) and the M4 infrastructure remit need a real Bee-backed implementation.Testing
cargo test -p nexum-runtimecovers the newremote_store_beeunit suite (wiremock-backed: upload/download happy paths and misses, feed read/write incl. missing batch/key, malformed reference, disabled handle, bad config at boot) and the config table's parse + feed-key redaction test; existing supervisor/test_utils fixtures updated for the newremotecomponent slot.AI Assistance
Implemented with Claude Code assistance; reviewed by a human before merge.
Closes #151