Skip to content
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

WASM Client Features #1339

Closed
10 tasks done
jsdanielh opened this issue Feb 13, 2023 · 6 comments
Closed
10 tasks done

WASM Client Features #1339

jsdanielh opened this issue Feb 13, 2023 · 6 comments
Assignees
Labels

Comments

@jsdanielh
Copy link
Member

jsdanielh commented Feb 13, 2023

@sisou sisou changed the title Full wasm support WASM Client Features Feb 15, 2023
@sisou
Copy link
Member

sisou commented Feb 15, 2023

So I just tested disconnection/reconnection behavior. Detection of network loss takes around 10-12 seconds (all peers leave and consensus is marked as "lost" when the number of peers drop under the configured minimum). However, when network is reconnected, the client does not start reconnecting by itself. So we need a way to tell it to start connecting again. Or we need to kill it and start a new client, but the first option would be better.

@sisou
Copy link
Member

sisou commented Feb 15, 2023

As for the export of further primitives and structs, we will run into various problems with Rust things that wasm-bindgen does not (yet) support:

  • It cannot generate bindings for trait implementations, so e.g. the from_hex method of PrivateKey is not supported
  • It cannot generate/convert pub const properties in implementations, so e.g. the SIZE constant on PrivateKey is not supported, preventing the whole impl bock from getting generated.

I think exposing these extra classes to JS would require proxying them by structs that wasm-bindgen understands.

Related wasm-bindgen issue and incomplete draft PR for trait impls.

@sisou
Copy link
Member

sisou commented Feb 15, 2023

Proxying the structs we want to expose could look like this: eee2035. This creates a class PrivateKey in JS with the methods static fromHex(hex: string): PrivateKey and toHex(): string.

Doing this for all classes we want to expose and their APIs will be a lot of work though.

@sisou
Copy link
Member

sisou commented Feb 15, 2023

I extended the proof-of-concept for the proxied structs in 64714ad. One thing to note is that every struct that is passed to JS is pushed onto the WASM stack, and only removed when its free() method is called, which cannot be called automatically by JS on garbage collection, if I understood that correctly. So all created objects will leak memory if not explicitly freed by userland code.

This is a problem when for example accessing a public or private key on a keypair, as that will create a new copy of that object on the stack.

@sisou
Copy link
Member

sisou commented Feb 15, 2023

Good news! wasm-bindgen actually supports automatic freeing of the rust struct when the Javascript reference is dereferenced (i.e. garbage collected). wasm-pack also merged support for it, but has not released a new version with it. It can however be enabled by an environment flag:
rustwasm/wasm-pack#937 (comment)

Enabling this feature requires support for WeakRefs in browsers, but support is pretty good and only getting better: https://caniuse.com/mdn-javascript_builtins_weakref

So I'd say let's enable that and pass structs to JS to our heart's content! 👌

@sisou sisou added the WASM label Feb 21, 2023
@jsdanielh
Copy link
Member Author

jsdanielh commented May 2, 2023

All items are now addressed with the exception of multisig which will be tracked in a different issue as documented in the issue description.

@jsdanielh jsdanielh added this to the Nimiq PoS Testnet milestone May 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants