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

[web3.js] Replace sha256 and secp256k1 impls #27390

Merged
merged 2 commits into from
Aug 25, 2022
Merged

[web3.js] Replace sha256 and secp256k1 impls #27390

merged 2 commits into from
Aug 25, 2022

Conversation

steveluscher
Copy link
Contributor

@steveluscher steveluscher commented Aug 25, 2022

Problem

Notwithstanding the fact that the web3.js library arguably should not include the Secp256k1Program utilities (they should be their own package) the dependency tree that utility pulls in is massive. This PR aims to replace the signing and hashing algorithms therein with smaller ones having fewer dependencies.

Summary of Changes

  • Replaced @ethersproject/sha2 with @noble/hashes/sha256
  • Replaced secp256k1 with @noble/secp256k1

Bundle size

Published the development build to npm and compared it to the latest version using bundlephobia.

Before After
image image

Bundle size is reduced by ~39% after gzip.

Dependency tree

Using NPMGraph:

Before After
image image

Number of modules depended upon was reduced by ~14% and number of maintainers in the transitive dependency chain by ~13%.

Performance

Consider the performance of generating public keys using a seed. Use this script:

const PublicKey = require('./lib/index.cjs').PublicKey;

for (let ii = 0; ii < 1000000; ii++) {
  PublicKey.createWithSeed(PublicKey.default, 'seed', PublicKey.default);
}

Before

% time node perf.js
node perf.js  7.91s user 0.07s system 107% cpu 7.438 total

After

% time node perf.js
node perf.js  2.88s user 0.04s system 112% cpu 2.604 total

Public keys get generated in ~63% less time.


Consider the performance of generating secp256k1 program instructions. Use this script:

const {Secp256k1Program} = require('./lib/index.cjs');
const params = {
  ethAddress: 'f7b2de6be9e978210721bf68fa2457c7affc56fe',
  message: Buffer.from(
    new Uint8Array([73, 74, 72, 69, 110, 67, 20, 61, 64, 64, 72, 65, 73, 73]),
  ),
  signature: new Uint8Array([
    95, 139, 180, 41, 127, 36, 3, 8, 210, 141, 95, 84, 249, 73, 210, 177, 182,
    212, 144, 23, 234, 110, 228, 69, 29, 68, 225, 12, 140, 150, 197, 52, 85, 71,
    180, 12, 53, 32, 156, 132, 194, 76, 52, 174, 145, 255, 171, 180, 221, 68, 3,
    28, 134, 121, 220, 100, 53, 57, 29, 43, 156, 43, 98, 101,
  ]),
  recoveryId: 0,
};

for (let ii = 0; ii < 10000000; ii++) {
  Secp256k1Program.createInstructionWithEthAddress(params);
}

Before

% time node perf.js
node perf.js  29.29s user 0.52s system 112% cpu 26.480 total

After

% time node perf.js
node perf.js  29.24s user 0.50s system 112% cpu 26.389 total

No change in runtime.

Compatibility notes

  • Though not tested, this change should be as compatible with the browser and React Native as the previous version. Though @noble/secp256k1 is incompatible with React Native because of a dependency on SubtleCrypto, the particular codepaths that we use in the Secp256k1 program utils don't exercise any of those codepaths.
  • This PR accidentally makes web3.js compatible with rapid prototyping systems like JSBin. Here's an example. It imports https://unpkg.com/@solana/[email protected]/lib/index.iife.js

Addresses solana-labs/solana-web3.js#1103.
Unintentionally fixes #26371.

@codecov
Copy link

codecov bot commented Aug 25, 2022

Codecov Report

Merging #27390 (2df2146) into master (e779032) will decrease coverage by 0.1%.
The diff coverage is n/a.

@@            Coverage Diff            @@
##           master   solana-labs/solana#27390     +/-   ##
=========================================
- Coverage    76.9%    76.7%   -0.2%     
=========================================
  Files          48       48             
  Lines        2505     2516     +11     
  Branches      355      359      +4     
=========================================
+ Hits         1927     1931      +4     
- Misses        448      456      +8     
+ Partials      130      129      -1     

Copy link
Contributor

@jnwng jnwng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm! thank you for the copious amounts of data backing up this change

Copy link
Contributor

@jordaaash jordaaash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@steveluscher steveluscher merged commit 1a836ab into solana-labs:master Aug 25, 2022
@steveluscher steveluscher deleted the replace-sha256-and-secp256k1-impl branch August 25, 2022 20:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

web3.js: Make a build that's compatible with rapid prototyping environments like JSBin
3 participants