diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml new file mode 100644 index 00000000..31d6e465 --- /dev/null +++ b/.github/workflows/node.js.yml @@ -0,0 +1,28 @@ +# This workflow will do a clean install of node dependencies, cache/restore them, build the source code and run tests across different versions of node +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions + +name: Node.js CI + +on: + push: + pull_request: + +jobs: + build: + + runs-on: ubuntu-latest + + strategy: + matrix: + node-version: [10.x] + # See supported Node.js release schedule at https://nodejs.org/en/about/releases/ + + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v2 + with: + node-version: ${{ matrix.node-version }} + cache: 'npm' + - run: npm ci + - run: npm test diff --git a/.gitignore b/.gitignore index c9b88323..60327a58 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,4 @@ node_modules # hbbft-posdao-contracts specific files .network .pk -.mnemonic \ No newline at end of file +.mnemonic* \ No newline at end of file diff --git a/contracts/CertifierHbbft.sol b/contracts/CertifierHbbft.sol index f67f7f6d..f914f84b 100644 --- a/contracts/CertifierHbbft.sol +++ b/contracts/CertifierHbbft.sol @@ -87,6 +87,7 @@ contract CertifierHbbft is UpgradeableOwned, ICertifier { external view returns(bool) { + if (_certified[_who]) { return true; } @@ -101,9 +102,8 @@ contract CertifierHbbft is UpgradeableOwned, ICertifier { // since the node cache the list of certifiers // and the permission contracts checks anyway, // if the specific 0 gas transaction is allowed or not. - IStakingHbbft stakingContract = IStakingHbbft(validatorSetContract.stakingContract()); - return stakingContract.isPoolActive(stakingAddress); + return stakingAddress != address(0); } /// @dev Returns a boolean flag indicating whether the specified address is allowed to use zero gas price diff --git a/contracts/TxPermissionHbbft.sol b/contracts/TxPermissionHbbft.sol index 2b3d91be..88458727 100644 --- a/contracts/TxPermissionHbbft.sol +++ b/contracts/TxPermissionHbbft.sol @@ -81,6 +81,7 @@ contract TxPermissionHbbft is UpgradeableOwned, ITxPermission { validatorSetContract = IValidatorSetHbbft(_validatorSet); keyGenHistoryContract = IKeyGenHistory(_keyGenHistoryContract); minimumGasPrice = 1000000000; // (1 gwei) + blockGasLimit = 1000000000; // 1 giga gas block } /// @dev Adds the address for which transactions of any type must be allowed. diff --git a/contracts/ValidatorSetHbbft.sol b/contracts/ValidatorSetHbbft.sol index 8373bb79..69a33c3d 100644 --- a/contracts/ValidatorSetHbbft.sol +++ b/contracts/ValidatorSetHbbft.sol @@ -5,13 +5,13 @@ import "./interfaces/IKeyGenHistory.sol"; import "./interfaces/IRandomHbbft.sol"; import "./interfaces/IStakingHbbft.sol"; import "./interfaces/IValidatorSetHbbft.sol"; -import "./upgradeability/UpgradeabilityAdmin.sol"; +import "./upgradeability/UpgradeableOwned.sol"; import "./libs/SafeMath.sol"; /// @dev Stores the current validator set and contains the logic for choosing new validators /// before each staking epoch. The logic uses a random seed generated and stored by the `RandomHbbft` contract. -contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { +contract ValidatorSetHbbft is UpgradeableOwned, IValidatorSetHbbft { using SafeMath for uint256; // =============================================== Storage ======================================================== @@ -91,10 +91,9 @@ contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { /// the value is of type timestamp mapping(address => uint256) public validatorAvailableSince; - // ============================================== Constants ======================================================= /// @dev The max number of validators. - uint256 public constant MAX_VALIDATORS = 25; + uint256 public maxValidators; // ================================================ Events ======================================================== @@ -204,6 +203,7 @@ contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { _setStakingAddress(miningAddress, _initialStakingAddresses[i]); } + maxValidators = 7; } @@ -230,7 +230,7 @@ contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { } /// @dev Implements the logic which forms a new validator set. If the number of active pools - /// is greater than MAX_VALIDATORS, the logic chooses the validators randomly using a random seed generated and + /// is greater than maxValidators, the logic chooses the validators randomly using a random seed generated and /// stored by the `RandomHbbft` contract. /// Automatically called by the `BlockRewardHbbft.reward` function at the latest block of the staking epoch. function newValidatorSet() @@ -285,6 +285,13 @@ contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { return; } + if (_pendingValidators.length == 0) { + // if there are no "pending validators" that + // should write their keys, then there is + // nothing to do here. + return; + } + // check if the current epoch should have been ended already // but some of the validators failed to write his PARTS / ACKS. @@ -364,8 +371,21 @@ contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { forcedPools[i] = goodValidators[i]; } + // this tells the staking contract that the key generation failed + // so the staking conract is able to prolong this staking period. stakingContract.notifyKeyGenFailed(); - _newValidatorSet(forcedPools); + + // is there anyone left that can get elected ?? + // if not, we just continue with the validator set we have now, + // for another round, + // hopefully that on or the other node operators get his pool fixed. + // the Deadline just stays a full time window. + // therefore the Node Operators might get a chance that + // many manage to fix the problem, + // and we can get a big takeover. + if (stakingContract.getPoolsToBeElected().length > 0) { + _newValidatorSet(forcedPools); + } } /// @dev Reports that the malicious validator misbehaved at the specified block. @@ -444,6 +464,12 @@ contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { _setStakingAddress(_miningAddress, _stakingAddress); } + function setMaxValidators(uint256 _maxValidators) + external + onlyOwner { + maxValidators = _maxValidators; + } + // =============================================== Getters ======================================================== /// @dev Returns a boolean flag indicating whether delegators of the specified pool are currently banned. @@ -715,6 +741,22 @@ contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { return stakingContract.getPoolPublicKey(stakingByMiningAddress[_miningAddress]); } + /// @dev in Hbbft there are sweet spots for the choice of validator counts + /// those are FLOOR((n - 1)/3) * 3 + 1 + /// values: 1 - 4 - 7 - 10 - 13 - 16 - 19 - 22 - 25 + /// more about: https://github.com/DMDcoin/hbbft-posdao-contracts/issues/84 + /// @return a sweet spot n for a given number n + function getValidatorCountSweetSpot(uint256 _possibleValidatorCount) + public + view + returns(uint256) { + require(_possibleValidatorCount > 0, "_possibleValidatorCount must not be 0"); + if (_possibleValidatorCount < 4) { + return _possibleValidatorCount; + } + return ((_possibleValidatorCount - 1) / 3) * 3 + 1; + } + // ============================================== Internal ======================================================== /// @dev Updates the total reporting counter (see the `reportingCounterTotal` public mapping) for the current @@ -736,17 +778,22 @@ contract ValidatorSetHbbft is UpgradeabilityAdmin, IValidatorSetHbbft { reportingCounterTotal[currentStakingEpoch] = 0; } } - + function _newValidatorSet(address[] memory _forcedPools) internal { address[] memory poolsToBeElected = stakingContract.getPoolsToBeElected(); - // Choose new validators - if (poolsToBeElected.length > MAX_VALIDATORS) { + + uint256 numOfValidatorsToBeElected = + poolsToBeElected.length >= maxValidators || poolsToBeElected.length == 0 ? maxValidators : + getValidatorCountSweetSpot(poolsToBeElected.length); + + // Choose new validators > ) + if (poolsToBeElected.length > numOfValidatorsToBeElected) { uint256 poolsToBeElectedLength = poolsToBeElected.length; (uint256[] memory likelihood, uint256 likelihoodSum) = stakingContract.getPoolsLikelihood(); - address[] memory newValidators = new address[](MAX_VALIDATORS); + address[] memory newValidators = new address[](numOfValidatorsToBeElected); uint256 indexNewValidator = 0; for(uint256 iForced = 0; iForced < _forcedPools.length; iForced++) { diff --git a/contracts/base/BlockRewardHbbftBase.sol b/contracts/base/BlockRewardHbbftBase.sol index fd0a1c44..e5622d1a 100644 --- a/contracts/base/BlockRewardHbbftBase.sol +++ b/contracts/base/BlockRewardHbbftBase.sol @@ -259,8 +259,7 @@ contract BlockRewardHbbftBase is UpgradeableOwned, IBlockRewardHbbft { // Choose new validators validatorSetContract.newValidatorSet(); } else if (currentTimestamp >= stakingContract.stakingFixedEpochEndTime() ) { - // removed, because availability handling is not implemented yet in the client implementation. - // validatorSetContract.handleFailedKeyGeneration(); + validatorSetContract.handleFailedKeyGeneration(); } } } diff --git a/contracts/interfaces/IValidatorSetHbbft.sol b/contracts/interfaces/IValidatorSetHbbft.sol index 112fb30a..d94cc335 100644 --- a/contracts/interfaces/IValidatorSetHbbft.sol +++ b/contracts/interfaces/IValidatorSetHbbft.sol @@ -32,7 +32,7 @@ interface IValidatorSetHbbft { function isValidatorOrPending(address) external view returns(bool); function isPendingValidator(address) external view returns(bool); function getPendingValidatorKeyGenerationMode(address) external view returns(KeyGenMode); - function MAX_VALIDATORS() external view returns(uint256); // solhint-disable-line func-name-mixedcase + function maxValidators() external view returns(uint256); function miningByStakingAddress(address) external view returns(address); function randomContract() external view returns(address); function reportMaliciousCallable(address, address, uint256) external view returns(bool, bool); diff --git a/package-lock.json b/package-lock.json index 8e1654dd..85af9447 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4086,66 +4086,84 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "ganache-cli": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.10.2.tgz", - "integrity": "sha512-wCuQjy7k040J8hii1KQ/dYHv8qjdHIcP3fw331AWPqQjeqNquf5HVVQNJOYXINTDofMDkCMQv3ru4ze/A+WyPQ==", + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ganache-cli/-/ganache-cli-6.12.2.tgz", + "integrity": "sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw==", "dev": true, "requires": { - "ethereumjs-util": "6.1.0", - "scrypt": "6.0.3", + "ethereumjs-util": "6.2.1", "source-map-support": "0.5.12", "yargs": "13.2.4" }, "dependencies": { + "@types/bn.js": { + "version": "4.11.6", + "bundled": true, + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/node": { + "version": "14.11.2", + "bundled": true, + "dev": true + }, + "@types/pbkdf2": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/secp256k1": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "@types/node": "*" + } + }, "ansi-regex": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "bundled": true, "dev": true }, "ansi-styles": { "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "bundled": true, "dev": true, "requires": { "color-convert": "^1.9.0" } }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, - "bip66": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", - "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "base-x": { + "version": "3.0.8", + "bundled": true, "dev": true, "requires": { "safe-buffer": "^5.0.1" } }, + "blakejs": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, "bn.js": { "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "bundled": true, "dev": true }, "brorand": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "bundled": true, "dev": true }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "bundled": true, "dev": true, "requires": { "buffer-xor": "^1.0.3", @@ -4156,28 +4174,42 @@ "safe-buffer": "^5.0.1" } }, + "bs58": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" + } + }, "buffer-from": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "bundled": true, "dev": true }, "buffer-xor": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "bundled": true, "dev": true }, "camelcase": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "bundled": true, "dev": true }, "cipher-base": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "bundled": true, "dev": true, "requires": { "inherits": "^2.0.1", @@ -4186,8 +4218,7 @@ }, "cliui": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "bundled": true, "dev": true, "requires": { "string-width": "^3.1.0", @@ -4197,8 +4228,7 @@ }, "color-convert": { "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "bundled": true, "dev": true, "requires": { "color-name": "1.1.3" @@ -4206,14 +4236,12 @@ }, "color-name": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "bundled": true, "dev": true }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "bundled": true, "dev": true, "requires": { "cipher-base": "^1.0.1", @@ -4225,8 +4253,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "bundled": true, "dev": true, "requires": { "cipher-base": "^1.0.3", @@ -4239,8 +4266,7 @@ }, "cross-spawn": { "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "bundled": true, "dev": true, "requires": { "nice-try": "^1.0.4", @@ -4252,25 +4278,12 @@ }, "decamelize": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "bundled": true, "dev": true }, - "drbg.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", - "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, - "requires": { - "browserify-aes": "^1.0.6", - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4" - } - }, "elliptic": { "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "bundled": true, "dev": true, "requires": { "bn.js": "^4.4.0", @@ -4284,38 +4297,56 @@ }, "emoji-regex": { "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "bundled": true, "dev": true }, "end-of-stream": { "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "bundled": true, "dev": true, "requires": { "once": "^1.4.0" } }, + "ethereum-cryptography": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "@types/pbkdf2": "^3.0.0", + "@types/secp256k1": "^4.0.1", + "blakejs": "^1.1.0", + "browserify-aes": "^1.2.0", + "bs58check": "^2.1.2", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "hash.js": "^1.1.7", + "keccak": "^3.0.0", + "pbkdf2": "^3.0.17", + "randombytes": "^2.1.0", + "safe-buffer": "^5.1.2", + "scrypt-js": "^3.0.0", + "secp256k1": "^4.0.1", + "setimmediate": "^1.0.5" + } + }, "ethereumjs-util": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-6.1.0.tgz", - "integrity": "sha512-URESKMFbDeJxnAxPppnk2fN6Y3BIatn9fwn76Lm8bQlt+s52TpG8dN9M66MLPuRAiAOIqL3dfwqWJf0sd0fL0Q==", + "version": "6.2.1", + "bundled": true, "dev": true, "requires": { + "@types/bn.js": "^4.11.3", "bn.js": "^4.11.0", "create-hash": "^1.1.2", + "elliptic": "^6.5.2", + "ethereum-cryptography": "^0.1.3", "ethjs-util": "0.1.6", - "keccak": "^1.0.2", - "rlp": "^2.0.0", - "safe-buffer": "^5.1.1", - "secp256k1": "^3.0.1" + "rlp": "^2.2.3" } }, "ethjs-util": { "version": "0.1.6", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", - "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", + "bundled": true, "dev": true, "requires": { "is-hex-prefixed": "1.0.0", @@ -4324,8 +4355,7 @@ }, "evp_bytestokey": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "bundled": true, "dev": true, "requires": { "md5.js": "^1.3.4", @@ -4334,8 +4364,7 @@ }, "execa": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "bundled": true, "dev": true, "requires": { "cross-spawn": "^6.0.0", @@ -4347,16 +4376,9 @@ "strip-eof": "^1.0.0" } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true - }, "find-up": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "bundled": true, "dev": true, "requires": { "locate-path": "^3.0.0" @@ -4364,14 +4386,12 @@ }, "get-caller-file": { "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "bundled": true, "dev": true }, "get-stream": { "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "bundled": true, "dev": true, "requires": { "pump": "^3.0.0" @@ -4379,8 +4399,7 @@ }, "hash-base": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "bundled": true, "dev": true, "requires": { "inherits": "^2.0.4", @@ -4390,8 +4409,7 @@ }, "hash.js": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "bundled": true, "dev": true, "requires": { "inherits": "^2.0.3", @@ -4400,8 +4418,7 @@ }, "hmac-drbg": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "bundled": true, "dev": true, "requires": { "hash.js": "^1.0.3", @@ -4411,56 +4428,46 @@ }, "inherits": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "bundled": true, "dev": true }, "invert-kv": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "bundled": true, "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "bundled": true, "dev": true }, "is-hex-prefixed": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", + "bundled": true, "dev": true }, "is-stream": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "bundled": true, "dev": true }, "isexe": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "bundled": true, "dev": true }, "keccak": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", - "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", + "version": "3.0.1", + "bundled": true, "dev": true, "requires": { - "bindings": "^1.2.1", - "inherits": "^2.0.3", - "nan": "^2.2.1", - "safe-buffer": "^5.1.0" + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" } }, "lcid": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "bundled": true, "dev": true, "requires": { "invert-kv": "^2.0.0" @@ -4468,8 +4475,7 @@ }, "locate-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "bundled": true, "dev": true, "requires": { "p-locate": "^3.0.0", @@ -4478,8 +4484,7 @@ }, "map-age-cleaner": { "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "bundled": true, "dev": true, "requires": { "p-defer": "^1.0.0" @@ -4487,8 +4492,7 @@ }, "md5.js": { "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "bundled": true, "dev": true, "requires": { "hash-base": "^3.0.0", @@ -4498,8 +4502,7 @@ }, "mem": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "bundled": true, "dev": true, "requires": { "map-age-cleaner": "^0.1.1", @@ -4509,38 +4512,37 @@ }, "mimic-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "bundled": true, "dev": true }, "minimalistic-assert": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "bundled": true, "dev": true }, "minimalistic-crypto-utils": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "bundled": true, "dev": true }, "nice-try": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "bundled": true, + "dev": true + }, + "node-addon-api": { + "version": "2.0.2", + "bundled": true, + "dev": true + }, + "node-gyp-build": { + "version": "4.2.3", + "bundled": true, "dev": true }, "npm-run-path": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "bundled": true, "dev": true, "requires": { "path-key": "^2.0.0" @@ -4548,8 +4550,7 @@ }, "once": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "bundled": true, "dev": true, "requires": { "wrappy": "1" @@ -4557,8 +4558,7 @@ }, "os-locale": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "bundled": true, "dev": true, "requires": { "execa": "^1.0.0", @@ -4568,26 +4568,22 @@ }, "p-defer": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "bundled": true, "dev": true }, "p-finally": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "bundled": true, "dev": true }, "p-is-promise": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "bundled": true, "dev": true }, "p-limit": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "bundled": true, "dev": true, "requires": { "p-try": "^2.0.0" @@ -4595,8 +4591,7 @@ }, "p-locate": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "bundled": true, "dev": true, "requires": { "p-limit": "^2.0.0" @@ -4604,36 +4599,51 @@ }, "p-try": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "bundled": true, "dev": true }, "path-exists": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "bundled": true, "dev": true }, "path-key": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "bundled": true, "dev": true }, + "pbkdf2": { + "version": "3.1.1", + "bundled": true, + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "pump": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "bundled": true, "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, + "randombytes": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, "readable-stream": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "bundled": true, "dev": true, "requires": { "inherits": "^2.0.3", @@ -4643,20 +4653,17 @@ }, "require-directory": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "bundled": true, "dev": true }, "require-main-filename": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "bundled": true, "dev": true }, "ripemd160": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "bundled": true, "dev": true, "requires": { "hash-base": "^3.0.0", @@ -4665,8 +4672,7 @@ }, "rlp": { "version": "2.2.6", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.2.6.tgz", - "integrity": "sha512-HAfAmL6SDYNWPUOJNrM500x4Thn4PZsEy5pijPh40U9WfNk0z15hUYzO9xVIMAdIHdFtD8CBDHd75Td1g36Mjg==", + "bundled": true, "dev": true, "requires": { "bn.js": "^4.11.1" @@ -4674,42 +4680,42 @@ }, "safe-buffer": { "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "bundled": true, + "dev": true + }, + "scrypt-js": { + "version": "3.0.1", + "bundled": true, "dev": true }, "secp256k1": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.8.0.tgz", - "integrity": "sha512-k5ke5avRZbtl9Tqx/SA7CbY3NF6Ro+Sj9cZxezFzuBlLDmyqPiL8hJJ+EmzD8Ig4LUDByHJ3/iPOVoRixs/hmw==", + "version": "4.0.2", + "bundled": true, "dev": true, "requires": { - "bindings": "^1.5.0", - "bip66": "^1.1.5", - "bn.js": "^4.11.8", - "create-hash": "^1.2.0", - "drbg.js": "^1.0.1", "elliptic": "^6.5.2", - "nan": "^2.14.0", - "safe-buffer": "^5.1.2" + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.0" } }, "semver": { "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bundled": true, "dev": true }, "set-blocking": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "bundled": true, + "dev": true + }, + "setimmediate": { + "version": "1.0.5", + "bundled": true, "dev": true }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "bundled": true, "dev": true, "requires": { "inherits": "^2.0.1", @@ -4718,8 +4724,7 @@ }, "shebang-command": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "bundled": true, "dev": true, "requires": { "shebang-regex": "^1.0.0" @@ -4727,26 +4732,22 @@ }, "shebang-regex": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "bundled": true, "dev": true }, "signal-exit": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "bundled": true, "dev": true }, "source-map": { "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "bundled": true, "dev": true }, "source-map-support": { "version": "0.5.12", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", - "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", + "bundled": true, "dev": true, "requires": { "buffer-from": "^1.0.0", @@ -4755,8 +4756,7 @@ }, "string-width": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "bundled": true, "dev": true, "requires": { "emoji-regex": "^7.0.1", @@ -4766,8 +4766,7 @@ }, "string_decoder": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "bundled": true, "dev": true, "requires": { "safe-buffer": "~5.2.0" @@ -4775,8 +4774,7 @@ }, "strip-ansi": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "bundled": true, "dev": true, "requires": { "ansi-regex": "^4.1.0" @@ -4784,14 +4782,12 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "bundled": true, "dev": true }, "strip-hex-prefix": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", - "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", + "bundled": true, "dev": true, "requires": { "is-hex-prefixed": "1.0.0" @@ -4799,14 +4795,12 @@ }, "util-deprecate": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "bundled": true, "dev": true }, "which": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "bundled": true, "dev": true, "requires": { "isexe": "^2.0.0" @@ -4814,14 +4808,12 @@ }, "which-module": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "bundled": true, "dev": true }, "wrap-ansi": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "bundled": true, "dev": true, "requires": { "ansi-styles": "^3.2.0", @@ -4831,20 +4823,17 @@ }, "wrappy": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "bundled": true, "dev": true }, "y18n": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "bundled": true, "dev": true }, "yargs": { "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "bundled": true, "dev": true, "requires": { "cliui": "^5.0.0", @@ -4862,8 +4851,7 @@ }, "yargs-parser": { "version": "13.1.2", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", - "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "bundled": true, "dev": true, "requires": { "camelcase": "^5.0.0", @@ -7470,16 +7458,6 @@ } } }, - "scrypt": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", - "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.0.8" - } - }, "scrypt-js": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-2.0.4.tgz", diff --git a/package.json b/package.json index 4e064d4b..7672c6ba 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,7 @@ "chai-as-promised": "^7.1.1", "chai-bn": "^0.1.1", "eth-gas-reporter": "^0.2.17", - "ganache-cli": "^6.10.1", + "ganache-cli": "^6.12.2", "mochawesome": "^6.1.1", "node-fetch": "^2.6.0", "solc": "^0.5.16", diff --git a/scripts/contractUpdates/update_single_contract.js b/scripts/contractUpdates/update_single_contract.js index a87bf86b..866b5c97 100644 --- a/scripts/contractUpdates/update_single_contract.js +++ b/scripts/contractUpdates/update_single_contract.js @@ -31,11 +31,12 @@ async function doDeployContracts() { // const KEY_GEN_HISTORY_CONTRACT = '0x7000000000000000000000000000000000000001'; - const contractToUpdate = 'TxPermissionHbbft'; + const contractToUpdate = 'ValidatorSetHbbft'; const contractAddresses = { - TxPermissionHbbft: '0x4000000000000000000000000000000000000001' + TxPermissionHbbft: '0x4000000000000000000000000000000000000001', + ValidatorSetHbbft: '0x1000000000000000000000000000000000000001' } const address = contractAddresses[contractToUpdate]; diff --git a/scripts/make_spec_hbbft.js b/scripts/make_spec_hbbft.js index d6082d99..78418d34 100755 --- a/scripts/make_spec_hbbft.js +++ b/scripts/make_spec_hbbft.js @@ -91,6 +91,11 @@ async function main() { spec.name = networkName; spec.params.networkID = networkID; + const minimumBlockTime = Number.parseInt(process.env.MINIMUM_BLOCK_TIME); + if (minimumBlockTime > 0) { + spec.engine.hbbft.params.minimumBlockTime = minimumBlockTime; + } + let contractsCompiled = {}; for (let i = 0; i < contracts.length; i++) { const contractName = contracts[i]; diff --git a/templates/spec_hbbft.json b/templates/spec_hbbft.json index 0509a951..a6d44c4b 100644 --- a/templates/spec_hbbft.json +++ b/templates/spec_hbbft.json @@ -3,16 +3,17 @@ "engine": { "hbbft": { "params": { - "minimumBlockTime": 10, + "minimumBlockTime": 1, + "maximumBlockTime": 30, "transactionQueueSizeTrigger": 1, "blockRewardContractAddress": "0x2000000000000000000000000000000000000001" } } }, "params": { - "gasLimitBoundDivisor": "0x400", + "gasLimitBoundDivisor": "0x4", "maximumExtraDataSize": "0x20", - "minGasLimit": "0x1388", + "minGasLimit": "0x138800", "networkID": "777004", "eip140Transition": "0x0", "eip211Transition": "0x0", @@ -32,7 +33,7 @@ "seal": { "generic": "0x0" }, - "difficulty": "0x20000", + "difficulty": "0x1", "author": "0x0000000000000000000000000000000000000000", "timestamp": "0x00", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", diff --git a/test/KeyGenHistory.js b/test/KeyGenHistory.js index a432c450..1970f34f 100644 --- a/test/KeyGenHistory.js +++ b/test/KeyGenHistory.js @@ -267,7 +267,9 @@ contract('InitializerHbbft', async accounts => { const pendingValidators = await validatorSetHbbft.getPendingValidators.call(); - pendingValidators.should.be.deep.equal([initializingMiningAddresses[0]]); + // since there was never another electable candidate, the system should still + // tread the one and only pending validator still as pending validator. + pendingValidators.should.be.deep.equal([newPoolMiningAddress]); await writePart('1', parts[0], pendingValidators[0]); @@ -311,7 +313,7 @@ contract('InitializerHbbft', async accounts => { }); it('1/2 KeyGeneration - PART Failure', async () => { - //tests a 2 validators setup. + //tests a 2 validators setup. // 1 manages to write it's part. // 1 does not manage to write it's part. // expected behavior: @@ -497,9 +499,15 @@ async function callReward(isEpochEndBlock) { //and simulate a block mining (calling reward()) async function timeTravelToTransition() { + let currentTS = await validatorSetHbbft.getCurrentTimestamp.call(); let startTimeOfNextPhaseTransition = await stakingHbbft.startTimeOfNextPhaseTransition.call(); + if (logOutput) { + console.log(`timetraveling from ${currentTS} to ${startTimeOfNextPhaseTransition }`); + } + await validatorSetHbbft.setCurrentTimestamp(startTimeOfNextPhaseTransition); - const currentTS = await validatorSetHbbft.getCurrentTimestamp.call(); + currentTS = await validatorSetHbbft.getCurrentTimestamp.call(); + currentTS.should.be.bignumber.equal(startTimeOfNextPhaseTransition); await callReward(false); } diff --git a/test/ValidatorSetHbbft.js b/test/ValidatorSetHbbft.js index cc04ab6a..f5c35db3 100644 --- a/test/ValidatorSetHbbft.js +++ b/test/ValidatorSetHbbft.js @@ -437,7 +437,7 @@ contract('ValidatorSetHbbft', async accounts => { const newValidators = await validatorSetHbbft.getPendingValidators.call(); - newValidators.length.should.be.equal((await validatorSetHbbft.MAX_VALIDATORS.call()).toNumber()); + newValidators.length.should.be.equal((await validatorSetHbbft.maxValidators.call()).toNumber()); for (let i = 0; i < newValidators.length; i++) { miningAddresses.indexOf(newValidators[i].toLowerCase()).should.be.gte(0); @@ -648,6 +648,31 @@ contract('ValidatorSetHbbft', async accounts => { } }); }); + + it('hbbft sweet spots are calculated correct. getValidatorCountSweetSpot', async() => { + + + + const expectedResults = + [ 1,2,3, + 4,4,4, + 7,7,7, + 10,10,10, + 13,13,13, + 16,16,16, + 19,19,19, + 22,22,22, + 25 + ]; + + for (let i = 0; i < expectedResults.length; i++) { + const expected = expectedResults[i]; + const result = await validatorSetHbbft.getValidatorCountSweetSpot.call(i + 1); + // console.log(`i: ${i}, expected: ${expected}, result: ${result}`); + new BN(result).should.be.bignumber.equal(new BN(expected)); + } + + }); }); // TODO: ...add other tests...