Skip to content

[DRAFT] [DO NOT MERGE] Wasm second iteration#5321

Draft
v1rtl wants to merge 12 commits into
ethersphere:masterfrom
v1rtl:wasm-second-iteration
Draft

[DRAFT] [DO NOT MERGE] Wasm second iteration#5321
v1rtl wants to merge 12 commits into
ethersphere:masterfrom
v1rtl:wasm-second-iteration

Conversation

@v1rtl

@v1rtl v1rtl commented Jan 16, 2026

Copy link
Copy Markdown

Checklist

  • I have read the coding guide.
  • My change requires a documentation update, and I have done it.
  • I have added tests to cover my changes.
  • I have filled out the description and linked the related issues.

Description

Open API Spec Version Changes (if applicable)

Motivation and Context (Optional)

Related Issue (Optional)

Screenshots (if appropriate):

@v1rtl v1rtl force-pushed the wasm-second-iteration branch 3 times, most recently from c598404 to fc0682a Compare January 22, 2026 20:42
@v1rtl v1rtl force-pushed the wasm-second-iteration branch from a6748db to dfad167 Compare June 2, 2026 09:30
Comment thread wasm-demo/interstitial.js

function setStatus(text) {
s.textContent = text;
console.log("[bzz-page]", text);
v1rtl added 12 commits June 2, 2026 12:39
Forks rebased onto bee v2.8's pinned versions (go-libp2p v0.48.0,
go-ethereum v1.16.9, goleveldb) with js-only patches behind //go:build js.
Native build is unaffected (native side identical to upstream).
pkg/fs wraps os file operations behind an OsFile interface.
fs_native.go (!js) delegates to os; fs_js.go (js,wasm) provides a
syscall/js-backed virtual filesystem for the browser.
Swap direct os.* file calls for pkg/fs equivalents in keystore, sharky
recovery, and storer so the same code compiles for js/wasm (where pkg/fs
is js-backed) while remaining identical on native. io/fs aliased to
nativeFs to avoid the package-name collision.
Keep Discover/sortAddrsByTCPPreference/isDNSProtocol shared (preserving
v2.8 TCP-preference ordering) and extract only the resolver: native uses
madns.DefaultResolver; wasm uses a DNS-over-HTTPS resolver since browsers
have no system resolver.
Extract the API listener+serve into startAPIServer: native serves over a
TCP listener; wasm registers the handler with the service worker via
wasmhttp. node.go stays shared (api.New/Mount and the existing chainEnabled
guard are platform-agnostic). Adds go-wasm-http-server dep for the js build.
Keep the Service struct and all methods shared in libp2p.go; move the
native constructor (TCP/WS/WSS, AutoTLS, AutoNAT) to libp2p_native.go and
add libp2p_js.go which builds a browser host over the wasmws WebSocket
transport with no listeners. Adds js errno sentinels and the wasmws dep.
Add a 'wasm' Makefile target (GOARCH=wasm GOOS=js, nethttpomithttp2) that
outputs wasm-demo/bee.wasm, plus the wasm-demo/ service-worker harness
(sw.js, wasm_exec.js, index.html, main.js). Build artifacts (bee.wasm,
sw_bundle.js) are gitignored. No cmd split needed: cmd/bee compiles as-is.
Relax the non-empty underlay validation in bzz.ParseAddress/MarshalJSON so
browser/wasm and strict-NAT peers that cannot be dialed back can still
handshake and use protocols over existing connections. Guard the Connect
addressbook.Put so such peers are not stored for reconnection (v2.8 already
guards handleIncoming and the reacher). Port of pr-5326; peer registry
rename already landed upstream via ethersphere#5337.

Note: this is a deliberate protocol relaxation vs upstream v2.8.
Point the bootnode at /dnsaddr/mainnet.ethswarm.org (resolved in-browser via
DoH), set network-id=1/--mainnet=true, fresh data-dir. Add serve.js (Bun
static server with application/wasm MIME and root SW scope).
python -m http.server (3.11+) already serves bee.wasm as application/wasm
and the rest with appropriate content-types; no custom server needed.
Brings in @zenfs/dom@1.2.9 which exposes the IndexedDB backend for ZenFS.
Used to mount /home/user/.bee/mainnet/localstore on IndexedDB so retrieved
chunks survive page reloads (without persisting peer/identity state).
…rstitial

Service-worker gateway extensions to the existing demo, mirroring the IPFS
service-worker-gateway pattern (https://inbrowser.link) but for Swarm:

* Subdomain detection in sw.js: <cid>.localhost, <cid>.bzz.localhost, and
  <cid>.bytes.localhost (the last routes to bee's /bytes endpoint for raw
  chunk retrieval, the others to /bzz for manifest-style content). The
  subdomain label is passed verbatim to bee, which resolves it via the
  cidv1 resolver (swarm-manifest codec 0xfa, keccak-256 multihash, base32
  multibase) back to the underlying 32-byte chunk address.

* main.js register-and-reload bootstrap: subdomain origins register the SW
  on first visit, then reload so the controller can intercept the next
  navigation.

* Readiness probe (/__bee_ready) backed by /peers + a 20s SW-side startup
  grace. Bee bypasses --warmup-time for light nodes (warmupTime=0 in
  pkg/node/node.go for !FullNodeMode), so kademlia bins haven't populated
  by the time the API opens. The grace gives them time before we let the
  page issue retrieval requests.

* interstitial.js: polls readiness, surfaces distinct states (warming
  grace, peer wait, API not ready), and reloads once truly ready so the
  SW's navigation handler forwards to bee.

* IndexedDB-backed localstore mount: chunks + their leveldb index persist
  across reloads so repeat visits don't re-fetch the same chunks. Other
  paths stay InMemory so identity / kademlia / accounting state doesn't
  leak across sessions.

* navigate-mode waitUntil(10s) keeps the SW alive after responses so bee's
  background cache-write goroutines (Cache().Put scheduled async in
  pkg/storer/netstore.go) have time to flush to IndexedDB before Chrome
  idle-kills the worker.

* Bee error passthrough: 4xx/5xx navigation responses surface bee's actual
  JSON error message in a terminal page instead of a misleading
  'content not reachable' string.
@v1rtl v1rtl force-pushed the wasm-second-iteration branch from dfad167 to 1de9ef1 Compare June 2, 2026 09:39
@acud

acud commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

@v1rtl is there a point with having this PR open? we're trying to do some housekeeping with the old stale PRs. what's the plan?

@v1rtl

v1rtl commented Jun 5, 2026

Copy link
Copy Markdown
Author

yeah. I sync it with mainline periodically, but i don't intend to merge it

@acud

acud commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

would it not be better to work on it in a fork then?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants