-
Notifications
You must be signed in to change notification settings - Fork 55
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
Upgrade to WASM and Rust Node.js addon (N-API). #53
Conversation
lib/validate.js
Outdated
]); | ||
|
||
function isUint8Array(value) { | ||
return value instanceof Uint8Array; |
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.
iirc there was an issue in another library where some environments this doesn't work well.
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 remember only this issue -- cryptocoinjs/secp256k1-node#175 🤔 I think that value
can be anything while it's correct work with Uint8Array.prototype.set (we copy input value data to WASM input buffer with set
).
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.
Do you think it worth to change to something like?
function itemsInRange(value) {
for (let i = 0; i < value.length; ++i) {
if (value[i] < 0 || value[i] > 0xff) return false;
}
return true;
}
function isUint8ArrayLike(value, length) {
return value instanceof Uint8Array || (
value !== undefined && value !== null && value.length === length && itemsInRange(value)
)
}
My crappy wasm-pack WASM which did so many bad inefficient rust things was 153KB... but when it is gzipped it is reduced by size 65%. Maybe some of the optimization tools I used (like wee_alloc and the WASM strippers I used in the docker command etc.) will help. I see you are already using wasm-opt.
|
This PR is historic and godlike. Moving JS libraries to depend on libsecp256k1 via a slim interface built from a single rust code base compiled into WASM and NAPI/NEON bindings is a huge leap towards having a "less insecure" JS Bitcoin ecosystem. |
|
Finally, first benchmark! Wasm vs js: 2x for sign and pk creation, 4x for verify, etc. full output (linux i5-8250U)
full output for Apple M1
Rust addon with different `opt-level` benchmarks
after
bench on debian:i686 (VirtualBox)
|
Need few more things:
but this should not prevent review. Hope that review will not take a long time @junderw 😆 |
I am still in the middle of review. One quick fix I would like to see:
|
Changed in fanatid#15. |
Changed to ES6 import only in fanatid#16 |
tACK 364b416 |
Leftover tasks:
|
Moved to #55 |
WIP... huge upgrade: move from C++ Node.js addon (NAN) and JS (elliptic) to WebAssembly and Rust Node.js addon (
probably napi, or maybe neon?napi).At the moment of creating pull request:
Next steps for moving pull request from the draft:
Remove secp256k1-sys crate. We can use bitcoin-core/secp256k1 directly with minimum additional things. At creation moment optimized release WASM file is 400KB, what is insane.Investigate how to reduce size withsecp256k1-sys
. Use patched secp256k1-sys fanatid/tiny-secp256k1#3Add tests to oursecp256k1
FFI crate.(, or use optionalDependencies? More benches fanatid/tiny-secp256k1#8profile.release
inCargo.toml
,#![no_std]
)Add prebuildify for Node.js addon.Node.js (at least v12.0.0) does not support modules great, soAdd test in browser env fanatid/tiny-secp256k1#4import
will be good for browsers, while for Node.js we will need to convert our code torequire
.I hope that I can handle all this 😅