Skip to content
This repository was archived by the owner on Mar 5, 2025. It is now read-only.

implement fallback from built-in scrypt to scryptsy/scrypt packages #2952

Merged
merged 5 commits into from
Jul 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- Length check of the PK added to the ``fromPrivateKey`` method of the ``Account`` model (#2928)

### Changed

- fsevents bumbed to v1.2.9 (#2951)

### Fixed

- miner.startMining fixed (#2877)
- Subscription type definitions fixed (#2919)
- ``ContractOptions`` type definitions corrected (#2939)
- Scrypt compatibility with older and newer nodejs versions fixed (#2952)
- Encryption of the V3Keystore fixed (#2950)

56 changes: 47 additions & 9 deletions packages/web3-eth-accounts/src/crypto/Scrypt.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,64 @@ let scrypt;
const isNode = Object.prototype.toString.call(typeof process !== 'undefined' ? process : 0) === '[object process]';
if (isNode) {
const NODE_MIN_VER_WITH_BUILTIN_SCRYPT = '10.5.0';
const NODE_MIN_VER_INCOMPAT_SCRYPT_PKG = '12.0.0';
const semver = require('semver');
const useNodeBuiltin = isNode && semver.Range('>=' + NODE_MIN_VER_WITH_BUILTIN_SCRYPT).test(process.version);

const tryScryptPackage = (function() {
let scryptPackage;
return function() {
if (scryptPackage !== undefined) {
return scryptPackage;
}
try {
scryptPackage = require('scrypt');
} catch (error) {
if (/was compiled against a different/.test(error.message)) {
throw error;
}
scryptPackage = null;
}
return scryptPackage;
};
})();

const canImprove = function(nodeVer) {
return `can improve web3's peformance when running Node.js versions older than ${nodeVer} by installing the (deprecated) scrypt package in your project`;
};

if (useNodeBuiltin) {
const crypto = require('crypto');
let fallbackCount = 0;
scrypt = function(key, salt, N, r, p, dkLength) {
return crypto.scryptSync(key, salt, dkLength, {N, r, p});
try {
return crypto.scryptSync(key, salt, dkLength, {N, r, p});
} catch (error) {
if (/scrypt:memory limit exceeded/.test(error.message)) {
const scryptPackage = tryScryptPackage();
if (scryptPackage) {
return scryptPackage.hashSync(key, {N: N, r: r, p: p}, dkLength, salt);
}
fallbackCount += 1;
console.warn(
'\u001B[33m%s\u001B[0m',
`Memory limit exceeded for Node's built-in crypto.scrypt, falling back to scryptsy (times: ${fallbackCount}), if this happens frequently you ${canImprove(
NODE_MIN_VER_INCOMPAT_SCRYPT_PKG
)}`
);
return scryptsy(key, salt, N, r, p, dkLength);
}
throw error;
}
};
} else {
let scryptPackage;
try {
scryptPackage = require('scrypt');
const scryptPackage = tryScryptPackage();
if (scryptPackage) {
scrypt = function(key, salt, N, r, p, dkLength) {
return scryptPackage.hashSync(key, {N, r, p}, dkLength, salt);
};
} catch (error) {
console.warn(
'\u001B[33m%s\u001B[0m',
`You can improve web3's peformance when running Node.js versions older than ${NODE_MIN_VER_WITH_BUILTIN_SCRYPT} by installing the (deprecated) scrypt package in your project`
);
} else {
console.warn('\u001B[33m%s\u001B[0m', `You ${canImprove(NODE_MIN_VER_WITH_BUILTIN_SCRYPT)}`);
}
}
}
Expand Down