diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c4ebdd60db..8d1d049ab88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/packages/web3-eth-accounts/src/crypto/Scrypt.js b/packages/web3-eth-accounts/src/crypto/Scrypt.js index 6ee02dc5186..b49997d3f33 100644 --- a/packages/web3-eth-accounts/src/crypto/Scrypt.js +++ b/packages/web3-eth-accounts/src/crypto/Scrypt.js @@ -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)}`); } } }