Skip to content

fix: chain follows end cleanly for the resolver and broker, and gateway archives load in full and from cache - #368

Open
replghost wants to merge 7 commits into
mainfrom
fix/resolver-transport-stop
Open

replghost wants to merge 7 commits into
mainfrom
fix/resolver-transport-stop

Conversation

@replghost

@replghost replghost commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Generic chain-transport, resolver and content-delivery fixes, taken out of the PolkaVM runtime PR (#185) so they can land on their own. Nothing here depends on PolkaVM, the vendored host SDK, notifications or the sandbox contract.

Fixes

Protocol broker (packages/protocol/src/broker.ts)

  • A release the node refuses stops the follow. When the broker's own chainHead_v1_unpin fails, blocks stay pinned that no session holds, and the node may also have dropped them. The broker now unfollows upstream and sends every follower stop, so their owners follow again. A release still in flight when its follow ends is forgotten, so its late reply cannot stop the next follow.
  • Late followers hear every live fork. A session joining a shared follow used to be replayed only the best block's ancestors. A later bestBlockChanged to another fork then named a block that session had never heard of. Now every live block is replayed, parents before children.
  • Retired follow tokens stay local. A request under a follow token the broker has retired (after a stop or unfollow) used to reach the node unchanged. It is now answered locally: chainHead_v1_stopOperation succeeds, since there is nothing left to stop, and anything else fails with Unknown subscription/token.
  • Legacy transaction watches reach their session. The broker did not own author_submitAndWatchExtrinsic subscriptions, so their author_extrinsicUpdate events arrived for an unknown token and were dropped. The local signer from feat(ui): use a Polkadot App account locally from the debug panel #362 registers its allowances through that watch, so registration never completed on main. The broker now owns and releases these subscriptions, and the watch guard ends them with a legacy dropped update when the transport disconnects (packages/protocol/src/watch-guard.ts).

Resolver (packages/resolver)

  • A follow that stops, is destroyed, or cannot unpin fails its reads as stopped. destroy() now ends the raw API the same way a stop does: it notifies its owner once, rejects whenReady(), and fails every read still in flight with ApiStoppedError. Before, those reads were left with papi's DisjointError, or hung on a dead transport. A refused unpin ends the follow instead of keeping history that nothing will release, and a follow initialized without a finalized block stops at once.
  • A stop from a replaced follow leaves the new client alone. Both backends (light client and RPC) now cache a client before subscribing to its stop, ignore stops from a client that is no longer cached, and clear their references before tearing a client down. A follow that stops after becoming ready but before it is cached fails that attempt, so the light-client resolver rebuilds rather than reading through it. An RPC connection abandoned by a network switch can no longer clear its replacement's pending connection, which used to let the next resolve open a duplicate client.

Content (packages/content)

  • Nested files load in full. The importer nests large files under intermediate dag-pb nodes. Those nodes were read as their (usually empty) inline data, so any file nested more than one level deep loaded as zero bytes. They now recurse into their links. A file node's own inline bytes are kept, ahead of its linked chunks.
  • Gateway CAR requests can be cached. ?format=car already selects the CAR representation. The extra Accept: application/vnd.ipld.car header made the gateway skip its immutable-content cache, so every load went back to origin. Requested-CID and CAR-block verification are unchanged.
  • Bitswap discovery coverage. New tests cover provider discovery, which main already does: a child block that no connected peer had yet is fetched on a later attempt, concurrent retries each get their own answer, and a block no peer serves fails at the total retry budget. The block-cache fixtures now finish loading the relay module before a case installs one.

Relationship to #359

#359 changes how withBestBlock retries reads the node reports as inaccessible: it restarts the whole read at the current head. This PR keeps main's pinned-read design and leaves that retry alone. The two touch different lines of api.ts, merge without conflicts, and the merged resolver suite passes.

Not included

Verification

  • npm run typecheck, npm run lint, npm run format:check, npm test (all packages)
  • Each new test fails without its fix:
    • broker: 3 of the 4 new cases fail on main's broker. The fourth guards the stale-release clearing, which only exists with the fix.
    • resolver lifecycle: 4 of 10 fail on main's api.ts, and 2 fail on main's broker.
    • resolve and RPC-resolve races: all 4 new cases fail on main.
    • nested archive: fails on main.
  • Merged with fix(resolver): restart inaccessible reads at the current head #359's head: no conflicts, and the resolver suite passes (167 tests).
  • CI-environment build (VITE_NETWORKS=paseo-next-v2,previewnet VITE_METRICS=true VITE_SENTRY_DSN=…) and the functional suite with the CI threshold: 81 specs, 68 passed, 13 skipped (navigation and host-settings cases that skip themselves; none in network-transport), 0 failed in every gated file.

…very fork, and keeps retired tokens local

A broker-owned unpin the node refuses leaves blocks pinned that no session
holds, so the shared follow now stops for every follower instead of growing
retention unseen; a release still in flight when its follow ends stops
nothing. A session joining a shared follow late is replayed every live fork,
not only the best block's ancestors, so a later best switch never names a
block it has not heard of. A follow token the broker retired is never
forwarded to the node, and stopping an operation under it answers success.
…inline bytes first

The importer nests large files under intermediate dag-pb stem nodes. A stem
was read as its (usually empty) inline data, so every file beyond one link
level loaded as zero bytes; stems now recurse into their links. A file
node's own inline bytes are kept ahead of its linked chunks instead of being
dropped.
…mmutable cache serves them

`?format=car` already selects the CAR representation. The extra
`Accept: application/vnd.ipld.car` header made the gateway bypass its
immutable-content cache for the same archive, so every load went to origin.
Requested-CID and CAR-block verification are unchanged.
…tures from module loading

Provider discovery coverage: a child block no connected peer had yet is
fetched on a later attempt after its root succeeded, concurrent retries get
their own answers, and a block no peer serves fails at the total retry
budget. The block-cache fixtures finish loading the relay module before a
case installs one, so an import that outlives a timed-out case can no longer
install its listener after teardown.
…one, and a follow that stopped before caching is rebuilt

Both resolution backends now cache a client before subscribing to its stop,
check that the stop belongs to the client still cached, and clear their
references before tearing a client down. A late stop from a follow that was
already replaced no longer destroys its replacement, and a follow that
stopped after it became ready but before it was cached fails the attempt so
the resolver rebuilds instead of reading through it. An RPC connection
abandoned by a network switch can no longer clear its replacement's pending
connection and make the next resolve open a duplicate client.
…unpin fails its reads as stopped

Destroying the raw API now ends it like a stop: it notifies its owner once,
rejects readiness, and fails every read still in flight with
`ApiStoppedError` instead of leaving it to papi's `DisjointError` or a
transport that may never answer. A block the node refuses to unpin ends the
follow, so its owner redials rather than retaining history nothing will
release, and a follow initialized without a finalized block stops at once.
The new tests drive the installed substrate client against a scripted
chainHead server, directly and through the protocol broker, and check that no
block is unpinned while a read still uses it.
@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Bundle Size Report

Eager path (module entry + modulepreloaded chunks):

Path Raw Brotli Gzip
host/(eager path) 413.4 KB (-8 B) 141.1 KB (-103 B) 161.1 KB (-2 B)
host/landing/(eager path) 349.6 KB 118.6 KB (-62 B) 135.6 KB (+9 B)
sandbox/(eager path) 242.1 KB (+162 B) 69.5 KB (+61 B) 80.5 KB (+54 B)

Chunks over 500 KB:

File Raw Brotli Gzip
host/assets/truapi_provider_bg.wasm 4.01 MB 955.7 KB 1.27 MB
host/assets/truapi_server_bg.wasm 2.70 MB 731.0 KB 965.5 KB
host/assets/truapi_signing_bg.wasm 2.92 MB 791.8 KB 1.02 MB
host/assets/truapi_verifiable_bg.wasm 4.89 MB 4.61 MB 4.64 MB
Total 16.31 MB (+1.7 KB) 7.62 MB (+391 B) (compression rate: 53%) 8.53 MB (+465 B)
All files
File Raw Brotli Gzip
host/.well-known/apple-app-site-association 505 B 505 B 505 B
host/.well-known/assetlinks.json 2.1 KB 343 B 427 B
host/assets/AccountContent.js 2.4 KB 1.1 KB (+8 B) 1.2 KB (-3 B)
host/assets/AnchoredContent.js 2.1 KB 823 B (-1 B) 899 B
host/assets/AuthButton.js 4.6 KB 1.9 KB (+19 B) 2.1 KB (+8 B)
host/assets/AuthButton.css 1.5 KB 535 B 634 B (+1 B)
host/assets/AuthModal.js 8.0 KB (+11 B) 2.9 KB (-3 B) 3.2 KB (+9 B)
host/assets/AuthModal.css 3.4 KB (+17 B) 815 B (+3 B) 961 B (+6 B)
host/assets/Button.js 2.1 KB 947 B (+3 B) 1.1 KB (+2 B)
host/assets/ChainsContent.js 7.3 KB 2.5 KB (+3 B) 2.8 KB (+2 B)
host/assets/ChatDock.css 469 B 469 B 469 B
host/assets/ChatDock.js 2.3 KB 1.1 KB (-5 B) 1.2 KB (-2 B)
host/assets/ChatPanel.css 5.8 KB 1.3 KB (+1 B) 1.5 KB (+1 B)
host/assets/ChatPanel.js 20.6 KB 6.4 KB (+15 B) 7.2 KB (+2 B)
host/assets/Chip.js 435 B 435 B 435 B
host/assets/DropdownMenu.css 788 B 788 B 788 B
host/assets/DropdownMenu.js 2.5 KB 1.2 KB (-25 B) 1.3 KB (-3 B)
host/assets/DropdownMenuSurface.js 2.0 KB 911 B (-2 B) 1.0 KB (-2 B)
host/assets/FloatingLayer.js 2.6 KB 1.1 KB 1.2 KB (+2 B)
host/assets/IconButton.js 1.3 KB 627 B (+2 B) 740 B
host/assets/LandingAuth.js 238 B 238 B 238 B
host/assets/LandingNav.js 2.8 KB 1.3 KB (+1 B) 1.5 KB (+1 B)
host/assets/LandingNav.css 1.5 KB 488 B (+6 B) 581 B
host/assets/LandingPart.js 648 B 648 B 648 B
host/assets/LandingRecents.js 2.6 KB 1.1 KB (-3 B) 1.2 KB (+4 B)
host/assets/LandingRecents.css 1.3 KB 459 B (+5 B) 578 B (+1 B)
host/assets/LoadingScreen.css 3.3 KB (-19 B) 1.0 KB (-5 B) 1.2 KB (-7 B)
host/assets/LoadingScreen.js 3.8 KB (-8 B) 1.7 KB (+1 B) 2.0 KB (+5 B)
host/assets/LogoWordmark.css 15.5 KB (+17 B) 3.0 KB (-3 B) 3.4 KB (+7 B)
host/assets/Modal.js 2.7 KB 1.0 KB (+4 B) 1.1 KB (+2 B)
host/assets/ModalLayer.js 5.0 KB 2.1 KB 2.3 KB (-1 B)
host/assets/PermissionsContent.js 4.5 KB 1.7 KB (+6 B) 1.9 KB (+2 B)
host/assets/Popover.js 4.3 KB 1.7 KB (-3 B) 1.9 KB (+1 B)
host/assets/PopoverSurface.js 1.3 KB 645 B (+28 B) 705 B
host/assets/SectionLabel.js 1.1 KB 400 B (+1 B) 451 B
host/assets/SegmentedControl.js 1.5 KB 743 B (+6 B) 831 B
host/assets/SessionStore.js 35.9 KB 9.8 KB (-58 B) 12.3 KB (-2 B)
host/assets/SettingsContent.css 4.1 KB 1007 B (-5 B) 1.2 KB
host/assets/SettingsContent.js 9.7 KB 3.2 KB (-5 B) 3.6 KB (+2 B)
host/assets/ShieldIcons.js 1.2 KB 460 B 530 B
host/assets/Spinner.js 241 B 241 B 241 B
host/assets/StatusDot.css 563 B 563 B 563 B
host/assets/StatusDot.js 563 B 563 B 563 B
host/assets/Surface.js 1.6 KB 687 B (+2 B) 774 B (+1 B)
host/assets/Topbar.astro_astro_type_script_index_0_lang.js 468 B 468 B 468 B
host/assets/TopbarActions.js 9.6 KB 3.3 KB (+19 B) 3.7 KB
host/assets/TopbarActions.css 1.3 KB 487 B (+7 B) 589 B (+2 B)
host/assets/TopbarReveal.css 683 B (-4 B) 683 B (-4 B) 683 B (-4 B)
host/assets/TopbarReveal.js 804 B (-2 B) 804 B (-2 B) 804 B (-2 B)
host/assets/UrlPill.astro_astro_type_script_index_0_lang.js 528 B 528 B 528 B
host/assets/UrlPillShield.css 956 B 956 B 956 B
host/assets/UrlPillShield.js 4.6 KB 1.6 KB (-2 B) 1.8 KB (-1 B)
host/assets/VerificationContent.js 1.3 KB 629 B (+5 B) 719 B (+1 B)
host/assets/Well.js 1.2 KB 532 B (+1 B) 612 B (-2 B)
host/assets/_md.js 1.6 KB 799 B 867 B
host/assets/_u64.js 768 B 768 B 768 B
host/assets/account.js 1.2 KB 563 B 643 B (-1 B)
host/assets/active.CPsmhfHv.js 238 B 238 B 238 B
host/assets/app-roots.js 351 B 351 B 351 B
host/assets/auth-controller.js 5.2 KB 2.0 KB (+3 B) 2.3 KB
host/assets/auth.js 386 B 386 B 386 B
host/assets/base.js 4.6 KB 1.9 KB 2.0 KB
host/assets/bitswap.js 12.1 KB 4.2 KB (+8 B) 4.7 KB (+2 B)
host/assets/blake2.js (×2) 12.7 KB 4.9 KB 5.6 KB
host/assets/bridge.js 126.2 KB (+1.0 KB) 28.9 KB (+218 B) 34.6 KB (+297 B)
host/assets/broken.js 248 B 248 B 248 B
host/assets/browser.js 22.6 KB 7.4 KB 8.4 KB
host/assets/chain-sync.js 2.9 KB 1.2 KB 1.3 KB
host/assets/chat-panel.js 2.7 KB 1.0 KB (+1 B) 1.1 KB (-3 B)
host/assets/cid-cache.js 2.0 KB 872 B (+2 B) 964 B (+1 B)
host/assets/client.js (×2) 17.2 KB 6.2 KB 6.8 KB
host/assets/create-store.js 107.6 KB 32.2 KB (-16 B) 36.1 KB (-4 B)
host/assets/db.js 2.3 KB 811 B 940 B
host/assets/device.js 235 B 235 B 235 B
host/assets/dist.js 65 B 65 B 65 B
host/assets/dot-url.js 232 B 232 B 232 B
host/assets/dotli-debug-bus.js (×2) 798 B 798 B 798 B
host/assets/drag.js 430 B 430 B 430 B
host/assets/error-copy.js 259 B 259 B 259 B
host/assets/errors.js (×3) 3.4 KB 1.9 KB 2.0 KB
host/assets/fetch.js 65.0 KB (+202 B) 16.8 KB (+38 B) 19.4 KB (+56 B)
host/assets/fit.js 584 B 584 B 584 B
host/assets/focus.js 1.3 KB 531 B 676 B
host/assets/html.js 435 B 435 B 435 B
host/assets/idle.js 323 B 323 B 323 B
host/assets/in-sheet.js 64 B 64 B 64 B
host/assets/index.css 11.9 KB (-23 B) 2.7 KB (+2 B) 3.0 KB (-13 B)
host/assets/index.astro_astro_type_script_index_0_lang.js 35.5 KB 11.9 KB (-17 B) 13.2 KB (-1 B)
host/assets/ipfs.js 908 B (-46 B) 908 B (-46 B) 908 B (-46 B)
host/assets/landing.css 7.7 KB 1.5 KB (-2 B) 1.8 KB (-4 B)
host/assets/landing.astro_astro_type_script_index_0_lang.js 206 B 206 B 206 B
host/assets/lazy.js (×2) 3.3 KB 1.9 KB (+11 B) 2.0 KB (-3 B)
host/assets/loading.js 268 B 268 B 268 B
host/assets/local-wallet-core.js 3.1 KB 1.4 KB (+3 B) 1.5 KB (+2 B)
host/assets/log.js 1.6 KB 699 B 798 B
host/assets/manifest-types.js 3.6 KB 1.1 KB 1.3 KB
host/assets/manifest.js 21.1 KB (+197 B) 7.0 KB (+61 B) 7.7 KB (+75 B)
host/assets/metrics.js 2.0 KB 882 B 992 B
host/assets/modal-stack.js 681 B 681 B 681 B
host/assets/mount.js (×2) 141.4 KB 41.6 KB (+33 B) 48.7 KB (-8 B)
host/assets/mount.css (×2) 22.3 KB 5.1 KB (-12 B) 5.9 KB (+11 B)
host/assets/network-health.js 3.2 KB 1.3 KB (+8 B) 1.4 KB
host/assets/network-monitor.js 2.8 KB 1.1 KB 1.2 KB
host/assets/network.js (×2) 4.6 KB 2.1 KB 2.3 KB
host/assets/perf.js 148 B 148 B 148 B
host/assets/permission-changes.js 340 B 340 B 340 B
host/assets/permissions.js (×2) 4.4 KB 1.8 KB 2.0 KB
host/assets/phone.Bu6jif0Q.js 307 B 307 B 307 B
host/assets/preload-helper.js 1.4 KB 664 B 792 B
host/assets/product-frame-layout.js 1.0 KB 468 B (-12 B) 536 B (-2 B)
host/assets/product.js 422 B 422 B 422 B
host/assets/proofs.js 26.0 KB 7.6 KB 8.3 KB
host/assets/provider.js 22.2 KB 5.9 KB 6.7 KB
host/assets/recent-labels.js 787 B 787 B 787 B
host/assets/reduced-motion.js 97 B 97 B 97 B
host/assets/resolve.js 4.6 KB (+97 B) 1.8 KB (+30 B) 2.0 KB (+32 B)
host/assets/rolldown-runtime.js 716 B 716 B 716 B
host/assets/root.js 444 B 444 B 444 B
host/assets/rpc-chain.js 28.9 KB 9.3 KB 10.2 KB
host/assets/rpc-resolve.js 2.3 KB (+79 B) 1009 B (+22 B) 1.1 KB (+25 B)
host/assets/runtime-config.js 4.8 KB 1.5 KB 1.7 KB (-3 B)
host/assets/scale-ts.js 4.8 KB 1.9 KB 2.1 KB
host/assets/scale.js 2.2 KB 999 B 1.1 KB
host/assets/settings-actions.js 10.1 KB 3.6 KB (-4 B) 4.0 KB (-3 B)
host/assets/settings-glyph.js 283 B 283 B 283 B
host/assets/settings.js 353 B 353 B 353 B
host/assets/sha2.js 1.9 KB 968 B 1.1 KB
host/assets/shared-mode.js (×2) 1.8 KB 828 B 930 B
host/assets/signing-worker.js (×2) 40.1 KB 9.1 KB 10.3 KB
host/assets/spans.js 824 B 824 B 824 B
host/assets/src.js 80.0 KB 25.1 KB 27.7 KB
host/assets/startup.css 5.7 KB 1.7 KB 1.9 KB
host/assets/startup.js 11.9 KB 4.3 KB (+5 B) 4.8 KB
host/assets/toasts.js 4.5 KB 1.6 KB (-2 B) 1.8 KB (-2 B)
host/assets/topbar.BTLIaz4j.js 2.0 KB 853 B 981 B
host/assets/topbar-status.js 2.2 KB 907 B 1.0 KB (-1 B)
host/assets/topbar.Bq-n4Klp.js 196 B 196 B 196 B
host/assets/topbar.js 575 B 575 B 575 B
host/assets/truapi_provider_bg.wasm 4.01 MB 955.7 KB 1.27 MB
host/assets/truapi_server_bg.wasm 2.70 MB 731.0 KB 965.5 KB
host/assets/truapi_signing_bg.wasm 2.92 MB 791.8 KB 1.02 MB
host/assets/truapi_verifiable.js 14.3 KB 2.8 KB 3.2 KB
host/assets/truapi_verifiable_bg.wasm 4.89 MB 4.61 MB 4.64 MB
host/assets/twoX.js 8.5 KB 3.0 KB 3.3 KB
host/assets/ui.js 3.9 KB 1.4 KB (-3 B) 1.6 KB (-1 B)
host/assets/url-pill.js 382 B 382 B 382 B
host/assets/use-store.js 366 B 366 B 366 B
host/assets/utils.js 3.5 KB 1.4 KB 1.5 KB
host/assets/verify.js (×2) 12.9 KB 4.4 KB 4.8 KB
host/assets/wallet-boot.js 805 B 805 B 805 B
host/assets/wallet-mode.js 184 B 184 B 184 B
host/assets/wallet-switch.js 623 B 623 B 623 B
host/assets/web.js (×2) 93.5 KB 29.2 KB (+1 B) 32.1 KB (+3 B)
host/assets/worker-runtime.js (×2) 37.2 KB 8.8 KB 10.0 KB
host/favicon.svg 1.8 KB 1.8 KB 1.8 KB
host/host-sw.js 9.6 KB 2.6 KB (+7 B) 2.9 KB (-6 B)
host/host_version.json 109 B 109 B 109 B
host/icon-192.png 12.5 KB 12.5 KB 12.5 KB
host/icon-512.png 42.8 KB 42.8 KB 42.8 KB
host/index.html 53.4 KB (-13 B) 12.8 KB (-25 B) 15.0 KB (-13 B)
host/landing.html 38.4 KB (-1 B) 9.6 KB (-7 B) 11.4 KB
host/manifest.webmanifest 441 B 441 B 441 B
host/workbox.js 14.8 KB 4.6 KB 5.1 KB
sandbox/app-sw.js 5.1 KB 1.9 KB (-3 B) 2.2 KB (-3 B)
sandbox/assets/bitswap-bridge.js 1.2 KB 582 B (-2 B) 670 B (-3 B)
sandbox/assets/fetch.js 4.0 KB (-46 B) 1.4 KB (-4 B) 1.6 KB (-3 B)
sandbox/assets/index.css 10.4 KB 2.6 KB 2.9 KB (-2 B)
sandbox/assets/index.js 238.1 KB (+208 B) 68.1 KB (+65 B) 79.3 KB (+60 B)
sandbox/assets/mount.js 66.6 KB 22.0 KB (+16 B) 24.2 KB (-4 B)
sandbox/assets/mount.css 15.6 KB 3.0 KB (-11 B) 3.4 KB (-2 B)
sandbox/favicon.svg 1.8 KB 1.8 KB 1.8 KB
sandbox/host_version.json 108 B 108 B 108 B
sandbox/index.html 1.7 KB 409 B (+4 B) 611 B (-2 B)
Total 16.31 MB (+1.7 KB) 7.62 MB (+391 B) (compression rate: 53%) 8.53 MB (+465 B)

Commit: bbd4689

@github-actions

github-actions Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

⚡ Performance Report

Cold Start

Overall: 🔴 regressed  |  p50: 10.72s → 11.82s (+10.3%)  |  p95: 11.79s → 12.30s (+4.4%)  |  Mann-Whitney: z=3.48 ✅ significant

Phase breakdown
Phase Base p50 PR p50 p50 Δ Base p95 PR p95 p95 Δ Verdict
End-to-end 10.72s 11.82s +1.10s (+10.3%) 11.79s 12.30s +514ms (+4.4%) 🔴 regressed
Host total 7.91s 8.62s +708ms (+9.0%) 8.88s 9.23s +350ms (+3.9%) 🔴 regressed
Name resolution 7.69s 8.36s +661ms (+8.6%) 8.66s 8.99s +332ms (+3.8%) 🔴 regressed
App total 2.78s 3.11s +336ms (+12.1%) 3.20s 3.25s +49ms (+1.5%) 🔴 regressed

Warm Start

Overall: 🔴 regressed  |  p50: 424ms → 435ms (+2.6%)  |  p95: 451ms → 472ms (+4.7%)  |  Mann-Whitney: z=3.06 ✅ significant

Phase breakdown
Phase Base p50 PR p50 p50 Δ Base p95 PR p95 p95 Δ Verdict
End-to-end 424ms 435ms +11ms (+2.6%) 451ms 472ms +21ms (+4.7%) 🔴 regressed
Host total 139ms 151ms +12ms (+8.6%) 151ms 161ms +10ms (+6.6%) 🔴 regressed
App total 262ms 262ms 0ms (0.0%) 276ms 289ms +13ms (+4.7%) ⚪ unchanged

Lukewarm Start (different site, same session)

Overall: 🔴 regressed  |  p50: 13.82s → 14.51s (+5.0%)  |  p95: 14.69s → 15.38s (+4.7%)  |  Mann-Whitney: z=2.60 ✅ significant

Phase breakdown
Phase Base p50 PR p50 p50 Δ Base p95 PR p95 p95 Δ Verdict
End-to-end 13.82s 14.51s +686ms (+5.0%) 14.69s 15.38s +696ms (+4.7%) 🔴 regressed
Host total 9.22s 9.41s +192ms (+2.1%) 9.84s 10.10s +253ms (+2.6%) 🔴 regressed
Name resolution 7.24s 7.54s +309ms (+4.3%) 7.80s 8.17s +364ms (+4.7%) 🔴 regressed
App total 4.52s 4.83s +315ms (+7.0%) 4.79s 5.53s +734ms (+15.3%) 🟠 uncertain

Commit: bbd4689  |  Outliers (>2x best) discarded before stats

…itted them

The broker did not own author_submitAndWatchExtrinsic subscriptions, so their author_extrinsicUpdate events arrived for an unknown token and were dropped. The local wallet's core registers its allowances through that legacy watch, so the registration never completed. The broker now owns and releases those subscriptions, and the watch guard ends them with a legacy dropped update when the transport disconnects.
@replghost
replghost marked this pull request as ready for review October 12, 2026 19:32
@replghost
replghost requested a review from a team as a code owner October 12, 2026 19:32

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant