-
Notifications
You must be signed in to change notification settings - Fork 36
Add browser support, remove dependencies #90
Conversation
Hi @paulmillr, thanks for bringing this up! This will definitely need some discussion, but also something worth to think about. On the BigInt changes, I personally think it is still a bit too early to draw these in since Safari has just only recently added support afaik, not even sure if only in the dev build or the main release. We should definitely handle these things (UInt8Array, BigInt) separately on discussion. |
Great. Thanks for not closing this immediately! |
TIL! current browser support not great: Global 83.45% https://caniuse.com/bigint |
@paulmillr you should convert this to a "draft PR" if possible since its more of a proof of concept than a PR (e.g. renaming package) |
@kumavis i've moved package renaming changes into a separate branch, so the current one only contains necessary changes. |
Global browser support is 88.72% now |
The "format" step errors are completely NOT helpful. Cannot tell what's wrong here. All unit tests pass. |
global browser support is 91.22% now |
@paulmillr there seems to be a merge conflict rn |
@talentlessguy yeah, I have no incentive to keep it up to date if it isn't planning to be merged. |
I see.. |
hey @paulmillr thanks for being so early with this PR :) we added BigInt support with #85 and browser support in #102. We output es5 and if people need a bundle they can typically do it with browserify or webpack, and can polyfill Buffer. We have previously had some team discussions regarding switching from Buffers to Uint8Array for both performance and fewer dependencies. I think we would be open to it, and starting with a relatively small repository like this should be a good experiment. Would you be able to update this PR to just include the Uint8Array change? I am also happy to take it over if you're busy with other things at the moment. I would be interested in doing a quick benchmark to see if it does make a noticeable difference in speed. The only thing I am thinking now is that we have a PR in progress to dedupe some internal helper functions by adding ethereumjs-util (#104), but that has Buffer dependency. |
Hi @ryanio I work on supply chain security for npm and eth ecosystems.
So, you should definitely switch to bigints. If you won't, your dependencies will, in any case -- and very soon. I don't see how it makes sense for RLP to depend on anything. It should be a dead-simple 300LOC lib. I can re-submit this PR that would bring dep count to 0. I don't see any point of RLP depending on bn.js. Bn.js is shitty, for real. |
@paulmillr thanks for the reply! that's helpful insight to avoid for ~30 LOC as you say. yes I have been following some of your work on the ethereum-cryptography rework and it's really amazing. unfortunately we can't upgrade to native bigint support without breaking non-bigint environments completely, so we have to be careful about our upgrade paths and have to wait for major versions, but I think we are approaching it soon. We also saw these benchmarks where bn.js was faster in some cases than BigInt, so that leaves us confused whether a total switch within our repositories would be worth it at all. |
@ryanio If bn.js was faster than bigints, then my libraries would be slower than all those "established" ones which use all sorts of bn.js optimizations. They aren't, noble is many times faster. You need to see a real-env usage, not synthetic benchmarks that don't count garbage collection / ram impact on perf etc.
You will be upgraded automatically at some point in the future, just like all "core" ETH projects, since ethereum-cryptography is included everywhere. Why wait? You can release 3.0 that's breaking "as per semver", include uint8array and native bigints and be done with it. Everyone who wants to support old environments can keep using 2.x, and we can provide updates to 2.x for a bit. |
P.S. i've ran the benchmarks and commented in the gist you've mentioned - even in this synthetic benchmark native bigints are faster |
@paulmillr thanks for your continued feedback! Do you think it would be better to go straight to BigInt, or use a polyfill-able library like JSBI that in the future could be transformed with e.g. If we consume ethereum-cryptography v2 maybe the JSBI step would be redundant since we'll already be expected to support native syntax? |
I haven't tested polyfills and have no feedback in my repos about polyfills during the last 2+ years. So, not really sure whether they work at all. I think it doesn't make huge sense to use polyfills, because bigints are natively supported in all major environments. The only unsupported old ones are Safari+iOS Safari 13 (that's 2% of all users, the browsers are 2+ years old); Chrome <66 (0.64%, 3.5 years old); Firefox <67 (0.54%, 2.5 years old), IE11 (2013). Node supported bigints since 2018, all versions that ship security updates (LTS) support bigints. 2022 seems like a good time to use bigints in all sorts of apps. |
@paulmillr Alright great well I'd love to get this branch rebased on the latest master. I looked through the code and it all looks excellent. Let me know if that's okay with you, I can push to your remote or copy it over to our remote and work on it from there. One thing I'd like to apply in the src is a trick we learned from #100 to avoid creating an extra slice when checking hex prefix: |
@ryanio I can rebase it, are you planning on merging it if everything goes fine? |
I have not yet asked the team to see if there is any hesitation against it, but I am in favor and would be motivated to do a rlp v3 release with zero deps, BigInt, and Uint8Arrays in place of Buffers, that seems nice to me. I will propose in our internal chat. |
Cool, just don't want to spend another bunch of hours on something non-mergeable |
Okay, this took three more hours, really hoping on getting this in @ryanio @holgerd77 Also, my
|
I'm also guessing a typescript compilation update would be needed because we're building file for browsers now. Not sure how to do it. |
@paulmillr thanks for updating and working on this! So far in response we have had all positive reception to the v3 idea so we can very likely make this happen :) We might move this repository to the monorepo, or continue to develop on it standalone, undecided yet but will let you know, regardless we can still use this PR. Regarding your
Our build step on current master will output a |
Also, another library improvement suggestion, what do you think of default exporting an RLP class with static methods encode/decode, so people can do Then if one wanted something extra like an exported type, could do My reasoning is to prefer not to encourage use of namespace (wildcard *) imports, like https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-namespace.md |
What do you mean by this commit/comment? I found the multi-line syntax is helpful for viewing the tooltips in VS Code, where single line comments using |
For dev please run |
unsure what's up with GitHub tests, they're running fine on my mac |
the tests look like they are passing now, what it's catching on now is a known karma-typescript issue which was fixed by monounity/karma-typescript#502 but there hasn't been a release yet. you can try updating the package.json dependency to |
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! thanks @paulmillr awesome stuff.
I will follow up with a PR to fix the karma runner which is where the ci is failing.
This is an awesome addition, thanks @paulmillr! I've had a use case where a browser version of RLP was required. A potential approach with regard to making Buffer usable in browser environments is by using this drop in replacement: https://github.com/feross/buffer In node environments it will just use the Node libraries, in browser environments it will use the imported library. |
@HDauven just to clarify: the comment from above is just referring to the existing versions of the RLP library, correct? With an RLP v3 release using Uint8Array you should not have any problems with polyfilling anything respectively think about polyfills? 🤔 Or let me know if I misunderstood your comment in some way. |
Hi,
This probably won't get merged right now -- but I want to get the idea exposed.
Basically Buffer is not supported in browsers. An Uint8Array should be used instead, since all Buffers are actually Uint8Arrays. This would allow to support browsers out-of-box.
As for bn.js, all major browsers and node.js versions right now support native bigints. At some point rlp should switch to native bigints -- which would allow to drop dependencies. We could ditch bn.js change for now, but I think it's important to switch to Uint8Arrays at some point. The lib could be used in browsers a lot.
I've made a fork - all tests pass. Let me know what you think