Closed paulmillr closed 1 month ago
+1 to this! I was going to open a similar issue just now.
At MetaMask we have also had to deal with this dependency being introduced into our dependency tree (via ethereumjs
) and essentially breaking builds because arbitrary WASM eval isn't allowed by our CSP:
Refused to compile or instantiate WebAssembly module because neither 'wasm-eval' nor 'unsafe-eval' is an allowed source of script in the following Content Security Policy directive: "script-src 'self'"
We are currently forced to exclude @chainsafe/as-sha256
from our builds entirely and would definitely prefer a more platform agnostic dependency to be used for SHA256.
I see your concerns and would love to find a setup to benefits both web and nodejs consumers. For Lodestar's beacon node the speed of 64B hashes is crucial for performance since it's one of the most frequent ops we do.
@FrederikBolding would there be some approach like platform aware entrypoints that would fix your build issue? Say a-la https://www.npmjs.com/package/cross-fetch
@dapplion Yeah. Separate entry points for the browser, React Native and Node.js (e.g. via package.json fields) may alleviate some of the pain points for us. However, the ideal would probably be the possibility to opt-in/out of using WASM at all. Not sure if there is a good pattern for doing that other than publishing two packages 😅
Why not allow passing sha implementation as a function? Default can be either no hashing at all or noble-hashes because of compatibility.
Why not allow passing sha implementation as a function? Default can be either no hashing at all or noble-hashes because of compatibility.
That should work too right
CC @wemeetagain
That sounds like a good idea to me!
That's what we are doing in our trie library (after a similar discussion): https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/trie/src/types.ts#L51
Looks like the proposed fix has been released for this, but it uses the exports
field in the package.json, which not all tools seemingly support yet. Therefore, bumping the version in the EthereumJS monorepo causes failed tests.
I have yet to try bumping in the MetaMask extension, but there is a chance that our build pipeline doesn't support exports
either.
I agree, using exports field for this particular case does not bring any benefits.
Removing exports
should not be complicated:
".": "./lib/index.js",
"./hasher": "./lib/hasher/index.js",
"./hasher/as-sha256": "./lib/hasher/as-sha256.js",
"./hasher/noble": "./lib/hasher/noble.js"
will need to be removed; files will need to be moved top-level (lib/hasher/index.js => hasher/index.js) OR export paths will need to be renamed (hashes/noble => lib/hasher/noble.js)
This is not exactly an exotic or new feature, it has been a feature since node v12.7.0. And it's the recommended approach according to the docs.
Unfortunately, as we've seen, there are problems. Collecting links here for posterity.
https://github.com/ethereumjs/ethereumjs-monorepo/pull/2622
06 04 2023 22:41:04.633:ERROR [karma-server]: UncaughtException: Error: Unable to resolve module [@chainsafe/persistent-merkle-tree/hasher] from [/home/runner/work/ethereumjs-monorepo/ethereumjs-monorepo/node_modules/@chainsafe/ssz/lib/util/merkleize.js]
resolve.alias
fields in the karma.conf.js
for every subpath export (in every karma.conf.js
in their monorepo that uses the ssz library :crying_cat_face: ), was the issue resolved: https://github.com/ethereumjs/ethereumjs-monorepo/pull/2622/files#diff-1a5ee9e029a125a1b3ba72931fd6c8708f9388ecf0df25091fc9fa197fdb9df1R18-R25It seems under the hood, karma-typescript
uses browserify's browser-resolve
package, which uses browserify's resolve
package. Which brings us to:
https://github.com/browserify/resolve/pull/224
resolve
fails to properly resolve exports
. At least until this PR is merged. I was hoping that this would be an opportunity to file a bug, make fix in upstream tooling, or to fix some tooling configuration. However it seems that this is a known issue that does not have a positive outlook for being resolved in the near term.
I think we can mitigate this by using the same strategy as is used in the ethereum-cryptography
library. It publishes built javascript files under the root directory, and manually ensures that subpath exports match the paths of the files that are exported. So non-compliant resolvers may still resolve everything. This strategy is fitting for us as we would like to soon publish these libraries as ESM as well, and this provides us a path that can also keep backwards compatibility here.
@wemeetagain It's not as elegant as exports, but this works for Browserify and Webpack: https://github.com/ChainSafe/ssz/pull/318
I have verified that this fixes any problems in the MetaMask extension build process when importing @chainsafe/ssz
.
@wemeetagain It's not as elegant as exports, but this works for Browserify and Webpack: #318
I have verified that this fixes any problems in the MetaMask extension build process when importing
@chainsafe/ssz
.
🙏
Thanks a lot for the feedback, great timing since I am just preparing release notes for releases today including this fix! 🙂
@holgerd77 Sorry, just to clarify. We'll need to fix the exports issue before the MetaMask problems are entirely fixed.
But haven't gotten a response on that PR yet.
@holgerd77 Sorry, just to clarify. We'll need to fix the exports issue before the MetaMask problems are entirely fixed.
But haven't gotten a response on that PR yet.
Ok, I'll pause our release process (nothing urgent to be released), maybe there is a chance that this can get settled and still included within our release round.
@paulmillr @FrederikBolding should this issue be closed off now?
(it's slightly slower for 32B inputs, but executing 1 million hashes of 32b items at once is not a common case)