New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: recover from smoldot crashes #2162
Conversation
e0b6fbe
to
aa938d2
Compare
5d9b087
to
0bd1a32
Compare
3960cd4
to
8b66785
Compare
0bd1a32
to
02dcfc5
Compare
43010a8
to
7f27ec1
Compare
db7734e
to
58f1b5a
Compare
08f3132
to
0651f5e
Compare
afc4b04
to
6f8cbe0
Compare
packages/light-client-extension-helpers/src/background/json-rpc-provider.ts
Outdated
Show resolved
Hide resolved
packages/light-client-extension-helpers/src/background/json-rpc-provider.ts
Outdated
Show resolved
Hide resolved
packages/light-client-extension-helpers/src/background/json-rpc-provider.ts
Outdated
Show resolved
Hide resolved
packages/light-client-extension-helpers/src/background/json-rpc-provider.ts
Outdated
Show resolved
Hide resolved
export * from "./client" | ||
export * from "./types" | ||
export * from "./tasks" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know that this pattern exists throughout the repo, but IMO I think it'd be better practice to be explicit about the exports from a package rather than use * exports (just so the library interface is obvious just looking at this root file and not needing to traverse other stuff :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah but I find its really easy to forget to add a new type that should get re-exported and then it gets missed during code review because people don't really pay attention to that.
For anything that should be kept 100% internal I like to use the @internal
jsdoc tag and then with stripeInternal
set true
in your tsconfig, these definitions won't be included in the d.ts`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup totally true; we forget to export types in Rust a fair bit, but personally I much prefer to forget exporting a type than to accidentally export a type I didn't mean to; it's easier to go one way than the other! But mainly it just makes it super easy at a glance to see what's being provided by the package.
TIL about @internal
; that's cool to know about! Ultimately I'm not super fussed about this so happy to stick with the *'s + @internal
's if you prefer that way around!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Gonna opt for the YOLO approach and just use @internal.
But if you want to actually see what the publicly export types are u can run corepack pnpm turbo build
then open the dist
folder and each of the the subpath exports will have a d.ts
file in it showing the public api.
1c54377
to
c08f9fb
Compare
c08f9fb
to
0092711
Compare
packages/light-client-extension-helpers/src/background/json-rpc-provider.ts
Show resolved
Hide resolved
packages/light-client-extension-helpers/src/background/json-rpc-provider.ts
Outdated
Show resolved
Hide resolved
I think this is ready to ship. Made a slight tweak to the superivse method to accept an abort signal instead of returning a stop function. |
if (options.abortSignal) { | ||
options.abortSignal.addEventListener("abort", () => { | ||
stopped = true | ||
}) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: could move this next to the other options.abortSignal
code so it's clear that we either bail immediately if stopped or add event to listen for stop if not already :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM from what I understand, and much more readable now! Good job :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Solid PR! LGTM!
Fixes: #1786 (github will probably auto-close this issue but it shouldnt closed until the extension is updated on the chrome store).
Adds smoldot recovery to
light-client-extension-helpers
.This change adds a wrapper to the smoldot client to add a
restart
method and change theAddChainOptions
to acceptAddChainOptions
for potentialRelayChains instead ofChain
objects, becauseChain
objects cannot persist between smoldot restarts.This change also creates a custom JSON RPC Provider that will automatically re-connect to the chain it was connected to post-smoldot restart with the exact same
AddChainOptions
.To actually perform restarts, there is now a
supervise
function that gets invoked duringregister
that repeatedly callsaddChain
with an empty chain spec. The moment that there is aCrashError
from smoldot, smoldot gets restarted.Testing
Follow the instructions in the repo README.md to run the extension and open the demo page. Then repeatedly disconnect and re-connect from VPN and watch the extension console for smoldot crashes.
Demo
https://www.loom.com/share/c00c5348596d447a8ff371d043a3a818?sid=f3967a38-b725-460a-8c84-10975befbc99
Old Description
This PR addresses issue 1786, which prevents Substrate Connect from recovering when Smoldot crashes. The current fix attempt in PR 2157 has issues with recovery, chain handle management, and observability.
This PR introduces a new library using Effect to manage Smoldot restarts and JSON RPC provider connections. It ensures that each chain's lifecycle is tied to a single Smoldot client. When a Smoldot client is killed, all chains automatically disconnect and reconnect to the new Smoldot client in the JSON RPC Provider implementation. This approach improves recovery and simplifies chain management.
However, this change requires additional feature work in future PRs before it can fully replace the background folder in the light client extension helpers. Future PRs will need to adapt the existing codebase to utilize the new Smoldot management and chain handling capabilities.
The key benefits are:
The most important file you'll want to be reviewing is the JSON RPC Provider implementation: https://github.com/paritytech/substrate-connect/pull/2162/files#diff-00e4cc89f4df6dfb8719cbbe32fd288d8a4bb1e26a1932817814734d3bf556b1
Use it yourself!
1. Clone this PR 2. corepack pnpm i 3. cd packages/light-client-experimental 4. corepack pnpm turbo build 5. pnpm dlx tsx ./scripts/testing.ts
If you want to have some fun you can also adjust the log levels in the testing script.