ethereum / js-ethereum-cryptography

Every cryptographic primitive needed to work on Ethereum, for the browser and Node.js

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question on expected time for browser computation

alanorwick opened this issue · comments

When running MetaMask and attempting to create a bulk group of secp256k1 addresses, my browser is spending a lot of time computing the comb10MulTo (10 seconds on 123 addresses / ~50% total runtime) that is downstream of the getPublicKey used in the ethereum-cryptography package.

Apologies if this is the wrong place to ask but is this expected when doing this sort of computation? Running the program outside of the browser is near instant. Feel free to close this issue if it is not intended to be opened here.

CallTrace for reference:
Screen Shot 2021-11-16 at 10 24 34 PM

Circling myself in here, Holger from EthereumJS. MetaMask is using our Wallet library under the hood, did a quick search, I guess it's in this eth-hd-keyring package.

We are still on ^0.1.3 (and since this is below v1 this would mean that caret here includes all versions below v0.2) - see e.g. this article for context (needed to reread to be sure myself). For the moment we wouldn't want to update to v0.2 yet, since an audit is still outstanding.

We will consider though switching to v1.0 (audited version of v0.2) though once released, we are a bit unsure though if we would give up too much on backwards compatibility with the BigInt integration, we'll carefully read the announced upgrade guide.

Just to confirm - maybe from @paulmillr: an update n v1.0 should make this use case from above substantially faster, right? Is this roughly quantifiable what a gain would be achieved here, as some decision helper?

All right. 😄

@holgerd77 it could be faster after upgrade, but the main question here is how the hd keyring / pubkeys are derived through the app. If this persists, there can be some ways of optimizing the logic.

For the record, calculating 123 public keys from privates in noble-secp takes 20 milliseconds on M1. Which is 500x faster.

@holgerd77 correct on the eth-hd-keyring, that's where I was doing the address generation.

@paulmillr what do you mean by how the hd keyring / pubkeys are derived? Would this be a symptom of MetaMask, the wallet library (ethereumjs-wallet), or something else? Is the 20 millisecond calculation done in browser for M1? My calculation even on Intel Mac chip locally is in the milliseconds, i.e whenever I do yarn test in the eth-hd-keyring for 100+ address generations.

Thank you both for your assistance, still learning a lot of the downstream packages.

@alanorwick browser perf should not differ much. It could be 3x slower, but not 50x.

Agreed on that it shouldn't differ too much although I'm curious as to why it is. Just reran the MetaMask code for 100 wallets and it came out to 10 seconds. Locally it's 2.43ms for 100 addresses. Do you have any resources on other ways to test the browser performance? I'll ask in the MetaMask repos as well.

You can run benchmark js with https://github.com/hugomrdias/playwright-test in all browsers, main thread, worker, service worker and extension contexts.

v1.0 is out now, ethereumjs-util would be also upgraded to native bigints asap, so old issues related to third-party bigints are not relevant anymore 👍