From 48c532c8d75eb837f755ff4f9952de04f601d198 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Neboj=C5=A1a=20Obradovi=C4=87?= Date: Wed, 8 May 2019 17:55:24 +0200 Subject: [PATCH] Testnet Release 3.0.7 (#930) - Prevent remote control to crash finalize command. - Use latest Kadence from v5 branch which includes fix for the Hashcash. - Use Churn plugin to filter invalid connections. --- config/config.json | 37 +++- .../Ethereum/migrations/2_total_migration.js | 11 +- modules/Blockchain/Ethereum/truffle.js | 8 +- modules/RemoteControl.js | 5 + .../command/dh/dh-offer-finalized-command.js | 33 ++-- modules/logger.js | 13 +- modules/network/kademlia/kademlia.js | 27 ++- package-lock.json | 171 ++++++++++-------- package.json | 4 +- test/bdd/features/network.feature | 15 ++ test/bdd/steps/network.js | 47 ++++- test/modules/utilities.test.js | 8 +- 12 files changed, 255 insertions(+), 124 deletions(-) diff --git a/config/config.json b/config/config.json index 79405450f0..b52d268bcc 100644 --- a/config/config.json +++ b/config/config.json @@ -77,7 +77,12 @@ "bootstraps": ["https://developbs.origintrial.me:5278/#05edf19bd36906240503e2e2e2f18d13f8211d2f"], "remoteWhitelist": ["54.93.223.161", "127.0.0.1"], "solutionDifficulty": 8, - "identityDifficulty": 8 + "identityDifficulty": 8, + "churnPlugin": { + "cooldownBaseTimeout": "5m", + "cooldownMultiplier": 2, + "cooldownResetTime": "60m" + } }, "bugSnag": { "releaseStage": "development" @@ -156,7 +161,7 @@ "network_id": "rinkeby", "gas_limit": "2000000", "gas_price": "20000000000", - "hub_contract_address": "0x16d553B9765b6Aa9fE7C45Dfa1a1839fD88DD7bc", + "hub_contract_address": "0xA272797Bfc59946388D89CdB6821dEeC927E0E36", "plugins": [ { "enabled": false, @@ -178,7 +183,12 @@ "bootstraps": ["https://stagingbs.origintrial.me:5278/#1754b56ce26212eab45bc523c36e1d4bf57ea30e"], "remoteWhitelist": ["54.93.223.161", "127.0.0.1"], "solutionDifficulty": 14, - "identityDifficulty": 12 + "identityDifficulty": 12, + "churnPlugin": { + "cooldownBaseTimeout": "5m", + "cooldownMultiplier": 2, + "cooldownResetTime": "60m" + } }, "bugSnag": { "releaseStage": "staging" @@ -279,7 +289,12 @@ "bootstraps": ["https://82.196.10.12:5278/#e2f7ab11d0dd34595dfb2e71b4937ec8d790df84"], "remoteWhitelist": ["54.93.223.161", "127.0.0.1"], "solutionDifficulty": 14, - "identityDifficulty": 12 + "identityDifficulty": 12, + "churnPlugin": { + "cooldownBaseTimeout": "5m", + "cooldownMultiplier": 2, + "cooldownResetTime": "60m" + } }, "bugSnag": { "releaseStage": "stable" @@ -383,7 +398,12 @@ ], "remoteWhitelist": ["127.0.0.1", "localhost"], "solutionDifficulty": 14, - "identityDifficulty": 12 + "identityDifficulty": 12, + "churnPlugin": { + "cooldownBaseTimeout": "5m", + "cooldownMultiplier": 2, + "cooldownResetTime": "60m" + } }, "bugSnag": { "releaseStage": "testnet" @@ -487,7 +507,12 @@ ], "remoteWhitelist": ["127.0.0.1"], "solutionDifficulty": 14, - "identityDifficulty": 12 + "identityDifficulty": 12, + "churnPlugin": { + "cooldownBaseTimeout": "5m", + "cooldownMultiplier": 2, + "cooldownResetTime": "60m" + } }, "bugSnag": { "releaseStage": "mariner" diff --git a/modules/Blockchain/Ethereum/migrations/2_total_migration.js b/modules/Blockchain/Ethereum/migrations/2_total_migration.js index 62da1b4446..2b5f5d9e22 100644 --- a/modules/Blockchain/Ethereum/migrations/2_total_migration.js +++ b/modules/Blockchain/Ethereum/migrations/2_total_migration.js @@ -272,7 +272,7 @@ module.exports = async (deployer, network, accounts) => { console.log(`\t Holding contract address: \t\t${holding.address}`); break; case 'rinkeby': - await deployer.deploy(Hub, { gas: 6000000, from: accounts[0] }) + await deployer.deploy(Hub) .then((result) => { hub = result; }); @@ -281,21 +281,18 @@ module.exports = async (deployer, network, accounts) => { profileStorage = await deployer.deploy( ProfileStorage, hub.address, - { gas: 6000000, from: accounts[0] }, ); await hub.setContractAddress('ProfileStorage', profileStorage.address); holdingStorage = await deployer.deploy( HoldingStorage, hub.address, - { gas: 6000000, from: accounts[0] }, ); await hub.setContractAddress('HoldingStorage', holdingStorage.address); litigationStorage = await deployer.deploy( LitigationStorage, hub.address, - { gas: 6000000, from: accounts[0] }, ); await hub.setContractAddress('LitigationStorage', litigationStorage.address); @@ -304,23 +301,21 @@ module.exports = async (deployer, network, accounts) => { await hub.setContractAddress('Token', '0x98d9a611ad1b5761bdc1daac42c48e4d54cf5882'); - profile = await deployer.deploy(Profile, hub.address, { gas: 7000000, from: accounts[0] }); + profile = await deployer.deploy(Profile, hub.address); await hub.setContractAddress('Profile', profile.address); - holding = await deployer.deploy(Holding, hub.address, { gas: 7000000, from: accounts[0] }); + holding = await deployer.deploy(Holding, hub.address); await hub.setContractAddress('Holding', holding.address); litigation = await deployer.deploy( Litigation, hub.address, - { gas: 7000000, from: accounts[0] }, ); await hub.setContractAddress('Litigation', litigation.address); replacement = await deployer.deploy( Replacement, hub.address, - { gas: 7000000, from: accounts[0] }, ); await hub.setContractAddress('Replacement', replacement.address); diff --git a/modules/Blockchain/Ethereum/truffle.js b/modules/Blockchain/Ethereum/truffle.js index 2c8b366b1e..c96e28e031 100644 --- a/modules/Blockchain/Ethereum/truffle.js +++ b/modules/Blockchain/Ethereum/truffle.js @@ -47,7 +47,7 @@ module.exports = { update: { host: 'localhost', // Connect to geth on the specified port: 8545, - provider: () => new HDWalletProvider(mnemonic, `https://rinkeby.infura.io/${process.env.RINKEBY_ACCESS_KEY}`), + provider: () => new HDWalletProvider(mnemonic, `https://rinkeby.infura.io/v3/${process.env.RINKEBY_ACCESS_KEY}`), network_id: 4, gas: 6000000, // Gas limit used for deploys websockets: true, @@ -71,9 +71,9 @@ module.exports = { rinkeby: { host: 'localhost', // Connect to geth on the specified port: 8545, - provider: () => new HDWalletProvider(mnemonic, `https://rinkeby.infura.io/${process.env.RINKEBY_ACCESS_KEY}`), + provider: () => new HDWalletProvider(mnemonic, `https://rinkeby.infura.io/v3/${process.env.RINKEBY_ACCESS_KEY}`), network_id: 4, - gas: 6000000, // Gas limit used for deploys + gas: 6500000, // Gas limit used for deploys websockets: true, skipDryRun: true, }, @@ -81,7 +81,7 @@ module.exports = { live: { host: 'localhost', port: 8545, - provider: () => new HDWalletProvider(mnemonic, `https://mainnet.infura.io/${process.env.MAINNET_ACCESS_KEY}`), + provider: () => new HDWalletProvider(mnemonic, `https://mainnet.infura.io/v3/${process.env.MAINNET_ACCESS_KEY}`), network_id: 1, gas: 6000000, // Gas limit used for deploys websockets: true, diff --git a/modules/RemoteControl.js b/modules/RemoteControl.js index fcc24e360e..de4366927e 100644 --- a/modules/RemoteControl.js +++ b/modules/RemoteControl.js @@ -367,6 +367,11 @@ class RemoteControl { async (bid) => { const holding = await this._findHoldingByBid(bid); + if (holding == null || holding.data_set_id == null) { + this.log.debug('Failed to get holding data for for bid %s.', bid); + return; + } + const dataInfo = await Models.data_info.findOne({ where: { data_set_id: holding.data_set_id, diff --git a/modules/command/dh/dh-offer-finalized-command.js b/modules/command/dh/dh-offer-finalized-command.js index 60827c1a25..a8d745bfe4 100644 --- a/modules/command/dh/dh-offer-finalized-command.js +++ b/modules/command/dh/dh-offer-finalized-command.js @@ -54,21 +54,26 @@ class DhOfferFinalizedCommand extends Command { this.logger.important(`I've been chosen for offer ${offerId}.`); await this.remoteControl.onCompletedBids(); - const scheduledTime = (bid.holding_time_in_minutes * 60 * 1000) + (60 * 1000); - return { - commands: [ - { - name: 'dhPayOutCommand', - delay: scheduledTime, - retries: 3, - transactional: false, - data: { - offerId, - viaAPI: false, + + if (this.config.disableAutoPayouts !== true) { + const scheduledTime = + (bid.holding_time_in_minutes * 60 * 1000) + (60 * 1000); + return { + commands: [ + { + name: 'dhPayOutCommand', + delay: scheduledTime, + retries: 3, + transactional: false, + data: { + offerId, + viaAPI: false, + }, }, - }, - ], - }; + ], + }; + } + return Command.empty(); } bid.status = 'NOT_CHOSEN'; diff --git a/modules/logger.js b/modules/logger.js index f2f32a6b94..b66e5aeb5e 100644 --- a/modules/logger.js +++ b/modules/logger.js @@ -3,6 +3,8 @@ require('winston-daily-rotate-file'); // eslint-disable-next-line require('winston-papertrail').Papertrail; require('winston-loggly-bulk'); +const util = require('util'); + const runtimeConfigJson = require('../config/config.json')[process.env.NODE_ENV]; const colors = require('colors/safe'); @@ -121,13 +123,12 @@ class Logger { // Extend logger object to properly log 'Error' types const origLog = logger.log; - logger.log = (level, msg) => { - if (msg instanceof Error) { - // eslint-disable-next-line prefer-rest-params - const args = Array.prototype.slice.call(arguments); - args[1] = msg.stack; - origLog.apply(logger, args); + logger.log = (level, ...rest) => { + if (rest[0] instanceof Error) { + rest[1] = rest[0].stack; + origLog.apply(logger, rest); } else { + const msg = util.format(...rest); const transformed = Logger.transformLog(level, msg); if (!transformed) { return; diff --git a/modules/network/kademlia/kademlia.js b/modules/network/kademlia/kademlia.js index 13f9ecdc2f..00c2a4c958 100644 --- a/modules/network/kademlia/kademlia.js +++ b/modules/network/kademlia/kademlia.js @@ -244,6 +244,29 @@ class Kademlia { })); this.log.info('Hashcash initialised'); + this.node.blacklist = this.node.plugin(kadence.churnfilter({ + cooldownBaseTimeout: this.config.network.churnPlugin.cooldownBaseTimeout, + cooldownMultiplier: this.config.network.churnPlugin.cooldownMultiplier, + cooldownResetTime: this.config.network.churnPlugin.cooldownResetTime, + })); + this.log.info('Churn filter initialised'); + + // Patch Churn to ignore all outgoing requests towards blacklisted contacts. + const send = this.node.send.bind(this.node); + this.node.send = function (method, params, target, handler) { + try { + const contactId = target[0].toString('hex'); + if (this.node.blacklist.hasBlock(contactId)) { + this.log.debug('Trying to send to blacklisted contact: %s.', contactId); + return handler(Error('Contact blacklisted.')); + } + send(method, params, target, handler); + } catch (e) { + this.log.error('Failed to check for blacklist'); + handler(Error('Failed to check for blacklist.')); + } + }.bind(this); + if (this.config.onion_enabled) { this.enableOnion(); } @@ -254,8 +277,8 @@ class Kademlia { // Use verbose logging if enabled if (process.env.LOGS_LEVEL_DEBUG) { - this.node.rpc.deserializer.append(new IncomingMessage(this.log)); - this.node.rpc.serializer.prepend(new OutgoingMessage(this.log)); + this.node.rpc.deserializer.append(() => new IncomingMessage(this.log)); + this.node.rpc.serializer.prepend(() => new OutgoingMessage(this.log)); } // Cast network nodes to an array if (typeof this.config.network.bootstraps === 'string') { diff --git a/package-lock.json b/package-lock.json index a334e56327..9eebafbe09 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "origintrail_node", - "version": "3.0.6", + "version": "3.0.7", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -172,9 +172,7 @@ "integrity": "sha512-0OdKaIq5rsQaO/U/24h0G2w+btpXxf8HUwTRO8xlCtpoL8E5LL+ViRV1pGgFnB0XTnADr/E6/boi1YbqicjnAA==" }, "@kadenceproject/kadence": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@kadenceproject/kadence/-/kadence-4.4.0.tgz", - "integrity": "sha512-ic/cSyhF16jzDslcV9o9xsnDtHNNLhZJaFf1vS0k59v0dx5RBYVMeVJ9Jlwz/l3lTGv06eH7Q4tC+MDGfDe68Q==", + "version": "git+https://git@gitlab.com/deadcanaries/kadence.git#ded8f643174c965a6b2efb44ec26a4a833d355c6", "requires": { "async": "2.6.1", "atbf": "1.1.0", @@ -2201,7 +2199,7 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" } } @@ -2411,14 +2409,14 @@ } }, "cheerio": { - "version": "1.0.0-rc.2", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.2.tgz", - "integrity": "sha1-S59TqBsn5NXawxwP/Qz6A8xoMNs=", + "version": "1.0.0-rc.3", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz", + "integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==", "requires": { "css-select": "1.2.0", - "dom-serializer": "0.1.0", + "dom-serializer": "0.1.1", "entities": "1.1.2", - "htmlparser2": "3.10.0", + "htmlparser2": "3.10.1", "lodash": "4.17.10", "parse5": "3.0.3" } @@ -2925,19 +2923,19 @@ }, "css-select": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "requires": { "boolbase": "1.0.0", - "css-what": "2.1.2", + "css-what": "2.1.3", "domutils": "1.5.1", "nth-check": "1.0.2" } }, "css-what": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.2.tgz", - "integrity": "sha512-wan8dMWQ0GUeF7DGEPVjhHemVW/vy6xUYmFzRY8RYqgA0JtXC9rJmbScBjqSu6dg9q0lwPQy6ZAmJVr3PPTvqQ==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", + "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==" }, "csv": { "version": "1.2.1", @@ -3430,19 +3428,12 @@ } }, "dom-serializer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", + "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", "requires": { - "domelementtype": "1.1.3", + "domelementtype": "1.3.1", "entities": "1.1.2" - }, - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=" - } } }, "dom-walk": { @@ -3451,16 +3442,16 @@ "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=" }, "domelementtype": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.2.1.tgz", - "integrity": "sha512-SQVCLFS2E7G5CRCMdn6K9bIhRj1bS6QBWZfF0TUPh4V/BbqrQ619IdSS3/izn0FZ+9l+uODzaZjb08fjOfablA==" + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" }, "domhandler": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", "requires": { - "domelementtype": "1.2.1" + "domelementtype": "1.3.1" } }, "domutils": { @@ -3468,8 +3459,8 @@ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.2.1" + "dom-serializer": "0.1.1", + "domelementtype": "1.3.1" } }, "dotenv": { @@ -10822,7 +10813,6 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "optional": true, "requires": { "inflight": "1.0.6", "inherits": "2.0.3", @@ -10984,16 +10974,47 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=" }, "granax": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/granax/-/granax-3.1.4.tgz", - "integrity": "sha512-MhmOZs4c2KKCYqC5ORANfW535QTvkqAGOZPTBpiUsdqtgF5sOix14pDsq3Ye11kx+C6IgFPQZoTmifESDBswaA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/granax/-/granax-3.2.0.tgz", + "integrity": "sha512-62wNzm4vohffJYlGhe9KsrkgxmT9RhYiYAlkHL56GW1nH9lMww8V379k+dzF2q6CRVp86lfy4Rauvkh/KiyXsw==", "requires": { "7zip": "0.0.6", "async": "2.6.1", - "latest-torbrowser-version": "2.0.1", + "latest-torbrowser-version": "2.0.2", "merge": "1.2.1", "mkdirp": "0.5.1", - "ncp": "2.0.0" + "mv": "2.1.1", + "ncp": "2.0.0", + "progress": "2.0.3", + "rimraf": "2.6.3" + }, + "dependencies": { + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "requires": { + "glob": "7.1.3" + } + } } }, "growl": { @@ -11212,40 +11233,35 @@ "resolved": "https://registry.npmjs.org/hsv3/-/hsv3-1.1.5.tgz", "integrity": "sha512-ImLUb/uECAZloccS86fhKw2K5EIqFInk4gP3hsAUxCyQPLaTBa9lfUcAH9dBXNvtvXRJ6qzoVkq0NAFL7u/XNw==", "requires": { - "commander": "2.19.0", - "granax": "3.1.4", + "commander": "2.20.0", + "granax": "3.2.0", "mkdirp": "0.5.1" }, "dependencies": { "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==" } } }, "htmlparser2": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz", - "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==", + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", "requires": { - "domelementtype": "1.3.0", + "domelementtype": "1.3.1", "domhandler": "2.4.2", "domutils": "1.5.1", "entities": "1.1.2", "inherits": "2.0.3", - "readable-stream": "3.0.6" + "readable-stream": "3.3.0" }, "dependencies": { - "domelementtype": { - "version": "1.3.0", - "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=" - }, "readable-stream": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.0.6.tgz", - "integrity": "sha512-9E1oLoOWfhSXHGv6QlwXJim7uNzd9EVlWK+21tCU9Ju/kR0/p2AZYPz4qSchgO8PlLIH4FpZYfzwS+rEksZjIg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.3.0.tgz", + "integrity": "sha512-EsI+s3k3XsW+fU8fQACLN59ky34AZ14LoeVZpYwmZvldCFo0r0gnelwF2TcMjLor/BTL5aDJVBMkss0dthToPw==", "requires": { "inherits": "2.0.3", "string_decoder": "1.1.1", @@ -12143,21 +12159,14 @@ } }, "latest-torbrowser-version": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/latest-torbrowser-version/-/latest-torbrowser-version-2.0.1.tgz", - "integrity": "sha512-HtbbcKs6cl7Tz4RG+l1uulWd+tOJujn8wqyXd2zZjPRk9rO/mslg7Ajg72beEFCXwHPWZzwVR+w8mPO5yDiOWg==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/latest-torbrowser-version/-/latest-torbrowser-version-2.0.2.tgz", + "integrity": "sha512-2cg5j8szOY0g3jlyLZhye9as3oJihNJD3DN9+I7tdXMEBW4ZKH8Blq17xtj5Q2jtV7v8NjRCkBrXz3zPEjMWLQ==", "requires": { "async": "2.6.1", - "cheerio": "1.0.0-rc.2", + "cheerio": "1.0.0-rc.3", "follow-redirects": "1.5.0", "semver": "5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", - "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" - } } }, "lazystream": { @@ -13281,7 +13290,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -13403,7 +13412,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=", - "optional": true, "requires": { "mkdirp": "0.5.1", "ncp": "2.0.0", @@ -13414,7 +13422,6 @@ "version": "2.4.5", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=", - "optional": true, "requires": { "glob": "6.0.4" } @@ -13501,8 +13508,7 @@ "ncp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", - "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=", - "optional": true + "integrity": "sha1-GVoh1sRuNh0vsSgbo4uR6d9727M=" }, "nedb": { "version": "1.8.0", @@ -13530,7 +13536,7 @@ }, "needle": { "version": "1.1.2", - "resolved": "http://registry.npmjs.org/needle/-/needle-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/needle/-/needle-1.1.2.tgz", "integrity": "sha1-0oQaElv9dP77MMA0QQQ2kGHD4To=", "requires": { "debug": "2.6.9", @@ -13564,7 +13570,7 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" } } @@ -22783,7 +22789,7 @@ }, "jsonfile": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { "graceful-fs": "4.1.11" @@ -24364,17 +24370,22 @@ "resolved": "https://registry.npmjs.org/wmic/-/wmic-0.1.0.tgz", "integrity": "sha1-eLQasR0VTLgSgZ4SkWdNrVXY4dc=", "requires": { - "async": "2.6.1", + "async": "2.6.2", "iconv-lite": "0.4.23" }, "dependencies": { "async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz", + "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==", "requires": { - "lodash": "4.17.10" + "lodash": "4.17.11" } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" } } }, diff --git a/package.json b/package.json index 37a7bd4f17..cdfdcb6cea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "origintrail_node", - "version": "3.0.6", + "version": "3.0.7", "description": "OriginTrail node", "main": ".eslintrc.js", "config": { @@ -79,7 +79,7 @@ "snyk": true, "dependencies": { "@garbados/merkle-tree": "^1.0.3-alpha", - "@kadenceproject/kadence": "^4.4.0", + "@kadenceproject/kadence": "git+https://git@gitlab.com/deadcanaries/kadence.git#v5.0.1", "ajv": "^5.5.2", "arangojs": "^5.8.0", "async": "^2.6.0", diff --git a/test/bdd/features/network.feature b/test/bdd/features/network.feature index b1f167814e..28899bf405 100644 --- a/test/bdd/features/network.feature +++ b/test/bdd/features/network.feature @@ -136,6 +136,21 @@ Feature: Test basic network features And DC waits for holding time Then selected DHes should be payed out + @first + Scenario: DH with disabled auto-payouts + Given the replication difficulty is 0 + And I setup 5 nodes + And I override configuration for all nodes + | dc_holding_time_in_minutes | 1 | + | disableAutoPayouts | true | + And I start the nodes + And I use 1st node as DC + And DC imports "importers/xml_examples/Retail/01_Green_to_pink_shipment.xml" as GS1 + Given DC initiates the replication for last imported dataset + And I wait for replications to finish + And DC waits for holding time + Then selected DHes should not be payed out + @first Scenario: Node with diff management and operational wallet should successfully start Given I setup 1 node diff --git a/test/bdd/steps/network.js b/test/bdd/steps/network.js index 8c673ca7be..cbd0c51f70 100644 --- a/test/bdd/steps/network.js +++ b/test/bdd/steps/network.js @@ -16,6 +16,7 @@ const ImportUtilities = require('../../../modules/ImportUtilities'); const LocalBlockchain = require('./lib/local-blockchain'); const httpApiHelper = require('./lib/http-api-helper'); const utilities = require('./lib/utilities'); +const Models = require('../../../models'); // Identity difficulty 8. const bootstrapIdentity = { @@ -30,7 +31,17 @@ const bootstrapIdentity = { * @param rawTable */ function unpackRawTable(rawTable) { - const parse = val => (Number.isNaN(Number(val)) ? val : Number(val)); + const parse = (val) => { + if (!Number.isNaN(Number(val))) { + return Number(val); + } + + if (val.toLowerCase() === 'true' || val.toLowerCase() === 'false') { + return Boolean(val); + } + + return val; + }; const unpacked = {}; if (rawTable) { @@ -816,6 +827,40 @@ Given(/^selected DHes should be payed out*$/, { timeout: 180000 }, async functio return Promise.all(myPromises); }); +Given(/^selected DHes should not be payed out*$/, { timeout: 180000 }, async function () { + expect(this.state.nodes.length, 'No started nodes').to.be.greaterThan(0); + expect(!!this.state.dc, 'DC node not defined. Use other step to define it.').to.be.equal(true); + + const { dc } = this.state; + const myPromises = []; + + this.state.nodes.forEach((node) => { + if (node === dc) { + // Skip the DC node. + return; + } + myPromises.push(new Promise(async (accept, reject) => { + // Check each node for payout command. + + Models.sequelize.options.storage = node.systemDbPath; + await Models.sequelize.sync(); + const payOutCommands = await Models.sequelize.models.commands.findAll({ + where: { + name: 'dhPayOutCommand', + }, + }); + + if (payOutCommands.length === 0) { + accept(); + } else { + reject(Error('Command dhPayOutCommand should not be scheduled.')); + } + })); + }); + + return Promise.all(myPromises); +}); + Given(/^I set (\d+)[st|nd|rd|th]+ node's management wallet to be different then operational wallet$/, { timeout: 3000000 }, function (nodeIndex) { expect(nodeIndex, 'Invalid index.').to.be.within(0, this.state.nodes.length); diff --git a/test/modules/utilities.test.js b/test/modules/utilities.test.js index ea2943ef68..204503f0c2 100644 --- a/test/modules/utilities.test.js +++ b/test/modules/utilities.test.js @@ -42,12 +42,18 @@ describe('Utilities module', () => { ); assert.hasAllKeys( config.network, [ - 'id', 'hostname', 'bootstraps', + 'id', 'hostname', 'bootstraps', 'churnPlugin', 'remoteWhitelist', 'identityDifficulty', 'solutionDifficulty', ], `Some config items are missing in config.network for environment '${environment}'`, ); + assert.hasAllKeys( + config.network.churnPlugin, [ + 'cooldownBaseTimeout', 'cooldownMultiplier', 'cooldownResetTime', + ], + `Some config items are missing in config.network.churnPlugin for environment '${environment}'`, + ); assert.hasAllKeys( config.bugSnag, ['releaseStage'], `Some config items are missing in config.bugSnag for environment '${environment}'`,