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

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

Merged
merged 5 commits into from
Jul 18, 2019
Merged
Changes from 1 commit
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
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