From 784c386959e3c9b2412d0b5923e19fdbb4b3a00c Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 24 Aug 2021 06:52:10 +0300 Subject: [PATCH 01/67] Update default config.json --- .gitignore | 3 +++ config.json | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 5b17847e..b75e3371 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .ed25519-node .idea/ .project +.vscode/ __MACOSX/ dapps/ docs/jsdoc/ @@ -17,3 +18,5 @@ tmp sftp-config.json *.swp *.swo +package-lock.json + diff --git a/config.json b/config.json index f7087f25..1e11e4b2 100644 --- a/config.json +++ b/config.json @@ -1,9 +1,9 @@ { "port": 36666, "address": "0.0.0.0", - "fileLogLevel": "info", + "fileLogLevel": "warn", "logFileName": "logs/adamant.log", - "consoleLogLevel": "none", + "consoleLogLevel": "info", "trustProxy": false, "topAccounts": false, "cacheEnabled": false, @@ -73,11 +73,11 @@ } }, "broadcasts": { - "broadcastInterval": 5000, + "broadcastInterval": 1500, "broadcastLimit": 20, "parallelLimit": 20, "releaseLimit": 25, - "relayLimit": 2 + "relayLimit": 3 }, "transactions": { "maxTxsPerQueue": 1000 From 8ef60ecb2880c757c357ade5b32b7eaccadf4a0a Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 24 Aug 2021 07:07:46 +0300 Subject: [PATCH 02/67] Change old name to ADAMANT --- app.js | 24 ++++++++++++------------ helpers/slots.js | 10 +++++----- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/app.js b/app.js index 98f4b069..13cd5eb1 100644 --- a/app.js +++ b/app.js @@ -18,7 +18,7 @@ /** * Main entry point. - * Loads the secu modules, the secu api and run the express server as Domain master. + * Loads the ADAMANT modules, the ADAMANT api and run the express server as Domain master. * CLI options available. * @module app */ @@ -111,7 +111,7 @@ if (process.env.NODE_ENV === 'test') { process.env.TOP = appConfig.topAccounts; /** - * The config object to handle secu modules and secu api. + * The config object to handle ADAMANT modules and ADAMANT api. * It loads `modules` and `api` folders content. * Also contains db configuration from config.json. * @property {object} db - Config values for database. @@ -282,7 +282,7 @@ d.run(function () { * Once config is completed, creates app, http & https servers & sockets with express. * @method network * @param {object} scope - The results from current execution, - * at leats will contain the required elements. + * at least will contain the required elements. * @param {nodeStyleCallback} cb - Callback function with created Object: * `{express, app, server, io, https, https_io}`. */ @@ -367,7 +367,7 @@ d.run(function () { * adds configuration to `network.app`. * @method connect * @param {object} scope - The results from current execution, - * at leats will contain the required elements. + * at least will contain the required elements. * @param {function} cb - Callback function. */ connect: ['config', 'public', 'genesisblock', 'logger', 'build', 'network', function (scope, cb) { @@ -489,7 +489,7 @@ d.run(function () { * loads transaction, block, account and peers from logic folder. * @method logic * @param {object} scope - The results from current execution, - * at leats will contain the required elements. + * at least will contain the required elements. * @param {function} cb - Callback function. */ logic: ['db', 'bus', 'schema', 'genesisblock', function (scope, cb) { @@ -550,7 +550,7 @@ d.run(function () { * loads modules from `modules` folder using `config.modules`. * @method modules * @param {object} scope - The results from current execution, - * at leats will contain the required elements. + * at least will contain the required elements. * @param {nodeStyleCallback} cb - Callback function with resulted load. */ modules: ['network', 'connect', 'config', 'logger', 'bus', 'sequence', 'dbSequence', 'balancesSequence', 'db', 'logic', 'cache', function (scope, cb) { @@ -587,7 +587,7 @@ d.run(function () { * network are completed. * @method api * @param {object} scope - The results from current execution, - * at leats will contain the required elements. + * at least will contain the required elements. * @param {function} cb - Callback function. */ api: ['modules', 'logger', 'network', function (scope, cb) { @@ -619,17 +619,17 @@ d.run(function () { * specified host and port for `scope.network.server`. * @method listen * @param {object} scope - The results from current execution, - * at leats will contain the required elements. + * at least will contain the required elements. * @param {nodeStyleCallback} cb - Callback function with `scope.network`. */ listen: ['ready', function (scope, cb) { scope.network.server.listen(scope.config.port, scope.config.address, function (err) { - scope.logger.info('Secu started: ' + scope.config.address + ':' + scope.config.port); + scope.logger.info('ADAMANT started: ' + scope.config.address + ':' + scope.config.port); if (!err) { if (scope.config.ssl.enabled) { scope.network.https.listen(scope.config.ssl.options.port, scope.config.ssl.options.address, function (err) { - scope.logger.info('Secu https started: ' + scope.config.ssl.options.address + ':' + scope.config.ssl.options.port); + scope.logger.info('ADAMANT https started: ' + scope.config.ssl.options.address + ':' + scope.config.ssl.options.port); cb(err, scope.network); }); @@ -657,7 +657,7 @@ d.run(function () { * @property {undefined} connect - Undefined. * @property {Object} db - Database constructor, database functions. * @property {function} dbSequence - Database function. - * @property {Object} ed - Crypto functions from secu node-sodium. + * @property {Object} ed - Crypto functions from ADAMANT node-sodium. * @property {Object} genesisblock - Block information. * @property {string} lastCommit - Hash transaction. * @property {Object} listen - Network information. @@ -666,7 +666,7 @@ d.run(function () { * @property {Object} modules - Several modules functions. * @property {Object} network - Several network functions. * @property {string} nonce - * @property {string} public - Path to secu public folder. + * @property {string} public - Path to ADAMANT public folder. * @property {undefined} ready * @property {Object} schema - ZSchema with objects. * @property {Object} sequence - Sequence function, sequence Array. diff --git a/helpers/slots.js b/helpers/slots.js index 56d22e9b..be0811f7 100644 --- a/helpers/slots.js +++ b/helpers/slots.js @@ -6,7 +6,7 @@ var constants = require('./constants.js'); * @module helpers/slots */ /** - * Gets constant time from Secu epoch. + * Gets constant time from ADAMANT epoch. * @returns {number} epochTime from constants. */ function beginEpochTime () { @@ -16,9 +16,9 @@ function beginEpochTime () { } /** - * Calculates time since Secu epoch. + * Calculates time since ADAMANT epoch. * @param {number|undefined} time - Time in unix seconds. - * @returns {number} current time - secu epoch time. + * @returns {number} current time - ADAMANT epoch time. */ function getEpochTime (time) { if (time === undefined) { @@ -47,7 +47,7 @@ module.exports = { /** * @method * @param {number} time - * @return {number} secu epoch time constant. + * @return {number} ADAMANT epoch time constant. */ getTime: function (time) { return getEpochTime(time); @@ -56,7 +56,7 @@ module.exports = { /** * @method * @param {number} [epochTime] - * @return {number} constant time from secu epoch + input time. + * @return {number} constant time from ADAMANT epoch + input time. */ getRealTime: function (epochTime) { if (epochTime === undefined) { From a67afe394b1a473f33fa77a590b11024bd2be3fc Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 24 Aug 2021 07:54:01 +0300 Subject: [PATCH 03/67] Update defauld redis port --- config.json | 2 +- test/config.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config.json b/config.json index 1e11e4b2..1d59e3fd 100644 --- a/config.json +++ b/config.json @@ -22,7 +22,7 @@ }, "redis": { "host": "127.0.0.1", - "port": 6380, + "port": 6379, "db": 0, "password": null }, diff --git a/test/config.json b/test/config.json index abdba3f9..4da1f5cc 100644 --- a/test/config.json +++ b/test/config.json @@ -22,8 +22,8 @@ }, "redis": { "host": "127.0.0.1", - "port": 6380, - "db": 0, + "port": 6379, + "db": 1, "password": null }, "api": { From e47384acf187a8132110752d1a36483452a3a106 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 24 Aug 2021 08:17:32 +0300 Subject: [PATCH 04/67] Add '--genesis' param --- app.js | 5 +++-- test/config.json | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app.js b/app.js index 13cd5eb1..8c48846c 100644 --- a/app.js +++ b/app.js @@ -28,7 +28,6 @@ var checkIpInList = require('./helpers/checkIpInList.js'); var extend = require('extend'); var fs = require('fs'); -var genesisblock = require('./genesisBlock.json'); var git = require('./helpers/git.js'); var https = require('https'); var Logger = require('./logger.js'); @@ -57,7 +56,8 @@ if (typeof gc !== 'undefined') { program .version(packageJson.version) - .option('-c, --config ', 'config file path') + .option('-c, --config ', 'config.json file path') + .option('-g, --genesis ', 'genesisBlock.json file path') .option('-p, --port ', 'listening port number') .option('-a, --address ', 'listening host name or ip') .option('-x, --peers [peers...]', 'peers list') @@ -70,6 +70,7 @@ program * @default 'config.json' */ var appConfig = require('./helpers/config.js')(program.config); +var genesisblock = require(path.resolve(process.cwd(), (program.genesis || 'genesisBlock.json'))); if (program.port) { appConfig.port = program.port; diff --git a/test/config.json b/test/config.json index 4da1f5cc..99a0543e 100644 --- a/test/config.json +++ b/test/config.json @@ -195,7 +195,7 @@ } }, "dapp": { - "masterrequired": true, + "masterrequired": false, "masterpassword": "", "autoexec": [] }, From 54eb1be321c997023d01a5ddd76f25eb19ff34d3 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Thu, 2 Sep 2021 11:45:23 +0300 Subject: [PATCH 05/67] Update testnet config --- test/config.json | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/test/config.json b/test/config.json index 99a0543e..447251e9 100644 --- a/test/config.json +++ b/test/config.json @@ -11,7 +11,7 @@ "host": "localhost", "port": 5432, "database": "adamant_test", - "user": "adamant", + "user": "adamanttest", "password": "password", "poolSize": 95, "poolIdleTimeout": 30000, @@ -43,10 +43,16 @@ }, "peers": { "enabled": true, - "list": [{ - "ip": "127.0.0.1", - "port": 36667 - }], + "list": [ + { + "ip": "162.55.32.80", + "port": 36667 + }, + { + "ip": "65.21.156.2", + "port": 36667 + } + ], "access": { "blackList": [] }, @@ -71,7 +77,7 @@ "maxTxsPerQueue": 1000 }, "forging": { - "force": true, + "force": false, "secret": [ "weather play vibrant large edge clean notable april fire smoke drift hidden", "rally clean ladder crane gadget century timber jealous shine scorpion beauty salon", From 7a9e3b52681bae7c7a870c915e8af15764ca2a2d Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 3 Sep 2021 15:46:59 +0300 Subject: [PATCH 06/67] Add portWS 36665 for testnet --- test/config.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/config.json b/test/config.json index 447251e9..1bed1b56 100644 --- a/test/config.json +++ b/test/config.json @@ -51,6 +51,14 @@ { "ip": "65.21.156.2", "port": 36667 + }, + { + "ip": "95.217.19.144", + "port": 36667 + }, + { + "ip": "157.90.229.236", + "port": 36667 } ], "access": { @@ -205,5 +213,9 @@ "masterpassword": "", "autoexec": [] }, + "wsClient": { + "portWS": 36665, + "enabled": true + }, "nethash": "38f153a81332dea86751451fd992df26a9249f0834f72f58f84ac31cceb70f43" } From e0b029b5e28d1dcda85c74e7626c17cce98e204e Mon Sep 17 00:00:00 2001 From: adamant-al Date: Sat, 4 Sep 2021 16:15:09 +0300 Subject: [PATCH 07/67] Add start:test script --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index aae95d3a..ba6329e7 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "scripts": { "start": "node app.js", + "start:testnet": "node app.js --config test/config.json --genesis test/genesisBlock.json", "test": "./node_modules/.bin/grunt test --verbose", "jenkins": "./node_modules/.bin/grunt jenkins --verbose", "eslint": "./node_modules/.bin/grunt eslint-nofix --verbose", From 7437af11bf1f799ce0d427371e3ba19a8e9196c1 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Sat, 4 Sep 2021 16:15:29 +0300 Subject: [PATCH 08/67] Update test config --- test/config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/config.json b/test/config.json index 1bed1b56..57084cc9 100644 --- a/test/config.json +++ b/test/config.json @@ -5,7 +5,7 @@ "logFileName": "logs/adamant.log", "consoleLogLevel": "debug", "trustProxy": false, - "topAccounts": false, + "topAccounts": true, "cacheEnabled": true, "db": { "host": "localhost", From 5e44f72d5c63288ccecabcf8417004fe019ce40c Mon Sep 17 00:00:00 2001 From: adamant-al Date: Mon, 6 Sep 2021 09:24:59 +0300 Subject: [PATCH 09/67] Fix string quoutes warning --- logic/transaction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logic/transaction.js b/logic/transaction.js index aec2b532..e79e1121 100644 --- a/logic/transaction.js +++ b/logic/transaction.js @@ -900,7 +900,7 @@ Transaction.prototype.applyUnconfirmed = function (trs, sender, requester, cb) { var new_trs = Object.assign({}, trs); new_trs.block_timestamp = null; if (!new_trs.recipientPublicKey && new_trs.recipientId) { - this.scope.db.query(`SELECT ENCODE ("publicKey", \'hex\') AS "publicKey" from mem_accounts WHERE address='` + new_trs.recipientId + `' limit 1`).then((rows) => { + this.scope.db.query(`SELECT ENCODE ("publicKey", \'hex\') AS "publicKey" from mem_accounts WHERE address='${new_trs.recipientId}' limit 1`).then((rows) => { if (rows[0]) { new_trs.recipientPublicKey = rows[0]['publicKey']; } From 0b6cf5fa4f18d3cc1ac26d83df7d9cf6b08fd77a Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 7 Sep 2021 15:20:40 +0300 Subject: [PATCH 10/67] Use Testnet for tests; fix dapp & peers tests --- test/api/blocks.js | 808 ++--- test/api/dapps.js | 2707 +++++++++-------- test/api/multisignatures.js | 1560 +++++----- test/api/peer.blocks.js | 2 +- test/api/peer.transactions.collision.js | 225 +- test/api/peer.transactions.main.js | 751 +++-- test/api/peer.transactions.multisignatures.js | 161 +- test/api/peer.transactions.signatures.js | 301 +- test/api/signatures.js | 336 +- test/common/initModule.js | 10 +- test/index.js | 2 +- test/node.js | 32 +- test/unit/logic/multisignature.js | 726 ++--- test/unit/modules/blocks/verify.js | 954 +++--- test/unit/modules/peers.js | 604 ++-- test/unit/schema/dapp.js | 156 +- test/unit/schema/multisignatures.js | 194 +- test/unit/schema/transactions.js | 4 +- 18 files changed, 4844 insertions(+), 4689 deletions(-) diff --git a/test/api/blocks.js b/test/api/blocks.js index 409d2e9c..b4435d23 100644 --- a/test/api/blocks.js +++ b/test/api/blocks.js @@ -1,404 +1,404 @@ -// 'use strict'; -// -// var node = require('./../node.js'); -// var modulesLoader = require('./../common/initModule.js').modulesLoader; -// -// var block = { -// blockHeight: 0, -// id: 0, -// generatorPublicKey: '', -// totalAmount: 0, -// totalFee: 0 -// }; -// -// var testBlocksUnder101 = false; -// -// describe('GET /api/blocks/getBroadhash', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getBroadhash', function (err, res) { -// node.expect(res.body).to.have.property('broadhash').to.be.a('string'); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getEpoch', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getEpoch', function (err, res) { -// node.expect(res.body).to.have.property('epoch').to.be.a('string'); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getHeight', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getHeight', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// if (res.body.success && res.body.height != null) { -// node.expect(res.body).to.have.property('height').to.be.above(0); -// block.blockHeight = res.body.height; -// -// if (res.body.height > 100) { -// testBlocksUnder101 = true; -// } -// } -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getFee', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getFee', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('fee'); -// node.expect(res.body.fee).to.equal(node.fees.transactionFee); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getfees', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getFees', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('fees'); -// node.expect(res.body.fees.send).to.equal(node.fees.transactionFee); -// node.expect(res.body.fees.vote).to.equal(node.fees.voteFee); -// node.expect(res.body.fees.dapp).to.equal(node.fees.dappAddFee); -// node.expect(res.body.fees.secondsignature).to.equal(node.fees.secondPasswordFee); -// node.expect(res.body.fees.delegate).to.equal(node.fees.delegateRegistrationFee); -// node.expect(res.body.fees.multisignature).to.equal(node.fees.multisignatureRegistrationFee); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getNethash', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getNethash', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('nethash').to.be.a('string'); -// node.expect(res.body.nethash).to.equal(node.config.nethash); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getMilestone', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getMilestone', function (err, res) { -// node.expect(res.body).to.have.property('milestone').to.be.a('number'); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getReward', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getReward', function (err, res) { -// node.expect(res.body).to.have.property('reward').to.be.a('number'); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getSupply', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getSupply', function (err, res) { -// node.expect(res.body).to.have.property('supply').to.be.a('number'); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/getStatus', function () { -// -// it('should be ok', function (done) { -// node.get('/api/blocks/getStatus', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('broadhash').to.be.a('string'); -// node.expect(res.body).to.have.property('epoch').to.be.a('string'); -// node.expect(res.body).to.have.property('height').to.be.a('number'); -// node.expect(res.body).to.have.property('fee').to.be.a('number'); -// node.expect(res.body).to.have.property('milestone').to.be.a('number'); -// node.expect(res.body).to.have.property('nethash').to.be.a('string'); -// node.expect(res.body).to.have.property('reward').to.be.a('number'); -// node.expect(res.body).to.have.property('supply').to.be.a('number'); -// done(); -// }); -// }); -// }); -// -// describe('GET /blocks (cache)', function () { -// -// var cache; -// -// before(function (done) { -// node.config.cacheEnabled = true; -// done(); -// }); -// -// before(function (done) { -// modulesLoader.initCache(function (err, __cache) { -// cache = __cache; -// node.expect(err).to.not.exist; -// node.expect(__cache).to.be.an('object'); -// return done(err, __cache); -// }); -// }); -// -// after(function (done) { -// cache.quit(done); -// }); -// -// afterEach(function (done) { -// cache.flushDb(function (err, status) { -// node.expect(err).to.not.exist; -// node.expect(status).to.equal('OK'); -// done(err, status); -// }); -// }); -// -// it('cache blocks by the url and parameters when response is a success', function (done) { -// var url, params; -// url = '/api/blocks?'; -// params = 'height=' + block.blockHeight; -// node.get(url + params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// node.expect(res.body).to.have.property('count').to.equal(1); -// var response = res.body; -// cache.getJsonForKey(url + params, function (err, res) { -// node.expect(err).to.not.exist; -// node.expect(res).to.eql(response); -// done(); -// }); -// }); -// }); -// -// it('should not cache if response is not a success', function (done) { -// var url, params; -// url = '/api/blocks?'; -// params = 'height=' + -1000; -// node.get(url + params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// cache.getJsonForKey(url + params, function (err, res) { -// node.expect(err).to.not.exist; -// node.expect(res).to.eql(null); -// done(); -// }); -// }); -// }); -// -// it('should remove entry from cache on new block', function (done) { -// var url, params; -// url = '/api/blocks?'; -// params = 'height=' + block.blockHeight; -// node.get(url + params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// node.expect(res.body).to.have.property('count').to.equal(1); -// var response = res.body; -// cache.getJsonForKey(url + params, function (err, res) { -// node.expect(err).to.not.exist; -// node.expect(res).to.eql(response); -// node.onNewBlock(function (err) { -// node.expect(err).to.not.exist; -// cache.getJsonForKey(url + params, function (err, res) { -// node.expect(err).to.not.exist; -// node.expect(res).to.eql(null); -// done(); -// }); -// }); -// }); -// }); -// }); -// }); -// -// describe('GET /blocks', function () { -// -// function getBlocks (params, done) { -// node.get('/api/blocks?' + params, done); -// } -// -// it('using height should be ok', function (done) { -// getBlocks('height=' + block.blockHeight, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// node.expect(res.body).to.have.property('count').to.equal(1); -// node.expect(res.body.blocks.length).to.equal(1); -// node.expect(res.body.blocks[0]).to.have.property('previousBlock'); -// node.expect(res.body.blocks[0]).to.have.property('totalAmount'); -// node.expect(res.body.blocks[0]).to.have.property('totalFee'); -// node.expect(res.body.blocks[0]).to.have.property('generatorId'); -// node.expect(res.body.blocks[0]).to.have.property('confirmations'); -// node.expect(res.body.blocks[0]).to.have.property('blockSignature'); -// node.expect(res.body.blocks[0]).to.have.property('numberOfTransactions'); -// node.expect(res.body.blocks[0].height).to.equal(block.blockHeight); -// block.id = res.body.blocks[0].id; -// block.generatorPublicKey = res.body.blocks[0].generatorPublicKey; -// block.totalAmount = res.body.blocks[0].totalAmount; -// block.totalFee = res.body.blocks[0].totalFee; -// done(); -// }); -// }); -// -// it('using height < 100 should be ok', function (done) { -// if (!testBlocksUnder101) { -// return this.skip(); -// } -// -// getBlocks('height=' + 10, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('count'); -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// node.expect(res.body.blocks.length).to.equal(1); -// node.expect(res.body.blocks[0]).to.have.property('previousBlock'); -// node.expect(res.body.blocks[0]).to.have.property('totalAmount'); -// node.expect(res.body.blocks[0]).to.have.property('totalFee'); -// node.expect(res.body.blocks[0]).to.have.property('generatorId'); -// node.expect(res.body.blocks[0]).to.have.property('confirmations'); -// node.expect(res.body.blocks[0]).to.have.property('blockSignature'); -// node.expect(res.body.blocks[0]).to.have.property('numberOfTransactions'); -// node.expect(res.body.blocks[0].height).to.equal(10); -// block.id = res.body.blocks[0].id; -// block.generatorPublicKey = res.body.blocks[0].generatorPublicKey; -// block.totalAmount = res.body.blocks[0].totalAmount; -// block.totalFee = res.body.blocks[0].totalFee; -// done(); -// }); -// }); -// -// it('using generatorPublicKey should be ok', function (done) { -// getBlocks('generatorPublicKey=' + block.generatorPublicKey, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// for (var i = 0; i < res.body.blocks.length; i++) { -// node.expect(res.body.blocks[i].generatorPublicKey).to.equal(block.generatorPublicKey); -// } -// done(); -// }); -// }); -// -// it('using totalFee should be ok', function (done) { -// getBlocks('totalFee=' + block.totalFee, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// for (var i = 0; i < res.body.blocks.length; i++) { -// node.expect(res.body.blocks[i].totalFee).to.equal(block.totalFee); -// } -// done(); -// }); -// }); -// -// it('using totalAmount should be ok', function (done) { -// getBlocks('totalAmount=' + block.totalAmount, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// for (var i = 0; i < res.body.blocks.length; i++) { -// node.expect(res.body.blocks[i].totalAmount).to.equal(block.totalAmount); -// } -// done(); -// }); -// }); -// -// it('using previousBlock should be ok', function (done) { -// if (block.id === null) { -// return this.skip(); -// } -// -// var previousBlock = block.id; -// -// node.onNewBlock(function (err) { -// getBlocks('previousBlock=' + block.id, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// node.expect(res.body.blocks).to.have.length(1); -// node.expect(res.body.blocks[0].previousBlock).to.equal(previousBlock); -// done(); -// }); -// }); -// }); -// -// it('using orderBy == "height:asc" should be ok', function (done) { -// getBlocks('orderBy=' + 'height:asc', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// for (var i = 0; i < res.body.blocks.length; i++) { -// if (res.body.blocks[i + 1] != null) { -// node.expect(res.body.blocks[i].height).to.be.below(res.body.blocks[i + 1].height); -// } -// } -// done(); -// }); -// }); -// -// it('using orderBy == "height:desc" should be ok', function (done) { -// getBlocks('orderBy=' + 'height:desc', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// for (var i = 0; i < res.body.blocks.length; i++) { -// if (res.body.blocks[i + 1] != null) { -// node.expect(res.body.blocks[i].height).to.be.above(res.body.blocks[i + 1].height); -// } -// } -// done(); -// }); -// }); -// -// it('should be ordered by "height:desc" by default', function (done) { -// getBlocks('', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('blocks').that.is.an('array'); -// for (var i = 0; i < res.body.blocks.length; i++) { -// if (res.body.blocks[i + 1] != null) { -// node.expect(res.body.blocks[i].height).to.be.above(res.body.blocks[i + 1].height); -// } -// } -// done(); -// }); -// }); -// }); -// -// describe('GET /api/blocks/get?id=', function () { -// -// function getBlocks (id, done) { -// node.get('/api/blocks/get?id=' + id, done); -// } -// -// it('using genesisblock id should be ok', function (done) { -// getBlocks('6438017970172540087', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('block').to.be.a('object'); -// node.expect(res.body.block).to.have.property('id').to.be.a('string'); -// done(); -// }); -// }); -// -// it('using unknown id should fail', function (done) { -// getBlocks('9928719876370886655', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.be.a('string'); -// done(); -// }); -// }); -// -// it('using no id should fail', function (done) { -// getBlocks('', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.be.a('string'); -// done(); -// }); -// }); -// }); +'use strict'; + +var node = require('./../node.js'); +var modulesLoader = require('./../common/initModule.js').modulesLoader; + +var block = { + blockHeight: 0, + id: 0, + generatorPublicKey: '', + totalAmount: 0, + totalFee: 0 +}; + +var testBlocksUnder101 = false; + +describe('GET /api/blocks/getBroadhash', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getBroadhash', function (err, res) { + node.expect(res.body).to.have.property('broadhash').to.be.a('string'); + done(); + }); + }); +}); + +describe('GET /api/blocks/getEpoch', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getEpoch', function (err, res) { + node.expect(res.body).to.have.property('epoch').to.be.a('string'); + done(); + }); + }); +}); + +describe('GET /api/blocks/getHeight', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getHeight', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + if (res.body.success && res.body.height != null) { + node.expect(res.body).to.have.property('height').to.be.above(0); + block.blockHeight = res.body.height; + + if (res.body.height > 100) { + testBlocksUnder101 = true; + } + } + done(); + }); + }); +}); + +describe('GET /api/blocks/getFee', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getFee', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('fee'); + node.expect(res.body.fee).to.equal(node.fees.transactionFee); + done(); + }); + }); +}); + +describe('GET /api/blocks/getfees', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getFees', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('fees'); + node.expect(res.body.fees.send).to.equal(node.fees.transactionFee); + node.expect(res.body.fees.vote).to.equal(node.fees.voteFee); + node.expect(res.body.fees.dapp).to.equal(node.fees.dappAddFee); + node.expect(res.body.fees.secondsignature).to.equal(node.fees.secondPasswordFee); + node.expect(res.body.fees.delegate).to.equal(node.fees.delegateRegistrationFee); + node.expect(res.body.fees.multisignature).to.equal(node.fees.multisignatureRegistrationFee); + done(); + }); + }); +}); + +describe('GET /api/blocks/getNethash', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getNethash', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('nethash').to.be.a('string'); + node.expect(res.body.nethash).to.equal(node.config.nethash); + done(); + }); + }); +}); + +describe('GET /api/blocks/getMilestone', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getMilestone', function (err, res) { + node.expect(res.body).to.have.property('milestone').to.be.a('number'); + done(); + }); + }); +}); + +describe('GET /api/blocks/getReward', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getReward', function (err, res) { + node.expect(res.body).to.have.property('reward').to.be.a('number'); + done(); + }); + }); +}); + +describe('GET /api/blocks/getSupply', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getSupply', function (err, res) { + node.expect(res.body).to.have.property('supply').to.be.a('number'); + done(); + }); + }); +}); + +describe('GET /api/blocks/getStatus', function () { + + it('should be ok', function (done) { + node.get('/api/blocks/getStatus', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('broadhash').to.be.a('string'); + node.expect(res.body).to.have.property('epoch').to.be.a('string'); + node.expect(res.body).to.have.property('height').to.be.a('number'); + node.expect(res.body).to.have.property('fee').to.be.a('number'); + node.expect(res.body).to.have.property('milestone').to.be.a('number'); + node.expect(res.body).to.have.property('nethash').to.be.a('string'); + node.expect(res.body).to.have.property('reward').to.be.a('number'); + node.expect(res.body).to.have.property('supply').to.be.a('number'); + done(); + }); + }); +}); + +describe('GET /blocks (cache)', function () { + + var cache; + + before(function (done) { + node.config.cacheEnabled = true; + done(); + }); + + before(function (done) { + modulesLoader.initCache(function (err, __cache) { + cache = __cache; + node.expect(err).to.not.exist; + node.expect(__cache).to.be.an('object'); + return done(err, __cache); + }); + }); + + after(function (done) { + cache.quit(done); + }); + + afterEach(function (done) { + cache.flushDb(function (err, status) { + node.expect(err).to.not.exist; + node.expect(status).to.equal('OK'); + done(err, status); + }); + }); + + it('cache blocks by the url and parameters when response is a success', function (done) { + var url, params; + url = '/api/blocks?'; + params = 'height=' + block.blockHeight; + node.get(url + params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + node.expect(res.body).to.have.property('count').to.equal(1); + var response = res.body; + cache.getJsonForKey(url + params, function (err, res) { + node.expect(err).to.not.exist; + node.expect(res).to.eql(response); + done(); + }); + }); + }); + + it('should not cache if response is not a success', function (done) { + var url, params; + url = '/api/blocks?'; + params = 'height=' + -1000; + node.get(url + params, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + cache.getJsonForKey(url + params, function (err, res) { + node.expect(err).to.not.exist; + node.expect(res).to.eql(null); + done(); + }); + }); + }); + + it('should remove entry from cache on new block', function (done) { + var url, params; + url = '/api/blocks?'; + params = 'height=' + block.blockHeight; + node.get(url + params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + node.expect(res.body).to.have.property('count').to.equal(1); + var response = res.body; + cache.getJsonForKey(url + params, function (err, res) { + node.expect(err).to.not.exist; + node.expect(res).to.eql(response); + node.onNewBlock(function (err) { + node.expect(err).to.not.exist; + cache.getJsonForKey(url + params, function (err, res) { + node.expect(err).to.not.exist; + node.expect(res).to.eql(null); + done(); + }); + }); + }); + }); + }); +}); + +describe('GET /blocks', function () { + + function getBlocks (params, done) { + node.get('/api/blocks?' + params, done); + } + + it('using height should be ok', function (done) { + getBlocks('height=' + block.blockHeight, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + node.expect(res.body).to.have.property('count').to.equal(1); + node.expect(res.body.blocks.length).to.equal(1); + node.expect(res.body.blocks[0]).to.have.property('previousBlock'); + node.expect(res.body.blocks[0]).to.have.property('totalAmount'); + node.expect(res.body.blocks[0]).to.have.property('totalFee'); + node.expect(res.body.blocks[0]).to.have.property('generatorId'); + node.expect(res.body.blocks[0]).to.have.property('confirmations'); + node.expect(res.body.blocks[0]).to.have.property('blockSignature'); + node.expect(res.body.blocks[0]).to.have.property('numberOfTransactions'); + node.expect(res.body.blocks[0].height).to.equal(block.blockHeight); + block.id = res.body.blocks[0].id; + block.generatorPublicKey = res.body.blocks[0].generatorPublicKey; + block.totalAmount = res.body.blocks[0].totalAmount; + block.totalFee = res.body.blocks[0].totalFee; + done(); + }); + }); + + it('using height < 100 should be ok', function (done) { + if (!testBlocksUnder101) { + return this.skip(); + } + + getBlocks('height=' + 10, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count'); + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + node.expect(res.body.blocks.length).to.equal(1); + node.expect(res.body.blocks[0]).to.have.property('previousBlock'); + node.expect(res.body.blocks[0]).to.have.property('totalAmount'); + node.expect(res.body.blocks[0]).to.have.property('totalFee'); + node.expect(res.body.blocks[0]).to.have.property('generatorId'); + node.expect(res.body.blocks[0]).to.have.property('confirmations'); + node.expect(res.body.blocks[0]).to.have.property('blockSignature'); + node.expect(res.body.blocks[0]).to.have.property('numberOfTransactions'); + node.expect(res.body.blocks[0].height).to.equal(10); + block.id = res.body.blocks[0].id; + block.generatorPublicKey = res.body.blocks[0].generatorPublicKey; + block.totalAmount = res.body.blocks[0].totalAmount; + block.totalFee = res.body.blocks[0].totalFee; + done(); + }); + }); + + it('using generatorPublicKey should be ok', function (done) { + getBlocks('generatorPublicKey=' + block.generatorPublicKey, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + for (var i = 0; i < res.body.blocks.length; i++) { + node.expect(res.body.blocks[i].generatorPublicKey).to.equal(block.generatorPublicKey); + } + done(); + }); + }); + + it('using totalFee should be ok', function (done) { + getBlocks('totalFee=' + block.totalFee, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + for (var i = 0; i < res.body.blocks.length; i++) { + node.expect(res.body.blocks[i].totalFee).to.equal(block.totalFee); + } + done(); + }); + }); + + it('using totalAmount should be ok', function (done) { + getBlocks('totalAmount=' + block.totalAmount, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + for (var i = 0; i < res.body.blocks.length; i++) { + node.expect(res.body.blocks[i].totalAmount).to.equal(block.totalAmount); + } + done(); + }); + }); + + it('using previousBlock should be ok', function (done) { + if (block.id === null) { + return this.skip(); + } + + var previousBlock = block.id; + + node.onNewBlock(function (err) { + getBlocks('previousBlock=' + block.id, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + node.expect(res.body.blocks).to.have.length(1); + node.expect(res.body.blocks[0].previousBlock).to.equal(previousBlock); + done(); + }); + }); + }); + + it('using orderBy == "height:asc" should be ok', function (done) { + getBlocks('orderBy=' + 'height:asc', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + for (var i = 0; i < res.body.blocks.length; i++) { + if (res.body.blocks[i + 1] != null) { + node.expect(res.body.blocks[i].height).to.be.below(res.body.blocks[i + 1].height); + } + } + done(); + }); + }); + + it('using orderBy == "height:desc" should be ok', function (done) { + getBlocks('orderBy=' + 'height:desc', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + for (var i = 0; i < res.body.blocks.length; i++) { + if (res.body.blocks[i + 1] != null) { + node.expect(res.body.blocks[i].height).to.be.above(res.body.blocks[i + 1].height); + } + } + done(); + }); + }); + + it('should be ordered by "height:desc" by default', function (done) { + getBlocks('', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('blocks').that.is.an('array'); + for (var i = 0; i < res.body.blocks.length; i++) { + if (res.body.blocks[i + 1] != null) { + node.expect(res.body.blocks[i].height).to.be.above(res.body.blocks[i + 1].height); + } + } + done(); + }); + }); +}); + +describe('GET /api/blocks/get?id=', function () { + + function getBlocks (id, done) { + node.get('/api/blocks/get?id=' + id, done); + } + + it('using genesisblock id should be ok', function (done) { + getBlocks('6438017970172540087', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('block').to.be.a('object'); + node.expect(res.body.block).to.have.property('id').to.be.a('string'); + done(); + }); + }); + + it('using unknown id should fail', function (done) { + getBlocks('9928719876370886655', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.be.a('string'); + done(); + }); + }); + + it('using no id should fail', function (done) { + getBlocks('', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.be.a('string'); + done(); + }); + }); +}); diff --git a/test/api/dapps.js b/test/api/dapps.js index e6ba045d..0fa4cde7 100644 --- a/test/api/dapps.js +++ b/test/api/dapps.js @@ -1,1352 +1,1355 @@ -// 'use strict'; -// -// var node = require('./../node.js'); -// var clearDatabaseTable = require('../common/globalBefore').clearDatabaseTable; -// var modulesLoader = require('../common/initModule').modulesLoader; -// -// var dapp = {}; -// var account = node.randomTxAccount(); -// var account2 = node.randomTxAccount(); -// -// function openAccount (account, done) { -// node.post('/api/accounts/open', { -// secret: account.password -// }, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('account').that.is.an('object'); -// account.address = res.body.account.address; -// account.publicKey = res.body.account.publicKey; -// account.balance = res.body.account.balance; -// done(err, res); -// }); -// } -// -// function putTransaction (params, done) { -// node.put('/api/transactions/', params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.onNewBlock(function (err) { -// done(err, res); -// }); -// }); -// } -// -// before(function (done) { -// modulesLoader.getDbConnection(function (err, db) { -// if (err) { -// return done(err); -// } -// -// node.async.every(['dapps', 'outtransfer', 'intransfer'], function (table, cb) { -// clearDatabaseTable(db, modulesLoader.logger, table, cb); -// }, done); -// }); -// }); -// -// before(function (done) { -// // Send to LISK to account 1 address -// setTimeout(function () { -// var randomLISK = node.randomLISK(); -// var expectedFee = node.expectedFee(randomLISK); -// -// putTransaction({ -// secret: node.gAccount.password, -// amount: randomLISK, -// recipientId: account.address -// }, done); -// }, 2000); -// }); -// -// before(function (done) { -// // Send to LISK to account 2 address -// setTimeout(function () { -// var randomLISK = node.randomLISK(); -// var expectedFee = node.expectedFee(randomLISK); -// -// putTransaction({ -// secret: node.gAccount.password, -// amount: randomLISK, -// recipientId: account2.address -// }, done); -// }, 2000); -// }); -// -// var validDapp; -// -// beforeEach(function (done) { -// validDapp = { -// secret: account.password, -// category: node.randomProperty(node.dappCategories), -// type: node.dappTypes.DAPP, -// name: node.randomApplicationName(), -// description: 'A dapp added via API autotest', -// tags: 'handy dizzy pear airplane alike wonder nifty curve young probable tart concentrate', -// link: node.guestbookDapp.link, -// icon: node.guestbookDapp.icon -// }; -// done(); -// }); -// -// describe('PUT /dapps', function () { -// -// var validParams; -// -// beforeEach(function (done) { -// validParams = validDapp; -// validParams.link = validParams.link.replace(/\.zip/, node.randomApplicationName() + '.zip'); -// done(); -// }); -// -// it('using account with no funds should fail', function (done) { -// validParams.secret = node.randomPassword(); -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// -// it('using no name should fail', function (done) { -// delete validParams.name; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using very long name should fail', function (done) { -// validParams.name = 'Lorem ipsum dolor sit amet, conse'; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using numeric name should fail', function (done) { -// validParams.name = 12345; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using very long description should fail', function (done) { -// validParams.description = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient c'; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using numeric description should fail', function (done) { -// validParams.description = 12345; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using very long tag should fail', function (done) { -// validParams.tags = 'develop,rice,voiceless,zonked,crooked,consist,price,extend,sail,treat,pie,massive,fail,maid,summer,verdant,visitor,bushes,abrupt,beg,black-and-white,flight,twist'; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using numeric tags should fail', function (done) { -// validParams.tags = 12345; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using numeric link should fail', function (done) { -// validParams.link = 12345; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using numeric icon should fail', function (done) { -// validParams.icon = 12345; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// describe('from account with second signature enabled', function (done) { -// before(function (done) { -// node.put('/api/signatures', { -// secret: account2.password, -// secondSecret: account2.secondPassword -// }, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transaction').that.is.an('object'); -// node.onNewBlock(done); -// }); -// }); -// -// beforeEach(function (done) { -// validParams.secret = account2.password; -// validParams.secondSecret = account2.secondPassword; -// done(); -// }); -// -// it('using no second passphrase should fail', function (done) { -// delete validParams.secondSecret; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using invalid second passphrase should fail', function (done) { -// validParams.secondSecret = node.randomPassword(); -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using valid second passphrase should be ok', function (done) { -// validParams.secondSecret = account2.secondPassword; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// done(); -// }); -// }); -// }); -// -// it('using valid params should be ok', function (done) { -// validParams.link = node.guestbookDapp.link; -// -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body.transaction).to.have.property('id'); -// dapp = validParams; -// dapp.transactionId = res.body.transaction.id; -// done(); -// }); -// }); -// -// it('using existing dapp name should fail', function (done) { -// validParams.name = dapp.name; -// -// node.onNewBlock(function (err) { -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// }); -// -// it('using existing dapp link should fail', function (done) { -// validParams.link = dapp.link; -// -// node.onNewBlock(function (err) { -// node.put('/api/dapps', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// }); -// }); -// -// describe('PUT /api/dapps/transaction', function () { -// -// function putTransaction (params, done) { -// node.put('/api/dapps/transaction', params, done); -// } -// -// before(function (done) { -// node.expect(dapp).to.be.a('object'); -// node.expect(dapp).to.have.property('transactionId').to.be.not.null; -// done(); -// }); -// -// var validParams; -// -// beforeEach(function (done) { -// validParams = { -// secret: account.password, -// dappId: dapp.transactionId, -// amount: 100000000 -// }; -// done(); -// }); -// -// it('using no secret should fail', function (done) { -// delete validParams.secret; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Missing required property: secret'); -// done(); -// }); -// }); -// -// it('using random secret should fail', function (done) { -// validParams.secret = node.randomPassword(); -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// -// it('using secret with length > 100 should fail', function (done) { -// validParams.secret = 'major patient image mom reject theory glide brisk polar source rely inhale major patient image mom re'; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (101 chars), maximum 100'); -// done(); -// }); -// }); -// -// it('using no amount should fail', function (done) { -// delete validParams.amount; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Missing required property: amount'); -// done(); -// }); -// }); -// -// it('using amount < 0 should fail', function (done) { -// validParams.amount = -1; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Value -1 is less than minimum 1'); -// done(); -// }); -// }); -// -// it('using amount > balance should fail', function (done) { -// openAccount(account, function (err, res) { -// validParams.amount = new node.bignum(account.balance).plus('1').toNumber(); -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// }); -// -// it('using amount > 100M should fail', function (done) { -// validParams.amount = 10000000000000002; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Value 10000000000000002 is greater than maximum 10000000000000000'); -// done(); -// }); -// }); -// -// it('using numeric publicKey should fail', function (done) { -// validParams.publicKey = 1; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using numeric secondSecret should fail', function (done) { -// validParams.secondSecret = 1; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using secondSecret with length > 100 should fail', function (done) { -// validParams.secondSecret = 'major patient image mom reject theory glide brisk polar source rely inhale major patient image mom re'; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (101 chars), maximum 100'); -// done(); -// }); -// }); -// -// it('using no dappId should fail', function (done) { -// delete validParams.dappId; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Missing required property: dappId'); -// done(); -// }); -// }); -// -// it('using numeric dappId should fail', function (done) { -// validParams.dappId = 1; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using dappId with length > 20 should fail', function (done) { -// validParams.dappId = '012345678901234567890'; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (21 chars), maximum 20'); -// done(); -// }); -// }); -// -// it('using unknown dappId', function (done) { -// validParams.dappId = '8713095156789756398'; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Application not found: ' + validParams.dappId); -// done(); -// }); -// }); -// -// it('using numeric multisigAccountPublicKey should fail', function (done) { -// validParams.multisigAccountPublicKey = 1; -// -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using valid params should be ok', function (done) { -// putTransaction(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.not.be.empty; -// done(); -// }); -// }); -// }); -// -// describe('PUT /api/dapps/withdrawal', function () { -// -// function putWithdrawal (params, done) { -// node.put('/api/dapps/withdrawal', params, done); -// } -// -// before(function (done) { -// node.expect(dapp).to.be.a('object'); -// node.expect(dapp).to.have.property('transactionId').to.be.not.null; -// done(); -// }); -// -// var validParams; -// -// beforeEach(function (done) { -// var randomAccount = node.randomTxAccount(); -// var keys = node.lisk.crypto.getKeys(randomAccount.password); -// var recipientId = node.lisk.crypto.getAddress(keys.publicKey); -// var transaction = node.lisk.transaction.createTransaction(randomAccount.address, 100000000, account.password); -// -// validParams = { -// secret: account.password, -// amount: 100000000, -// dappId: dapp.transactionId, -// transactionId: transaction.id, -// recipientId: recipientId -// }; -// -// done(); -// }); -// -// it('using no secret should fail', function (done) { -// delete validParams.secret; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Missing required property: secret'); -// done(); -// }); -// }); -// -// it('using random secret should fail', function (done) { -// validParams.secret = node.randomPassword(); -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// -// it('using secret with length > 100 should fail', function (done) { -// validParams.secret = 'major patient image mom reject theory glide brisk polar source rely inhale major patient image mom re'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (101 chars), maximum 100'); -// done(); -// }); -// }); -// -// it('using no amount should fail', function (done) { -// delete validParams.amount; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Missing required property: amount'); -// done(); -// }); -// }); -// -// it('using amount < 0 should fail', function (done) { -// validParams.amount = -1; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Value -1 is less than minimum 1'); -// done(); -// }); -// }); -// -// it('using amount > balance should fail', function (done) { -// openAccount(account, function (err, res) { -// validParams.amount = new node.bignum(account.balance).plus('1').toNumber(); -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// }); -// -// it('using amount > 100M should fail', function (done) { -// validParams.amount = 10000000000000002; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Value 10000000000000002 is greater than maximum 10000000000000000'); -// done(); -// }); -// }); -// -// it('using numeric secondSecret should fail', function (done) { -// validParams.secondSecret = 1; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using secondSecret with length > 100 should fail', function (done) { -// validParams.secondSecret = 'major patient image mom reject theory glide brisk polar source rely inhale major patient image mom re'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (101 chars), maximum 100'); -// done(); -// }); -// }); -// -// it('using no dappId should fail', function (done) { -// delete validParams.dappId; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Missing required property: dappId'); -// done(); -// }); -// }); -// -// it('using numeric dappId should fail', function (done) { -// validParams.dappId = 1; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using alphanumeric dappId should fail', function (done) { -// validParams.dappId = '1L'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Object didn\'t pass validation for format id: 1L'); -// done(); -// }); -// }); -// -// it('using blank dappId should fail', function (done) { -// validParams.dappId = ''; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too short (0 chars), minimum 1'); -// done(); -// }); -// }); -// -// it('using dappId with length > 20 should fail', function (done) { -// validParams.dappId = '012345678901234567890'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (21 chars), maximum 20'); -// done(); -// }); -// }); -// -// it('using unknown dappId', function (done) { -// validParams.dappId = '8713095156789756398'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Application not found: ' + validParams.dappId); -// done(); -// }); -// }); -// -// it('using no transactionId should fail', function (done) { -// delete validParams.transactionId; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Missing required property: transactionId'); -// done(); -// }); -// }); -// -// it('using numeric transactionId should fail', function (done) { -// validParams.transactionId = 1; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using alphanumeric transactionId should fail', function (done) { -// validParams.transactionId = '1L'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Object didn\'t pass validation for format id: 1L'); -// done(); -// }); -// }); -// -// it('using blank transactionId should fail', function (done) { -// validParams.transactionId = ''; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too short (0 chars), minimum 1'); -// done(); -// }); -// }); -// -// it('using transactionId with length > 20 should fail', function (done) { -// validParams.transactionId = '012345678901234567890'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (21 chars), maximum 20'); -// done(); -// }); -// }); -// -// it('using no recipientId should fail', function (done) { -// delete validParams.recipientId; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Missing required property: recipientId'); -// done(); -// }); -// }); -// -// it('using numeric recipientId should fail', function (done) { -// validParams.recipientId = 12; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using recipientId with length < 2 should fail', function (done) { -// validParams.recipientId = '1'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Object didn\'t pass validation for format address: 1'); -// done(); -// }); -// }); -// -// it('using recipientId with length > 22 should fail', function (done) { -// validParams.recipientId = '0123456789012345678901L'; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (23 chars), maximum 22'); -// done(); -// }); -// }); -// -// it('using recipientId without an "L" should fail', function (done) { -// validParams.recipientId = validParams.recipientId.replace('L', ''); -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.match(/Object didn\'t pass validation for format address: [0-9]+/); -// done(); -// }); -// }); -// -// it('using numeric multisigAccountPublicKey should fail', function (done) { -// validParams.multisigAccountPublicKey = 1; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); -// done(); -// }); -// }); -// -// it('using valid params should be ok', function (done) { -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.not.be.empty; -// done(); -// }); -// }); -// -// it('using same valid params twice should fail', function (done) { -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.not.be.empty; -// -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.contain('Transaction is already processed'); -// done(); -// }); -// }); -// }); -// -// it('using already confirmed params after new block should fail', function (done) { -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.not.be.empty; -// -// node.onNewBlock(function (err) { -// putWithdrawal(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('Transaction is already confirmed: ' + validParams.transactionId); -// done(); -// }); -// }); -// }); -// }); -// }); -// -// describe('GET /dapps', function () { -// -// before(function (done) { -// node.onNewBlock(done); -// }); -// -// function getDapps (params, done) { -// node.get('/api/dapps?' + params, done); -// } -// -// it('user orderBy == "category:asc" should be ok', function (done) { -// getDapps('orderBy=' + 'category:asc', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// if (res.body.dapps[0] != null) { -// for (var i = 0; i < res.body.dapps.length; i++) { -// if (res.body.dapps[i + 1] != null) { -// node.expect(res.body.dapps[i].category).to.be.at.most(res.body.dapps[i + 1].category); -// } -// } -// } -// done(); -// }); -// }); -// -// it('user orderBy == "category:desc" should be ok', function (done) { -// getDapps('orderBy=' + 'category:desc', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// if (res.body.dapps[0] != null) { -// for (var i = 0; i < res.body.dapps.length; i++) { -// if (res.body.dapps[i + 1] != null) { -// node.expect(res.body.dapps[i].category).to.be.at.least(res.body.dapps[i + 1].category); -// } -// } -// } -// done(); -// }); -// }); -// -// it('using category should be ok', function (done) { -// var randomCategory = node.randomProperty(node.dappCategories, true); -// -// getDapps('category=' + randomCategory, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// if (res.body.dapps.length > 0) { -// node.expect(res.body.dapps[0].category).to.equal(node.dappCategories[randomCategory]); -// } -// done(); -// }); -// }); -// -// it('using name should be ok', function (done) { -// var name = ''; -// -// if (dapp !== {} && dapp != null) { -// name = dapp.name; -// } else { -// name = 'test'; -// } -// -// getDapps('name=' + name, function (err, res) { -// node.expect(res.body).to.have.property('success'); -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// if (name !== 'test') { -// node.expect(res.body.dapps).to.have.length.above(0); -// node.expect(res.body.dapps[0].name).to.equal(name); -// } -// done(); -// }); -// }); -// -// it('using type should be ok', function (done) { -// var type = node.randomProperty(node.dappTypes); -// -// getDapps('type=' + type, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// for (var i = 0; i < res.body.dapps.length; i++) { -// if (res.body.dapps[i] != null) { -// node.expect(res.body.dapps[i].type).to.equal(type); -// } -// } -// done(); -// }); -// }); -// -// it('using numeric link should fail', function (done) { -// var link = 12345; -// -// getDapps('link=' + link, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using string link should be ok', function (done) { -// var link = node.guestbookDapp.link; -// -// getDapps('link=' + link, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// for (var i = 0; i < res.body.dapps.length; i++) { -// if (res.body.dapps[i] != null) { -// node.expect(res.body.dapps[i].link).to.equal(link); -// } -// } -// done(); -// }); -// }); -// -// it('using no limit should be ok', function (done) { -// getDapps('', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// if (res.body.dapps.length > 0) { -// dapp = res.body.dapps[0]; -// dapp = dapp; -// } -// done(); -// }); -// }); -// -// it('using limit == 3 should be ok', function (done) { -// var limit = 3; -// -// getDapps('limit=' + limit, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// node.expect(res.body.dapps).to.have.length.at.most(limit); -// done(); -// }); -// }); -// -// it('using offset should be ok', function (done) { -// var offset = 1; -// var secondDapp; -// -// getDapps('', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// if (res.body.dapps[1] != null) { -// secondDapp = res.body.dapps[1]; -// -// getDapps('offset=' + 1, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// node.expect(res.body.dapps[0]).to.deep.equal(secondDapp); -// }); -// } -// done(); -// }); -// }); -// }); -// -// describe('GET /dapps?id=', function () { -// -// function getDapps (id, done) { -// node.get('/api/dapps?id=' + id, done); -// } -// -// it('using no id should fail', function (done) { -// getDapps('', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too short (0 chars), minimum 1: #/id'); -// done(); -// }); -// }); -// -// it('using id with length > 20 should fail', function (done) { -// getDapps('012345678901234567890', function (err, res) { -// node.expect(res.body).to.have.property('success').to.not.be.ok; -// node.expect(res.body).to.have.property('error').to.equal('String is too long (21 chars), maximum 20: #/id'); -// done(); -// }); -// }); -// -// it('using unknown id should be ok', function (done) { -// var dappId = '8713095156789756398'; -// -// getDapps(dappId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// done(); -// }); -// }); -// -// it('using valid id should be ok', function (done) { -// getDapps(dapp.transactionId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// node.expect(res.body.dapps[0].transactionId).to.equal(dapp.transactionId); -// done(); -// }); -// }); -// }); -// -// describe('POST /api/dapps/install', function () { -// -// function postInstall (params, done) { -// node.post('/api/dapps/install', params, done); -// } -// -// before(function (done) { -// node.expect(dapp).to.be.a('object'); -// node.expect(dapp).to.have.property('transactionId').to.be.not.null; -// done(); -// }); -// -// var validParams; -// -// beforeEach(function (done) { -// validParams = { -// id: dapp.transactionId, -// master: node.config.dapp.masterpassword -// }; -// done(); -// }); -// -// it('using no id should fail', function (done) { -// delete validParams.id; -// -// postInstall(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using unknown id should fail', function (done) { -// validParams.id = 'unknown'; -// -// postInstall(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using valid params should be ok', function (done) { -// postInstall(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('path'); -// dapp = dapp; -// done(); -// }); -// }); -// -// describe('when link is 404 not found', function () { -// var toBeNotFound; -// -// beforeEach(function (done) { -// toBeNotFound = validDapp; -// toBeNotFound.link = toBeNotFound.link.replace(/\.zip/, node.randomApplicationName() + '.zip'); -// done(); -// }); -// -// it('should fail', function (done) { -// node.put('/api/dapps', toBeNotFound, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body.transaction).to.have.property('id').that.is.not.empty; -// validParams.id = res.body.transaction.id; -// -// node.onNewBlock(function (err) { -// postInstall(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.match(/[0-9]+ Installation failed: Received bad response code 404/); -// done(); -// }); -// }); -// }); -// }); -// }); -// }); -// -// describe('GET /api/dapps/installed', function () { -// -// it('should be ok', function (done) { -// var flag = 0; -// -// node.get('/api/dapps/installed', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// for (var i = 0; i < res.body.dapps.length; i++) { -// if (res.body.dapps[i] != null) { -// if (res.body.dapps[i].transactionId === dapp.transactionId) { -// flag += 1; -// } -// } -// } -// node.expect(flag).to.equal(1); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/dapps/installedIds', function () { -// -// it('should be ok', function (done) { -// var flag = 0; -// -// node.get('/api/dapps/installedIds', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('ids').that.is.an('array'); -// for (var i = 0; i < res.body.ids.length; i++) { -// if (res.body.ids[i] != null) { -// if (res.body.ids[i] === dapp.transactionId) { -// flag += 1; -// } -// } -// } -// node.expect(flag).to.equal(1); -// done(); -// }); -// }); -// }); -// -// describe('GET /api/dapps/search?q=', function () { -// -// function getSearch (params, done) { -// node.get('/api/dapps/search?' + params, done); -// } -// -// it('using invalid params should fail', function (done) { -// var q = 1234; -// var category = 'good'; -// var installed = 'true'; -// -// var params = 'q=' + q + '&category=' + category + '&installed=' + installed; -// -// getSearch(params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using valid parameters should be ok', function (done) { -// var q = 'a'; -// var category = node.randomProperty(node.dappCategories, true); -// var installed = 1; -// -// var params = 'q=' + q + '&installed='+ installed + '&category=' + node.dappCategories[category]; -// -// getSearch(params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// done(); -// }); -// }); -// -// it('using installed = 0 should be ok', function (done) { -// var q = 's'; -// var category = node.randomProperty(node.dappCategories); -// var installed = 0; -// -// var params = 'q=' + q + '&installed='+ installed + '&category=' + category; -// -// getSearch(params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('dapps').that.is.an('array'); -// done(); -// }); -// }); -// }); -// -// describe('POST /api/dapps/launch', function () { -// -// function postLaunch (params, done) { -// node.post('/api/dapps/launch', params, done); -// } -// -// before(function (done) { -// node.expect(dapp).to.be.a('object'); -// node.expect(dapp).to.have.property('transactionId').to.be.not.null; -// done(); -// }); -// -// var validParams; -// -// beforeEach(function (done) { -// validParams = { -// id: dapp.transactionId, -// master: node.config.dapp.masterpassword -// }; -// done(); -// }); -// -// it('using no id should fail', function (done) { -// delete validParams.id; -// -// postLaunch(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using unknown id should fail', function (done) { -// validParams.id = 'unknown'; -// -// postLaunch(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using empty params array should fail', function (done) { -// validParams.params = []; -// -// postLaunch(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using valid params should be ok', function (done) { -// postLaunch(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.get('/api/dapps/launched', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('launched').that.is.an('array'); -// var flag = 0; -// -// for (var i = 0; i < res.body.launched.length; i++) { -// if (res.body.launched[i] != null) { -// if (res.body.launched[i] === dapp.transactionId) { -// flag += 1; -// } -// } -// } -// node.expect(flag).to.equal(1); -// }); -// done(); -// }); -// }); -// }); -// -// describe('POST /api/dapps/stop', function () { -// -// function postStop (params, done) { -// node.post('/api/dapps/stop', params, done); -// } -// -// before(function (done) { -// node.expect(dapp).to.be.a('object'); -// node.expect(dapp).to.have.property('transactionId').to.be.not.null; -// done(); -// }); -// -// var validParams; -// -// beforeEach(function (done) { -// validParams = { -// id: dapp.transactionId, -// master: node.config.dapp.masterpassword -// }; -// done(); -// }); -// -// it('using no id should fail', function (done) { -// delete validParams.id; -// -// postStop(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using unknown id should fail', function (done) { -// validParams.id = 'unknown'; -// -// postStop(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using valid params should be ok', function (done) { -// postStop(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// done(); -// }); -// }); -// }); -// -// describe('GET /api/dapps/categories', function () { -// -// it('should be ok', function (done) { -// node.get('/api/dapps/categories', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('categories').that.is.an('object'); -// for (var i in node.dappCategories) { -// node.expect(res.body.categories[i]).to.equal(node.dappCategories[i]); -// } -// done(); -// }); -// }); -// }); -// -// describe('POST /api/dapps/uninstall', function () { -// -// function postUninstall (params, done) { -// node.post('/api/dapps/uninstall', params, done); -// } -// -// before(function (done) { -// node.expect(dapp).to.be.a('object'); -// node.expect(dapp).to.have.property('transactionId').to.be.not.null; -// done(); -// }); -// -// var validParams; -// -// beforeEach(function (done) { -// validParams = { -// id: dapp.transactionId, -// master: node.config.dapp.masterpassword -// }; -// done(); -// }); -// -// it('using no id should fail', function (done) { -// delete validParams.id; -// -// postUninstall(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using unknown id should fail', function (done) { -// validParams.id = 'unknown'; -// -// postUninstall(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using valid params should be ok', function (done) { -// postUninstall(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// done(); -// }); -// }); -// }); +'use strict'; + +var node = require('./../node.js'); +var clearDatabaseTable = require('../common/globalBefore').clearDatabaseTable; +var modulesLoader = require('../common/initModule').modulesLoader; + +var dapp = {}; +var account = node.randomTxAccount(); +var account2 = node.randomTxAccount(); + +function openAccount (account, done) { + node.post('/api/accounts/open', { + secret: account.password + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('account').that.is.an('object'); + account.address = res.body.account.address; + account.publicKey = res.body.account.publicKey; + account.balance = res.body.account.balance; + done(err, res); + }); +} + +function putTransaction (params, done) { + node.put('/api/transactions/', params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(function (err) { + done(err, res); + }); + }); +} + +before(function (done) { + modulesLoader.getDbConnection(function (err, db) { + if (err) { + return done(err); + } + + node.async.every(['dapps', 'outtransfer', 'intransfer'], function (table, cb) { + clearDatabaseTable(db, modulesLoader.logger, table, cb); + }, done); + }); +}); + +before(function (done) { + // Send to LISK to account 1 address + setTimeout(function () { + var randomLISK = node.randomLISK(); + var expectedFee = node.expectedFee(randomLISK); + + putTransaction({ + secret: node.gAccount.password, + amount: randomLISK, + recipientId: account.address + }, done); + }, 2000); +}); + +before(function (done) { + // Send to LISK to account 2 address + setTimeout(function () { + var randomLISK = node.randomLISK(); + var expectedFee = node.expectedFee(randomLISK); + + putTransaction({ + secret: node.gAccount.password, + amount: randomLISK, + recipientId: account2.address + }, done); + }, 2000); +}); + +var validDapp; + +beforeEach(function (done) { + validDapp = { + secret: account.password, + category: node.randomProperty(node.dappCategories), + type: node.dappTypes.DAPP, + name: node.randomApplicationName(), + description: 'A dapp added via API autotest', + tags: 'handy dizzy pear airplane alike wonder nifty curve young probable tart concentrate', + link: node.guestbookDapp.link, + icon: node.guestbookDapp.icon + }; + done(); +}); + +describe('PUT /dapps', function () { + + var validParams; + + beforeEach(function (done) { + validParams = validDapp; + validParams.link = validParams.link.replace(/\.zip/, node.randomApplicationName() + '.zip'); + done(); + }); + + it('using account with no funds should fail', function (done) { + validParams.secret = node.randomAccount().password; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + + it('using no name should fail', function (done) { + delete validParams.name; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using very long name should fail', function (done) { + validParams.name = 'Lorem ipsum dolor sit amet, conse'; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using numeric name should fail', function (done) { + validParams.name = 12345; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using very long description should fail', function (done) { + validParams.description = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient c'; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using numeric description should fail', function (done) { + validParams.description = 12345; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using very long tag should fail', function (done) { + validParams.tags = 'develop,rice,voiceless,zonked,crooked,consist,price,extend,sail,treat,pie,massive,fail,maid,summer,verdant,visitor,bushes,abrupt,beg,black-and-white,flight,twist'; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using numeric tags should fail', function (done) { + validParams.tags = 12345; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using numeric link should fail', function (done) { + validParams.link = 12345; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using numeric icon should fail', function (done) { + validParams.icon = 12345; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + describe('from account with second signature enabled', function (done) { + before(function (done) { + node.put('/api/signatures', { + secret: account2.password, + secondSecret: account2.secondPassword + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction').that.is.an('object'); + node.onNewBlock(done); + }); + }); + + beforeEach(function (done) { + validParams.secret = account2.password; + validParams.secondSecret = account2.secondPassword; + done(); + }); + + // secondSecret are not used in /api/dapps + // it('using no second passphrase should fail', function (done) { + // delete validParams.secondSecret; + + // node.put('/api/dapps', validParams, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.not.ok; + // node.expect(res.body).to.have.property('error'); + // done(); + // }); + // }); + + // secondSecret are not used in /api/dapps + // it('using invalid second passphrase should fail', function (done) { + // validParams.secondSecret = node.randomAccount().password; + + // node.put('/api/dapps', validParams, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.not.ok; + // node.expect(res.body).to.have.property('error'); + // done(); + // }); + // }); + + it('using valid second passphrase should be ok', function (done) { + validParams.secondSecret = account2.secondPassword; + + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + done(); + }); + }); + }); + + it('using valid params should be ok', function (done) { + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body.transaction).to.have.property('id'); + dapp = validParams; + dapp.transactionId = res.body.transaction.id; + done(); + }); + }); + + it('using existing dapp name should fail', function (done) { + validParams.name = dapp.name; + + node.onNewBlock(function (err) { + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + it('using existing dapp link should fail', function (done) { + validParams.link = dapp.link; + + node.onNewBlock(function (err) { + node.put('/api/dapps', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + }); +}); + +describe('PUT /api/dapps/transaction', function () { + + function putTransaction (params, done) { + node.put('/api/dapps/transaction', params, done); + } + + before(function (done) { + node.expect(dapp).to.be.a('object'); + node.expect(dapp).to.have.property('transactionId').to.be.not.null; + done(); + }); + + var validParams; + + beforeEach(function (done) { + validParams = { + secret: account.password, + dappId: dapp.transactionId, + amount: 100000000 + }; + done(); + }); + + it('using no secret should fail', function (done) { + delete validParams.secret; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Missing required property: secret'); + done(); + }); + }); + + it('using random secret should fail', function (done) { + validParams.secret = node.randomAccount().password; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + + it('using secret with length > 100 should fail', function (done) { + validParams.secret = 'major patient image mom reject theory glide brisk polar source rely inhale major patient image mom re'; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (101 chars), maximum 100'); + done(); + }); + }); + + it('using no amount should fail', function (done) { + delete validParams.amount; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Missing required property: amount'); + done(); + }); + }); + + it('using amount < 0 should fail', function (done) { + validParams.amount = -1; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Value -1 is less than minimum 1'); + done(); + }); + }); + + it('using amount > balance should fail', function (done) { + openAccount(account, function (err, res) { + validParams.amount = new node.bignum(account.balance).plus('1').toNumber(); + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + it('using amount > 100M should fail', function (done) { + validParams.amount = 10000000000000002; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Value 10000000000000002 is greater than maximum 9800000000000000'); + done(); + }); + }); + + it('using numeric publicKey should fail', function (done) { + validParams.publicKey = 1; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using numeric secondSecret should fail', function (done) { + validParams.secondSecret = 1; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using secondSecret with length > 100 should fail', function (done) { + validParams.secondSecret = 'major patient image mom reject theory glide brisk polar source rely inhale major patient image mom re'; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (101 chars), maximum 100'); + done(); + }); + }); + + it('using no dappId should fail', function (done) { + delete validParams.dappId; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Missing required property: dappId'); + done(); + }); + }); + + it('using numeric dappId should fail', function (done) { + validParams.dappId = 1; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using dappId with length > 20 should fail', function (done) { + validParams.dappId = '012345678901234567890'; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (21 chars), maximum 20'); + done(); + }); + }); + + it('using unknown dappId', function (done) { + validParams.dappId = '8713095156789756398'; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Application not found: ' + validParams.dappId); + done(); + }); + }); + + it('using numeric multisigAccountPublicKey should fail', function (done) { + validParams.multisigAccountPublicKey = 1; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using valid params should be ok', function (done) { + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.not.be.empty; + done(); + }); + }); +}); + +describe('PUT /api/dapps/withdrawal', function () { + + function putWithdrawal (params, done) { + node.put('/api/dapps/withdrawal', params, done); + } + + before(function (done) { + node.expect(dapp).to.be.a('object'); + node.expect(dapp).to.have.property('transactionId').to.be.not.null; + done(); + }); + + var validParams; + + beforeEach(function (done) { + var randomAccount = node.randomTxAccount(); + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + validParams = { + secret: account.password, + amount: 100000000, + dappId: dapp.transactionId, + transactionId: transaction.id, + recipientId: randomAccount.address + }; + + done(); + }); + + it('using no secret should fail', function (done) { + delete validParams.secret; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Missing required property: secret'); + done(); + }); + }); + + it('using random secret should fail', function (done) { + validParams.secret = node.randomAccount().password; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + + it('using secret with length > 100 should fail', function (done) { + validParams.secret = 'major patient image mom reject theory glide brisk polar source rely inhale major patient image mom re'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (101 chars), maximum 100'); + done(); + }); + }); + + it('using no amount should fail', function (done) { + delete validParams.amount; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Missing required property: amount'); + done(); + }); + }); + + it('using amount < 0 should fail', function (done) { + validParams.amount = -1; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Value -1 is less than minimum 1'); + done(); + }); + }); + + it('using amount > balance should fail', function (done) { + openAccount(account, function (err, res) { + validParams.amount = new node.bignum(account.balance).plus('1').toNumber(); + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + + it('using amount > 100M should fail', function (done) { + validParams.amount = 10000000000000002; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Value 10000000000000002 is greater than maximum 9800000000000000'); + done(); + }); + }); + + it('using numeric secondSecret should fail', function (done) { + validParams.secondSecret = 1; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using secondSecret with length > 100 should fail', function (done) { + validParams.secondSecret = 'major patient image mom reject theory glide brisk polar source rely inhale major patient image mom re'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (101 chars), maximum 100'); + done(); + }); + }); + + it('using no dappId should fail', function (done) { + delete validParams.dappId; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Missing required property: dappId'); + done(); + }); + }); + + it('using numeric dappId should fail', function (done) { + validParams.dappId = 1; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using alphanumeric dappId should fail', function (done) { + validParams.dappId = '1L'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Object didn\'t pass validation for format id: 1L'); + done(); + }); + }); + + it('using blank dappId should fail', function (done) { + validParams.dappId = ''; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too short (0 chars), minimum 1'); + done(); + }); + }); + + it('using dappId with length > 20 should fail', function (done) { + validParams.dappId = '012345678901234567890'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (21 chars), maximum 20'); + done(); + }); + }); + + it('using unknown dappId', function (done) { + validParams.dappId = '8713095156789756398'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Application not found: ' + validParams.dappId); + done(); + }); + }); + + it('using no transactionId should fail', function (done) { + delete validParams.transactionId; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Missing required property: transactionId'); + done(); + }); + }); + + it('using numeric transactionId should fail', function (done) { + validParams.transactionId = 1; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using alphanumeric transactionId should fail', function (done) { + validParams.transactionId = '1L'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Object didn\'t pass validation for format id: 1L'); + done(); + }); + }); + + it('using blank transactionId should fail', function (done) { + validParams.transactionId = ''; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too short (0 chars), minimum 1'); + done(); + }); + }); + + it('using transactionId with length > 20 should fail', function (done) { + validParams.transactionId = '012345678901234567890'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (21 chars), maximum 20'); + done(); + }); + }); + + it('using no recipientId should fail', function (done) { + delete validParams.recipientId; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Missing required property: recipientId'); + done(); + }); + }); + + it('using numeric recipientId should fail', function (done) { + validParams.recipientId = 12; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using recipientId with length < 2 should fail', function (done) { + validParams.recipientId = '1'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Object didn\'t pass validation for format address: 1'); + done(); + }); + }); + + it('using recipientId with length > 22 should fail', function (done) { + validParams.recipientId = 'U0123456789012345678901'; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (23 chars), maximum 22'); + done(); + }); + }); + + it('using recipientId without an "U" should fail', function (done) { + validParams.recipientId = validParams.recipientId.replace('U', ''); + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.match(/Object didn\'t pass validation for format address: [0-9]+/); + done(); + }); + }); + + it('using numeric multisigAccountPublicKey should fail', function (done) { + validParams.multisigAccountPublicKey = 1; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Expected type string but found type integer'); + done(); + }); + }); + + it('using valid params should be ok', function (done) { + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.not.be.empty; + done(); + }); + }); + + it('using same valid params twice should fail', function (done) { + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.not.be.empty; + + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.contain('Transaction is already processed'); + done(); + }); + }); + }); + + it('using already confirmed params after new block should fail', function (done) { + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.not.be.empty; + + node.onNewBlock(function (err) { + putWithdrawal(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('Transaction is already confirmed: ' + validParams.transactionId); + done(); + }); + }); + }); + }); +}); + +describe('GET /dapps', function () { + + before(function (done) { + node.onNewBlock(done); + }); + + function getDapps (params, done) { + node.get('/api/dapps?' + params, done); + } + + it('user orderBy == "category:asc" should be ok', function (done) { + getDapps('orderBy=' + 'category:asc', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + if (res.body.dapps[0] != null) { + for (var i = 0; i < res.body.dapps.length; i++) { + if (res.body.dapps[i + 1] != null) { + node.expect(res.body.dapps[i].category).to.be.at.most(res.body.dapps[i + 1].category); + } + } + } + done(); + }); + }); + + it('user orderBy == "category:desc" should be ok', function (done) { + getDapps('orderBy=' + 'category:desc', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + if (res.body.dapps[0] != null) { + for (var i = 0; i < res.body.dapps.length; i++) { + if (res.body.dapps[i + 1] != null) { + node.expect(res.body.dapps[i].category).to.be.at.least(res.body.dapps[i + 1].category); + } + } + } + done(); + }); + }); + + it('using category should be ok', function (done) { + var randomCategory = node.randomProperty(node.dappCategories, true); + + getDapps('category=' + randomCategory, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + if (res.body.dapps.length > 0) { + node.expect(res.body.dapps[0].category).to.equal(node.dappCategories[randomCategory]); + } + done(); + }); + }); + + it('using name should be ok', function (done) { + var name = ''; + + if (dapp !== {} && dapp != null) { + name = dapp.name; + } else { + name = 'test'; + } + + getDapps('name=' + name, function (err, res) { + node.expect(res.body).to.have.property('success'); + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + if (name !== 'test') { + node.expect(res.body.dapps).to.have.length.above(0); + node.expect(res.body.dapps[0].name).to.equal(name); + } + done(); + }); + }); + + it('using type should be ok', function (done) { + var type = node.randomProperty(node.dappTypes); + + getDapps('type=' + type, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + for (var i = 0; i < res.body.dapps.length; i++) { + if (res.body.dapps[i] != null) { + node.expect(res.body.dapps[i].type).to.equal(type); + } + } + done(); + }); + }); + + it('using numeric link should fail', function (done) { + var link = 12345; + + getDapps('link=' + link, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using string link should be ok', function (done) { + var link = node.guestbookDapp.link; + + getDapps('link=' + link, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + for (var i = 0; i < res.body.dapps.length; i++) { + if (res.body.dapps[i] != null) { + node.expect(res.body.dapps[i].link).to.equal(link); + } + } + done(); + }); + }); + + it('using no limit should be ok', function (done) { + getDapps('', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + if (res.body.dapps.length > 0) { + dapp = res.body.dapps[0]; + dapp = dapp; + } + done(); + }); + }); + + it('using limit == 3 should be ok', function (done) { + var limit = 3; + + getDapps('limit=' + limit, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + node.expect(res.body.dapps).to.have.length.at.most(limit); + done(); + }); + }); + + it('using offset should be ok', function (done) { + var offset = 1; + var secondDapp; + + getDapps('', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + if (res.body.dapps[1] != null) { + secondDapp = res.body.dapps[1]; + + getDapps('offset=' + 1, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + node.expect(res.body.dapps[0]).to.deep.equal(secondDapp); + }); + } + done(); + }); + }); +}); + +describe('GET /dapps?id=', function () { + + function getDapps (id, done) { + node.get('/api/dapps?id=' + id, done); + } + + it('using no id should fail', function (done) { + getDapps('', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too short (0 chars), minimum 1: #/id'); + done(); + }); + }); + + it('using id with length > 20 should fail', function (done) { + getDapps('012345678901234567890', function (err, res) { + node.expect(res.body).to.have.property('success').to.not.be.ok; + node.expect(res.body).to.have.property('error').to.equal('String is too long (21 chars), maximum 20: #/id'); + done(); + }); + }); + + it('using unknown id should be ok', function (done) { + var dappId = '8713095156789756398'; + + getDapps(dappId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + done(); + }); + }); + + it('using valid id should be ok', function (done) { + getDapps(dapp.transactionId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + node.expect(res.body.dapps[0].transactionId).to.equal(dapp.transactionId); + done(); + }); + }); +}); + +describe('POST /api/dapps/install', function () { + + function postInstall (params, done) { + node.post('/api/dapps/install', params, done); + } + + before(function (done) { + node.expect(dapp).to.be.a('object'); + node.expect(dapp).to.have.property('transactionId').to.be.not.null; + done(); + }); + + var validParams; + + beforeEach(function (done) { + validParams = { + id: dapp.transactionId, + master: 'node.config.dapp.masterpassword' + }; + done(); + }); + + it('using no id should fail', function (done) { + delete validParams.id; + + postInstall(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using unknown id should fail', function (done) { + validParams.id = 'unknown'; + + postInstall(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using valid params should be ok', function (done) { + postInstall(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('path'); + dapp = dapp; + done(); + }); + }); + + describe('when link is 404 not found', function () { + var toBeNotFound; + + beforeEach(function (done) { + toBeNotFound = validDapp; + toBeNotFound.link = toBeNotFound.link.replace(/\.zip/, node.randomApplicationName() + '.zip'); + done(); + }); + + it('should fail', function (done) { + node.put('/api/dapps', toBeNotFound, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body.transaction).to.have.property('id').that.is.not.empty; + validParams.id = res.body.transaction.id; + + node.onNewBlock(function (err) { + postInstall(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.match(/[0-9]+ Installation failed: Received bad response code 404/); + done(); + }); + }); + }); + }); + }); +}); + +describe('GET /api/dapps/installed', function () { + + it('should be ok', function (done) { + var flag = 0; + + node.get('/api/dapps/installed', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + for (var i = 0; i < res.body.dapps.length; i++) { + if (res.body.dapps[i] != null) { + if (res.body.dapps[i].transactionId === dapp.transactionId) { + flag += 1; + } + } + } + node.expect(flag).to.equal(1); + done(); + }); + }); +}); + +describe('GET /api/dapps/installedIds', function () { + + it('should be ok', function (done) { + var flag = 0; + + node.get('/api/dapps/installedIds', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('ids').that.is.an('array'); + for (var i = 0; i < res.body.ids.length; i++) { + if (res.body.ids[i] != null) { + if (res.body.ids[i] === dapp.transactionId) { + flag += 1; + } + } + } + node.expect(flag).to.equal(1); + done(); + }); + }); +}); + +describe('GET /api/dapps/search?q=', function () { + + function getSearch (params, done) { + node.get('/api/dapps/search?' + params, done); + } + + it('using invalid params should fail', function (done) { + var q = 1234; + var category = 'good'; + var installed = 'true'; + + var params = 'q=' + q + '&category=' + category + '&installed=' + installed; + + getSearch(params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using valid parameters should be ok', function (done) { + var q = 'a'; + var category = node.randomProperty(node.dappCategories, true); + var installed = 1; + + var params = 'q=' + q + '&installed='+ installed + '&category=' + node.dappCategories[category]; + + getSearch(params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + done(); + }); + }); + + it('using installed = 0 should be ok', function (done) { + var q = 's'; + var category = node.randomProperty(node.dappCategories); + var installed = 0; + + var params = 'q=' + q + '&installed='+ installed + '&category=' + category; + + getSearch(params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('dapps').that.is.an('array'); + done(); + }); + }); +}); + +describe('POST /api/dapps/launch', function () { + + function postLaunch (params, done) { + node.post('/api/dapps/launch', params, done); + } + + before(function (done) { + node.expect(dapp).to.be.a('object'); + node.expect(dapp).to.have.property('transactionId').to.be.not.null; + done(); + }); + + var validParams; + + beforeEach(function (done) { + validParams = { + id: dapp.transactionId, + master: 'node.config.dapp.masterpassword' + }; + done(); + }); + + it('using no id should fail', function (done) { + delete validParams.id; + + postLaunch(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using unknown id should fail', function (done) { + validParams.id = 'unknown'; + + postLaunch(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using empty params array should fail', function (done) { + validParams.params = []; + + postLaunch(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + // it is not an app actually and will not work + // it('using valid params should be ok', function (done) { + // postLaunch(validParams, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.ok; + // node.get('/api/dapps/launched', function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.ok; + // node.expect(res.body).to.have.property('launched').that.is.an('array'); + // var flag = 0; + + // for (var i = 0; i < res.body.launched.length; i++) { + // if (res.body.launched[i] != null) { + // if (res.body.launched[i] === dapp.transactionId) { + // flag += 1; + // } + // } + // } + // node.expect(flag).to.equal(1); + // }); + // done(); + // }); + // }); +}); + +describe('POST /api/dapps/stop', function () { + + function postStop (params, done) { + node.post('/api/dapps/stop', params, done); + } + + before(function (done) { + node.expect(dapp).to.be.a('object'); + node.expect(dapp).to.have.property('transactionId').to.be.not.null; + done(); + }); + + var validParams; + + beforeEach(function (done) { + validParams = { + id: dapp.transactionId, + master: 'node.config.dapp.masterpassword' + }; + done(); + }); + + it('using no id should fail', function (done) { + delete validParams.id; + + postStop(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using unknown id should fail', function (done) { + validParams.id = 'unknown'; + + postStop(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + // it is not an app actually and will not work + // it('using valid params should be ok', function (done) { + // postStop(validParams, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.ok; + // done(); + // }); + // }); +}); + +describe('GET /api/dapps/categories', function () { + + it('should be ok', function (done) { + node.get('/api/dapps/categories', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('categories').that.is.an('object'); + for (var i in node.dappCategories) { + node.expect(res.body.categories[i]).to.equal(node.dappCategories[i]); + } + done(); + }); + }); +}); + +describe('POST /api/dapps/uninstall', function () { + + function postUninstall (params, done) { + node.post('/api/dapps/uninstall', params, done); + } + + before(function (done) { + node.expect(dapp).to.be.a('object'); + node.expect(dapp).to.have.property('transactionId').to.be.not.null; + done(); + }); + + var validParams; + + beforeEach(function (done) { + validParams = { + id: dapp.transactionId, + master: 'node.config.dapp.masterpassword' + }; + done(); + }); + + it('using no id should fail', function (done) { + delete validParams.id; + + postUninstall(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using unknown id should fail', function (done) { + validParams.id = 'unknown'; + + postUninstall(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using valid params should be ok', function (done) { + postUninstall(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + done(); + }); + }); +}); diff --git a/test/api/multisignatures.js b/test/api/multisignatures.js index 854bea00..f590580c 100644 --- a/test/api/multisignatures.js +++ b/test/api/multisignatures.js @@ -1,780 +1,780 @@ -// 'use strict'; -// -// var async = require('async'); -// var node = require('./../node.js'); -// -// var constants = require('../../helpers/constants.js'); -// -// var totalMembers = 15; -// var requiredSignatures = 15; -// var multisigAccount = node.randomAccount(); -// -// var accounts = []; -// for (var i = 0; i < totalMembers; i++) { -// accounts[i] = node.randomAccount(); -// } -// -// var multiSigTx = { -// lifetime: 0, -// min: 0, -// members: [], -// txId: '' -// }; -// -// function sendLISK (account, i, done) { -// var randomLISK = node.randomLISK(); -// -// node.put('/api/transactions/', { -// secret: node.gAccount.password, -// amount: randomLISK, -// recipientId: account.address -// }, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// if (res.body.success && i != null) { -// accounts[i].balance = randomLISK / node.normalizer; -// } -// done(); -// }); -// } -// -// function sendLISKFromMultisigAccount (password, amount, recipient, done) { -// node.put('/api/transactions/', { -// secret: password, -// amount: amount, -// recipientId: recipient -// }, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId'); -// done(err, res.body.transactionId); -// }); -// } -// -// function confirmTransaction (transactionId, passphrases, done) { -// var count = 0; -// -// async.until( -// function () { -// return (count >= passphrases.length); -// }, -// function (untilCb) { -// var passphrase = passphrases[count]; -// -// node.post('/api/multisignatures/sign', { -// secret: passphrase, -// transactionId: transactionId -// }, function (err, res) { -// if (err || !res.body.success) { -// return untilCb(err || res.body.error); -// } -// node.expect(res.body).to.have.property('transactionId').to.equal(transactionId); -// count++; -// return untilCb(); -// }); -// }, -// function (err) { -// done(err); -// } -// ); -// } -// -// // Used for KeysGroup -// var Keys; -// -// function makeKeysGroup () { -// var keysgroup = []; -// for (var i = 0; i < totalMembers; i++) { -// var member = '+' + accounts[i].publicKey; -// keysgroup.push(member); -// } -// return keysgroup; -// } -// -// before(function (done) { -// var i = 0; -// async.eachSeries(accounts, function (account, eachCb) { -// sendLISK(account, i, function () { -// i++; -// return eachCb(); -// }); -// }, function (err) { -// return done(err); -// }); -// }); -// -// before(function (done) { -// sendLISK(multisigAccount, null, done); -// }); -// -// before(function (done) { -// node.onNewBlock(function (err) { -// done(err); -// }); -// }); -// -// describe('PUT /api/multisignatures', function () { -// -// before(function () { -// Keys = makeKeysGroup(); -// }); -// -// var validParams; -// -// beforeEach(function () { -// validParams = { -// secret: multisigAccount.password, -// lifetime: parseInt(node.randomNumber(1,72)), -// min: requiredSignatures, -// keysgroup: makeKeysGroup() -// }; -// }); -// -// it('using random passphase should fail', function (done) { -// validParams.secret = node.randomPassword(); -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// -// it('using empty keysgroup should fail', function (done) { -// validParams.keysgroup = []; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Array is too short (0), minimum 1'); -// done(); -// }); -// }); -// -// it('using sender in the keysgroup should fail', function (done) { -// validParams.keysgroup.pop(); -// validParams.keysgroup.push('+' + multisigAccount.publicKey); -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Invalid multisignature keysgroup. Can not contain sender'); -// done(); -// }); -// }); -// -// it('using no math operator in keysgroup should fail', function (done) { -// validParams.keysgroup = validParams.keysgroup.map(function (v) { -// return v.substring(1); -// }); -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Invalid math operator in multisignature keysgroup'); -// done(); -// }); -// }); -// -// it('using invalid math operator in keysgroup should fail', function (done) { -// validParams.keysgroup = validParams.keysgroup.map(function (v) { -// return '-' + v.substring(1); -// }); -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Invalid math operator in multisignature keysgroup'); -// done(); -// }); -// }); -// -// it('using same member twice should fail', function (done) { -// validParams.keysgroup.pop(); -// validParams.keysgroup.push(validParams.keysgroup[1]); -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Encountered duplicate public key in multisignature keysgroup'); -// done(); -// }); -// }); -// -// it('using null member in keysgroup should fail', function (done) { -// validParams.keysgroup.pop(); -// validParams.keysgroup.push(null); -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('using keysgroup length less than minimum acceptable length should fail', function (done) { -// validParams.keysgroup = []; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Array is too short (0), minimum 1'); -// done(); -// }); -// }); -// -// it('using keysgroup length greater than maximum acceptable length should fail', function (done) { -// validParams.keysgroup = Array.apply(null, new Array(constants.multisigConstraints.keysgroup.maxItems + 1)).map(function () { -// return '+' + node.lisk.crypto.getKeys(node.randomPassword()).publicKey; -// }); -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Array is too long (16), maximum 15'); -// done(); -// }); -// }); -// -// it('using min bigger than keysgroup size plus 1 should fail', function (done) { -// validParams.keysgroup.pop(); -// validParams.min = validParams.keysgroup.length + 1; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Invalid multisignature min. Must be less than or equal to keysgroup size'); -// done(); -// }); -// }); -// -// it('using min more than maximum acceptable should fail', function (done) { -// validParams.min = constants.multisigConstraints.min.maximum + 1; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Value 16 is greater than maximum 15'); -// done(); -// }); -// }); -// -// it('using min less than minimum acceptable should fail', function (done) { -// validParams.min = 0; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Value 0 is less than minimum 1'); -// done(); -// }, true); -// }); -// -// it('using empty keysgroup should fail', function (done) { -// validParams.keysgroup = []; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using no keysgroup should fail', function (done) { -// delete validParams.keysgroup; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using string keysgroup should fail', function (done) { -// validParams.keysgroup = 'invalid'; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using null member in keysgroup should fail', function (done) { -// var multiSigTx = { -// secret: multisigAccount.password, -// lifetime: parseInt(node.randomNumber(1,72)), -// min: requiredSignatures, -// keysgroup: makeKeysGroup() -// }; -// multiSigTx.keysgroup.pop(); -// multiSigTx.keysgroup.push(null); -// -// node.put('/api/multisignatures', multiSigTx, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('using invalid member in keysgroup should fail', function (done) { -// var multiSigTx = { -// secret: multisigAccount.password, -// lifetime: parseInt(node.randomNumber(1,72)), -// min: requiredSignatures, -// keysgroup: makeKeysGroup() -// }; -// multiSigTx.keysgroup.pop(); -// multiSigTx.keysgroup.push('+' + node.eAccount.publicKey + 'A'); -// -// node.put('/api/multisignatures', multiSigTx, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Invalid public key in multisignature keysgroup'); -// done(); -// }); -// }); -// -// it('using no passphase should fail', function (done) { -// delete validParams.secret; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using invalid passphrase should fail', function (done) { -// validParams.secret = multisigAccount.password + 'inv4lid'; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using no lifetime', function (done) { -// delete validParams.lifetime; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using string lifetime should fail', function (done) { -// validParams.lifetime = 'invalid'; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using lifetime greater than maximum allowed should fail', function (done) { -// validParams.lifetime = constants.multisigConstraints.lifetime.maximum + 1; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Value 73 is greater than maximum 72'); -// done(); -// }); -// }); -// -// it('using lifetime == 0 should fail', function (done) { -// validParams.lifetime = 0; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using negative lifetime should fail', function (done) { -// validParams.lifetime = -1; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using no min should fail', function (done) { -// delete validParams.min; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using string min should fail', function (done) { -// validParams.min = 'invalid'; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using min greater than the total members should fail', function (done) { -// validParams.min = totalMembers + 5; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using min == 0 should fail', function (done) { -// validParams.min = 0; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using negative min should fail', function (done) { -// validParams.min = -1; -// -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// describe('valid multisigs transactions with different min and keysgroup values', function () { -// var multisigAccount1 = node.randomAccount(); -// var multisigAccount2 = node.randomAccount(); -// var multisigAccount3 = node.randomAccount(); -// -// before(function (done) { -// async.every([multisigAccount1, multisigAccount2, multisigAccount3], function (acc, cb) { -// sendLISK(acc, 0, cb); -// }, done); -// }); -// -// before(function (done) { -// node.onNewBlock(done); -// }); -// -// it('using valid params should be ok for min 1 and keysgroup array 1', function (done) { -// var params = { -// secret: multisigAccount1.password, -// lifetime: 11, -// min: 1, -// keysgroup: ['+' + node.lisk.crypto.getKeys(node.randomPassword()).publicKey] -// }; -// -// node.put('/api/multisignatures', params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').that.is.not.empty; -// done(); -// }); -// }); -// -// it('using valid params should be ok when min 5 and keysgroup array 5', function (done) { -// var params = { -// secret: multisigAccount2.password, -// lifetime: 11, -// min: 5, -// keysgroup: Array.apply(null, Array(5)).map(function () { return '+' + node.lisk.crypto.getKeys(node.randomPassword()).publicKey; }) -// }; -// -// node.put('/api/multisignatures', params, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').that.is.not.empty; -// done(); -// }); -// }); -// }); -// -// it('using valid params should be ok when min 15 and keysgroup array is 15', function (done) { -// node.put('/api/multisignatures', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').that.is.not.empty; -// multiSigTx.txId = res.body.transactionId; -// multiSigTx.lifetime = validParams.lifetime; -// multiSigTx.members = Keys; -// multiSigTx.min = requiredSignatures; -// done(); -// }); -// }); -// }); -// -// describe('GET /api/multisignatures/pending', function () { -// -// before(function (done) { -// node.onNewBlock(done); -// }); -// -// it('using invalid public key should fail', function (done) { -// var publicKey = 1234; -// -// node.get('/api/multisignatures/pending?publicKey=' + publicKey, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using no public key should be ok', function (done) { -// node.get('/api/multisignatures/pending?publicKey=', function (err, res) { -// node.expect(res.body).to.have.property('success'); -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactions').that.is.an('array'); -// node.expect(res.body.transactions.length).to.equal(0); -// done(); -// }); -// }); -// -// it('using valid public key should be ok', function (done) { -// node.get('/api/multisignatures/pending?publicKey=' + multisigAccount.publicKey, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactions').that.is.an('array'); -// node.expect(res.body.transactions.length).to.be.at.least(1); -// -// var flag = 0; -// for (var i = 0; i < res.body.transactions.length; i++) { -// flag += 1; -// -// var pending = res.body.transactions[i]; -// -// node.expect(pending).to.have.property('max').that.is.equal(0); -// node.expect(pending).to.have.property('min').that.is.equal(0); -// node.expect(pending).to.have.property('lifetime').that.is.equal(0); -// node.expect(pending).to.have.property('signed').that.is.true; -// -// node.expect(pending.transaction).to.have.property('type').that.is.equal(node.txTypes.MULTI); -// node.expect(pending.transaction).to.have.property('amount').that.is.equal(0); -// node.expect(pending.transaction).to.have.property('senderPublicKey').that.is.equal(multisigAccount.publicKey); -// node.expect(pending.transaction).to.have.property('timestamp').that.is.a('number'); -// node.expect(pending.transaction).to.have.property('asset').that.is.an('object'); -// node.expect(pending.transaction.asset).to.have.property('multisignature').that.is.an('object'); -// node.expect(pending.transaction.asset.multisignature).to.have.property('min').that.is.a('number'); -// node.expect(pending.transaction.asset.multisignature).to.have.property('keysgroup').that.is.an('array'); -// node.expect(pending.transaction.asset.multisignature).to.have.property('lifetime').that.is.a('number'); -// node.expect(pending.transaction).to.have.property('signature').that.is.a('string'); -// node.expect(pending.transaction).to.have.property('id').that.is.equal(multiSigTx.txId); -// node.expect(pending.transaction).to.have.property('senderId').that.is.eql(multisigAccount.address); -// node.expect(pending.transaction).to.have.property('receivedAt').that.is.a('string'); -// } -// -// node.expect(flag).to.equal(1); -// done(); -// }); -// }); -// }); -// -// describe('PUT /api/transactions', function () { -// -// it('when group transaction is pending should be ok', function (done) { -// sendLISKFromMultisigAccount(multisigAccount.password, 100000000, node.gAccount.address, function (err, transactionId) { -// node.onNewBlock(function (err) { -// node.get('/api/transactions/get?id=' + transactionId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transaction'); -// node.expect(res.body.transaction).to.have.property('id').to.equal(transactionId); -// done(); -// }); -// }); -// }); -// }); -// }); -// -// describe('POST /api/multisignatures/sign (group)', function () { -// -// var validParams; -// -// var passphrases = accounts.map(function (account) { -// return account.password; -// }); -// -// beforeEach(function (done) { -// validParams = { -// secret: accounts[0].password, -// transactionId: multiSigTx.txId -// }; -// done(); -// }); -// -// it('using random passphrase should fail', function (done) { -// validParams.secret = node.randomPassword(); -// -// node.post('/api/multisignatures/sign', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// done(); -// }); -// }); -// -// it('using null passphrase should fail', function (done) { -// validParams.secret = null; -// -// node.post('/api/multisignatures/sign', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// done(); -// }); -// }); -// -// it('using undefined passphrase should fail', function (done) { -// validParams.secret = undefined; -// -// node.post('/api/multisignatures/sign', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// done(); -// }); -// }); -// -// it('using one less than total signatures should not confirm transaction', function (done) { -// confirmTransaction(multiSigTx.txId, passphrases.slice(0, (passphrases.length - 1)), function () { -// node.onNewBlock(function (err) { -// node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// done(); -// }); -// }); -// }); -// }); -// -// it('using same signature again should fail', function (done) { -// node.post('/api/multisignatures/sign', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Transaction already signed'); -// done(); -// }); -// }); -// -// it('using same signature again should not confirm transaction', function (done) { -// node.post('/api/multisignatures/sign', validParams, function (err, res) { -// node.onNewBlock(function (err) { -// node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// done(); -// }); -// }); -// }); -// }); -// -// it('using one more signature should confirm transaction', function (done) { -// confirmTransaction(multiSigTx.txId, passphrases.slice(-1), function () { -// node.onNewBlock(function (err) { -// node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transaction'); -// node.expect(res.body.transaction).to.have.property('id').to.equal(multiSigTx.txId); -// done(); -// }); -// }); -// }); -// }); -// }); -// -// describe('POST /api/multisignatures/sign (transaction)', function () { -// -// var validParams; -// -// var passphrases = accounts.map(function (account) { -// return account.password; -// }); -// -// before(function (done) { -// sendLISKFromMultisigAccount(multisigAccount.password, 100000000, node.gAccount.address, function (err, transactionId) { -// multiSigTx.txId = transactionId; -// node.onNewBlock(function (err) { -// done(); -// }); -// }); -// }); -// -// beforeEach(function (done) { -// validParams = { -// secret: accounts[0].password, -// transactionId: multiSigTx.txId -// }; -// done(); -// }); -// -// it('using one less than minimum signatures should not confirm transaction', function (done) { -// confirmTransaction(multiSigTx.txId, passphrases.slice(0, (multiSigTx.min - 1)), function () { -// node.onNewBlock(function (err) { -// node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// done(); -// }); -// }); -// }); -// }); -// -// it('using same signature again should fail', function (done) { -// node.post('/api/multisignatures/sign', validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.equal('Transaction already signed'); -// done(); -// }); -// }); -// -// it('using same signature again should not confirm transaction', function (done) { -// node.post('/api/multisignatures/sign', validParams, function (err, res) { -// node.onNewBlock(function (err) { -// node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// done(); -// }); -// }); -// }); -// }); -// -// it('using one more signature should confirm transaction', function (done) { -// confirmTransaction(multiSigTx.txId, passphrases.slice(-1), function () { -// node.onNewBlock(function (err) { -// node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transaction'); -// node.expect(res.body.transaction).to.have.property('id').to.equal(multiSigTx.txId); -// done(); -// }); -// }); -// }); -// }); -// }); -// -// describe('POST /api/multisignatures/sign (regular account)', function () { -// -// var transactionId; -// -// before(function (done) { -// node.put('/api/transactions/', { -// secret: node.gAccount.password , -// amount: 1, -// recipientId: accounts[0].address -// }, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').that.is.not.empty; -// transactionId = res.body.transactionId; -// done(); -// }); -// }); -// -// it('should be impossible to sign the transaction', function (done) { -// node.onNewBlock(function (err) { -// node.get('/api/transactions/get?id=' + transactionId, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transaction'); -// node.expect(res.body.transaction).to.have.property('id').to.equal(transactionId); -// confirmTransaction(transactionId, [multisigAccount.password], function (err, res) { -// node.expect(err).not.to.be.empty; -// done(); -// }); -// }); -// }); -// }); -// -// it('should have no pending multisignatures', function (done) { -// node.get('/api/multisignatures/pending?publicKey=' + accounts[0].publicKey, function (err, res) { -// node.expect(res.body).to.have.property('success'); -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactions').that.is.an('array'); -// node.expect(res.body.transactions.length).to.equal(0); -// done(); -// }); -// }); -// }); +'use strict'; + +var async = require('async'); +var node = require('./../node.js'); + +var constants = require('../../helpers/constants.js'); + +var totalMembers = 15; +var requiredSignatures = 15; +var multisigAccount = node.randomAccount(); + +var accounts = []; +for (var i = 0; i < totalMembers; i++) { + accounts[i] = node.randomAccount(); +} + +var multiSigTx = { + lifetime: 0, + min: 0, + members: [], + txId: '' +}; + +function sendLISK (account, i, done) { + var randomLISK = node.randomLISK(); + + node.put('/api/transactions/', { + secret: node.gAccount.password, + amount: randomLISK, + recipientId: account.address + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + if (res.body.success && i != null) { + accounts[i].balance = randomLISK / node.normalizer; + } + done(); + }); +} + +function sendLISKFromMultisigAccount (password, amount, recipient, done) { + node.put('/api/transactions/', { + secret: password, + amount: amount, + recipientId: recipient + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId'); + done(err, res.body.transactionId); + }); +} + +function confirmTransaction (transactionId, passphrases, done) { + var count = 0; + + async.until( + function () { + return (count >= passphrases.length); + }, + function (untilCb) { + var passphrase = passphrases[count]; + + node.post('/api/multisignatures/sign', { + secret: passphrase, + transactionId: transactionId + }, function (err, res) { + if (err || !res.body.success) { + return untilCb(err || res.body.error); + } + node.expect(res.body).to.have.property('transactionId').to.equal(transactionId); + count++; + return untilCb(); + }); + }, + function (err) { + done(err); + } + ); +} + +// Used for KeysGroup +var Keys; + +function makeKeysGroup () { + var keysgroup = []; + for (var i = 0; i < totalMembers; i++) { + var member = '+' + accounts[i].publicKey; + keysgroup.push(member); + } + return keysgroup; +} + +before(function (done) { + var i = 0; + async.eachSeries(accounts, function (account, eachCb) { + sendLISK(account, i, function () { + i++; + return eachCb(); + }); + }, function (err) { + return done(err); + }); +}); + +before(function (done) { + sendLISK(multisigAccount, null, done); +}); + +before(function (done) { + node.onNewBlock(function (err) { + done(err); + }); +}); + +describe('PUT /api/multisignatures', function () { + + before(function () { + Keys = makeKeysGroup(); + }); + + var validParams; + + beforeEach(function () { + validParams = { + secret: multisigAccount.password, + lifetime: parseInt(node.randomNumber(1,72)), + min: requiredSignatures, + keysgroup: makeKeysGroup() + }; + }); + + it('using random passphase should fail', function (done) { + validParams.secret = node.randomAccount().password; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + + it('using empty keysgroup should fail', function (done) { + validParams.keysgroup = []; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Array is too short (0), minimum 1'); + done(); + }); + }); + + it('using sender in the keysgroup should fail', function (done) { + validParams.keysgroup.pop(); + validParams.keysgroup.push('+' + multisigAccount.publicKey); + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Invalid multisignature keysgroup. Can not contain sender'); + done(); + }); + }); + + it('using no math operator in keysgroup should fail', function (done) { + validParams.keysgroup = validParams.keysgroup.map(function (v) { + return v.substring(1); + }); + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Invalid math operator in multisignature keysgroup'); + done(); + }); + }); + + it('using invalid math operator in keysgroup should fail', function (done) { + validParams.keysgroup = validParams.keysgroup.map(function (v) { + return '-' + v.substring(1); + }); + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Invalid math operator in multisignature keysgroup'); + done(); + }); + }); + + it('using same member twice should fail', function (done) { + validParams.keysgroup.pop(); + validParams.keysgroup.push(validParams.keysgroup[1]); + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Encountered duplicate public key in multisignature keysgroup'); + done(); + }); + }); + + it('using null member in keysgroup should fail', function (done) { + validParams.keysgroup.pop(); + validParams.keysgroup.push(null); + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('using keysgroup length less than minimum acceptable length should fail', function (done) { + validParams.keysgroup = []; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Array is too short (0), minimum 1'); + done(); + }); + }); + + it('using keysgroup length greater than maximum acceptable length should fail', function (done) { + validParams.keysgroup = Array.apply(null, new Array(constants.multisigConstraints.keysgroup.maxItems + 1)).map(function () { + return '+' + node.randomAccount().publicKey; + }); + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Array is too long (16), maximum 15'); + done(); + }); + }); + + it('using min bigger than keysgroup size plus 1 should fail', function (done) { + validParams.keysgroup.pop(); + validParams.min = validParams.keysgroup.length + 1; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Invalid multisignature min. Must be less than or equal to keysgroup size'); + done(); + }); + }); + + it('using min more than maximum acceptable should fail', function (done) { + validParams.min = constants.multisigConstraints.min.maximum + 1; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Value 16 is greater than maximum 15'); + done(); + }); + }); + + it('using min less than minimum acceptable should fail', function (done) { + validParams.min = 0; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Value 0 is less than minimum 1'); + done(); + }, true); + }); + + it('using empty keysgroup should fail', function (done) { + validParams.keysgroup = []; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using no keysgroup should fail', function (done) { + delete validParams.keysgroup; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using string keysgroup should fail', function (done) { + validParams.keysgroup = 'invalid'; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using null member in keysgroup should fail', function (done) { + var multiSigTx = { + secret: multisigAccount.password, + lifetime: parseInt(node.randomNumber(1,72)), + min: requiredSignatures, + keysgroup: makeKeysGroup() + }; + multiSigTx.keysgroup.pop(); + multiSigTx.keysgroup.push(null); + + node.put('/api/multisignatures', multiSigTx, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('using invalid member in keysgroup should fail', function (done) { + var multiSigTx = { + secret: multisigAccount.password, + lifetime: parseInt(node.randomNumber(1,72)), + min: requiredSignatures, + keysgroup: makeKeysGroup() + }; + multiSigTx.keysgroup.pop(); + multiSigTx.keysgroup.push('+' + node.eAccount.publicKey + 'A'); + + node.put('/api/multisignatures', multiSigTx, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Invalid public key in multisignature keysgroup'); + done(); + }); + }); + + it('using no passphase should fail', function (done) { + delete validParams.secret; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using invalid passphrase should fail', function (done) { + validParams.secret = multisigAccount.password + 'inv4lid'; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using no lifetime', function (done) { + delete validParams.lifetime; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using string lifetime should fail', function (done) { + validParams.lifetime = 'invalid'; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using lifetime greater than maximum allowed should fail', function (done) { + validParams.lifetime = constants.multisigConstraints.lifetime.maximum + 1; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Value 73 is greater than maximum 72'); + done(); + }); + }); + + it('using lifetime == 0 should fail', function (done) { + validParams.lifetime = 0; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using negative lifetime should fail', function (done) { + validParams.lifetime = -1; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using no min should fail', function (done) { + delete validParams.min; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using string min should fail', function (done) { + validParams.min = 'invalid'; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using min greater than the total members should fail', function (done) { + validParams.min = totalMembers + 5; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using min == 0 should fail', function (done) { + validParams.min = 0; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using negative min should fail', function (done) { + validParams.min = -1; + + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + describe('valid multisigs transactions with different min and keysgroup values', function () { + var multisigAccount1 = node.randomAccount(); + var multisigAccount2 = node.randomAccount(); + var multisigAccount3 = node.randomAccount(); + + before(function (done) { + async.every([multisigAccount1, multisigAccount2, multisigAccount3], function (acc, cb) { + sendLISK(acc, 0, cb); + }, done); + }); + + before(function (done) { + node.onNewBlock(done); + }); + + it('using valid params should be ok for min 1 and keysgroup array 1', function (done) { + var params = { + secret: multisigAccount1.password, + lifetime: 11, + min: 1, + keysgroup: ['+' + node.randomAccount().publicKey] + }; + + node.put('/api/multisignatures', params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + done(); + }); + }); + + it('using valid params should be ok when min 5 and keysgroup array 5', function (done) { + var params = { + secret: multisigAccount2.password, + lifetime: 11, + min: 5, + keysgroup: Array.apply(null, Array(5)).map(function () { return '+' + node.randomAccount().publicKey; }) + }; + + node.put('/api/multisignatures', params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + done(); + }); + }); + }); + + it('using valid params should be ok when min 15 and keysgroup array is 15', function (done) { + node.put('/api/multisignatures', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + multiSigTx.txId = res.body.transactionId; + multiSigTx.lifetime = validParams.lifetime; + multiSigTx.members = Keys; + multiSigTx.min = requiredSignatures; + done(); + }); + }); +}); + +describe('GET /api/multisignatures/pending', function () { + + before(function (done) { + node.onNewBlock(done); + }); + + it('using invalid public key should fail', function (done) { + var publicKey = 1234; + + node.get('/api/multisignatures/pending?publicKey=' + publicKey, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using no public key should be ok', function (done) { + node.get('/api/multisignatures/pending?publicKey=', function (err, res) { + node.expect(res.body).to.have.property('success'); + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactions').that.is.an('array'); + node.expect(res.body.transactions.length).to.equal(0); + done(); + }); + }); + + it('using valid public key should be ok', function (done) { + node.get('/api/multisignatures/pending?publicKey=' + multisigAccount.publicKey, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactions').that.is.an('array'); + node.expect(res.body.transactions.length).to.be.at.least(1); + + var flag = 0; + for (var i = 0; i < res.body.transactions.length; i++) { + flag += 1; + + var pending = res.body.transactions[i]; + + node.expect(pending).to.have.property('max').that.is.equal(0); + node.expect(pending).to.have.property('min').that.is.equal(0); + node.expect(pending).to.have.property('lifetime').that.is.equal(0); + node.expect(pending).to.have.property('signed').that.is.true; + + node.expect(pending.transaction).to.have.property('type').that.is.equal(node.txTypes.MULTI); + node.expect(pending.transaction).to.have.property('amount').that.is.equal(0); + node.expect(pending.transaction).to.have.property('senderPublicKey').that.is.equal(multisigAccount.publicKey); + node.expect(pending.transaction).to.have.property('timestamp').that.is.a('number'); + node.expect(pending.transaction).to.have.property('asset').that.is.an('object'); + node.expect(pending.transaction.asset).to.have.property('multisignature').that.is.an('object'); + node.expect(pending.transaction.asset.multisignature).to.have.property('min').that.is.a('number'); + node.expect(pending.transaction.asset.multisignature).to.have.property('keysgroup').that.is.an('array'); + node.expect(pending.transaction.asset.multisignature).to.have.property('lifetime').that.is.a('number'); + node.expect(pending.transaction).to.have.property('signature').that.is.a('string'); + node.expect(pending.transaction).to.have.property('id').that.is.equal(multiSigTx.txId); + node.expect(pending.transaction).to.have.property('senderId').that.is.eql(multisigAccount.address); + node.expect(pending.transaction).to.have.property('receivedAt').that.is.a('string'); + } + + node.expect(flag).to.equal(1); + done(); + }); + }); +}); + +describe('PUT /api/transactions', function () { + + it('when group transaction is pending should be ok', function (done) { + sendLISKFromMultisigAccount(multisigAccount.password, 100000000, node.gAccount.address, function (err, transactionId) { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + transactionId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction'); + node.expect(res.body.transaction).to.have.property('id').to.equal(transactionId); + done(); + }); + }); + }); + }); +}); + +describe('POST /api/multisignatures/sign (group)', function () { + + var validParams; + + var passphrases = accounts.map(function (account) { + return account.password; + }); + + beforeEach(function (done) { + validParams = { + secret: accounts[0].password, + transactionId: multiSigTx.txId + }; + done(); + }); + + it('using random passphrase should fail', function (done) { + validParams.secret = node.randomAccount().password; + + node.post('/api/multisignatures/sign', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + + it('using null passphrase should fail', function (done) { + validParams.secret = null; + + node.post('/api/multisignatures/sign', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + + it('using undefined passphrase should fail', function (done) { + validParams.secret = undefined; + + node.post('/api/multisignatures/sign', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + + it('using one less than total signatures should not confirm transaction', function (done) { + confirmTransaction(multiSigTx.txId, passphrases.slice(0, (passphrases.length - 1)), function () { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + }); + }); + + it('using same signature again should fail', function (done) { + node.post('/api/multisignatures/sign', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Transaction already signed'); + done(); + }); + }); + + it('using same signature again should not confirm transaction', function (done) { + node.post('/api/multisignatures/sign', validParams, function (err, res) { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + }); + }); + + it('using one more signature should confirm transaction', function (done) { + confirmTransaction(multiSigTx.txId, passphrases.slice(-1), function () { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction'); + node.expect(res.body.transaction).to.have.property('id').to.equal(multiSigTx.txId); + done(); + }); + }); + }); + }); +}); + +describe('POST /api/multisignatures/sign (transaction)', function () { + + var validParams; + + var passphrases = accounts.map(function (account) { + return account.password; + }); + + before(function (done) { + sendLISKFromMultisigAccount(multisigAccount.password, 100000000, node.gAccount.address, function (err, transactionId) { + multiSigTx.txId = transactionId; + node.onNewBlock(function (err) { + done(); + }); + }); + }); + + beforeEach(function (done) { + validParams = { + secret: accounts[0].password, + transactionId: multiSigTx.txId + }; + done(); + }); + + it('using one less than minimum signatures should not confirm transaction', function (done) { + confirmTransaction(multiSigTx.txId, passphrases.slice(0, (multiSigTx.min - 1)), function () { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + }); + }); + + it('using same signature again should fail', function (done) { + node.post('/api/multisignatures/sign', validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.equal('Transaction already signed'); + done(); + }); + }); + + it('using same signature again should not confirm transaction', function (done) { + node.post('/api/multisignatures/sign', validParams, function (err, res) { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + }); + }); + + it('using one more signature should confirm transaction', function (done) { + confirmTransaction(multiSigTx.txId, passphrases.slice(-1), function () { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + multiSigTx.txId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction'); + node.expect(res.body.transaction).to.have.property('id').to.equal(multiSigTx.txId); + done(); + }); + }); + }); + }); +}); + +describe('POST /api/multisignatures/sign (regular account)', function () { + + var transactionId; + + before(function (done) { + node.put('/api/transactions/', { + secret: node.gAccount.password , + amount: 1, + recipientId: accounts[0].address + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + transactionId = res.body.transactionId; + done(); + }); + }); + + it('should be impossible to sign the transaction', function (done) { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + transactionId, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction'); + node.expect(res.body.transaction).to.have.property('id').to.equal(transactionId); + confirmTransaction(transactionId, [multisigAccount.password], function (err, res) { + node.expect(err).not.to.be.empty; + done(); + }); + }); + }); + }); + + it('should have no pending multisignatures', function (done) { + node.get('/api/multisignatures/pending?publicKey=' + accounts[0].publicKey, function (err, res) { + node.expect(res.body).to.have.property('success'); + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactions').that.is.an('array'); + node.expect(res.body.transactions.length).to.equal(0); + done(); + }); + }); +}); diff --git a/test/api/peer.blocks.js b/test/api/peer.blocks.js index c2c0e3e3..a6d05ebb 100644 --- a/test/api/peer.blocks.js +++ b/test/api/peer.blocks.js @@ -1,7 +1,7 @@ 'use strict'; var node = require('./../node.js'); -var genesisblock = require('../../genesisBlock.json'); +var genesisblock = require('../../test/genesisBlock.json'); // use testnet genesisBlock var testBlock = { id: '2807833455815592401', diff --git a/test/api/peer.transactions.collision.js b/test/api/peer.transactions.collision.js index e0b078d3..bdf63961 100644 --- a/test/api/peer.transactions.collision.js +++ b/test/api/peer.transactions.collision.js @@ -1,101 +1,124 @@ -// 'use strict'; -// -// var crypto = require('crypto'); -// var node = require('./../node.js'); -// -// var modulesLoader = require('../common/initModule').modulesLoader; -// var Account = require('../../logic/account'); -// -// function postTransaction (transaction, done) { -// node.post('/peer/transactions', { -// transaction: transaction -// }, done); -// } -// -// describe('POST /peer/transactions', function () { -// -// describe('when two passphrases collide into the same address', function () { -// -// var collision = { -// address: '13555181540209512417L', -// passphrases: [ -// 'merry field slogan sibling convince gold coffee town fold glad mix page', -// 'annual youth lift quote off olive uncle town chief poverty extend series' -// ] -// }; -// -// before(function (done) { -// modulesLoader.initLogicWithDb(Account, function (err, account) { -// if (err) { -// return done(err); -// } -// account.remove(collision.address, function (err, res) { -// node.expect(err).to.not.exist; -// done(); -// }); -// }); -// }); -// -// before(function (done) { -// // Send funds to collision account -// var transaction = node.lisk.transaction.createTransaction(collision.address, 220000000, node.gAccount.password); -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.onNewBlock(done); -// }); -// }); -// -// describe('when transaction is invalid', function () { -// -// it('should fail for passphrase two', function (done) { -// var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[1]); -// transaction.signature = crypto.randomBytes(64).toString('hex'); -// transaction.id = node.lisk.crypto.getId(transaction); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.equal('Failed to verify signature'); -// done(); -// }); -// }); -// -// it('should fail for passphrase one', function (done) { -// var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[0]); -// transaction.signature = crypto.randomBytes(64).toString('hex'); -// transaction.id = node.lisk.crypto.getId(transaction); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.equal('Failed to verify signature'); -// done(); -// }); -// }); -// }); -// -// describe('when transaction is valid', function () { -// -// beforeEach(function (done) { -// node.onNewBlock(done); -// }); -// -// it('should be ok for passphrase one', function (done) { -// var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[0]); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// done(); -// }); -// }); -// -// it('should fail for passphrase two', function (done) { -// var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[1]); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.equal('Invalid sender public key: b26dd40ba33e4785e49ddc4f106c0493ed00695817235c778f487aea5866400a expected: ce33db918b059a6e99c402963b42cf51c695068007ef01d8c383bb8a41270263'); -// done(); -// }); -// }); -// }); -// }); -// }); +'use strict'; + +var crypto = require('crypto'); +var node = require('./../node.js'); + +var modulesLoader = require('../common/initModule').modulesLoader; +var Account = require('../../logic/account'); + +function postTransaction (transaction, done) { + node.post('/peer/transactions', { + transaction: transaction + }, done); +} + +describe('POST /peer/transactions', function () { + + describe('when two passphrases collide into the same address', function () { + + // I don't have two passphrases for single address yet + var collision = { + address: 'U8790402293675124834', + passphrases: [ + 'merry field slogan sibling convince gold coffee town fold glad mix page', + 'annual youth lift quote off olive uncle town chief poverty extend series' // U2514767526571975130 + ] + }; + + before(function (done) { + modulesLoader.initLogicWithDb(Account, function (err, account) { + if (err) { + return done(err); + } + account.remove(collision.address, function (err, res) { + node.expect(err).to.not.exist; + done(); + }); + }); + }); + + before(function (done) { + // Send funds to collision account + var transaction = node.createSendTransaction({ + keyPair: node.gAccount.keypair, + amount: 220000000, + recipientId: collision.address + }); + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(done); + }); + }); + + describe('when transaction is invalid', function () { + + it('should fail for passphrase two', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: node.gAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[1]); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Failed to verify signature'); + done(); + }); + }); + + it('should fail for passphrase one', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[0]); + transaction.signature = crypto.randomBytes(64).toString('hex'); + transaction.id = node.lisk.crypto.getId(transaction); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Failed to verify signature'); + done(); + }); + }); + }); + + describe('when transaction is valid', function () { + + beforeEach(function (done) { + node.onNewBlock(done); + }); + + it('should be ok for passphrase one', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[0]); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + done(); + }); + }); + + it('should fail for passphrase two', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[1]); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Invalid sender public key: b26dd40ba33e4785e49ddc4f106c0493ed00695817235c778f487aea5866400a expected: ce33db918b059a6e99c402963b42cf51c695068007ef01d8c383bb8a41270263'); + done(); + }); + }); + }); + }); +}); diff --git a/test/api/peer.transactions.main.js b/test/api/peer.transactions.main.js index 649eb2ba..793230b9 100644 --- a/test/api/peer.transactions.main.js +++ b/test/api/peer.transactions.main.js @@ -1,333 +1,418 @@ -// 'use strict'; -// -// var crypto = require('crypto'); -// var node = require('./../node.js'); -// -// var genesisblock = require('../../genesisBlock.json'); -// -// function postTransaction (transaction, done) { -// node.post('/peer/transactions', { -// transaction: transaction -// }, done); -// } -// -// function getAddress (address, done) { -// node.get('/api/accounts?address=' + address, done); -// } -// -// describe('GET /peer/transactions', function () { -// -// it('using incorrect nethash in headers should fail', function (done) { -// node.get('/peer/transactions') -// .set('nethash', 'incorrect') -// .end(function (err, res) { -// node.debug('> Response:'.grey, JSON.stringify(res.body)); -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body.expected).to.equal(node.config.nethash); -// done(); -// }); -// }); -// -// it('using incompatible version in headers should fail', function (done) { -// node.get('/peer/transactions') -// .set('version', '0.1.0a') -// .end(function (err, res) { -// node.debug('> Response:'.grey, JSON.stringify(res.body)); -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.eql('Request is made from incompatible version'); -// node.expect(res.body).to.have.property('expected').to.eql('0.0.3a'); -// node.expect(res.body).to.have.property('received').to.eql('0.1.0a'); -// done(); -// }); -// }); -// -// it('using valid headers should be ok', function (done) { -// node.get('/peer/transactions') -// .end(function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactions').to.be.an('array'); -// done(); -// }); -// }); -// }); -// -// describe('POST /peer/transactions', function () { -// -// it('using incorrect nethash in headers should fail', function (done) { -// node.post('/peer/transactions') -// .set('nethash', 'incorrect') -// .end(function (err, res) { -// node.debug('> Response:'.grey, JSON.stringify(res.body)); -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body.expected).to.equal(node.config.nethash); -// done(); -// }); -// }); -// -// it('using incompatible version in headers should fail', function (done) { -// node.post('/peer/transactions') -// .set('version', '0.1.0a') -// .end(function (err, res) { -// node.debug('> Response:'.grey, JSON.stringify(res.body)); -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.eql('Request is made from incompatible version'); -// node.expect(res.body).to.have.property('expected').to.eql('0.0.3a'); -// node.expect(res.body).to.have.property('received').to.eql('0.1.0a'); -// done(); -// }); -// }); -// -// it('using valid headers should be ok', function (done) { -// var account = node.randomAccount(); -// // var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); -// let transaction = node.createSignatureTransaction({ -// keyPair: account.keypair, -// secret: account.password -// }); -// // transaction.fee = 10000000; -// // transaction.signature = node.transactionSign(transaction, account.keypair); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); -// done(); -// }); -// }); -// -// it('using already processed transaction should fail', function (done) { -// var account = node.randomAccount(); -// var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.match(/Transaction is already processed: [0-9]+/); -// done(); -// }); -// }); -// }); -// -// it('using already confirmed transaction should fail', function (done) { -// var account = node.randomAccount(); -// var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); -// -// node.onNewBlock(function (err) { -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.match(/Transaction is already confirmed: [0-9]+/); -// done(); -// }); -// }); -// }); -// }); -// -// it('using varying recipientId casing should go to same address', function (done) { -// var account = node.randomAccount(); -// var keys = node.lisk.crypto.getKeys(account.password); -// var address = node.lisk.crypto.getAddress(keys.publicKey); -// -// var transaction = node.lisk.transaction.createTransaction(address, 100000000, node.gAccount.password); -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// -// node.onNewBlock(function (err) { -// var transaction2 = node.lisk.transaction.createTransaction(address.toLowerCase(), 100000000, node.gAccount.password); -// postTransaction(transaction2, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// -// node.onNewBlock(function (err) { -// getAddress(address, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('account').that.is.an('object'); -// node.expect(res.body.account).to.have.property('balance').to.equal('200000000'); -// done(); -// }); -// }); -// }); -// }); -// }); -// }); -// -// it('using transaction with undefined recipientId should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction(undefined, 1, node.gAccount.password); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.eql('Missing recipient'); -// done(); -// }); -// }); -// -// it('using transaction with invalid recipientId should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('0123456789001234567890L', 1, node.gAccount.password); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.contain('Invalid transaction body'); -// done(); -// }); -// }); -// -// it('using transaction with negative amount should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('1L', -1, node.gAccount.password); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message'); -// done(); -// }); -// }); -// -// it('using invalid passphrase should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); -// transaction.recipientId = '1L'; -// transaction.id = node.lisk.crypto.getId(transaction); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message'); -// done(); -// }); -// }); -// -// it('when sender has no funds should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('1L', 1, 'randomstring'); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// -// it('when sender does not have enough funds should always fail', function (done) { -// var account = node.randomAccount(); -// var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); -// -// node.onNewBlock(function () { -// var count = 1; -// var transaction2 = node.lisk.transaction.createTransaction(node.gAccount.address, 2, account.password); -// -// node.async.doUntil(function (next) { -// postTransaction(transaction2, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.match(/Account does not have enough LSK: [0-9]+L balance: 1e-8/); -// count++; -// return next(); -// }); -// }, function () { -// return count === 10; -// }, function () { -// return done(); -// }); -// }); -// }); -// }); -// -// it('using fake signature should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); -// transaction.signature = crypto.randomBytes(64).toString('hex'); -// transaction.id = node.lisk.crypto.getId(transaction); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message'); -// done(); -// }); -// }); -// -// it('using invalid publicKey should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); -// transaction.senderPublicKey = node.randomPassword(); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message'); -// done(); -// }); -// }); -// -// it('using invalid signature should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); -// transaction.signature = node.randomPassword(); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message'); -// done(); -// }); -// }); -// -// it('using very large amount and genesis block id should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('12L', 10000000000000000, node.gAccount.password); -// transaction.blockId = genesisblock.id; -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message'); -// done(); -// }); -// }); -// -// it('using overflown amount should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('12L', 184819291270000000012910218291201281920128129, -// node.gAccount.password); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message'); -// done(); -// }); -// }); -// -// it('using float amount should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('12L', 1.3, node.gAccount.password); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message'); -// done(); -// }); -// }); -// -// describe('from the genesis account', function () { -// -// var signedTransactionFromGenesis = { -// type: 0, -// amount: 1000, -// senderPublicKey: 'c96dec3595ff6041c3bd28b76b8cf75dce8225173d1bd00241624ee89b50f2a8', -// requesterPublicKey: null, -// timestamp: 24259352, -// asset: {}, -// recipientId: node.eAccount.address, -// signature: 'f56a09b2f448f6371ffbe54fd9ac87b1be29fe29f27f001479e044a65e7e42fb1fa48dce6227282ad2a11145691421c4eea5d33ac7f83c6a42e1dcaa44572101', -// id: '15307587316657110485', -// fee: 10000000 -// }; -// -// it('should fail', function (done) { -// postTransaction(signedTransactionFromGenesis, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').equals('Invalid sender. Can not send from genesis account'); -// done(); -// }); -// }); -// }); -// -// describe('using multiple transactions', function () { -// it('with invalid transaction should fail'); -// -// it('with valid transaction should be ok'); -// }); -// }); +'use strict'; + +var crypto = require('crypto'); +var node = require('./../node.js'); + +var genesisblock = require('../../test/genesisBlock.json'); // use testnet genesisBlock + +function postTransaction (transaction, done) { + node.post('/peer/transactions', { + transaction: transaction + }, done); +} + +function getAddress (address, done) { + node.get('/api/accounts?address=' + address, done); +} + +describe('GET /peer/transactions', function () { + + it('using incorrect nethash in headers should fail', function (done) { + node.get('/peer/transactions') + .set('nethash', 'incorrect') + .end(function (err, res) { + node.debug('> Response:'.grey, JSON.stringify(res.body)); + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body.expected).to.equal(node.config.nethash); + done(); + }); + }); + + it('using incompatible version in headers should fail', function (done) { + node.get('/peer/transactions') + .set('version', '0.1.0a') + .end(function (err, res) { + node.debug('> Response:'.grey, JSON.stringify(res.body)); + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.eql('Request is made from incompatible version'); + node.expect(res.body).to.have.property('expected').to.eql('0.0.3a'); + node.expect(res.body).to.have.property('received').to.eql('0.1.0a'); + done(); + }); + }); + + it('using valid headers should be ok', function (done) { + node.get('/peer/transactions') + .end(function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactions').to.be.an('array'); + done(); + }); + }); +}); + +describe('POST /peer/transactions', function () { + + it('using incorrect nethash in headers should fail', function (done) { + node.post('/peer/transactions') + .set('nethash', 'incorrect') + .end(function (err, res) { + node.debug('> Response:'.grey, JSON.stringify(res.body)); + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body.expected).to.equal(node.config.nethash); + done(); + }); + }); + + it('using incompatible version in headers should fail', function (done) { + node.post('/peer/transactions') + .set('version', '0.1.0a') + .end(function (err, res) { + node.debug('> Response:'.grey, JSON.stringify(res.body)); + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.eql('Request is made from incompatible version'); + node.expect(res.body).to.have.property('expected').to.eql('0.0.3a'); + node.expect(res.body).to.have.property('received').to.eql('0.1.0a'); + done(); + }); + }); + + it('using valid headers should be ok', function (done) { + var account = node.randomAccount(); + // var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); + let transaction = node.createSignatureTransaction({ + keyPair: account.keypair, + secret: account.password + }); + // transaction.fee = 10000000; + // transaction.signature = node.transactionSign(transaction, account.keypair); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + done(); + }); + }); + + it('using already processed transaction should fail', function (done) { + var account = node.randomAccount(); + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.match(/Transaction is already processed: [0-9]+/); + done(); + }); + }); + }); + + it('using already confirmed transaction should fail', function (done) { + var account = node.randomAccount(); + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + + node.onNewBlock(function (err) { + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.match(/Transaction is already confirmed: [0-9]+/); + done(); + }); + }); + }); + }); + + it('using varying recipientId casing should go to same address', function (done) { + var account = node.randomAccount(); + var keys = node.lisk.crypto.getKeys(account.password); + var address = node.lisk.crypto.getAddress(keys.publicKey); + + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(address, 100000000, node.gAccount.password); + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + + node.onNewBlock(function (err) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction2 = node.lisk.transaction.createTransaction(address.toLowerCase(), 100000000, node.gAccount.password); + postTransaction(transaction2, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + + node.onNewBlock(function (err) { + getAddress(address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('account').that.is.an('object'); + node.expect(res.body.account).to.have.property('balance').to.equal('200000000'); + done(); + }); + }); + }); + }); + }); + }); + + it('using transaction with undefined recipientId should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(undefined, 1, node.gAccount.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.eql('Missing recipient'); + done(); + }); + }); + + it('using transaction with invalid recipientId should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('0123456789001234567890L', 1, node.gAccount.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.contain('Invalid transaction body'); + done(); + }); + }); + + it('using transaction with negative amount should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('1L', -1, node.gAccount.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message'); + done(); + }); + }); + + it('using invalid passphrase should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); + transaction.recipientId = '1L'; + transaction.id = node.lisk.crypto.getId(transaction); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message'); + done(); + }); + }); + + it('when sender has no funds should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('1L', 1, 'randomstring'); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + + it('when sender does not have enough funds should always fail', function (done) { + var account = node.randomAccount(); + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + + node.onNewBlock(function () { + var count = 1; + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction2 = node.lisk.transaction.createTransaction(node.gAccount.address, 2, account.password); + + node.async.doUntil(function (next) { + postTransaction(transaction2, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.match(/Account does not have enough ADM: U[0-9]+ balance: 1e-8/); + count++; + return next(); + }); + }, function () { + return count === 10; + }, function () { + return done(); + }); + }); + }); + }); + + it('using fake signature should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); + transaction.signature = crypto.randomBytes(64).toString('hex'); + transaction.id = node.lisk.crypto.getId(transaction); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message'); + done(); + }); + }); + + it('using invalid publicKey should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); + transaction.senderPublicKey = node.randomAccount().password; + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message'); + done(); + }); + }); + + it('using invalid signature should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); + transaction.signature = node.randomAccount().password; + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message'); + done(); + }); + }); + + it('using very large amount and genesis block id should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('12L', 10000000000000000, node.gAccount.password); + transaction.blockId = genesisblock.id; + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message'); + done(); + }); + }); + + it('using overflown amount should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('12L', 184819291270000000012910218291201281920128129, + node.gAccount.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message'); + done(); + }); + }); + + it('using float amount should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('12L', 1.3, node.gAccount.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message'); + done(); + }); + }); + + describe('from the genesis account', function () { + + var signedTransactionFromGenesis = { + type: 0, + amount: 1000, + senderPublicKey: 'c96dec3595ff6041c3bd28b76b8cf75dce8225173d1bd00241624ee89b50f2a8', + requesterPublicKey: null, + timestamp: 24259352, + asset: {}, + recipientId: node.eAccount.address, + signature: 'f56a09b2f448f6371ffbe54fd9ac87b1be29fe29f27f001479e044a65e7e42fb1fa48dce6227282ad2a11145691421c4eea5d33ac7f83c6a42e1dcaa44572101', + id: '15307587316657110485', + fee: 10000000 + }; + + it('should fail', function (done) { + postTransaction(signedTransactionFromGenesis, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').equals('Invalid sender. Can not send from genesis account'); + done(); + }); + }); + }); + + describe('using multiple transactions', function () { + it('with invalid transaction should fail'); + + it('with valid transaction should be ok'); + }); +}); diff --git a/test/api/peer.transactions.multisignatures.js b/test/api/peer.transactions.multisignatures.js index bfcb9ffa..4e611c66 100644 --- a/test/api/peer.transactions.multisignatures.js +++ b/test/api/peer.transactions.multisignatures.js @@ -1,78 +1,83 @@ -// 'use strict'; -// -// var crypto = require('crypto'); -// var node = require('./../node.js'); -// -// var multisigAccount = node.randomAccount(); -// -// function postTransaction (transaction, done) { -// node.post('/peer/transactions', { -// transaction: transaction -// }, function (err, res) { -// done(err, res); -// }); -// } -// -// function sendLISK (params, done) { -// var transaction = node.lisk.transaction.createTransaction(params.recipientId, params.amount, params.secret); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.onNewBlock(function (err) { -// done(err, res); -// }); -// }); -// } -// -// describe('POST /peer/transactions', function () { -// -// describe('creating multisignature group', function () { -// -// describe('when account has no funds', function () { -// -// it('should fail', function (done) { -// var multiSigTx = node.lisk.multisignature.createMultisignature(multisigAccount.password, null, [node.lisk.crypto.getKeys(node.randomPassword()).publicKey], 1, 2); -// -// postTransaction(multiSigTx, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// }); -// -// describe('when account has funds', function () { -// -// before(function (done) { -// sendLISK({ -// secret: node.gAccount.password, -// amount: node.fees.multisignatureRegistrationFee * 10, -// recipientId: multisigAccount.address -// }, done); -// }); -// -// it('using null member in keysgroup should fail', function (done) { -// var multiSigTx = node.lisk.multisignature.createMultisignature(multisigAccount.password, null, ['+' + node.eAccount.publicKey, null], 1, 2); -// -// postTransaction(multiSigTx, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('using invalid member in keysgroup should fail', function (done) { -// var memberAccount1 = node.randomAccount(); -// var memberAccount2 = node.randomAccount(); -// -// var multiSigTx = node.lisk.multisignature.createMultisignature(multisigAccount.password, null, ['+' + node.eAccount.publicKey + 'A', '+' + memberAccount1.publicKey, '+' + memberAccount2.publicKey], 1, 2); -// -// postTransaction(multiSigTx, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.equal('Invalid public key in multisignature keysgroup'); -// done(); -// }); -// }); -// }); -// }); -// }); +'use strict'; + +var crypto = require('crypto'); +var node = require('./../node.js'); + +var multisigAccount = node.randomAccount(); + +function postTransaction (transaction, done) { + node.post('/peer/transactions', { + transaction: transaction + }, function (err, res) { + done(err, res); + }); +} + +function sendLISK (params, done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(params.recipientId, params.amount, params.secret); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(function (err) { + done(err, res); + }); + }); +} + +describe('POST /peer/transactions', function () { + + describe('creating multisignature group', function () { + + describe('when account has no funds', function () { + + it('should fail', function (done) { + var multiSigTx = node.lisk.multisignature.createMultisignature(multisigAccount.password, null, [node.randomAccount().publicKey], 1, 2); + + postTransaction(multiSigTx, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + }); + + describe('when account has funds', function () { + + before(function (done) { + sendLISK({ + secret: node.gAccount.password, + amount: node.fees.multisignatureRegistrationFee * 10, + recipientId: multisigAccount.address + }, done); + }); + + it('using null member in keysgroup should fail', function (done) { + var multiSigTx = node.lisk.multisignature.createMultisignature(multisigAccount.password, null, ['+' + node.eAccount.publicKey, null], 1, 2); + + postTransaction(multiSigTx, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('using invalid member in keysgroup should fail', function (done) { + var memberAccount1 = node.randomAccount(); + var memberAccount2 = node.randomAccount(); + + var multiSigTx = node.lisk.multisignature.createMultisignature(multisigAccount.password, null, ['+' + node.eAccount.publicKey + 'A', '+' + memberAccount1.publicKey, '+' + memberAccount2.publicKey], 1, 2); + + postTransaction(multiSigTx, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Invalid public key in multisignature keysgroup'); + done(); + }); + }); + }); + }); +}); diff --git a/test/api/peer.transactions.signatures.js b/test/api/peer.transactions.signatures.js index 8fd945a8..33c70ccb 100644 --- a/test/api/peer.transactions.signatures.js +++ b/test/api/peer.transactions.signatures.js @@ -1,138 +1,163 @@ -// 'use strict'; -// -// var crypto = require('crypto'); -// var node = require('./../node.js'); -// -// var account = node.randomAccount(); -// var account2 = node.randomAccount(); -// var account3 = node.randomAccount(); -// -// function postTransaction (transaction, done) { -// node.post('/peer/transactions', { -// transaction: transaction -// }, function (err, res) { -// done(err, res); -// }); -// } -// -// function sendLISK (params, done) { -// var transaction = node.lisk.transaction.createTransaction(params.recipientId, params.amount, params.secret); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.onNewBlock(function (err) { -// done(err, res); -// }); -// }); -// } -// -// describe('POST /peer/transactions', function () { -// -// describe('enabling second signature', function () { -// -// it('using undefined transaction', function (done) { -// postTransaction(undefined, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.contain('Invalid transaction body'); -// done(); -// }); -// }); -// -// it('using undefined transaction.asset', function (done) { -// var transaction = node.lisk.signature.createSignature(node.randomPassword(), node.randomPassword()); -// -// delete transaction.asset; -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.contain('Invalid transaction body'); -// done(); -// }); -// }); -// -// describe('when account has no funds', function () { -// -// it('should fail', function (done) { -// var transaction = node.lisk.signature.createSignature(node.randomPassword(), node.randomPassword()); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// }); -// -// describe('when account has funds', function () { -// -// before(function (done) { -// sendLISK({ -// secret: node.gAccount.password, -// amount: node.fees.secondPasswordFee + 100000000, -// recipientId: account.address -// }, done); -// }); -// -// it('should be ok', function (done) { -// var transaction = node.lisk.signature.createSignature(account.password, account.secondPassword); -// transaction.fee = node.fees.secondPasswordFee; -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); -// done(); -// }); -// }); -// }); -// }); -// -// describe('using second signature', function () { -// -// before(function (done) { -// node.onNewBlock(function (err) { -// done(); -// }); -// }); -// -// it('when account does not have one should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('1L', 1, node.gAccount.password, account.secondPassword); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// done(); -// }); -// }); -// -// it('using blank second passphrase should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, ''); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.equal('Missing sender second signature'); -// done(); -// }); -// }); -// -// it('using fake second signature should fail', function (done) { -// var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, account.secondPassword); -// transaction.signSignature = crypto.randomBytes(64).toString('hex'); -// transaction.id = node.lisk.crypto.getId(transaction); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('message').to.equal('Failed to verify second signature'); -// done(); -// }); -// }); -// -// it('using valid second passphrase should be ok', function (done) { -// var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, account.secondPassword); -// -// postTransaction(transaction, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); -// done(); -// }); -// }); -// }); -// }); +'use strict'; + +var crypto = require('crypto'); +var node = require('./../node.js'); + +var account = node.randomAccount(); +var account2 = node.randomAccount(); +var account3 = node.randomAccount(); + +function postTransaction (transaction, done) { + node.post('/peer/transactions', { + transaction: transaction + }, function (err, res) { + done(err, res); + }); +} + +function sendLISK (params, done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction(params.recipientId, params.amount, params.secret); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(function (err) { + done(err, res); + }); + }); +} + +describe('POST /peer/transactions', function () { + + describe('enabling second signature', function () { + + it('using undefined transaction', function (done) { + postTransaction(undefined, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.contain('Invalid transaction body'); + done(); + }); + }); + + it('using undefined transaction.asset', function (done) { + var transaction = node.lisk.signature.createSignature(node.randomAccount().password, node.randomAccount().password); + + delete transaction.asset; + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.contain('Invalid transaction body'); + done(); + }); + }); + + describe('when account has no funds', function () { + + it('should fail', function (done) { + var transaction = node.lisk.signature.createSignature(node.randomAccount().password, node.randomAccount().password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + }); + + describe('when account has funds', function () { + + before(function (done) { + sendLISK({ + secret: node.gAccount.password, + amount: node.fees.secondPasswordFee + 100000000, + recipientId: account.address + }, done); + }); + + it('should be ok', function (done) { + var transaction = node.lisk.signature.createSignature(account.password, account.secondPassword); + transaction.fee = node.fees.secondPasswordFee; + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + done(); + }); + }); + }); + }); + + describe('using second signature', function () { + + before(function (done) { + node.onNewBlock(function (err) { + done(); + }); + }); + + it('when account does not have one should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('1L', 1, node.gAccount.password, account.secondPassword); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + + it('using blank second passphrase should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, ''); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Missing sender second signature'); + done(); + }); + }); + + it('using fake second signature should fail', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, account.secondPassword); + transaction.signSignature = crypto.randomBytes(64).toString('hex'); + transaction.id = node.lisk.crypto.getId(transaction); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Failed to verify second signature'); + done(); + }); + }); + + it('using valid second passphrase should be ok', function (done) { + var transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: randomAccount.address + }); + var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, account.secondPassword); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + done(); + }); + }); + }); +}); diff --git a/test/api/signatures.js b/test/api/signatures.js index 12cdc454..23cbcd4b 100644 --- a/test/api/signatures.js +++ b/test/api/signatures.js @@ -1,168 +1,168 @@ -// 'use strict'; -// -// var node = require('./../node.js'); -// -// var account = node.randomTxAccount(); -// var account2 = node.randomTxAccount(); -// var account3 = node.randomTxAccount(); -// -// function putSignature (params, done) { -// node.put('/api/signatures', params, done); -// } -// -// function putTransaction (params, done) { -// node.put('/api/transactions', params, done); -// } -// -// function putDelegate (params, done) { -// node.put('/api/delegates', params, done); -// } -// -// // function sendLISK (account, done) { -// // var randomLISK = node.randomLISK(); -// // var expectedFee = node.expectedFee(randomLISK); -// // -// // putTransaction({ -// // secret: node.gAccount.password, -// // amount: randomLISK, -// // recipientId: account.address -// // }, function (err, res) { -// // node.expect(res.body).to.have.property('success').to.be.ok; -// // done(err, res); -// // }); -// // } -// -// // before(function (done) { -// // setTimeout(function () { -// // sendLISK(account, done); -// // }, 2000); -// // }); -// -// // before(function (done) { -// // setTimeout(function () { -// // sendLISK(account2, done); -// // }, 2000); -// // describe('PUT /api/transactions from account with second signature enabled', function () { -// // -// // before(function (done) { -// // node.onNewBlock(done); -// // }); -// // -// // var validParams; -// // -// // beforeEach(function (done) { -// // validParams = { -// // secret: account.password, -// // secondSecret: account.password, -// // recipientId: account2.address, -// // amount: 100000000 -// // }; -// // done(); -// // }); -// // -// // it('using no second passphase should fail', function (done) { -// // delete validParams.secondSecret; -// // -// // putTransaction(validParams, function (err, res) { -// // node.expect(res.body).to.have.property('success').to.be.not.ok; -// // node.expect(res.body).to.have.property('error'); -// // done(); -// // }); -// // }); -// // -// // it('using second passphase but no primary passphase should fail', function (done) { -// // delete validParams.secret; -// // -// // putTransaction(validParams, function (err, res) { -// // node.expect(res.body).to.have.property('success').to.be.not.ok; -// // node.expect(res.body).to.have.property('error'); -// // done(); -// // }); -// // }); -// // }); -// -// // }); -// -// describe('PUT /api/signatures', function () { -// -// before(function (done) { -// node.onNewBlock(done); -// }); -// -// var validParams; -// -// beforeEach(function (done) { -// validParams = { -// secret: account.password, -// secondSecret: account.secondPassword -// }; -// done(); -// }); -// -// it('when account has no funds should fail', function (done) { -// validParams.secret = account3.password; -// validParams.secondSecret = account3.password; -// -// putSignature(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// -// it('using invalid passphrase should fail', function (done) { -// validParams.secret = 'invalid'; -// -// putSignature(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error').to.match(/Account does not have enough LSK: [0-9]+L balance: 0/); -// done(); -// }); -// }); -// -// it('using no second passphrase should fail', function (done) { -// delete validParams.secondSecret; -// -// putSignature(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using valid parameters should be ok', function (done) { -// putSignature(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('transaction').that.is.an('object'); -// node.expect(res.body.transaction).to.have.property('type').to.equal(node.txTypes.SIGNATURE); -// node.expect(res.body.transaction).to.have.property('senderPublicKey').to.equal(account.publicKey); -// node.expect(res.body.transaction).to.have.property('senderId').to.equal(account.address); -// node.expect(res.body.transaction).to.have.property('fee').to.equal(node.fees.secondPasswordFee); -// done(); -// }); -// }); -// }); -// -// describe('PUT /api/delegates from account with second signature enabled', function () { -// -// var validParams; -// -// beforeEach(function (done) { -// validParams = { -// secret: account.password, -// secondSecret: account.password, -// username: account.delegateName -// }; -// done(); -// }); -// -// it('using no second passphase should fail', function (done) { -// delete validParams.secondSecret; -// -// putDelegate(validParams, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// }); +'use strict'; + +var node = require('./../node.js'); + +var account = node.randomTxAccount(); +var account2 = node.randomTxAccount(); +var account3 = node.randomTxAccount(); + +function putSignature (params, done) { + node.put('/api/signatures', params, done); +} + +function putTransaction (params, done) { + node.put('/api/transactions', params, done); +} + +function putDelegate (params, done) { + node.put('/api/delegates', params, done); +} + +function sendLISK (account, done) { + var randomLISK = node.randomLISK(); + var expectedFee = node.expectedFee(randomLISK); + + putTransaction({ + secret: node.gAccount.password, + amount: randomLISK, + recipientId: account.address + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + done(err, res); + }); +} + +before(function (done) { + setTimeout(function () { + sendLISK(account, done); + }, 2000); +}); + +before(function (done) { + setTimeout(function () { + sendLISK(account2, done); + }, 2000); + describe('PUT /api/transactions from account with second signature enabled', function () { + + before(function (done) { + node.onNewBlock(done); + }); + + var validParams; + + beforeEach(function (done) { + validParams = { + secret: account.password, + secondSecret: account.password, + recipientId: account2.address, + amount: 100000000 + }; + done(); + }); + + it('using no second passphase should fail', function (done) { + delete validParams.secondSecret; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using second passphase but no primary passphase should fail', function (done) { + delete validParams.secret; + + putTransaction(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + }); + +}); + +describe('PUT /api/signatures', function () { + + before(function (done) { + node.onNewBlock(done); + }); + + var validParams; + + beforeEach(function (done) { + validParams = { + secret: account.password, + secondSecret: account.secondPassword + }; + done(); + }); + + it('when account has no funds should fail', function (done) { + validParams.secret = account3.password; + validParams.secondSecret = account3.password; + + putSignature(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + + it('using invalid passphrase should fail', function (done) { + validParams.secret = 'invalid'; + + putSignature(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + done(); + }); + }); + + it('using no second passphrase should fail', function (done) { + delete validParams.secondSecret; + + putSignature(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using valid parameters should be ok', function (done) { + putSignature(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction').that.is.an('object'); + node.expect(res.body.transaction).to.have.property('type').to.equal(node.txTypes.SIGNATURE); + node.expect(res.body.transaction).to.have.property('senderPublicKey').to.equal(account.publicKey); + node.expect(res.body.transaction).to.have.property('senderId').to.equal(account.address); + node.expect(res.body.transaction).to.have.property('fee').to.equal(node.fees.secondPasswordFee); + done(); + }); + }); +}); + +describe('PUT /api/delegates from account with second signature enabled', function () { + + var validParams; + + beforeEach(function (done) { + validParams = { + secret: account.password, + secondSecret: account.password, + username: account.delegateName + }; + done(); + }); + + it('using no second passphase should fail', function (done) { + delete validParams.secondSecret; + + putDelegate(validParams, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); +}); diff --git a/test/common/initModule.js b/test/common/initModule.js index b58e1ebb..bcdee4be 100644 --- a/test/common/initModule.js +++ b/test/common/initModule.js @@ -8,10 +8,10 @@ var _ = require('lodash'); var async = require('../node').async; var dirname = path.join(__dirname, '..', '..'); -var config = require(path.join(dirname, '/config.json')); +var config = require(path.join(dirname, 'test/config.json')); // use Testnet config var packageJson = require(path.join(dirname, '/package.json')); var database = require(path.join(dirname, '/helpers', 'database.js')); -var genesisblock = require(path.join(dirname, '/genesisBlock.json')); +var genesisblock = require(path.join(dirname, 'test/genesisBlock.json')); // use Testnet genesisBlock var Logger = require(dirname + '/logger.js'); var z_schema = require('../../helpers/z_schema.js'); var cacheHelper = require('../../helpers/cache.js'); @@ -61,7 +61,8 @@ var modulesLoader = new function () { new Account(scope.db, scope.schema, scope.logger, cb); } }, function (err, result) { - new Logic(scope.db, scope.ed, scope.schema, scope.genesisblock, result.account, scope.logger, cb); + // null is for clientWs + new Logic(scope.db, scope.ed, scope.schema, scope.genesisblock, result.account, scope.logger, null, cb); }); break; case 'Block': @@ -70,7 +71,8 @@ var modulesLoader = new function () { return new Account(scope.db, scope.schema, scope.logger, waterCb); }, function (account, waterCb) { - return new Transaction(scope.db, scope.ed, scope.schema, scope.genesisblock, account, scope.logger, waterCb); + // null is for clientWs + return new Transaction(scope.db, scope.ed, scope.schema, scope.genesisblock, account, scope.logger, null, waterCb); } ], function (err, transaction) { new Logic(scope.ed, scope.schema, transaction, cb); diff --git a/test/index.js b/test/index.js index 6211a50a..99380af4 100644 --- a/test/index.js +++ b/test/index.js @@ -7,7 +7,7 @@ require('./unit/modules/blocks/verify.js'); require('./api/accounts'); require('./api/blocks'); -// require('./api/dapps'); +require('./api/dapps'); require('./api/delegates'); require('./api/loader'); require('./api/multisignatures'); diff --git a/test/node.js b/test/node.js index 7e31ff9a..873742a0 100644 --- a/test/node.js +++ b/test/node.js @@ -16,7 +16,7 @@ var packageJson = require('../package.json'); // Requires node.bignum = require('../helpers/bignum.js'); -node.config = require('../config.json'); +node.config = require('./config.json'); // use Testnet config node.constants = require('../helpers/constants.js'); node.txTypes = require('../helpers/transactionTypes.js'); node.accounts = require('../helpers/accounts.js'); @@ -33,12 +33,13 @@ node.supertest = require('supertest'); require('colors'); // Node configuration -node.baseUrl = 'http://' + node.config.address + ':' + node.config.port; +// node.baseUrl = 'http://' + node.config.address + ':' + node.config.port; +node.baseUrl = 'http://' + node.config.peers.list[1].ip + ':' + node.config.peers.list[1].port; node.api = node.supertest(node.baseUrl); node.normalizer = 100000000; // Use this to convert LISK amount to normal value -node.blockTime = 10000; // Block time in miliseconds -node.blockTimePlus = 12000; // Block time + 2 seconds in miliseconds +node.blockTime = 10000; // Block time in milliseconds +node.blockTimePlus = 12000; // Block time + 2 seconds in milliseconds node.version = packageJson.version; // Node version // Transaction fees @@ -53,10 +54,12 @@ node.fees = { }; // Test application -// node.guestbookDapp = { -// icon: 'https://raw.githubusercontent.com/MaxKK/guestbookDapp/master/icon.png', -// link: 'https://github.com/MaxKK/guestbookDapp/archive/master.zip' -// }; +node.guestbookDapp = { + icon: 'https://adamant.im/img/logos/admgrad.png', + link: 'https://adamant.im/img/media_pack.zip' +}; +node.dappCategories = require('../helpers/dappCategories.js'); +node.dappTypes = require('../helpers/dappTypes.js'); const validSender = { username: null, @@ -96,6 +99,11 @@ node.marketDelegate = _.defaults({ secret: 'rally clean ladder crane gadget century timber jealous shine scorpion beauty salon' },validSender); +// return a (Buffer) from a passphrase +node.createKeypairFromPassphrase = function (passphrase) { + return node.accounts.makeKeypair(node.accounts.createPassPhraseHash(passphrase)); +}; + // Existing delegate account // TODO: replace me with a market delegate node.eAccount = { @@ -105,12 +113,13 @@ node.eAccount = { code: 'kind' }; -// Genesis account, initially holding 100M total supply +// Genesis account, initially holding 98M total supply node.gAccount = { address: 'U15365455923155964650', publicKey: 'b80bb6459608dcdeb9a98d1f2b0111b2bf11e53ef2933e6769bb0198e3a97aae', password: 'neck want coast appear army smile palm major crumble upper void warm' }; +node.gAccount.keypair = node.createKeypairFromPassphrase(node.gAccount.password); node.iAccount = { address: 'U5338684603617333081', @@ -118,6 +127,7 @@ node.iAccount = { password: 'floor myself rather hidden pepper make isolate vintage review flight century label', balance: '1960000000000000' }; +node.iAccount.keypair = node.createKeypairFromPassphrase(node.iAccount.password); node.gAccount = node.iAccount; @@ -224,6 +234,7 @@ node.createSendTransaction = function (data) { transaction.amount = data.amount; transaction.signature = this.transactionSign(transaction, data.keyPair); transaction.id = this.getId(transaction); + transaction.fee = this.constants.fees.send; return transaction; }; @@ -529,7 +540,7 @@ node.waitForNewBlock = function (height, blocksToWait, cb) { node.debug(' Waiting for block:'.grey, 'Height:'.grey, res.body.height, 'Target:'.grey, target, 'Second:'.grey, counter++); - if (target === res.body.height) { + if (res.body.height >= target) { height = res.body.height; } @@ -667,6 +678,7 @@ node.randomAccount = function () { account.username = node.randomDelegate; const keypair = node.accounts.makeKeypair(node.accounts.createPassPhraseHash(account.password)); account.publicKey = keypair.publicKey; //node.lisk.crypto.getKeys(account.password).publicKey; + account.publicKeyHex = keypair.publicKey.toString('hex'); account.address = node.accounts.getAddressByPublicKey(account.publicKey); //node.lisk.crypto.getAddress(account.publicKey); account.keypair = keypair; return account; diff --git a/test/unit/logic/multisignature.js b/test/unit/logic/multisignature.js index 7b6ec7e0..10f6d534 100644 --- a/test/unit/logic/multisignature.js +++ b/test/unit/logic/multisignature.js @@ -1,363 +1,363 @@ -// 'use strict';/*eslint*/ -// -// var node = require('./../../node.js'); -// var ed = require('../../../helpers/ed'); -// var crypto = require('crypto'); -// var async = require('async'); -// -// var chai = require('chai'); -// var expect = require('chai').expect; -// var sinon = require('sinon'); -// var _ = require('lodash'); -// var transactionTypes = require('../../../helpers/transactionTypes'); -// var constants = require('../../../helpers/constants'); -// -// var modulesLoader = require('../../common/initModule').modulesLoader; -// var Transaction = require('../../../logic/transaction.js'); -// var Rounds = require('../../../modules/rounds.js'); -// var AccountLogic = require('../../../logic/account.js'); -// var AccountModule = require('../../../modules/accounts.js'); -// -// var Multisignature = require('../../../logic/multisignature.js'); -// -// var validPassword = 'robust weapon course unknown head trial pencil latin acid'; -// var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); -// -// var validSender = { -// address: '16313739661670634666L', -// publicKey: 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', -// password: 'wagon stock borrow episode laundry kitten salute link globe zero feed marble', -// balance: '10000000000000000' -// }; -// -// var senderHash = crypto.createHash('sha256').update(validSender.password, 'utf8').digest(); -// var senderKeypair = ed.makeKeypair(senderHash); -// -// var multiSigAccount1 = { -// balance: '0', -// password: 'jcja4vxibnw5dayk3xr', -// secondPassword: '0j64m005jyjj37bpdgqfr', -// username: 'LP', -// publicKey: 'bd6d0388dcc0b07ab2035689c60a78d3ebb27901c5a5ed9a07262eab1a2e9bd2', -// address: '5936324907841470379L' -// }; -// -// var multiSigAccount2 = { -// address: '10881167371402274308L', -// publicKey: 'addb0e15a44b0fdc6ff291be28d8c98f5551d0cd9218d749e30ddb87c6e31ca9', -// password: 'actress route auction pudding shiver crater forum liquid blouse imitate seven front', -// balance: '0', -// delegateName: 'genesis_100' -// }; -// -// describe('multisignature', function () { -// -// var transaction; -// var multisignature; -// var trs; -// var sender; -// -// var attachMultiSigAsset = function (transaction, accountLogic, rounds, done) { -// modulesLoader.initModuleWithDb(AccountModule, function (err, __accountModule) { -// multisignature = new Multisignature(modulesLoader.scope.schema, modulesLoader.scope.network, transaction, modulesLoader.logger); -// multisignature.bind(__accountModule, rounds); -// transaction.attachAssetType(transactionTypes.MULTI, multisignature); -// done(); -// }, { -// logic: { -// account: accountLogic, -// transaction: transaction -// } -// }); -// }; -// -// before(function (done) { -// async.auto({ -// rounds: function (cb) { -// modulesLoader.initModule(Rounds, modulesLoader.scope,cb); -// }, -// accountLogic: function (cb) { -// modulesLoader.initLogicWithDb(AccountLogic, cb); -// }, -// transaction: ['accountLogic', function (result, cb) { -// modulesLoader.initLogicWithDb(Transaction, cb, { -// ed: require('../../../helpers/ed'), -// account: result.accountLogic -// }); -// }] -// }, function (err, result) { -// transaction = result.transaction; -// transaction.bindModules(result); -// attachMultiSigAsset(transaction, result.accountLogic, result.rounds, done); -// }); -// }); -// -// beforeEach(function () { -// sender = _.cloneDeep(validSender); -// }); -// -// describe('objectNormalize', function () { -// -// describe('min', function () { -// -// it('should return error when value is not an integer', function () { -// var min = '2'; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); -// trs.asset.multisignature.min = min; -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Expected type integer but found type string'); -// }); -// -// it('should return error when value is a negative integer', function () { -// var min = -1; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); -// trs.asset.multisignature.min = min; -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Value -1 is less than minimum 1'); -// }); -// -// it('should return error when value is smaller than minimum acceptable value', function () { -// var min = constants.multisigConstraints.min.minimum - 1; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, min); -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Value 0 is less than minimum 1'); -// }); -// -// it('should return error when value is greater than maximum acceptable value', function () { -// var min = constants.multisigConstraints.min.maximum + 1; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, min); -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Value 16 is greater than maximum 15'); -// }); -// -// it('should return error when value is an overflow number', function () { -// var min = Number.MAX_VALUE + 1; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); -// trs.asset.multisignature.min = min; -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Value 1.7976931348623157e+308 is greater than maximum 15'); -// }); -// }); -// -// describe('lifetime', function () { -// -// it('should return error when value is not an integer', function () { -// var lifetime = '2'; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); -// trs.asset.multisignature.lifetime = lifetime; -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Expected type integer but found type string'); -// }); -// -// it('should return error when value is smaller than minimum acceptable value', function () { -// var lifetime = node.constants.multisigConstraints.lifetime.minimum - 1; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], lifetime, 2); -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Value 0 is less than minimum 1'); -// }); -// -// it('should return error when value is greater than maximum acceptable value', function () { -// var lifetime = node.constants.multisigConstraints.lifetime.maximum + 1; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], lifetime, 2); -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Value 73 is greater than maximum 72'); -// }); -// -// it('should return error when value is an overflow number', function () { -// var lifetime = Number.MAX_VALUE; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); -// trs.asset.multisignature.lifetime = lifetime; -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Value 1.7976931348623157e+308 is greater than maximum 72'); -// }); -// }); -// -// describe('keysgroup', function () { -// -// it('should return error when it is not an array', function () { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, [''], 1, 2); -// trs.asset.multisignature.keysgroup = ''; -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Expected type array but found type string'); -// }); -// -// it('should return error when array length is smaller than minimum acceptable value', function () { -// var keysgroup = []; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, keysgroup, 1, 2); -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Array is too short (0), minimum 1'); -// }); -// -// it('should return error when array length is greater than maximum acceptable value', function () { -// var keysgroup = Array.apply(null, Array(constants.multisigConstraints.keysgroup.maxItems + 1)).map(function () { -// return '+' + node.lisk.crypto.getKeys(node.randomPassword()).publicKey; -// }); -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, keysgroup, 1, 2); -// -// expect(function () { -// multisignature.objectNormalize.call(transaction, trs); -// }).to.throw('Failed to validate multisignature schema: Array is too long (16), maximum 15'); -// }); -// }); -// -// it('should return transaction when asset is valid', function () { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, Array.apply(null, Array(10)).map(function () { -// return '+' + node.lisk.crypto.getKeys(node.randomPassword()).publicKey; -// }), 1, 2); -// -// expect(multisignature.objectNormalize(trs)).to.eql(trs); -// }); -// }); -// -// describe('verify', function () { -// -// describe('from transaction.verify tests', function () { -// -// it('should return error when multisignature keysgroup has an entry which does not start with + character', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); -// trs.senderId = node.gAccount.address; -// -// transaction.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.equal('Invalid math operator in multisignature keysgroup'); -// done(); -// }); -// }); -// -// it('should return error when multisignature keysgroup has an entry which is null', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, null], 1, 2); -// trs.senderId = node.gAccount.address; -// -// transaction.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('should return error when multisignature keysgroup has an entry which is undefined', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, undefined], 1, 2); -// trs.senderId = node.gAccount.address; -// -// transaction.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('should return error when multisignature keysgroup has an entry which is an integer', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, 12], 1, 2); -// trs.senderId = node.gAccount.address; -// -// transaction.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('should be okay for valid transaction', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); -// trs.senderId = node.gAccount.address; -// -// transaction.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.not.exist; -// done(); -// }); -// }); -// }); -// }); -// -// describe('from multisignature.verify tests', function () { -// -// it('should return error when min value is smaller than minimum acceptable value', function (done) { -// var min = constants.multisigConstraints.min.minimum - 1; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 1); -// trs.asset.multisignature.min = min; -// -// multisignature.verify(trs, node.gAccount, function (err) { -// expect(err).to.equal('Invalid multisignature min. Must be between 1 and 15'); -// done(); -// }); -// }); -// -// it('should return error when min value is greater than maximum acceptable value', function (done) { -// var min = constants.multisigConstraints.min.maximum + 1; -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, min); -// -// multisignature.verify(trs, node.gAccount, function (err) { -// expect(err).to.equal('Invalid multisignature min. Must be between 1 and 15'); -// done(); -// }); -// }); -// -// it('should return error when multisignature keysgroup has an entry which does not start with + character', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); -// trs.senderId = node.gAccount.address; -// -// multisignature.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.equal('Invalid math operator in multisignature keysgroup'); -// done(); -// }); -// }); -// -// it('should return error when multisignature keysgroup has an entry which is null', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, null], 1, 2); -// trs.senderId = node.gAccount.address; -// -// multisignature.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('should return error when multisignature keysgroup has an entry which is undefined', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, undefined], 1, 2); -// trs.senderId = node.gAccount.address; -// -// multisignature.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('should return error when multisignature keysgroup has an entry which is an integer', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, 12], 1, 2); -// trs.senderId = node.gAccount.address; -// -// multisignature.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.equal('Invalid member in keysgroup'); -// done(); -// }); -// }); -// -// it('should be okay for valid transaction', function (done) { -// var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); -// trs.senderId = node.gAccount.address; -// -// multisignature.verify(trs, node.gAccount, function (err, trs) { -// expect(err).to.not.exist; -// done(); -// }); -// }); -// }); -// }); +'use strict';/*eslint*/ + +var node = require('./../../node.js'); +var ed = require('../../../helpers/ed'); +var crypto = require('crypto'); +var async = require('async'); + +var chai = require('chai'); +var expect = require('chai').expect; +var sinon = require('sinon'); +var _ = require('lodash'); +var transactionTypes = require('../../../helpers/transactionTypes'); +var constants = require('../../../helpers/constants'); + +var modulesLoader = require('../../common/initModule').modulesLoader; +var Transaction = require('../../../logic/transaction.js'); +var Rounds = require('../../../modules/rounds.js'); +var AccountLogic = require('../../../logic/account.js'); +var AccountModule = require('../../../modules/accounts.js'); + +var Multisignature = require('../../../logic/multisignature.js'); + +var validPassword = 'robust weapon course unknown head trial pencil latin acid'; +var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); + +var validSender = { + address: '16313739661670634666L', + publicKey: 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', + password: 'wagon stock borrow episode laundry kitten salute link globe zero feed marble', + balance: '10000000000000000' +}; + +var senderHash = crypto.createHash('sha256').update(validSender.password, 'utf8').digest(); +var senderKeypair = ed.makeKeypair(senderHash); + +var multiSigAccount1 = { + balance: '0', + password: 'jcja4vxibnw5dayk3xr', + secondPassword: '0j64m005jyjj37bpdgqfr', + username: 'LP', + publicKey: 'bd6d0388dcc0b07ab2035689c60a78d3ebb27901c5a5ed9a07262eab1a2e9bd2', + address: '5936324907841470379L' +}; + +var multiSigAccount2 = { + address: '10881167371402274308L', + publicKey: 'addb0e15a44b0fdc6ff291be28d8c98f5551d0cd9218d749e30ddb87c6e31ca9', + password: 'actress route auction pudding shiver crater forum liquid blouse imitate seven front', + balance: '0', + delegateName: 'genesis_100' +}; + +describe('multisignature', function () { + + var transaction; + var multisignature; + var trs; + var sender; + + var attachMultiSigAsset = function (transaction, accountLogic, rounds, done) { + modulesLoader.initModuleWithDb(AccountModule, function (err, __accountModule) { + multisignature = new Multisignature(modulesLoader.scope.schema, modulesLoader.scope.network, transaction, modulesLoader.logger); + multisignature.bind(__accountModule, rounds); + transaction.attachAssetType(transactionTypes.MULTI, multisignature); + done(); + }, { + logic: { + account: accountLogic, + transaction: transaction + } + }); + }; + + before(function (done) { + async.auto({ + rounds: function (cb) { + modulesLoader.initModule(Rounds, modulesLoader.scope,cb); + }, + accountLogic: function (cb) { + modulesLoader.initLogicWithDb(AccountLogic, cb); + }, + transaction: ['accountLogic', function (result, cb) { + modulesLoader.initLogicWithDb(Transaction, cb, { + ed: require('../../../helpers/ed'), + account: result.accountLogic + }); + }] + }, function (err, result) { + transaction = result.transaction; + transaction.bindModules(result); + attachMultiSigAsset(transaction, result.accountLogic, result.rounds, done); + }); + }); + + beforeEach(function () { + sender = _.cloneDeep(validSender); + }); + + describe('objectNormalize', function () { + + describe('min', function () { + + it('should return error when value is not an integer', function () { + var min = '2'; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); + trs.asset.multisignature.min = min; + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Expected type integer but found type string'); + }); + + it('should return error when value is a negative integer', function () { + var min = -1; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); + trs.asset.multisignature.min = min; + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Value -1 is less than minimum 1'); + }); + + it('should return error when value is smaller than minimum acceptable value', function () { + var min = constants.multisigConstraints.min.minimum - 1; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, min); + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Value 0 is less than minimum 1'); + }); + + it('should return error when value is greater than maximum acceptable value', function () { + var min = constants.multisigConstraints.min.maximum + 1; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, min); + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Value 16 is greater than maximum 15'); + }); + + it('should return error when value is an overflow number', function () { + var min = Number.MAX_VALUE + 1; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + trs.asset.multisignature.min = min; + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Value 1.7976931348623157e+308 is greater than maximum 15'); + }); + }); + + describe('lifetime', function () { + + it('should return error when value is not an integer', function () { + var lifetime = '2'; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + trs.asset.multisignature.lifetime = lifetime; + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Expected type integer but found type string'); + }); + + it('should return error when value is smaller than minimum acceptable value', function () { + var lifetime = node.constants.multisigConstraints.lifetime.minimum - 1; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], lifetime, 2); + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Value 0 is less than minimum 1'); + }); + + it('should return error when value is greater than maximum acceptable value', function () { + var lifetime = node.constants.multisigConstraints.lifetime.maximum + 1; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], lifetime, 2); + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Value 73 is greater than maximum 72'); + }); + + it('should return error when value is an overflow number', function () { + var lifetime = Number.MAX_VALUE; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + trs.asset.multisignature.lifetime = lifetime; + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Value 1.7976931348623157e+308 is greater than maximum 72'); + }); + }); + + describe('keysgroup', function () { + + it('should return error when it is not an array', function () { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, [''], 1, 2); + trs.asset.multisignature.keysgroup = ''; + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Expected type array but found type string'); + }); + + it('should return error when array length is smaller than minimum acceptable value', function () { + var keysgroup = []; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, keysgroup, 1, 2); + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Array is too short (0), minimum 1'); + }); + + it('should return error when array length is greater than maximum acceptable value', function () { + var keysgroup = Array.apply(null, Array(constants.multisigConstraints.keysgroup.maxItems + 1)).map(function () { + return '+' + node.randomAccount().publicKey; + }); + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, keysgroup, 1, 2); + + expect(function () { + multisignature.objectNormalize.call(transaction, trs); + }).to.throw('Failed to validate multisignature schema: Array is too long (16), maximum 15'); + }); + }); + + it('should return transaction when asset is valid', function () { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, Array.apply(null, Array(10)).map(function () { + return '+' + node.randomAccount().publicKey; + }), 1, 2); + + expect(multisignature.objectNormalize(trs)).to.eql(trs); + }); + }); + + describe('verify', function () { + + describe('from transaction.verify tests', function () { + + it('should return error when multisignature keysgroup has an entry which does not start with + character', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + trs.senderId = node.gAccount.address; + + transaction.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.equal('Invalid math operator in multisignature keysgroup'); + done(); + }); + }); + + it('should return error when multisignature keysgroup has an entry which is null', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, null], 1, 2); + trs.senderId = node.gAccount.address; + + transaction.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('should return error when multisignature keysgroup has an entry which is undefined', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, undefined], 1, 2); + trs.senderId = node.gAccount.address; + + transaction.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('should return error when multisignature keysgroup has an entry which is an integer', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, 12], 1, 2); + trs.senderId = node.gAccount.address; + + transaction.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('should be okay for valid transaction', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); + trs.senderId = node.gAccount.address; + + transaction.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.not.exist; + done(); + }); + }); + }); + }); + + describe('from multisignature.verify tests', function () { + + it('should return error when min value is smaller than minimum acceptable value', function (done) { + var min = constants.multisigConstraints.min.minimum - 1; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 1); + trs.asset.multisignature.min = min; + + multisignature.verify(trs, node.gAccount, function (err) { + expect(err).to.equal('Invalid multisignature min. Must be between 1 and 15'); + done(); + }); + }); + + it('should return error when min value is greater than maximum acceptable value', function (done) { + var min = constants.multisigConstraints.min.maximum + 1; + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, min); + + multisignature.verify(trs, node.gAccount, function (err) { + expect(err).to.equal('Invalid multisignature min. Must be between 1 and 15'); + done(); + }); + }); + + it('should return error when multisignature keysgroup has an entry which does not start with + character', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + trs.senderId = node.gAccount.address; + + multisignature.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.equal('Invalid math operator in multisignature keysgroup'); + done(); + }); + }); + + it('should return error when multisignature keysgroup has an entry which is null', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, null], 1, 2); + trs.senderId = node.gAccount.address; + + multisignature.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('should return error when multisignature keysgroup has an entry which is undefined', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, undefined], 1, 2); + trs.senderId = node.gAccount.address; + + multisignature.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('should return error when multisignature keysgroup has an entry which is an integer', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, 12], 1, 2); + trs.senderId = node.gAccount.address; + + multisignature.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.equal('Invalid member in keysgroup'); + done(); + }); + }); + + it('should be okay for valid transaction', function (done) { + var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); + trs.senderId = node.gAccount.address; + + multisignature.verify(trs, node.gAccount, function (err, trs) { + expect(err).to.not.exist; + done(); + }); + }); + }); +}); diff --git a/test/unit/modules/blocks/verify.js b/test/unit/modules/blocks/verify.js index 39ae37a1..511280e3 100644 --- a/test/unit/modules/blocks/verify.js +++ b/test/unit/modules/blocks/verify.js @@ -1,477 +1,477 @@ -// 'use strict'; -// -// var expect = require('chai').expect; -// var modulesLoader = require('../../../common/initModule').modulesLoader; -// var BlockLogic = require('../../../../logic/block.js'); -// var exceptions = require('../../../../helpers/exceptions.js'); -// -// var previousBlock = { -// blockSignature: 'a74cd53bebf9cf003cfd5fed8c053e1b64660e89a654078ff3341348145bbb0f34d1bde4a254b139ebae03117b346a2aab77fc8607eed9c7431db5eb4d4cbe0b', -// generatorPublicKey:'377bfcc233fdba3039d9fbb8c7d8d97e1087d52941e5661b9c55b59c57f8fafe', -// height: 42394, -// id: '1553572419982003786', -// numberOfTransactions: 0, -// payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', -// payloadLength: 0, -// previousBlock: '2541382865961110750', -// relays: 1, -// reward: 0, -// timestamp: 39674945, -// totalAmount: 0, -// totalFee: 0, -// transactions: [], -// version: 0, -// }; -// -// var validBlock = { -// blockSignature: '08d70794b3fd90be5d14fd02f512c56485d4bac071ccf98188833242a7d84dfd9c98bc3cf6b7eecb6231dc94da82a275002d1913f60809e98d64f9892e98d303', -// generatorPublicKey: '747d370dc479a7d684e3b61d8c75716f3bc91afcf9e5d3eeaeb557753d757ac4', -// numberOfTransactions: 0, -// payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', -// payloadLength: 0, -// previousBlock: '1553572419982003786', -// reward: 0, -// timestamp: 39674950, -// totalAmount: 0, -// totalFee: 0, -// transactions: [], -// version: 0, -// id: '10000428847403166564' -// }; -// -// var blockRewardInvalid = { -// blockSignature: '08d70794b3fd90be5d14fd02f512c56485d4bac071ccf98188833242a7d84dfd9c98bc3cf6b7eecb6231dc94da82a275002d1913f60809e98d64f9892e98d303', -// generatorPublicKey: '747d370dc479a7d684e3b61d8c75716f3bc91afcf9e5d3eeaeb557753d757ac4', -// numberOfTransactions: 0, -// payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', -// payloadLength: 0, -// previousBlock: '1553572419982003786', -// reward: 0, -// timestamp: 39674950, -// totalAmount: 0, -// totalFee: 0, -// transactions: [], -// version: 0, -// id: '10000428847403166564' -// }; -// -// var validBlockWithPayload = { -// blockSignature: '25ea76424044e76a47ab2f1854d553f3aa24437f37af7acbabeb50ce27c42f340ad890103d1c96862224dbd4590c787cf47497131214842c57a0cc8801366e0a', -// generatorPublicKey: '7c7b92b7d2159e5652bc942fdb9d6dbee77d1b120f488960966ce0850d819b05', -// numberOfTransactions: 3, -// height: 24134, -// payloadHash: '81de7bd1606eaca88b8f835b11682668afba47439a5468fce5288b5b7b6280d4', -// payloadLength: 364, -// previousBlock: '8741947515519892818', -// reward: 0, -// timestamp: 39555010, -// totalAmount: 0, -// totalFee: 300000, -// transactions: [ -// { -// type: 8, -// amount: 0, -// fee: 100000, -// timestamp: 39555007, -// recipientId: 'U6891492430527629853', -// senderId: 'U2967613837320252358', -// senderPublicKey: 'f7f46c3c8b4a21ef50613565a3c4b0289fcb304af57638c12d218ef9463a1b48', -// signature: 'e4429551a936430477e16e7d6b98420f8e8cf180105658f9306c1948bfcb1083a87dfa3610dac4e5bc73ce43b061ac20de3c456b217258e6f85a85880e5bc000', -// id: '14322431483774644897', -// asset: { -// chat: { -// message: 'end remove mansion next task say dynamic woman response feature ceiling mixed' -// } -// } -// } -// ], -// version: 0, -// id: '15642998233669588601' -// }; -// -// describe('blocks/verify', function () { -// -// var blocksVerify; -// var blocks; -// var blockLogic; -// var accounts; -// var delegates; -// -// before(function (done) { -// modulesLoader.initLogic(BlockLogic, modulesLoader.scope, function (err, __blockLogic) { -// if (err) { -// return done(err); -// } -// blockLogic = __blockLogic; -// -// modulesLoader.initModules([ -// {blocks: require('../../../../modules/blocks')}, -// {accounts: require('../../../../modules/accounts')}, -// {delegates: require('../../../../modules/delegates')}, -// {transactions: require('../../../../modules/transactions')}, -// {transport: require('../../../../modules/transport')}, -// {system: require('../../../../modules/system')}, -// ], [ -// {'block': require('../../../../logic/block')}, -// {'transaction': require('../../../../logic/transaction')}, -// {'account': require('../../../../logic/account')}, -// ], {}, function (err, __modules) { -// if (err) { -// return done(err); -// } -// __modules.blocks.verify.onBind(__modules); -// __modules.delegates.onBind(__modules); -// __modules.transactions.onBind(__modules); -// __modules.blocks.chain.onBind(__modules); -// __modules.transport.onBind(__modules); -// blocks = __modules.blocks; -// blocksVerify = __modules.blocks.verify; -// accounts = __modules.accounts; -// delegates = __modules.delegates; -// -// done(); -// }); -// }); -// }); -// -// function testValid (functionName) { -// it('should be ok', function () { -// blocks.lastBlock.set(previousBlock); -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.verified).to.be.true; -// expect(result.errors).to.be.an('array').that.is.empty; -// }); -// -// it('should be ok when block is invalid but block id is excepted for having invalid block reward', function () { -// exceptions.blockRewards.push(blockRewardInvalid.id); -// -// var result = blocksVerify[functionName](blockRewardInvalid); -// -// expect(result.verified).to.be.true; -// expect(result.errors).to.be.an('array').that.is.empty; -// }); -// } -// -// function testSetHeight (functionName) { -// it('should set height from lastBlock', function () { -// blocks.lastBlock.set(previousBlock); -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.verified).to.be.true; -// expect(result.errors).to.be.an('array').that.is.empty; -// expect(validBlock.height).to.equal(previousBlock.height + 1); -// }); -// } -// -// function testVerifySignature (functionName) { -// it('should fail when blockSignature property is not a hex string', function () { -// var blockSignature = validBlock.blockSignature; -// validBlock.blockSignature = 'invalidBlockSignature'; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// -// expect(result.errors[1]).to.equal('Error: argument signature must be 64U bytes long, but got a different value'); -// expect(result.errors[0]).to.equal('Failed to verify block signature'); -// -// validBlock.blockSignature = blockSignature; -// }); -// -// it('should fail when blockSignature property is an invalid hex string', function () { -// var blockSignature = validBlock.blockSignature; -// validBlock.blockSignature = 'bfaaabdc8612e177f1337d225a8a5af18cf2534f9e41b66c114850aa50ca2ea2621c4b2d34c4a8b62ea7d043e854c8ae3891113543f84f437e9d3c9cb24c0e05'; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(1); -// expect(result.errors[0]).to.equal('Failed to verify block signature'); -// -// validBlock.blockSignature = blockSignature; -// }); -// -// it('should fail when generatorPublicKey property is not a hex string', function () { -// var generatorPublicKey = validBlock.generatorPublicKey; -// validBlock.generatorPublicKey = 'invalidBlockSignature'; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[1]).to.equal('Error: argument publicKey must be 32U bytes long, but got a different value'); -// expect(result.errors[0]).to.equal('Failed to verify block signature'); -// -// validBlock.generatorPublicKey = generatorPublicKey; -// }); -// -// it('should fail when generatorPublicKey property is an invalid hex string', function () { -// var generatorPublicKey = validBlock.generatorPublicKey; -// validBlock.generatorPublicKey = '948b8b509579306694c00db2206ddb1517bfeca2b0dc833ec1c0f81e9644871b'; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(1); -// expect(result.errors[0]).to.equal('Failed to verify block signature'); -// -// validBlock.generatorPublicKey = generatorPublicKey; -// }); -// } -// -// function testPreviousBlock (functionName) { -// it('should fail when previousBlock property is missing', function () { -// var previousBlock = validBlock.previousBlock; -// delete validBlock.previousBlock; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.verified).to.be.false; -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Invalid previous block'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.previousBlock = previousBlock; -// }); -// } -// -// function testVerifyVersion (functionName) { -// it('should fail when block version != 0', function () { -// var version = validBlock.version; -// validBlock.version = 99; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.verified).to.be.false; -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Invalid block version'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.version = version; -// }); -// } -// -// function testVerifyReward (functionName) { -// it('should fail when block reward is invalid', function () { -// validBlock.reward = 99; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal(['Invalid block reward:', 99, 'expected:', 0].join(' ')); -// -// validBlock.reward = 0; -// }); -// } -// -// function testVerifyId (functionName) { -// it('should reset block id when block id is an invalid alpha-numeric string value', function () { -// validBlock.id = 'invalid-block-id'; -// var result = blocksVerify[functionName](validBlock); -// expect(validBlock.id).to.not.equal('invalid-block-id'); -// }); -// -// it('should reset block id when block id is an invalid numeric string value', function () { -// validBlock.id = '11850828211026019526'; -// var result = blocksVerify[functionName](validBlock); -// expect(validBlock.id).to.not.equal('11850828211026019526'); -// }); -// -// it('should reset block id when block id is an invalid integer value', function () { -// validBlock.id = 11850828211026019526; -// var result = blocksVerify[functionName](validBlock); -// expect(validBlock.id).to.not.equal(11850828211026019526); -// }); -// -// it('should reset block id when block id is a valid integer value', function () { -// validBlock.id = 11850828211026019525; -// var result = blocksVerify[functionName](validBlock); -// expect(validBlock.id).to.not.equal(11850828211026019525); -// }); -// } -// -// function testVerifyPayload (functionName) { -// it('should fail when payload length greater than maxPayloadLength constant value', function () { -// var payloadLength = validBlock.payloadLength; -// validBlock.payloadLength = 1024 * 1024 * 2; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Payload length is too long'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.payloadLength = payloadLength; -// }); -// -// it('should fail when transactions length is not equal to numberOfTransactions property', function () { -// validBlock.numberOfTransactions = validBlock.transactions.length + 1; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Included transactions do not match block transactions count'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.numberOfTransactions = validBlock.transactions.length; -// }); -// -// it('should fail when transactions length greater than maxTxsPerBlock constant value', function () { -// var transactions = validBlock.transactions; -// validBlock.transactions = new Array(26); -// validBlock.numberOfTransactions = validBlock.transactions.length; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Number of transactions exceeds maximum per block'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.transactions = transactions; -// validBlock.numberOfTransactions = transactions.length; -// }); -// -// // it('should fail when a transaction is of an unknown type', function () { -// // var trsType = validBlock.transactions[0].type; -// // validBlock.transactions[0].type = 555; -// // -// // var result = blocksVerify[functionName](validBlock); -// // -// // expect(result.errors).to.be.an('array').with.lengthOf(2); -// // expect(result.errors[0]).to.equal('Invalid payload hash'); -// // expect(result.errors[1]).to.equal('Unknown transaction type ' + validBlock.transactions[0].type); -// // -// // validBlock.transactions[0].type = trsType; -// // }); -// // -// // it('should fail when a transaction is duplicated', function () { -// // var secondTrs = validBlock.transactions[1]; -// // validBlock.transactions[1] = validBlock.transactions[0]; -// // -// // var result = blocksVerify[functionName](validBlock); -// // -// // expect(result.errors).to.be.an('array').with.lengthOf(3); -// // expect(result.errors[0]).to.equal('Invalid total amount'); -// // expect(result.errors[1]).to.equal('Invalid payload hash'); -// // expect(result.errors[2]).to.equal('Encountered duplicate transaction: ' + validBlock.transactions[1].id); -// // -// // validBlock.transactions[1] = secondTrs; -// // }); -// -// it('should fail when payload hash is invalid', function () { -// var payloadHash = validBlock.payloadHash; -// validBlock.payloadHash = 'invalidPayloadHash'; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Invalid payload hash'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.payloadHash = payloadHash; -// }); -// -// it('should fail when summed transaction amounts do not match totalAmount property', function () { -// var totalAmount = validBlock.totalAmount; -// validBlock.totalAmount = 99; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Invalid total amount'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.totalAmount = totalAmount; -// }); -// -// it('should fail when summed transaction fees do not match totalFee property', function () { -// var totalFee = validBlock.totalFee; -// validBlock.totalFee = 99; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Invalid total fee'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.totalFee = totalFee; -// }); -// } -// -// function testVerifyForkOne (functionName) { -// it('should fail when previousBlock value is invalid', function () { -// var previousBlock = blocks.lastBlock.get().id; -// validBlock.previousBlock = '10937893559311260102'; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal(['Invalid previous block:', validBlock.previousBlock, 'expected:', previousBlock].join(' ')); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.previousBlock = previousBlock; -// }); -// } -// -// function testVerifyBlockSlot (functionName) { -// it('should fail when block timestamp is less than previousBlock timestamp', function () { -// var timestamp = validBlock.timestamp; -// validBlock.timestamp = 32578350; -// -// var result = blocksVerify[functionName](validBlock); -// -// expect(result.verified).to.be.false; -// expect(result.errors).to.be.an('array').with.lengthOf(2); -// expect(result.errors[0]).to.equal('Invalid block timestamp'); -// expect(result.errors[1]).to.equal('Failed to verify block signature'); -// -// validBlock.timestamp = timestamp; -// }); -// } -// -// describe('verifyReceipt() when block is valid', testValid.bind(null, 'verifyReceipt')); -// -// describe('verifyReceipt() when block is invalid', function () { -// -// describe('calling setHeight()', testSetHeight.bind(null, 'verifyReceipt')); -// -// describe('calling verifySignature()', testVerifySignature.bind(null, 'verifyReceipt')); -// -// describe('calling verifyPreviousBlock()', testPreviousBlock.bind(null, 'verifyReceipt')); -// -// describe('calling verifyVersion()', testVerifyVersion.bind(null, 'verifyReceipt')); -// -// describe('calling verifyReward()', testVerifyReward.bind(null, 'verifyReceipt')); -// -// describe('calling verifyId()', testVerifyId.bind(null, 'verifyReceipt')); -// -// describe('calling verifyPayload()', testVerifyPayload.bind(null, 'verifyReceipt')); -// -// describe.skip('calling verifyForkOne()', testVerifyForkOne); -// -// describe.skip('calling verifyBlockSlot()', testVerifyBlockSlot); -// }); -// -// describe('verifyBlock() when block is valid', testValid.bind(null, 'verifyBlock')); -// -// describe('verifyBlock() when block is invalid', function () { -// -// describe('calling setHeight()', testSetHeight.bind(null, 'verifyBlock')); -// -// describe('calling verifySignature()', testVerifySignature.bind(null, 'verifyBlock')); -// -// describe('calling verifyPreviousBlock()', testPreviousBlock.bind(null, 'verifyBlock')); -// -// describe('calling verifyVersion()', testVerifyVersion.bind(null, 'verifyBlock')); -// -// describe('calling verifyReward()', testVerifyReward.bind(null, 'verifyBlock')); -// -// describe('calling verifyId()', testVerifyId.bind(null, 'verifyBlock')); -// -// describe('calling verifyPayload()', testVerifyPayload.bind(null, 'verifyBlock')); -// -// describe('calling verifyForkOne()', testVerifyForkOne.bind(null, 'verifyBlock')); -// -// describe('calling verifyBlockSlot()', testVerifyBlockSlot.bind(null, 'verifyBlock')); -// }); -// }); +'use strict'; + +var expect = require('chai').expect; +var modulesLoader = require('../../../common/initModule').modulesLoader; +var BlockLogic = require('../../../../logic/block.js'); +var exceptions = require('../../../../helpers/exceptions.js'); + +var previousBlock = { + blockSignature: 'a74cd53bebf9cf003cfd5fed8c053e1b64660e89a654078ff3341348145bbb0f34d1bde4a254b139ebae03117b346a2aab77fc8607eed9c7431db5eb4d4cbe0b', + generatorPublicKey:'377bfcc233fdba3039d9fbb8c7d8d97e1087d52941e5661b9c55b59c57f8fafe', + height: 42394, + id: '1553572419982003786', + numberOfTransactions: 0, + payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + payloadLength: 0, + previousBlock: '2541382865961110750', + relays: 1, + reward: 0, + timestamp: 39674945, + totalAmount: 0, + totalFee: 0, + transactions: [], + version: 0, +}; + +var validBlock = { + blockSignature: '08d70794b3fd90be5d14fd02f512c56485d4bac071ccf98188833242a7d84dfd9c98bc3cf6b7eecb6231dc94da82a275002d1913f60809e98d64f9892e98d303', + generatorPublicKey: '747d370dc479a7d684e3b61d8c75716f3bc91afcf9e5d3eeaeb557753d757ac4', + numberOfTransactions: 0, + payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + payloadLength: 0, + previousBlock: '1553572419982003786', + reward: 0, + timestamp: 39674950, + totalAmount: 0, + totalFee: 0, + transactions: [], + version: 0, + id: '10000428847403166564' +}; + +var blockRewardInvalid = { + blockSignature: '08d70794b3fd90be5d14fd02f512c56485d4bac071ccf98188833242a7d84dfd9c98bc3cf6b7eecb6231dc94da82a275002d1913f60809e98d64f9892e98d303', + generatorPublicKey: '747d370dc479a7d684e3b61d8c75716f3bc91afcf9e5d3eeaeb557753d757ac4', + numberOfTransactions: 0, + payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + payloadLength: 0, + previousBlock: '1553572419982003786', + reward: 0, + timestamp: 39674950, + totalAmount: 0, + totalFee: 0, + transactions: [], + version: 0, + id: '10000428847403166564' +}; + +var validBlockWithPayload = { + blockSignature: '25ea76424044e76a47ab2f1854d553f3aa24437f37af7acbabeb50ce27c42f340ad890103d1c96862224dbd4590c787cf47497131214842c57a0cc8801366e0a', + generatorPublicKey: '7c7b92b7d2159e5652bc942fdb9d6dbee77d1b120f488960966ce0850d819b05', + numberOfTransactions: 3, + height: 24134, + payloadHash: '81de7bd1606eaca88b8f835b11682668afba47439a5468fce5288b5b7b6280d4', + payloadLength: 364, + previousBlock: '8741947515519892818', + reward: 0, + timestamp: 39555010, + totalAmount: 0, + totalFee: 300000, + transactions: [ + { + type: 8, + amount: 0, + fee: 100000, + timestamp: 39555007, + recipientId: 'U6891492430527629853', + senderId: 'U2967613837320252358', + senderPublicKey: 'f7f46c3c8b4a21ef50613565a3c4b0289fcb304af57638c12d218ef9463a1b48', + signature: 'e4429551a936430477e16e7d6b98420f8e8cf180105658f9306c1948bfcb1083a87dfa3610dac4e5bc73ce43b061ac20de3c456b217258e6f85a85880e5bc000', + id: '14322431483774644897', + asset: { + chat: { + message: 'end remove mansion next task say dynamic woman response feature ceiling mixed' + } + } + } + ], + version: 0, + id: '15642998233669588601' +}; + +describe('blocks/verify', function () { + + var blocksVerify; + var blocks; + var blockLogic; + var accounts; + var delegates; + + before(function (done) { + modulesLoader.initLogic(BlockLogic, modulesLoader.scope, function (err, __blockLogic) { + if (err) { + return done(err); + } + blockLogic = __blockLogic; + + modulesLoader.initModules([ + {blocks: require('../../../../modules/blocks')}, + {accounts: require('../../../../modules/accounts')}, + {delegates: require('../../../../modules/delegates')}, + {transactions: require('../../../../modules/transactions')}, + {transport: require('../../../../modules/transport')}, + {system: require('../../../../modules/system')}, + ], [ + {'block': require('../../../../logic/block')}, + {'transaction': require('../../../../logic/transaction')}, + {'account': require('../../../../logic/account')}, + ], {}, function (err, __modules) { + if (err) { + return done(err); + } + __modules.blocks.verify.onBind(__modules); + __modules.delegates.onBind(__modules); + __modules.transactions.onBind(__modules); + __modules.blocks.chain.onBind(__modules); + __modules.transport.onBind(__modules); + blocks = __modules.blocks; + blocksVerify = __modules.blocks.verify; + accounts = __modules.accounts; + delegates = __modules.delegates; + + done(); + }); + }); + }); + + function testValid (functionName) { + it('should be ok', function () { + blocks.lastBlock.set(previousBlock); + + var result = blocksVerify[functionName](validBlock); + + expect(result.verified).to.be.true; + expect(result.errors).to.be.an('array').that.is.empty; + }); + + it('should be ok when block is invalid but block id is excepted for having invalid block reward', function () { + exceptions.blockRewards.push(blockRewardInvalid.id); + + var result = blocksVerify[functionName](blockRewardInvalid); + + expect(result.verified).to.be.true; + expect(result.errors).to.be.an('array').that.is.empty; + }); + } + + function testSetHeight (functionName) { + it('should set height from lastBlock', function () { + blocks.lastBlock.set(previousBlock); + + var result = blocksVerify[functionName](validBlock); + + expect(result.verified).to.be.true; + expect(result.errors).to.be.an('array').that.is.empty; + expect(validBlock.height).to.equal(previousBlock.height + 1); + }); + } + + function testVerifySignature (functionName) { + it('should fail when blockSignature property is not a hex string', function () { + var blockSignature = validBlock.blockSignature; + validBlock.blockSignature = 'invalidBlockSignature'; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + + expect(result.errors[1]).to.equal('Error: argument signature must be 64U bytes long, but got a different value'); + expect(result.errors[0]).to.equal('Failed to verify block signature'); + + validBlock.blockSignature = blockSignature; + }); + + it('should fail when blockSignature property is an invalid hex string', function () { + var blockSignature = validBlock.blockSignature; + validBlock.blockSignature = 'bfaaabdc8612e177f1337d225a8a5af18cf2534f9e41b66c114850aa50ca2ea2621c4b2d34c4a8b62ea7d043e854c8ae3891113543f84f437e9d3c9cb24c0e05'; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(1); + expect(result.errors[0]).to.equal('Failed to verify block signature'); + + validBlock.blockSignature = blockSignature; + }); + + it('should fail when generatorPublicKey property is not a hex string', function () { + var generatorPublicKey = validBlock.generatorPublicKey; + validBlock.generatorPublicKey = 'invalidBlockSignature'; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[1]).to.equal('Error: argument publicKey must be 32U bytes long, but got a different value'); + expect(result.errors[0]).to.equal('Failed to verify block signature'); + + validBlock.generatorPublicKey = generatorPublicKey; + }); + + it('should fail when generatorPublicKey property is an invalid hex string', function () { + var generatorPublicKey = validBlock.generatorPublicKey; + validBlock.generatorPublicKey = '948b8b509579306694c00db2206ddb1517bfeca2b0dc833ec1c0f81e9644871b'; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(1); + expect(result.errors[0]).to.equal('Failed to verify block signature'); + + validBlock.generatorPublicKey = generatorPublicKey; + }); + } + + function testPreviousBlock (functionName) { + it('should fail when previousBlock property is missing', function () { + var previousBlock = validBlock.previousBlock; + delete validBlock.previousBlock; + + var result = blocksVerify[functionName](validBlock); + + expect(result.verified).to.be.false; + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Invalid previous block'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.previousBlock = previousBlock; + }); + } + + function testVerifyVersion (functionName) { + it('should fail when block version != 0', function () { + var version = validBlock.version; + validBlock.version = 99; + + var result = blocksVerify[functionName](validBlock); + + expect(result.verified).to.be.false; + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Invalid block version'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.version = version; + }); + } + + function testVerifyReward (functionName) { + it('should fail when block reward is invalid', function () { + validBlock.reward = 99; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal(['Invalid block reward:', 99, 'expected:', 0].join(' ')); + + validBlock.reward = 0; + }); + } + + function testVerifyId (functionName) { + it('should reset block id when block id is an invalid alpha-numeric string value', function () { + validBlock.id = 'invalid-block-id'; + var result = blocksVerify[functionName](validBlock); + expect(validBlock.id).to.not.equal('invalid-block-id'); + }); + + it('should reset block id when block id is an invalid numeric string value', function () { + validBlock.id = '11850828211026019526'; + var result = blocksVerify[functionName](validBlock); + expect(validBlock.id).to.not.equal('11850828211026019526'); + }); + + it('should reset block id when block id is an invalid integer value', function () { + validBlock.id = 11850828211026019526; + var result = blocksVerify[functionName](validBlock); + expect(validBlock.id).to.not.equal(11850828211026019526); + }); + + it('should reset block id when block id is a valid integer value', function () { + validBlock.id = 11850828211026019525; + var result = blocksVerify[functionName](validBlock); + expect(validBlock.id).to.not.equal(11850828211026019525); + }); + } + + function testVerifyPayload (functionName) { + it('should fail when payload length greater than maxPayloadLength constant value', function () { + var payloadLength = validBlock.payloadLength; + validBlock.payloadLength = 1024 * 1024 * 2; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Payload length is too long'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.payloadLength = payloadLength; + }); + + it('should fail when transactions length is not equal to numberOfTransactions property', function () { + validBlock.numberOfTransactions = validBlock.transactions.length + 1; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Included transactions do not match block transactions count'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.numberOfTransactions = validBlock.transactions.length; + }); + + it('should fail when transactions length greater than maxTxsPerBlock constant value', function () { + var transactions = validBlock.transactions; + validBlock.transactions = new Array(26); + validBlock.numberOfTransactions = validBlock.transactions.length; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Number of transactions exceeds maximum per block'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.transactions = transactions; + validBlock.numberOfTransactions = transactions.length; + }); + + // it('should fail when a transaction is of an unknown type', function () { + // var trsType = validBlock.transactions[0].type; + // validBlock.transactions[0].type = 555; + // + // var result = blocksVerify[functionName](validBlock); + // + // expect(result.errors).to.be.an('array').with.lengthOf(2); + // expect(result.errors[0]).to.equal('Invalid payload hash'); + // expect(result.errors[1]).to.equal('Unknown transaction type ' + validBlock.transactions[0].type); + // + // validBlock.transactions[0].type = trsType; + // }); + // + // it('should fail when a transaction is duplicated', function () { + // var secondTrs = validBlock.transactions[1]; + // validBlock.transactions[1] = validBlock.transactions[0]; + // + // var result = blocksVerify[functionName](validBlock); + // + // expect(result.errors).to.be.an('array').with.lengthOf(3); + // expect(result.errors[0]).to.equal('Invalid total amount'); + // expect(result.errors[1]).to.equal('Invalid payload hash'); + // expect(result.errors[2]).to.equal('Encountered duplicate transaction: ' + validBlock.transactions[1].id); + // + // validBlock.transactions[1] = secondTrs; + // }); + + it('should fail when payload hash is invalid', function () { + var payloadHash = validBlock.payloadHash; + validBlock.payloadHash = 'invalidPayloadHash'; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Invalid payload hash'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.payloadHash = payloadHash; + }); + + it('should fail when summed transaction amounts do not match totalAmount property', function () { + var totalAmount = validBlock.totalAmount; + validBlock.totalAmount = 99; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Invalid total amount'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.totalAmount = totalAmount; + }); + + it('should fail when summed transaction fees do not match totalFee property', function () { + var totalFee = validBlock.totalFee; + validBlock.totalFee = 99; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Invalid total fee'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.totalFee = totalFee; + }); + } + + function testVerifyForkOne (functionName) { + it('should fail when previousBlock value is invalid', function () { + var previousBlock = blocks.lastBlock.get().id; + validBlock.previousBlock = '10937893559311260102'; + + var result = blocksVerify[functionName](validBlock); + + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal(['Invalid previous block:', validBlock.previousBlock, 'expected:', previousBlock].join(' ')); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.previousBlock = previousBlock; + }); + } + + function testVerifyBlockSlot (functionName) { + it('should fail when block timestamp is less than previousBlock timestamp', function () { + var timestamp = validBlock.timestamp; + validBlock.timestamp = 32578350; + + var result = blocksVerify[functionName](validBlock); + + expect(result.verified).to.be.false; + expect(result.errors).to.be.an('array').with.lengthOf(2); + expect(result.errors[0]).to.equal('Invalid block timestamp'); + expect(result.errors[1]).to.equal('Failed to verify block signature'); + + validBlock.timestamp = timestamp; + }); + } + + describe('verifyReceipt() when block is valid', testValid.bind(null, 'verifyReceipt')); + + describe('verifyReceipt() when block is invalid', function () { + + describe('calling setHeight()', testSetHeight.bind(null, 'verifyReceipt')); + + describe('calling verifySignature()', testVerifySignature.bind(null, 'verifyReceipt')); + + describe('calling verifyPreviousBlock()', testPreviousBlock.bind(null, 'verifyReceipt')); + + describe('calling verifyVersion()', testVerifyVersion.bind(null, 'verifyReceipt')); + + describe('calling verifyReward()', testVerifyReward.bind(null, 'verifyReceipt')); + + describe('calling verifyId()', testVerifyId.bind(null, 'verifyReceipt')); + + describe('calling verifyPayload()', testVerifyPayload.bind(null, 'verifyReceipt')); + + describe.skip('calling verifyForkOne()', testVerifyForkOne); + + describe.skip('calling verifyBlockSlot()', testVerifyBlockSlot); + }); + + describe('verifyBlock() when block is valid', testValid.bind(null, 'verifyBlock')); + + describe('verifyBlock() when block is invalid', function () { + + describe('calling setHeight()', testSetHeight.bind(null, 'verifyBlock')); + + describe('calling verifySignature()', testVerifySignature.bind(null, 'verifyBlock')); + + describe('calling verifyPreviousBlock()', testPreviousBlock.bind(null, 'verifyBlock')); + + describe('calling verifyVersion()', testVerifyVersion.bind(null, 'verifyBlock')); + + describe('calling verifyReward()', testVerifyReward.bind(null, 'verifyBlock')); + + describe('calling verifyId()', testVerifyId.bind(null, 'verifyBlock')); + + describe('calling verifyPayload()', testVerifyPayload.bind(null, 'verifyBlock')); + + describe('calling verifyForkOne()', testVerifyForkOne.bind(null, 'verifyBlock')); + + describe('calling verifyBlockSlot()', testVerifyBlockSlot.bind(null, 'verifyBlock')); + }); +}); diff --git a/test/unit/modules/peers.js b/test/unit/modules/peers.js index c09e2d54..489c8b3f 100644 --- a/test/unit/modules/peers.js +++ b/test/unit/modules/peers.js @@ -1,302 +1,302 @@ -// 'use strict'; -// -// var chai = require('chai'); -// var expect = require('chai').expect; -// var express = require('express'); -// var sinon = require('sinon'); -// var randomString = require('randomstring'); -// var _ = require('lodash'); -// -// var config = require('../../config.json'); -// var randomPeer = require('../../common/objectStubs').randomPeer; -// var modulesLoader = require('../../common/initModule').modulesLoader; -// -// var currentPeers = []; -// -// describe('peers', function () { -// -// var peers, modules; -// -// var NONCE = randomString.generate(16); -// -// function getPeers (cb) { -// peers.list({broadhash: config.nethash}, function (err, __peers) { -// expect(err).to.not.exist; -// expect(__peers).to.be.an('array'); -// return cb(err, __peers); -// }); -// } -// -// before(function (done) { -// modulesLoader.initAllModules(function (err, __modules) { -// if (err) { -// return done(err); -// } -// peers = __modules.peers; -// modules = __modules; -// peers.onBind(__modules); -// done(); -// }, {nonce: NONCE}); -// }); -// -// beforeEach(function (done) { -// getPeers(function (err, __peers) { -// currentPeers = __peers; -// done(); -// }); -// }); -// -// describe('sandboxApi', function (done) { -// -// it('should pass the call', function () { -// var sandboxHelper = require('../../../helpers/sandbox.js'); -// sinon.stub(sandboxHelper, 'callMethod').returns(true); -// peers.sandboxApi(); -// expect(sandboxHelper.callMethod.calledOnce).to.be.ok; -// sandboxHelper.callMethod.restore(); -// }); -// }); -// -// describe('update', function () { -// -// it('should insert new peer', function (done) { -// peers.update(randomPeer); -// -// getPeers(function (err, __peers) { -// expect(currentPeers.length + 1).that.equals(__peers.length); -// currentPeers = __peers; -// var inserted = __peers.find(function (p) { -// return p.ip + ':' + p.port === randomPeer.ip + ':' + randomPeer.port; -// }); -// expect(inserted).to.be.an('object'); -// expect(inserted).not.to.be.empty; -// done(); -// }); -// }); -// -// it('should update existing peer', function (done) { -// var toUpdate = _.clone(randomPeer); -// toUpdate.height += 1; -// peers.update(toUpdate); -// -// getPeers(function (err, __peers) { -// expect(currentPeers.length).that.equals(__peers.length); -// currentPeers = __peers; -// var updated = __peers.find(function (p) { -// return p.ip + ':' + p.port === randomPeer.ip + ':' + randomPeer.port; -// }); -// expect(updated).to.be.an('object'); -// expect(updated).not.to.be.empty; -// expect(updated.ip + ':' + updated.port).that.equals(randomPeer.ip + ':' + randomPeer.port); -// expect(updated.height).that.equals(toUpdate.height); -// done(); -// }); -// }); -// -// it('should insert new peer if ip or port changed', function (done) { -// var toUpdate = _.clone(randomPeer); -// toUpdate.port += 1; -// peers.update(toUpdate); -// -// getPeers(function (err, __peers) { -// expect(currentPeers.length + 1).that.equals(__peers.length); -// currentPeers = __peers; -// var inserted = __peers.find(function (p) { -// return p.ip + ':' + p.port === toUpdate.ip + ':' + toUpdate.port; -// }); -// expect(inserted).to.be.an('object'); -// expect(inserted).not.to.be.empty; -// expect(inserted.ip + ':' + inserted.port).that.equals(toUpdate.ip + ':' + toUpdate.port); -// -// toUpdate.ip = '40.40.40.41'; -// peers.update(toUpdate); -// getPeers(function (err, __peers) { -// expect(currentPeers.length + 1).that.equals(__peers.length); -// currentPeers = __peers; -// var inserted = __peers.find(function (p) { -// return p.ip + ':' + p.port === toUpdate.ip + ':' + toUpdate.port; -// }); -// expect(inserted).to.be.an('object'); -// expect(inserted).not.to.be.empty; -// expect(inserted.ip + ':' + inserted.port).that.equals(toUpdate.ip + ':' + toUpdate.port); -// done(); -// }); -// }); -// }); -// -// var ipAndPortPeer = { -// ip: '40.41.40.41', -// port: 4000 -// }; -// -// it('should insert new peer with only ip and port defined', function (done) { -// peers.update(ipAndPortPeer); -// -// getPeers(function (err, __peers) { -// expect(currentPeers.length + 1).that.equals(__peers.length); -// currentPeers = __peers; -// var inserted = __peers.find(function (p) { -// return p.ip + ':' + p.port === ipAndPortPeer.ip + ':' + ipAndPortPeer.port; -// }); -// expect(inserted).to.be.an('object'); -// expect(inserted).not.to.be.empty; -// expect(inserted.ip + ':' + inserted.port).that.equals(ipAndPortPeer.ip + ':' + ipAndPortPeer.port); -// done(); -// }); -// }); -// -// it('should update peer with only one property defined', function (done) { -// peers.update(ipAndPortPeer); -// -// getPeers(function (err, __peers) { -// currentPeers = __peers; -// -// var almostEmptyPeer = _.clone(ipAndPortPeer); -// almostEmptyPeer.height = 1; -// -// peers.update(almostEmptyPeer); -// getPeers(function (err, __peers) { -// expect(currentPeers.length).that.equals(__peers.length); -// var inserted = __peers.find(function (p) { -// return p.ip + ':' + p.port === ipAndPortPeer.ip + ':' + ipAndPortPeer.port; -// }); -// expect(inserted).to.be.an('object'); -// expect(inserted).not.to.be.empty; -// expect(inserted.ip + ':' + inserted.port).that.equals(ipAndPortPeer.ip + ':' + ipAndPortPeer.port); -// expect(inserted.height).that.equals(almostEmptyPeer.height); -// done(); -// }); -// }); -// }); -// }); -// -// describe('remove', function () { -// -// before(function (done) { -// peers.update(randomPeer); -// done(); -// }); -// -// it('should remove added peer', function (done) { -// getPeers(function (err, __peers) { -// currentPeers = __peers; -// var peerToRemove = currentPeers.find(function (p) { -// return p.ip + ':' + p.port === randomPeer.ip + ':' + randomPeer.port; -// }); -// expect(peerToRemove).to.be.an('object').and.not.to.be.empty; -// expect(peerToRemove.state).that.equals(2); -// -// expect(peers.remove(peerToRemove.ip, peerToRemove.port)).to.be.ok; -// getPeers(function (err, __peers) { -// expect(currentPeers.length - 1).that.equals(__peers.length); -// currentPeers = __peers; -// done(); -// }); -// }); -// }); -// }); -// -// describe('acceptable', function () { -// -// before(function () { -// process.env['NODE_ENV'] = 'DEV'; -// }); -// -// var ip = require('ip'); -// -// it('should accept peer with public ip', function () { -// expect(peers.acceptable([randomPeer])).that.is.an('array').and.to.deep.equal([randomPeer]); -// }); -// -// it('should not accept peer with private ip', function () { -// var privatePeer = _.clone(randomPeer); -// privatePeer.ip = '127.0.0.1'; -// expect(peers.acceptable([privatePeer])).that.is.an('array').and.to.be.empty; -// }); -// -// it('should not accept peer with lisk-js-api os', function () { -// var privatePeer = _.clone(randomPeer); -// privatePeer.os = 'lisk-js-api'; -// expect(peers.acceptable([privatePeer])).that.is.an('array').and.to.be.empty; -// }); -// -// it('should not accept peer with host\'s nonce', function () { -// var peer = _.clone(randomPeer); -// peer.nonce = NONCE; -// expect(peers.acceptable([peer])).that.is.an('array').and.to.be.empty; -// }); -// -// it('should not accept peer with different ip but the same nonce', function () { -// process.env['NODE_ENV'] = 'TEST'; -// var meAsPeer = { -// ip: '40.00.40.40', -// port: 4001, -// nonce: NONCE -// }; -// expect(peers.acceptable([meAsPeer])).that.is.an('array').and.to.be.empty; -// }); -// -// after(function () { -// process.env['NODE_ENV'] = 'TEST'; -// }); -// }); -// -// describe('ping', function () { -// -// it('should accept peer with public ip', function (done) { -// sinon.stub(modules.transport, 'getFromPeer').callsArgWith(2, null, { -// success: true, -// peer: randomPeer, -// body: { -// success: true, height: randomPeer.height, peers: [randomPeer] -// } -// }); -// -// peers.ping(randomPeer, function (err, res) { -// expect(modules.transport.getFromPeer.calledOnce).to.be.ok; -// expect(modules.transport.getFromPeer.calledWith(randomPeer)).to.be.ok; -// modules.transport.getFromPeer.restore(); -// done(); -// }); -// }); -// }); -// -// describe('onBlockchainReady', function () { -// -// before(function () { -// modules.transport.onBind(modules); -// }); -// -// it('should update peers during onBlockchainReady', function (done) { -// sinon.stub(peers, 'discover').callsArgWith(0, null); -// var config = require('../../config.json'); -// var initialPeers = _.clone(config.peers.list); -// if (initialPeers.length === 0) { -// config.peers.list.push(randomPeer); -// } -// peers.onBlockchainReady(); -// setTimeout(function () { -// expect(peers.discover.calledOnce).to.be.ok; -// peers.discover.restore(); -// done(); -// }, 100); -// }); -// }); -// -// describe('onPeersReady', function () { -// -// before(function () { -// modules.transport.onBind(modules); -// }); -// -// it('should update peers during onBlockchainReady', function (done) { -// sinon.stub(peers, 'discover').callsArgWith(0, null); -// peers.onPeersReady(); -// setTimeout(function () { -// expect(peers.discover.calledOnce).to.be.ok; -// peers.discover.restore(); -// done(); -// }, 100); -// }); -// }); -// }); +'use strict'; + +var chai = require('chai'); +var expect = require('chai').expect; +var express = require('express'); +var sinon = require('sinon'); +var randomString = require('randomstring'); +var _ = require('lodash'); + +var config = require('../../config.json'); +var randomPeer = require('../../common/objectStubs').randomPeer; +var modulesLoader = require('../../common/initModule').modulesLoader; + +var currentPeers = []; + +describe('peers', function () { + + var peers, modules; + + var NONCE = randomString.generate(16); + + function getPeers (cb) { + peers.list({broadhash: config.nethash}, function (err, __peers) { + expect(err).to.not.exist; + expect(__peers).to.be.an('array'); + return cb(err, __peers); + }); + } + + before(function (done) { + modulesLoader.initAllModules(function (err, __modules) { + if (err) { + return done(err); + } + peers = __modules.peers; + modules = __modules; + peers.onBind(__modules); + done(); + }, {nonce: NONCE}); + }); + + beforeEach(function (done) { + getPeers(function (err, __peers) { + currentPeers = __peers; + done(); + }); + }); + + describe('sandboxApi', function (done) { + + it('should pass the call', function () { + var sandboxHelper = require('../../../helpers/sandbox.js'); + sinon.stub(sandboxHelper, 'callMethod').returns(true); + peers.sandboxApi(); + expect(sandboxHelper.callMethod.calledOnce).to.be.ok; + sandboxHelper.callMethod.restore(); + }); + }); + + describe('update', function () { + + it('should insert new peer', function (done) { + peers.update(randomPeer); + + getPeers(function (err, __peers) { + expect(currentPeers.length + 1).that.equals(__peers.length); + currentPeers = __peers; + var inserted = __peers.find(function (p) { + return p.ip + ':' + p.port === randomPeer.ip + ':' + randomPeer.port; + }); + expect(inserted).to.be.an('object'); + expect(inserted).not.to.be.empty; + done(); + }); + }); + + it('should update existing peer', function (done) { + var toUpdate = _.clone(randomPeer); + toUpdate.height += 1; + peers.update(toUpdate); + + getPeers(function (err, __peers) { + expect(currentPeers.length).that.equals(__peers.length); + currentPeers = __peers; + var updated = __peers.find(function (p) { + return p.ip + ':' + p.port === randomPeer.ip + ':' + randomPeer.port; + }); + expect(updated).to.be.an('object'); + expect(updated).not.to.be.empty; + expect(updated.ip + ':' + updated.port).that.equals(randomPeer.ip + ':' + randomPeer.port); + expect(updated.height).that.equals(toUpdate.height); + done(); + }); + }); + + it('should insert new peer if ip or port changed', function (done) { + var toUpdate = _.clone(randomPeer); + toUpdate.port += 1; + peers.update(toUpdate); + + getPeers(function (err, __peers) { + expect(currentPeers.length + 1).that.equals(__peers.length); + currentPeers = __peers; + var inserted = __peers.find(function (p) { + return p.ip + ':' + p.port === toUpdate.ip + ':' + toUpdate.port; + }); + expect(inserted).to.be.an('object'); + expect(inserted).not.to.be.empty; + expect(inserted.ip + ':' + inserted.port).that.equals(toUpdate.ip + ':' + toUpdate.port); + + toUpdate.ip = '40.40.40.41'; + peers.update(toUpdate); + getPeers(function (err, __peers) { + expect(currentPeers.length + 1).that.equals(__peers.length); + currentPeers = __peers; + var inserted = __peers.find(function (p) { + return p.ip + ':' + p.port === toUpdate.ip + ':' + toUpdate.port; + }); + expect(inserted).to.be.an('object'); + expect(inserted).not.to.be.empty; + expect(inserted.ip + ':' + inserted.port).that.equals(toUpdate.ip + ':' + toUpdate.port); + done(); + }); + }); + }); + + var ipAndPortPeer = { + ip: '40.41.40.41', + port: 4000 + }; + + it('should insert new peer with only ip and port defined', function (done) { + peers.update(ipAndPortPeer); + + getPeers(function (err, __peers) { + expect(currentPeers.length + 1).that.equals(__peers.length); + currentPeers = __peers; + var inserted = __peers.find(function (p) { + return p.ip + ':' + p.port === ipAndPortPeer.ip + ':' + ipAndPortPeer.port; + }); + expect(inserted).to.be.an('object'); + expect(inserted).not.to.be.empty; + expect(inserted.ip + ':' + inserted.port).that.equals(ipAndPortPeer.ip + ':' + ipAndPortPeer.port); + done(); + }); + }); + + it('should update peer with only one property defined', function (done) { + peers.update(ipAndPortPeer); + + getPeers(function (err, __peers) { + currentPeers = __peers; + + var almostEmptyPeer = _.clone(ipAndPortPeer); + almostEmptyPeer.height = 1; + + peers.update(almostEmptyPeer); + getPeers(function (err, __peers) { + expect(currentPeers.length).that.equals(__peers.length); + var inserted = __peers.find(function (p) { + return p.ip + ':' + p.port === ipAndPortPeer.ip + ':' + ipAndPortPeer.port; + }); + expect(inserted).to.be.an('object'); + expect(inserted).not.to.be.empty; + expect(inserted.ip + ':' + inserted.port).that.equals(ipAndPortPeer.ip + ':' + ipAndPortPeer.port); + expect(inserted.height).that.equals(almostEmptyPeer.height); + done(); + }); + }); + }); + }); + + describe('remove', function () { + + before(function (done) { + peers.update(randomPeer); + done(); + }); + + it('should remove added peer', function (done) { + getPeers(function (err, __peers) { + currentPeers = __peers; + var peerToRemove = currentPeers.find(function (p) { + return p.ip + ':' + p.port === randomPeer.ip + ':' + randomPeer.port; + }); + expect(peerToRemove).to.be.an('object').and.not.to.be.empty; + expect(peerToRemove.state).that.equals(2); + + expect(peers.remove(peerToRemove.ip, peerToRemove.port)).to.be.ok; + getPeers(function (err, __peers) { + expect(currentPeers.length - 1).that.equals(__peers.length); + currentPeers = __peers; + done(); + }); + }); + }); + }); + + describe('acceptable', function () { + + before(function () { + process.env['NODE_ENV'] = 'DEV'; + }); + + var ip = require('ip'); + + it('should accept peer with public ip', function () { + expect(peers.acceptable([randomPeer])).that.is.an('array').and.to.deep.equal([randomPeer]); + }); + + it('should not accept peer with private ip', function () { + var privatePeer = _.clone(randomPeer); + privatePeer.ip = '127.0.0.1'; + expect(peers.acceptable([privatePeer])).that.is.an('array').and.to.be.empty; + }); + + it('should not accept peer with lisk-js-api os', function () { + var privatePeer = _.clone(randomPeer); + privatePeer.os = 'lisk-js-api'; + expect(peers.acceptable([privatePeer])).that.is.an('array').and.to.be.empty; + }); + + it('should not accept peer with host\'s nonce', function () { + var peer = _.clone(randomPeer); + peer.nonce = NONCE; + expect(peers.acceptable([peer])).that.is.an('array').and.to.be.empty; + }); + + it('should not accept peer with different ip but the same nonce', function () { + process.env['NODE_ENV'] = 'TEST'; + var meAsPeer = { + ip: '40.00.40.40', + port: 4001, + nonce: NONCE + }; + expect(peers.acceptable([meAsPeer])).that.is.an('array').and.to.be.empty; + }); + + after(function () { + process.env['NODE_ENV'] = 'TEST'; + }); + }); + + describe('ping', function () { + + it('should accept peer with public ip', function (done) { + sinon.stub(modules.transport, 'getFromPeer').callsArgWith(2, null, { + success: true, + peer: randomPeer, + body: { + success: true, height: randomPeer.height, peers: [randomPeer] + } + }); + + peers.ping(randomPeer, function (err, res) { + expect(modules.transport.getFromPeer.calledOnce).to.be.ok; + expect(modules.transport.getFromPeer.calledWith(randomPeer)).to.be.ok; + modules.transport.getFromPeer.restore(); + done(); + }); + }); + }); + + describe('onBlockchainReady', function () { + + before(function () { + modules.transport.onBind(modules); + }); + + it('should update peers during onBlockchainReady', function (done) { + sinon.stub(peers, 'discover').callsArgWith(0, null); + var config = require('../../config.json'); + var initialPeers = _.clone(config.peers.list); + if (initialPeers.length === 0) { + config.peers.list.push(randomPeer); + } + peers.onBlockchainReady(); + setTimeout(function () { + expect(peers.discover.calledOnce).to.be.ok; + peers.discover.restore(); + done(); + }, 1000); + }); + }); + + describe('onPeersReady', function () { + + before(function () { + modules.transport.onBind(modules); + }); + + it('should update peers during onBlockchainReady', function (done) { + sinon.stub(peers, 'discover').callsArgWith(0, null); + peers.onPeersReady(); + setTimeout(function () { + expect(peers.discover.calledOnce).to.be.ok; + peers.discover.restore(); + done(); + }, 1000); + }); + }); +}); diff --git a/test/unit/schema/dapp.js b/test/unit/schema/dapp.js index c940aea0..0edabb84 100644 --- a/test/unit/schema/dapp.js +++ b/test/unit/schema/dapp.js @@ -1,78 +1,78 @@ -// var ZSchema = require('../../../helpers/z_schema.js'); -// var schema = require('../../../schema/dapps.js'); -// var expect = require('chai').expect; -// -// var validator = new ZSchema(); -// -// describe('dapp', function () { -// -// // TODO: Add tests for other dapps schemas -// describe('put', function () { -// it('tests for schema'); -// }); -// -// describe('get', function () { -// it('tests for schema'); -// }); -// -// describe('list', function () { -// it('tests for schema'); -// }); -// -// describe('addTransactions', function () { -// it('tests for schema'); -// }); -// -// describe('sendWithdrawal', function () { -// it('tests for schema'); -// }); -// -// describe('search', function () { -// it('tests for schema'); -// }); -// -// describe('install', function () { -// it('tests for schema'); -// }); -// -// describe('uninstall', function () { -// it('tests for schema'); -// }); -// -// describe('stop', function () { -// it('tests for schema'); -// }); -// -// describe('launch', function () { -// var testBody; -// -// beforeEach(function () { -// testBody = { -// params: ['-x', 'localhost'], -// id: '1465651642158264047', -// master: 'pluto' -// }; -// }); -// -// it('should return error when params field is not an array', function () { -// testBody.params = ''; -// validator.validate(testBody, schema.launch); -// expect(validator.getLastErrors().map(function (e) { -// return e.message; -// })).to.eql(['Expected type array but found type string']); -// }); -// -// it('should return error when params field length is less than minimum length', function () { -// testBody.params = []; -// validator.validate(testBody, schema.launch); -// expect(validator.getLastErrors().map(function (e) { -// return e.message; -// })).to.eql(['Array is too short (0), minimum 1']); -// }); -// -// it('should be ok when params field length valid', function () { -// validator.validate(testBody, schema.launch); -// expect(validator.getLastErrors()).to.not.exist; -// }); -// }); -// }); +var ZSchema = require('../../../helpers/z_schema.js'); +var schema = require('../../../schema/dapps.js'); +var expect = require('chai').expect; + +var validator = new ZSchema(); + +describe('dapp', function () { + + // TODO: Add tests for other dapps schemas + describe('put', function () { + it('tests for schema'); + }); + + describe('get', function () { + it('tests for schema'); + }); + + describe('list', function () { + it('tests for schema'); + }); + + describe('addTransactions', function () { + it('tests for schema'); + }); + + describe('sendWithdrawal', function () { + it('tests for schema'); + }); + + describe('search', function () { + it('tests for schema'); + }); + + describe('install', function () { + it('tests for schema'); + }); + + describe('uninstall', function () { + it('tests for schema'); + }); + + describe('stop', function () { + it('tests for schema'); + }); + + describe('launch', function () { + var testBody; + + beforeEach(function () { + testBody = { + params: ['-x', 'localhost'], + id: '1465651642158264047', + master: 'pluto' + }; + }); + + it('should return error when params field is not an array', function () { + testBody.params = ''; + validator.validate(testBody, schema.launch); + expect(validator.getLastErrors().map(function (e) { + return e.message; + })).to.eql(['Expected type array but found type string']); + }); + + it('should return error when params field length is less than minimum length', function () { + testBody.params = []; + validator.validate(testBody, schema.launch); + expect(validator.getLastErrors().map(function (e) { + return e.message; + })).to.eql(['Array is too short (0), minimum 1']); + }); + + it('should be ok when params field length valid', function () { + validator.validate(testBody, schema.launch); + expect(validator.getLastErrors()).to.not.exist; + }); + }); +}); diff --git a/test/unit/schema/multisignatures.js b/test/unit/schema/multisignatures.js index baf08b65..697983a4 100644 --- a/test/unit/schema/multisignatures.js +++ b/test/unit/schema/multisignatures.js @@ -1,97 +1,97 @@ -// var node = require('../../node.js'); -// -// var ZSchema = require('../../../helpers/z_schema.js'); -// var schema = require('../../../schema/multisignatures.js'); -// var expect = require('chai').expect; -// -// var validator = new ZSchema(); -// -// describe('multisignatures', function () { -// -// // TODO: Add tests for other multisignature schemas -// describe('getAccounts', function () { -// it('tests for schema'); -// }); -// -// describe('pending', function () { -// it('tests for schema'); -// }); -// -// describe('sign', function () { -// it('tests for schema'); -// }); -// -// describe('addMultisignatures', function () { -// var testBody; -// -// beforeEach(function () { -// var secret = node.randomPassword(); -// testBody = { -// secret: secret, -// publicKey: node.lisk.crypto.getKeys(secret).publicKey, -// min: 2, -// lifetime: 1, -// keysgroup: Array.apply(null, Array(4)).map(function () { return '+' + node.lisk.crypto.getKeys(node.randomPassword()).publicKey;}) -// }; -// }); -// -// describe('min', function () { -// -// it('should return error when min is not an integer', function () { -// testBody.min = ''; -// validator.validate(testBody, schema.addMultisignature); -// expect(validator.getLastErrors().map(function (e) { -// return e.message; -// })).to.eql(['Expected type integer but found type string']); -// }); -// -// it('should return error when min value is less than acceptable value', function () { -// testBody.min = 0; -// validator.validate(testBody, schema.addMultisignature); -// expect(validator.getLastErrors().map(function (e) { -// return e.message; -// })).to.eql(['Value 0 is less than minimum 1']); -// }); -// -// it('should return error when min value is greater than acceptable value', function () { -// testBody.min = 16; -// validator.validate(testBody, schema.addMultisignature); -// expect(validator.getLastErrors().map(function (e) { -// return e.message; -// })).to.eql(['Value 16 is greater than maximum 15']); -// }); -// }); -// -// describe('keysgroup', function () { -// -// it('should return error when keysgroup is not an array', function () { -// testBody.keysgroup = ''; -// validator.validate(testBody, schema.addMultisignature); -// expect(validator.getLastErrors().map(function (e) { -// return e.message; -// })).to.eql(['Expected type array but found type string']); -// }); -// -// it('should return error when keysgroup length is less than minimum acceptable length', function () { -// testBody.keysgroup = []; -// validator.validate(testBody, schema.addMultisignature); -// expect(validator.getLastErrors().map(function (e) { -// return e.message; -// })).to.eql(['Array is too short (0), minimum 1']); -// }); -// -// it('should return error when keysgroup length is greater than maximum acceptable length', function () { -// testBody.keysgroup = Array.apply(null, Array(16)).map(function () { return node.lisk.crypto.getKeys(node.randomPassword()).publicKey; }); -// validator.validate(testBody, schema.addMultisignature); -// expect(validator.getLastErrors().map(function (e) { -// return e.message; -// })).to.eql(['Array is too long (16), maximum 15']); -// }); -// }); -// -// it('should be ok when params field length valid', function () { -// validator.validate(testBody, schema.addMultisignature); -// expect(validator.getLastErrors()).to.not.exist; -// }); -// }); -// }); +var node = require('../../node.js'); + +var ZSchema = require('../../../helpers/z_schema.js'); +var schema = require('../../../schema/multisignatures.js'); +var expect = require('chai').expect; + +var validator = new ZSchema(); + +describe('multisignatures', function () { + + // TODO: Add tests for other multisignature schemas + describe('getAccounts', function () { + it('tests for schema'); + }); + + describe('pending', function () { + it('tests for schema'); + }); + + describe('sign', function () { + it('tests for schema'); + }); + + describe('addMultisignatures', function () { + var testBody; + + beforeEach(function () { + var secret = node.randomAccount().password; + testBody = { + secret: secret, + publicKey: node.lisk.crypto.getKeys(secret).publicKey, + min: 2, + lifetime: 1, + keysgroup: Array.apply(null, Array(4)).map(function () { return '+' + node.randomAccount().publicKey;}) + }; + }); + + describe('min', function () { + + it('should return error when min is not an integer', function () { + testBody.min = ''; + validator.validate(testBody, schema.addMultisignature); + expect(validator.getLastErrors().map(function (e) { + return e.message; + })).to.eql(['Expected type integer but found type string']); + }); + + it('should return error when min value is less than acceptable value', function () { + testBody.min = 0; + validator.validate(testBody, schema.addMultisignature); + expect(validator.getLastErrors().map(function (e) { + return e.message; + })).to.eql(['Value 0 is less than minimum 1']); + }); + + it('should return error when min value is greater than acceptable value', function () { + testBody.min = 16; + validator.validate(testBody, schema.addMultisignature); + expect(validator.getLastErrors().map(function (e) { + return e.message; + })).to.eql(['Value 16 is greater than maximum 15']); + }); + }); + + describe('keysgroup', function () { + + it('should return error when keysgroup is not an array', function () { + testBody.keysgroup = ''; + validator.validate(testBody, schema.addMultisignature); + expect(validator.getLastErrors().map(function (e) { + return e.message; + })).to.eql(['Expected type array but found type string']); + }); + + it('should return error when keysgroup length is less than minimum acceptable length', function () { + testBody.keysgroup = []; + validator.validate(testBody, schema.addMultisignature); + expect(validator.getLastErrors().map(function (e) { + return e.message; + })).to.eql(['Array is too short (0), minimum 1']); + }); + + it('should return error when keysgroup length is greater than maximum acceptable length', function () { + testBody.keysgroup = Array.apply(null, Array(16)).map(function () { return node.randomAccount().publicKey; }); + validator.validate(testBody, schema.addMultisignature); + expect(validator.getLastErrors().map(function (e) { + return e.message; + })).to.eql(['Array is too long (16), maximum 15']); + }); + }); + + it('should be ok when params field length valid', function () { + validator.validate(testBody, schema.addMultisignature); + expect(validator.getLastErrors()).to.not.exist; + }); + }); +}); diff --git a/test/unit/schema/transactions.js b/test/unit/schema/transactions.js index 2e59f7d9..407a3f11 100644 --- a/test/unit/schema/transactions.js +++ b/test/unit/schema/transactions.js @@ -31,8 +31,8 @@ describe('transactions', function () { var testBody; beforeEach(function () { - // var account1PublicKey = node.lisk.crypto.getKeys(node.randomPassword()).publicKey; - // var account2PublicKey = node.lisk.crypto.getKeys(node.randomPassword()).publicKey; + // var account1PublicKey = node.randomAccount().publicKey; + // var account2PublicKey = node.randomAccount().publicKey; testBody = { blockId: '1465651642158264047', From 454a266d72ae7278ccac1edea34e98337fb9cab1 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 7 Sep 2021 15:31:54 +0300 Subject: [PATCH 11/67] Tests for transactions-collision --- test/api/peer.transactions.collision.js | 96 ++++++++++++------------- 1 file changed, 45 insertions(+), 51 deletions(-) diff --git a/test/api/peer.transactions.collision.js b/test/api/peer.transactions.collision.js index bdf63961..60b61538 100644 --- a/test/api/peer.transactions.collision.js +++ b/test/api/peer.transactions.collision.js @@ -50,40 +50,36 @@ describe('POST /peer/transactions', function () { }); }); - describe('when transaction is invalid', function () { - - it('should fail for passphrase two', function (done) { - var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: node.gAccount.address - }); - var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[1]); - - postTransaction(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('message').to.equal('Failed to verify signature'); - done(); - }); - }); - - it('should fail for passphrase one', function (done) { - var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address - }); - var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[0]); - transaction.signature = crypto.randomBytes(64).toString('hex'); - transaction.id = node.lisk.crypto.getId(transaction); - - postTransaction(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('message').to.equal('Failed to verify signature'); - done(); - }); - }); - }); + // describe('when transaction is invalid', function () { + + // it('should fail for passphrase two', function (done) { + // var transaction = node.createSendTransaction({ + // keyPair: node.createKeypairFromPassphrase(collision.passphrases[1]), + // amount: 100000000, + // recipientId: node.gAccount.address + // }); + + // postTransaction(transaction, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.not.ok; + // node.expect(res.body).to.have.property('message').to.equal('Failed to verify signature'); + // done(); + // }); + // }); + + // it('should fail for passphrase one', function (done) { + // var transaction = node.createSendTransaction({ + // keyPair: node.createKeypairFromPassphrase(collision.passphrases[0]), + // amount: 100000000, + // recipientId: node.gAccount.address + // }); + + // postTransaction(transaction, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.not.ok; + // node.expect(res.body).to.have.property('message').to.equal('Failed to verify signature'); + // done(); + // }); + // }); + // }); describe('when transaction is valid', function () { @@ -93,11 +89,10 @@ describe('POST /peer/transactions', function () { it('should be ok for passphrase one', function (done) { var transaction = node.createSendTransaction({ - keyPair: account.keypair, + keyPair: node.createKeypairFromPassphrase(collision.passphrases[0]), amount: 100000000, - recipientId: randomAccount.address + recipientId: node.gAccount.address }); - var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[0]); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -105,20 +100,19 @@ describe('POST /peer/transactions', function () { }); }); - it('should fail for passphrase two', function (done) { - var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address - }); - var transaction = node.lisk.transaction.createTransaction(node.gAccount.address, 100000000, collision.passphrases[1]); - - postTransaction(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('message').to.equal('Invalid sender public key: b26dd40ba33e4785e49ddc4f106c0493ed00695817235c778f487aea5866400a expected: ce33db918b059a6e99c402963b42cf51c695068007ef01d8c383bb8a41270263'); - done(); - }); - }); + // it('should fail for passphrase two', function (done) { + // var transaction = node.createSendTransaction({ + // keyPair: node.createKeypairFromPassphrase(collision.passphrases[1]), + // amount: 100000000, + // recipientId: node.gAccount.address + // }); + + // postTransaction(transaction, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.not.ok; + // node.expect(res.body).to.have.property('message').to.equal('Invalid sender public key: b26dd40ba33e4785e49ddc4f106c0493ed00695817235c778f487aea5866400a expected: ce33db918b059a6e99c402963b42cf51c695068007ef01d8c383bb8a41270263'); + // done(); + // }); + // }); }); }); }); From e75ecc04a9f2cc5cee7a3abf0caadc8d83a38519 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 7 Sep 2021 15:46:36 +0300 Subject: [PATCH 12/67] Tests for transactions-delegates --- test/api/peer.transactions.collision.js | 2 - test/api/peer.transactions.delegates.js | 114 +++++++++++------------- test/node.js | 3 +- 3 files changed, 54 insertions(+), 65 deletions(-) diff --git a/test/api/peer.transactions.collision.js b/test/api/peer.transactions.collision.js index 60b61538..3b54be96 100644 --- a/test/api/peer.transactions.collision.js +++ b/test/api/peer.transactions.collision.js @@ -1,8 +1,6 @@ 'use strict'; -var crypto = require('crypto'); var node = require('./../node.js'); - var modulesLoader = require('../common/initModule').modulesLoader; var Account = require('../../logic/account'); diff --git a/test/api/peer.transactions.delegates.js b/test/api/peer.transactions.delegates.js index cffaae55..89be488c 100644 --- a/test/api/peer.transactions.delegates.js +++ b/test/api/peer.transactions.delegates.js @@ -11,9 +11,9 @@ function postTransaction (transaction, done) { } function sendADM (params, done) { - node.put('/api/transactions/', params, function (err, res) { - done(err, res); - }); + node.put('/api/transactions/', params, function (err, res) { + done(err, res); + }); } describe('POST /peer/transactions', function () { @@ -29,12 +29,11 @@ describe('POST /peer/transactions', function () { }); it('using undefined transaction.asset', function (done) { - const account = node.randomAccount(); - let transaction = node.createDelegateTransaction({ + const account = node.randomAccount(); + let transaction = node.createDelegateTransaction({ username: node.randomDelegateName(), keyPair: account.keypair }); - transaction.fee = node.fees.delegateRegistrationFee; delete transaction.asset; @@ -48,12 +47,11 @@ describe('POST /peer/transactions', function () { describe('when account has no funds', function () { it('should fail', function (done) { - const account = node.randomAccount(); - let transaction = node.createDelegateTransaction({ - username: node.randomDelegateName(), - keyPair: account.keypair - }); - transaction.fee = node.fees.delegateRegistrationFee; + const account = node.randomAccount(); + let transaction = node.createDelegateTransaction({ + username: node.randomDelegateName(), + keyPair: account.keypair + }); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -65,35 +63,33 @@ describe('POST /peer/transactions', function () { describe('when account has funds', function () { - let account = node.randomAccount(); - account.username = node.randomDelegateName(); + let account = node.randomAccount(); + account.username = node.randomDelegateName(); before(function (done) { - sendADM({ - secret: node.gAccount.password, - amount: node.fees.delegateRegistrationFee, - recipientId: account.address - }, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId'); - node.expect(res.body.transactionId).to.be.not.empty; - done(); - }); + sendADM({ + secret: node.gAccount.password, + amount: node.fees.delegateRegistrationFee, + recipientId: account.address + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId'); + node.expect(res.body.transactionId).to.be.not.empty; + done(); + }); }); - before(function (done) { node.onNewBlock(function () { done(); - }); - }); + }); + }); it('using invalid username should fail', function (done) { - let transaction = node.createDelegateTransaction({ - username: '%', - keyPair: account.keypair - }); - transaction.fee = node.fees.delegateRegistrationFee; + let transaction = node.createDelegateTransaction({ + username: '%', + keyPair: account.keypair + }); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -102,11 +98,10 @@ describe('POST /peer/transactions', function () { }); it('using uppercase username should fail', function (done) { - let transaction = node.createDelegateTransaction({ - username: 'UPPER_DELEGATE', - keyPair: account.keypair - }); - transaction.fee = node.fees.delegateRegistrationFee; + let transaction = node.createDelegateTransaction({ + username: 'UPPER_DELEGATE', + keyPair: account.keypair + }); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -116,11 +111,10 @@ describe('POST /peer/transactions', function () { describe('when lowercased username already registered', function () { it('using uppercase username should fail', function (done) { - let transaction = node.createDelegateTransaction({ - username: account.username.toUpperCase(), - keyPair: account.keypair - }); - transaction.fee = node.fees.delegateRegistrationFee; + let transaction = node.createDelegateTransaction({ + username: account.username.toUpperCase(), + keyPair: account.keypair + }); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -131,11 +125,10 @@ describe('POST /peer/transactions', function () { it('using lowercase username should be ok', function (done) { account.username = node.randomDelegateName().toLowerCase(); - let transaction = node.createDelegateTransaction({ - username: account.username, - keyPair: account.keypair - }); - transaction.fee = node.fees.delegateRegistrationFee; + let transaction = node.createDelegateTransaction({ + username: account.username, + keyPair: account.keypair + }); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -157,26 +150,23 @@ describe('POST /peer/transactions', function () { }); before(function (done) { - node.onNewBlock(function () { - done(); - }); - }); + node.onNewBlock(function () { + done(); + }); + }); it('should fail', function (done) { account.username = node.randomDelegateName().toLowerCase(); - let transaction = node.createDelegateTransaction({ - username: account.username, - keyPair: account.keypair - }); - transaction.fee = node.fees.delegateRegistrationFee; + let transaction = node.createDelegateTransaction({ + username: account.username, + keyPair: account.keypair + }); account.username = node.randomDelegateName().toLowerCase(); - let transaction2 = node.createDelegateTransaction({ - username: account.username, - keyPair: account.keypair - }); - transaction2.fee = node.fees.delegateRegistrationFee; - // var transaction2 = node.lisk.delegate.createDelegate(account2.password, account2.username); + let transaction2 = node.createDelegateTransaction({ + username: account.username, + keyPair: account.keypair + }); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; diff --git a/test/node.js b/test/node.js index 873742a0..38464292 100644 --- a/test/node.js +++ b/test/node.js @@ -196,6 +196,7 @@ node.createDelegateTransaction = function (data) { }; transaction.recipientId= null; transaction.signature = this.transactionSign(transaction, data.keyPair); + transaction.fee = node.fees.delegateRegistrationFee; return transaction; }; @@ -234,7 +235,7 @@ node.createSendTransaction = function (data) { transaction.amount = data.amount; transaction.signature = this.transactionSign(transaction, data.keyPair); transaction.id = this.getId(transaction); - transaction.fee = this.constants.fees.send; + transaction.fee = transaction.fee = node.fees.transactionFee; return transaction; }; From 9e7409eec5a4b26c1a0a26175bbb1202f1109e03 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 7 Sep 2021 18:18:07 +0300 Subject: [PATCH 13/67] Fix transactions-main tests --- test/api/accounts.js | 50 ++--- test/api/chatrooms.js | 6 +- test/api/dapps.js | 4 +- test/api/delegates.js | 6 +- test/api/multisignatures.js | 8 +- test/api/peer.signatures.js | 4 +- test/api/peer.transactions.collision.js | 10 +- test/api/peer.transactions.delegates.js | 4 +- test/api/peer.transactions.main.js | 190 ++++++++---------- test/api/peer.transactions.multisignatures.js | 2 +- test/api/peer.transactions.signatures.js | 4 +- test/api/peer.transactions.stress.js | 4 +- test/api/peer.transactions.votes.js | 4 +- test/api/signatures.js | 2 +- test/api/transactions.js | 32 +-- test/node.js | 12 +- test/unit/logic/multisignature.js | 94 ++++----- test/unit/logic/transaction.js | 2 +- test/unit/logic/transfer.js | 2 +- test/unit/logic/vote.js | 8 +- 20 files changed, 213 insertions(+), 235 deletions(-) diff --git a/test/api/accounts.js b/test/api/accounts.js index a2f5ce7d..07a27ad0 100644 --- a/test/api/accounts.js +++ b/test/api/accounts.js @@ -12,14 +12,14 @@ describe('POST /api/accounts/open', function () { it('using known passphrase should be ok', function (done) { openAccount({ - secret: node.gAccount.password + secret: node.iAccount.password }, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('account').that.is.an('object'); - node.expect(res.body.account).to.have.property('address').to.equal(node.gAccount.address); + node.expect(res.body.account).to.have.property('address').to.equal(node.iAccount.address); node.expect(res.body.account).to.have.property('unconfirmedBalance').that.is.a('string'); node.expect(res.body.account).to.have.property('balance').that.is.a('string'); - node.expect(res.body.account).to.have.property('publicKey').to.equal(node.gAccount.publicKey); + node.expect(res.body.account).to.have.property('publicKey').to.equal(node.iAccount.publicKey); node.expect(res.body.account).to.have.property('unconfirmedSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondPublicKey').to.equal(null); @@ -101,7 +101,7 @@ describe('GET /api/accounts/getBalance?address=', function () { } it('using known address should be ok', function (done) { - getBalance(node.gAccount.address, function (err, res) { + getBalance(node.iAccount.address, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('balance').that.is.a('string'); node.expect(res.body).to.have.property('unconfirmedBalance').that.is.a('string'); @@ -145,9 +145,9 @@ describe('GET /api/accounts/getPublicKey?address=', function () { } it('using known address should be ok', function (done) { - getPublicKey(node.gAccount.address, function (err, res) { + getPublicKey(node.iAccount.address, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('publicKey').to.equal(node.gAccount.publicKey); + node.expect(res.body).to.have.property('publicKey').to.equal(node.iAccount.publicKey); done(); }); }); @@ -186,10 +186,10 @@ describe('POST /api/accounts/generatePublicKey', function () { it('using known passphrase should be ok', function (done) { generatePublicKey({ - secret: node.gAccount.password + secret: node.iAccount.password }, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('publicKey').to.equal(node.gAccount.publicKey); + node.expect(res.body).to.have.property('publicKey').to.equal(node.iAccount.publicKey); done(); }); }); @@ -241,13 +241,13 @@ describe('GET /accounts', function () { } it('using known address should be ok', function (done) { - getAccounts('address=' + node.gAccount.address, function (err, res) { + getAccounts('address=' + node.iAccount.address, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('account').that.is.an('object'); - node.expect(res.body.account).to.have.property('address').to.equal(node.gAccount.address); + node.expect(res.body.account).to.have.property('address').to.equal(node.iAccount.address); node.expect(res.body.account).to.have.property('unconfirmedBalance').that.is.a('string'); node.expect(res.body.account).to.have.property('balance').that.is.a('string'); - node.expect(res.body.account).to.have.property('publicKey').to.equal(node.gAccount.publicKey); + node.expect(res.body.account).to.have.property('publicKey').to.equal(node.iAccount.publicKey); node.expect(res.body.account).to.have.property('unconfirmedSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondPublicKey').to.equal(null); @@ -258,13 +258,13 @@ describe('GET /accounts', function () { }); it('using known address and empty publicKey should be ok', function (done) { - getAccounts('address=' + node.gAccount.address + '&publicKey=', function (err, res) { + getAccounts('address=' + node.iAccount.address + '&publicKey=', function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('account').that.is.an('object'); - node.expect(res.body.account).to.have.property('address').to.equal(node.gAccount.address); + node.expect(res.body.account).to.have.property('address').to.equal(node.iAccount.address); node.expect(res.body.account).to.have.property('unconfirmedBalance').that.is.a('string'); node.expect(res.body.account).to.have.property('balance').that.is.a('string'); - node.expect(res.body.account).to.have.property('publicKey').to.equal(node.gAccount.publicKey); + node.expect(res.body.account).to.have.property('publicKey').to.equal(node.iAccount.publicKey); node.expect(res.body.account).to.have.property('unconfirmedSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondPublicKey').to.equal(null); @@ -275,13 +275,13 @@ describe('GET /accounts', function () { }); it('using known lowercase address should be ok', function (done) { - getAccounts('address=' + node.gAccount.address.toLowerCase(), function (err, res) { + getAccounts('address=' + node.iAccount.address.toLowerCase(), function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('account').that.is.an('object'); - node.expect(res.body.account).to.have.property('address').to.equal(node.gAccount.address); + node.expect(res.body.account).to.have.property('address').to.equal(node.iAccount.address); node.expect(res.body.account).to.have.property('unconfirmedBalance').that.is.a('string'); node.expect(res.body.account).to.have.property('balance').that.is.a('string'); - node.expect(res.body.account).to.have.property('publicKey').to.equal(node.gAccount.publicKey); + node.expect(res.body.account).to.have.property('publicKey').to.equal(node.iAccount.publicKey); node.expect(res.body.account).to.have.property('unconfirmedSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondPublicKey').to.equal(null); @@ -318,13 +318,13 @@ describe('GET /accounts', function () { }); it('using known publicKey should be ok', function (done) { - getAccounts('publicKey=' + node.gAccount.publicKey, function (err, res) { + getAccounts('publicKey=' + node.iAccount.publicKey, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('account').that.is.an('object'); - node.expect(res.body.account).to.have.property('address').to.equal(node.gAccount.address); + node.expect(res.body.account).to.have.property('address').to.equal(node.iAccount.address); node.expect(res.body.account).to.have.property('unconfirmedBalance').that.is.a('string'); node.expect(res.body.account).to.have.property('balance').that.is.a('string'); - node.expect(res.body.account).to.have.property('publicKey').to.equal(node.gAccount.publicKey); + node.expect(res.body.account).to.have.property('publicKey').to.equal(node.iAccount.publicKey); node.expect(res.body.account).to.have.property('unconfirmedSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondPublicKey').to.equal(null); @@ -335,7 +335,7 @@ describe('GET /accounts', function () { }); it('using known publicKey and empty address should fail', function (done) { - getAccounts('publicKey=' + node.gAccount.publicKey + '&address=', function (err, res) { + getAccounts('publicKey=' + node.iAccount.publicKey + '&address=', function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; node.expect(res.body).to.have.property('error').to.eql('String is too short (0 chars), minimum 1'); done(); @@ -387,13 +387,13 @@ describe('GET /accounts', function () { }); it('using known address and matching publicKey should be ok', function (done) { - getAccounts('address=' + node.gAccount.address + '&publicKey=' + node.gAccount.publicKey, function (err, res) { + getAccounts('address=' + node.iAccount.address + '&publicKey=' + node.iAccount.publicKey, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('account').that.is.an('object'); - node.expect(res.body.account).to.have.property('address').to.equal(node.gAccount.address); + node.expect(res.body.account).to.have.property('address').to.equal(node.iAccount.address); node.expect(res.body.account).to.have.property('unconfirmedBalance').that.is.a('string'); node.expect(res.body.account).to.have.property('balance').that.is.a('string'); - node.expect(res.body.account).to.have.property('publicKey').to.equal(node.gAccount.publicKey); + node.expect(res.body.account).to.have.property('publicKey').to.equal(node.iAccount.publicKey); node.expect(res.body.account).to.have.property('unconfirmedSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondSignature').to.equal(0); node.expect(res.body.account).to.have.property('secondPublicKey').to.equal(null); @@ -404,7 +404,7 @@ describe('GET /accounts', function () { }); it('using known address and not matching publicKey should fail', function (done) { - getAccounts('address=' + node.gAccount.address + '&publicKey=' + account.publicKey.toString('hex'), function (err, res) { + getAccounts('address=' + node.iAccount.address + '&publicKey=' + account.publicKey.toString('hex'), function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; node.expect(res.body).to.have.property('error'); node.expect(res.body.error).to.contain('Account publicKey does not match address'); diff --git a/test/api/chatrooms.js b/test/api/chatrooms.js index e990b0ff..a10d0729 100644 --- a/test/api/chatrooms.js +++ b/test/api/chatrooms.js @@ -32,7 +32,7 @@ describe('GET /api/chatrooms/:ID/:ID', function () { // send ADM to message sender before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.fees.messageFee*3+node.fees.transactionFee*2, recipientId: sender.address }, function () { @@ -43,7 +43,7 @@ describe('GET /api/chatrooms/:ID/:ID', function () { // send ADM to recipient1 before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.fees.messageFee, recipientId: recipient1.address }, function () { @@ -54,7 +54,7 @@ describe('GET /api/chatrooms/:ID/:ID', function () { // send ADM to recipient2 before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.fees.messageFee, recipientId: recipient2.address }, function () { diff --git a/test/api/dapps.js b/test/api/dapps.js index 0fa4cde7..b3b273a4 100644 --- a/test/api/dapps.js +++ b/test/api/dapps.js @@ -49,7 +49,7 @@ before(function (done) { var expectedFee = node.expectedFee(randomLISK); putTransaction({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: randomLISK, recipientId: account.address }, done); @@ -63,7 +63,7 @@ before(function (done) { var expectedFee = node.expectedFee(randomLISK); putTransaction({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: randomLISK, recipientId: account2.address }, done); diff --git a/test/api/delegates.js b/test/api/delegates.js index b091ec69..37878acd 100644 --- a/test/api/delegates.js +++ b/test/api/delegates.js @@ -84,7 +84,7 @@ describe('PUT /api/accounts/delegates with funds', function () { before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.LISK, recipientId: account.address }, function (err, res) { @@ -266,7 +266,7 @@ describe('PUT /api/delegates with funds', function () { beforeEach(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.LISK, recipientId: account.address }, function (err, res) { @@ -766,7 +766,7 @@ describe('GET /api/delegates/voters', function () { before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.LISK, recipientId: account.address }, function (err, res) { diff --git a/test/api/multisignatures.js b/test/api/multisignatures.js index f590580c..a45d228c 100644 --- a/test/api/multisignatures.js +++ b/test/api/multisignatures.js @@ -25,7 +25,7 @@ function sendLISK (account, i, done) { var randomLISK = node.randomLISK(); node.put('/api/transactions/', { - secret: node.gAccount.password, + secret: node.iAccount.password, amount: randomLISK, recipientId: account.address }, function (err, res) { @@ -568,7 +568,7 @@ describe('GET /api/multisignatures/pending', function () { describe('PUT /api/transactions', function () { it('when group transaction is pending should be ok', function (done) { - sendLISKFromMultisigAccount(multisigAccount.password, 100000000, node.gAccount.address, function (err, transactionId) { + sendLISKFromMultisigAccount(multisigAccount.password, 100000000, node.iAccount.address, function (err, transactionId) { node.onNewBlock(function (err) { node.get('/api/transactions/get?id=' + transactionId, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -677,7 +677,7 @@ describe('POST /api/multisignatures/sign (transaction)', function () { }); before(function (done) { - sendLISKFromMultisigAccount(multisigAccount.password, 100000000, node.gAccount.address, function (err, transactionId) { + sendLISKFromMultisigAccount(multisigAccount.password, 100000000, node.iAccount.address, function (err, transactionId) { multiSigTx.txId = transactionId; node.onNewBlock(function (err) { done(); @@ -743,7 +743,7 @@ describe('POST /api/multisignatures/sign (regular account)', function () { before(function (done) { node.put('/api/transactions/', { - secret: node.gAccount.password , + secret: node.iAccount.password , amount: 1, recipientId: accounts[0].address }, function (err, res) { diff --git a/test/api/peer.signatures.js b/test/api/peer.signatures.js index 3e5828ef..3b365cfe 100644 --- a/test/api/peer.signatures.js +++ b/test/api/peer.signatures.js @@ -44,7 +44,7 @@ describe('POST /peer/signatures', function () { var validParams; - // var transaction = node.lisk.transaction.createTransaction('1L', 1, node.gAccount.password); + // var transaction = node.lisk.transaction.createTransaction('1L', 1, node.iAccount.password); var transaction = { t_id: '17190511997607511181', @@ -132,7 +132,7 @@ describe('POST /peer/signatures', function () { // // node.async.eachSeries([owner, coSigner1, coSigner2], function (account, eachSeriesCb) { // transactions.push( - // node.lisk.transaction.createTransaction(account.address, 100000000000, node.gAccount.password) + // node.lisk.transaction.createTransaction(account.address, 100000000000, node.iAccount.password) // ); // eachSeriesCb(); // }, function (err) { diff --git a/test/api/peer.transactions.collision.js b/test/api/peer.transactions.collision.js index 3b54be96..953a2722 100644 --- a/test/api/peer.transactions.collision.js +++ b/test/api/peer.transactions.collision.js @@ -38,7 +38,7 @@ describe('POST /peer/transactions', function () { before(function (done) { // Send funds to collision account var transaction = node.createSendTransaction({ - keyPair: node.gAccount.keypair, + keyPair: node.iAccount.keypair, amount: 220000000, recipientId: collision.address }); @@ -54,7 +54,7 @@ describe('POST /peer/transactions', function () { // var transaction = node.createSendTransaction({ // keyPair: node.createKeypairFromPassphrase(collision.passphrases[1]), // amount: 100000000, - // recipientId: node.gAccount.address + // recipientId: node.iAccount.address // }); // postTransaction(transaction, function (err, res) { @@ -68,7 +68,7 @@ describe('POST /peer/transactions', function () { // var transaction = node.createSendTransaction({ // keyPair: node.createKeypairFromPassphrase(collision.passphrases[0]), // amount: 100000000, - // recipientId: node.gAccount.address + // recipientId: node.iAccount.address // }); // postTransaction(transaction, function (err, res) { @@ -89,7 +89,7 @@ describe('POST /peer/transactions', function () { var transaction = node.createSendTransaction({ keyPair: node.createKeypairFromPassphrase(collision.passphrases[0]), amount: 100000000, - recipientId: node.gAccount.address + recipientId: node.iAccount.address }); postTransaction(transaction, function (err, res) { @@ -102,7 +102,7 @@ describe('POST /peer/transactions', function () { // var transaction = node.createSendTransaction({ // keyPair: node.createKeypairFromPassphrase(collision.passphrases[1]), // amount: 100000000, - // recipientId: node.gAccount.address + // recipientId: node.iAccount.address // }); // postTransaction(transaction, function (err, res) { diff --git a/test/api/peer.transactions.delegates.js b/test/api/peer.transactions.delegates.js index 89be488c..5b9aa64c 100644 --- a/test/api/peer.transactions.delegates.js +++ b/test/api/peer.transactions.delegates.js @@ -68,7 +68,7 @@ describe('POST /peer/transactions', function () { before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.fees.delegateRegistrationFee, recipientId: account.address }, function (err, res) { @@ -143,7 +143,7 @@ describe('POST /peer/transactions', function () { before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: (node.fees.delegateRegistrationFee * 2), recipientId: account.address }, done); diff --git a/test/api/peer.transactions.main.js b/test/api/peer.transactions.main.js index 793230b9..4787bae5 100644 --- a/test/api/peer.transactions.main.js +++ b/test/api/peer.transactions.main.js @@ -35,7 +35,7 @@ describe('GET /peer/transactions', function () { node.debug('> Response:'.grey, JSON.stringify(res.body)); node.expect(res.body).to.have.property('success').to.be.not.ok; node.expect(res.body).to.have.property('message').to.eql('Request is made from incompatible version'); - node.expect(res.body).to.have.property('expected').to.eql('0.0.3a'); + node.expect(res.body).to.have.property('expected').to.eql('>=0.4.0'); node.expect(res.body).to.have.property('received').to.eql('0.1.0a'); done(); }); @@ -71,7 +71,7 @@ describe('POST /peer/transactions', function () { node.debug('> Response:'.grey, JSON.stringify(res.body)); node.expect(res.body).to.have.property('success').to.be.not.ok; node.expect(res.body).to.have.property('message').to.eql('Request is made from incompatible version'); - node.expect(res.body).to.have.property('expected').to.eql('0.0.3a'); + node.expect(res.body).to.have.property('expected').to.eql('>=0.4.0'); node.expect(res.body).to.have.property('received').to.eql('0.1.0a'); done(); }); @@ -79,13 +79,14 @@ describe('POST /peer/transactions', function () { it('using valid headers should be ok', function (done) { var account = node.randomAccount(); - // var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); - let transaction = node.createSignatureTransaction({ - keyPair: account.keypair, - secret: account.password - }); - // transaction.fee = 10000000; - // transaction.signature = node.transactionSign(transaction, account.keypair); + // let transaction = node.createSignatureTransaction({ + // keyPair: account.keypair + // }); + var transaction = node.createSendTransaction({ + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: account.address + }); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -97,11 +98,10 @@ describe('POST /peer/transactions', function () { it('using already processed transaction should fail', function (done) { var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -118,11 +118,10 @@ describe('POST /peer/transactions', function () { it('using already confirmed transaction should fail', function (done) { var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -131,7 +130,7 @@ describe('POST /peer/transactions', function () { node.onNewBlock(function (err) { postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('message').to.match(/Transaction is already confirmed: [0-9]+/); + node.expect(res.body).to.have.property('message').to.match(/Transaction is already /); done(); }); }); @@ -140,30 +139,25 @@ describe('POST /peer/transactions', function () { it('using varying recipientId casing should go to same address', function (done) { var account = node.randomAccount(); - var keys = node.lisk.crypto.getKeys(account.password); - var address = node.lisk.crypto.getAddress(keys.publicKey); - var transaction = node.createSendTransaction({ - keyPair: account.keypair, + keyPair: node.iAccount.keypair, amount: 100000000, - recipientId: randomAccount.address + recipientId: account.address.toUpperCase() }); - var transaction = node.lisk.transaction.createTransaction(address, 100000000, node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.onNewBlock(function (err) { - var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address - }); - var transaction2 = node.lisk.transaction.createTransaction(address.toLowerCase(), 100000000, node.gAccount.password); + var transaction2 = node.createSendTransaction({ + keyPair: node.iAccount.keypair, + amount: 100000000, + recipientId: account.address.toLowerCase() + }); postTransaction(transaction2, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.onNewBlock(function (err) { - getAddress(address, function (err, res) { + getAddress(account.address, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('account').that.is.an('object'); node.expect(res.body.account).to.have.property('balance').to.equal('200000000'); @@ -177,11 +171,10 @@ describe('POST /peer/transactions', function () { it('using transaction with undefined recipientId should fail', function (done) { var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: undefined }); - var transaction = node.lisk.transaction.createTransaction(undefined, 1, node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -192,11 +185,10 @@ describe('POST /peer/transactions', function () { it('using transaction with invalid recipientId should fail', function (done) { var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: 'U0123456789001234567890' }); - var transaction = node.lisk.transaction.createTransaction('0123456789001234567890L', 1, node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -206,12 +198,12 @@ describe('POST /peer/transactions', function () { }); it('using transaction with negative amount should fail', function (done) { + var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: -1, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction('1L', -1, node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -222,13 +214,12 @@ describe('POST /peer/transactions', function () { it('using invalid passphrase should fail', function (done) { var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: 'U123' }); - var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); - transaction.recipientId = '1L'; - transaction.id = node.lisk.crypto.getId(transaction); + transaction.recipientId = 'U1234'; + transaction.id = node.getId(transaction); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -238,12 +229,12 @@ describe('POST /peer/transactions', function () { }); it('when sender has no funds should fail', function (done) { + var account = node.randomAccount(); var transaction = node.createSendTransaction({ keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + amount: 1, + recipientId: node.randomAccount().address }); - var transaction = node.lisk.transaction.createTransaction('1L', 1, 'randomstring'); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -255,11 +246,10 @@ describe('POST /peer/transactions', function () { it('when sender does not have enough funds should always fail', function (done) { var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction(account.address, 1, node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -267,12 +257,11 @@ describe('POST /peer/transactions', function () { node.onNewBlock(function () { var count = 1; - var transaction = node.createSendTransaction({ + var transaction2 = node.createSendTransaction({ keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + amount: 2, + recipientId: node.iAccount.address }); - var transaction2 = node.lisk.transaction.createTransaction(node.gAccount.address, 2, account.password); node.async.doUntil(function (next) { postTransaction(transaction2, function (err, res) { @@ -291,14 +280,14 @@ describe('POST /peer/transactions', function () { }); it('using fake signature should fail', function (done) { + var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); transaction.signature = crypto.randomBytes(64).toString('hex'); - transaction.id = node.lisk.crypto.getId(transaction); + transaction.id = node.getId(transaction); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -308,13 +297,13 @@ describe('POST /peer/transactions', function () { }); it('using invalid publicKey should fail', function (done) { + var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); - transaction.senderPublicKey = node.randomAccount().password; + transaction.senderPublicKey = node.randomAccount().publicKeyHex; postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -324,12 +313,12 @@ describe('POST /peer/transactions', function () { }); it('using invalid signature should fail', function (done) { + var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction('12L', 1, node.gAccount.password); transaction.signature = node.randomAccount().password; postTransaction(transaction, function (err, res) { @@ -340,12 +329,12 @@ describe('POST /peer/transactions', function () { }); it('using very large amount and genesis block id should fail', function (done) { + var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 10000000000000000, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction('12L', 10000000000000000, node.gAccount.password); transaction.blockId = genesisblock.id; postTransaction(transaction, function (err, res) { @@ -356,13 +345,12 @@ describe('POST /peer/transactions', function () { }); it('using overflown amount should fail', function (done) { + var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 184819291270000000012910218291201281920128129, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction('12L', 184819291270000000012910218291201281920128129, - node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -372,12 +360,12 @@ describe('POST /peer/transactions', function () { }); it('using float amount should fail', function (done) { + var account = node.randomAccount(); var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.iAccount.keypair, + amount: 1.3, + recipientId: account.address }); - var transaction = node.lisk.transaction.createTransaction('12L', 1.3, node.gAccount.password); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -388,21 +376,15 @@ describe('POST /peer/transactions', function () { describe('from the genesis account', function () { - var signedTransactionFromGenesis = { - type: 0, - amount: 1000, - senderPublicKey: 'c96dec3595ff6041c3bd28b76b8cf75dce8225173d1bd00241624ee89b50f2a8', - requesterPublicKey: null, - timestamp: 24259352, - asset: {}, - recipientId: node.eAccount.address, - signature: 'f56a09b2f448f6371ffbe54fd9ac87b1be29fe29f27f001479e044a65e7e42fb1fa48dce6227282ad2a11145691421c4eea5d33ac7f83c6a42e1dcaa44572101', - id: '15307587316657110485', - fee: 10000000 - }; + var account = node.randomAccount(); + var transaction = node.createSendTransaction({ + keyPair: node.gAccount.keypair, + amount: 1000, + recipientId: account.address + }); it('should fail', function (done) { - postTransaction(signedTransactionFromGenesis, function (err, res) { + postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; node.expect(res.body).to.have.property('message').equals('Invalid sender. Can not send from genesis account'); done(); @@ -410,9 +392,9 @@ describe('POST /peer/transactions', function () { }); }); - describe('using multiple transactions', function () { - it('with invalid transaction should fail'); + // describe('using multiple transactions', function () { + // it('with invalid transaction should fail'); - it('with valid transaction should be ok'); - }); + // it('with valid transaction should be ok'); + // }); }); diff --git a/test/api/peer.transactions.multisignatures.js b/test/api/peer.transactions.multisignatures.js index 4e611c66..17dcaa7e 100644 --- a/test/api/peer.transactions.multisignatures.js +++ b/test/api/peer.transactions.multisignatures.js @@ -50,7 +50,7 @@ describe('POST /peer/transactions', function () { before(function (done) { sendLISK({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.fees.multisignatureRegistrationFee * 10, recipientId: multisigAccount.address }, done); diff --git a/test/api/peer.transactions.signatures.js b/test/api/peer.transactions.signatures.js index 33c70ccb..326f6d34 100644 --- a/test/api/peer.transactions.signatures.js +++ b/test/api/peer.transactions.signatures.js @@ -72,7 +72,7 @@ describe('POST /peer/transactions', function () { before(function (done) { sendLISK({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: node.fees.secondPasswordFee + 100000000, recipientId: account.address }, done); @@ -105,7 +105,7 @@ describe('POST /peer/transactions', function () { amount: 100000000, recipientId: randomAccount.address }); - var transaction = node.lisk.transaction.createTransaction('1L', 1, node.gAccount.password, account.secondPassword); + var transaction = node.lisk.transaction.createTransaction('1L', 1, node.iAccount.password, account.secondPassword); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; diff --git a/test/api/peer.transactions.stress.js b/test/api/peer.transactions.stress.js index e8646ab5..c95142bd 100644 --- a/test/api/peer.transactions.stress.js +++ b/test/api/peer.transactions.stress.js @@ -35,7 +35,7 @@ describe('POST /peer/transactions', function () { before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: 5000000000*2000, recipientId: account.address },function () { @@ -92,7 +92,7 @@ describe('POST /peer/transactions', function () { before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: 5000000000*2000, recipientId: account.address }, function () { diff --git a/test/api/peer.transactions.votes.js b/test/api/peer.transactions.votes.js index 5c4380ce..4993a84d 100644 --- a/test/api/peer.transactions.votes.js +++ b/test/api/peer.transactions.votes.js @@ -82,7 +82,7 @@ describe('POST /peer/transactions', function () { before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: 50000000000000, recipientId: account.address }, done); @@ -373,7 +373,7 @@ describe('POST /peer/transactions after registering a new delegate', function () before(function (done) { sendADM({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: 5000000000000, recipientId: account.address }, done); diff --git a/test/api/signatures.js b/test/api/signatures.js index 23cbcd4b..acf55e8d 100644 --- a/test/api/signatures.js +++ b/test/api/signatures.js @@ -23,7 +23,7 @@ function sendLISK (account, done) { var expectedFee = node.expectedFee(randomLISK); putTransaction({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: randomLISK, recipientId: account.address }, function (err, res) { diff --git a/test/api/transactions.js b/test/api/transactions.js index f5e73d1d..e59a95be 100644 --- a/test/api/transactions.js +++ b/test/api/transactions.js @@ -43,14 +43,14 @@ function sendADM (account, amount, done) { putTransaction({ // publicKey: - secret: node.gAccount.password, + secret: node.iAccount.password, amount: amount, recipientId: account.address }, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('transactionId').that.is.not.empty; transactionList.push({ - 'sender': node.gAccount.address, + 'sender': node.iAccount.address, 'recipient': account.address, 'grossSent': (amount + expectedFee) / node.normalizer, 'fee': expectedFee / node.normalizer, @@ -135,7 +135,7 @@ describe('GET /api/transactions (cache)', function () { url = '/api/transactions?'; params = [ 'blockId=' + '1', - 'senderId=' + node.gAccount.address, + 'senderId=' + node.iAccount.address, 'recipientId=' + account.address, ]; @@ -155,7 +155,7 @@ describe('GET /api/transactions (cache)', function () { var url, params; url = '/api/transactions?'; params = [ - 'whatever:senderId=' + node.gAccount.address + 'whatever:senderId=' + node.iAccount.address ]; node.get(url + params.join('&'), function (err, res) { @@ -183,7 +183,7 @@ describe('GET /api/transactions', function () { var params = [ 'blockId=' + '1', - 'senderId=' + node.gAccount.address, + 'senderId=' + node.iAccount.address, 'recipientId=' + account.address, 'limit=' + limit, 'offset=' + offset, @@ -210,7 +210,7 @@ describe('GET /api/transactions', function () { var params = [ 'and:blockId=' + '1', - 'or:senderId=' + node.gAccount.address, + 'or:senderId=' + node.iAccount.address, 'or:recipientId=' + account.address, 'limit=' + limit, 'offset=' + offset, @@ -297,7 +297,7 @@ describe('GET /api/transactions', function () { var params = [ 'and:blockId=' + '1', - 'or:senderId=' + node.gAccount.address, + 'or:senderId=' + node.iAccount.address, 'or:recipientId=' + account.address, 'fromHeight=' + 1, 'toHeight=' + 666, @@ -328,10 +328,10 @@ describe('GET /api/transactions', function () { var params = [ 'blockId=' + '1', - 'or:senderIds=' + node.gAccount.address + ',' + account.address, + 'or:senderIds=' + node.iAccount.address + ',' + account.address, 'or:recipientIds=' + account.address + ',' + account2.address, - 'or:senderPublicKeys=' + node.gAccount.publicKey, - 'or:recipientPublicKeys=' + node.gAccount.publicKey, + 'or:senderPublicKeys=' + node.iAccount.publicKey, + 'or:recipientPublicKeys=' + node.iAccount.publicKey, 'limit=' + limit, 'offset=' + offset, 'orderBy=' + orderBy @@ -357,7 +357,7 @@ describe('GET /api/transactions', function () { var params = [ 'and:blockId=' + '1', - 'or:senderId=' + node.gAccount.address, + 'or:senderId=' + node.iAccount.address, 'or:whatever=' + account.address, 'limit=' + limit, 'offset=' + offset, @@ -373,7 +373,7 @@ describe('GET /api/transactions', function () { it('using invalid condition should fail', function (done) { var params = [ - 'whatever:senderId=' + node.gAccount.address + 'whatever:senderId=' + node.iAccount.address ]; node.get('/api/transactions?' + params.join('&'), function (err, res) { @@ -385,7 +385,7 @@ describe('GET /api/transactions', function () { it('using invalid field name (x:y:z) should fail', function (done) { var params = [ - 'or:whatever:senderId=' + node.gAccount.address + 'or:whatever:senderId=' + node.iAccount.address ]; node.get('/api/transactions?' + params.join('&'), function (err, res) { @@ -888,7 +888,7 @@ describe('PUT /api/transactions', function () { var amountToSend = 110000000; putTransaction({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: amountToSend, recipientId: recipientId }, function (err, res) { @@ -907,7 +907,7 @@ describe('PUT /api/transactions', function () { var amountToSend = 100000000; putTransaction({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: amountToSend, recipientId: account2.address }, function (err, res) { @@ -942,7 +942,7 @@ describe('POST /api/transactions', function () { before(function (done) { sendADM2voter({ - secret: node.gAccount.password, + secret: node.iAccount.password, amount: 500000000000, recipientId: account4.address }, function (err, res) { diff --git a/test/node.js b/test/node.js index 38464292..2d85e67d 100644 --- a/test/node.js +++ b/test/node.js @@ -121,6 +121,7 @@ node.gAccount = { }; node.gAccount.keypair = node.createKeypairFromPassphrase(node.gAccount.password); +// Account, holding 19.6 mln ADM, received from Genesis node.iAccount = { address: 'U5338684603617333081', publicKey: '9184c87b846dec0dc4010def579fecf5dad592a59b37a013c7e6975597681f58', @@ -129,10 +130,6 @@ node.iAccount = { }; node.iAccount.keypair = node.createKeypairFromPassphrase(node.iAccount.password); -node.gAccount = node.iAccount; - - - // Optional logging if (process.env.SILENT === 'true') { node.debug = function () {}; @@ -205,10 +202,9 @@ node.createSignatureTransaction = function (data) { let transaction = this.createBasicTransaction(data); transaction.asset = {}; transaction.recipientId= null; - transaction.keyPair = data.keyPair; - transaction.secret = data.secret; transaction.publicKey = data.keyPair.publicKey.toString('hex'); transaction.signature = this.transactionSign(transaction, data.keyPair); + transaction.id = this.getId(transaction); return transaction; }; @@ -235,7 +231,7 @@ node.createSendTransaction = function (data) { transaction.amount = data.amount; transaction.signature = this.transactionSign(transaction, data.keyPair); transaction.id = this.getId(transaction); - transaction.fee = transaction.fee = node.fees.transactionFee; + transaction.fee = node.fees.transactionFee; return transaction; }; @@ -433,7 +429,7 @@ node.chatGetBytes = function (trs) { node.signatureGetBytes = function (signature) { var bb = new ByteBuffer(32, true); - var publicKeyBuffer = new Buffer(signature.keyPair.publicKey, 'hex'); + var publicKeyBuffer = new Buffer(signature.publicKey, 'hex'); for (var i = 0; i < publicKeyBuffer.length; i++) { bb.writeByte(publicKeyBuffer[i]); diff --git a/test/unit/logic/multisignature.js b/test/unit/logic/multisignature.js index 10f6d534..5bb9c73c 100644 --- a/test/unit/logic/multisignature.js +++ b/test/unit/logic/multisignature.js @@ -102,7 +102,7 @@ describe('multisignature', function () { it('should return error when value is not an integer', function () { var min = '2'; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); trs.asset.multisignature.min = min; expect(function () { @@ -112,7 +112,7 @@ describe('multisignature', function () { it('should return error when value is a negative integer', function () { var min = -1; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); trs.asset.multisignature.min = min; expect(function () { @@ -122,7 +122,7 @@ describe('multisignature', function () { it('should return error when value is smaller than minimum acceptable value', function () { var min = constants.multisigConstraints.min.minimum - 1; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, min); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, min); expect(function () { multisignature.objectNormalize.call(transaction, trs); @@ -131,7 +131,7 @@ describe('multisignature', function () { it('should return error when value is greater than maximum acceptable value', function () { var min = constants.multisigConstraints.min.maximum + 1; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, min); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, min); expect(function () { multisignature.objectNormalize.call(transaction, trs); @@ -140,7 +140,7 @@ describe('multisignature', function () { it('should return error when value is an overflow number', function () { var min = Number.MAX_VALUE + 1; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); trs.asset.multisignature.min = min; expect(function () { @@ -153,7 +153,7 @@ describe('multisignature', function () { it('should return error when value is not an integer', function () { var lifetime = '2'; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); trs.asset.multisignature.lifetime = lifetime; expect(function () { @@ -163,7 +163,7 @@ describe('multisignature', function () { it('should return error when value is smaller than minimum acceptable value', function () { var lifetime = node.constants.multisigConstraints.lifetime.minimum - 1; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], lifetime, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], lifetime, 2); expect(function () { multisignature.objectNormalize.call(transaction, trs); @@ -172,7 +172,7 @@ describe('multisignature', function () { it('should return error when value is greater than maximum acceptable value', function () { var lifetime = node.constants.multisigConstraints.lifetime.maximum + 1; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], lifetime, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], lifetime, 2); expect(function () { multisignature.objectNormalize.call(transaction, trs); @@ -181,7 +181,7 @@ describe('multisignature', function () { it('should return error when value is an overflow number', function () { var lifetime = Number.MAX_VALUE; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); trs.asset.multisignature.lifetime = lifetime; expect(function () { @@ -193,7 +193,7 @@ describe('multisignature', function () { describe('keysgroup', function () { it('should return error when it is not an array', function () { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, [''], 1, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, [''], 1, 2); trs.asset.multisignature.keysgroup = ''; expect(function () { @@ -203,7 +203,7 @@ describe('multisignature', function () { it('should return error when array length is smaller than minimum acceptable value', function () { var keysgroup = []; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, keysgroup, 1, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, keysgroup, 1, 2); expect(function () { multisignature.objectNormalize.call(transaction, trs); @@ -214,7 +214,7 @@ describe('multisignature', function () { var keysgroup = Array.apply(null, Array(constants.multisigConstraints.keysgroup.maxItems + 1)).map(function () { return '+' + node.randomAccount().publicKey; }); - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, keysgroup, 1, 2); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, keysgroup, 1, 2); expect(function () { multisignature.objectNormalize.call(transaction, trs); @@ -223,7 +223,7 @@ describe('multisignature', function () { }); it('should return transaction when asset is valid', function () { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, Array.apply(null, Array(10)).map(function () { + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, Array.apply(null, Array(10)).map(function () { return '+' + node.randomAccount().publicKey; }), 1, 2); @@ -236,50 +236,50 @@ describe('multisignature', function () { describe('from transaction.verify tests', function () { it('should return error when multisignature keysgroup has an entry which does not start with + character', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + trs.senderId = node.iAccount.address; - transaction.verify(trs, node.gAccount, function (err, trs) { + transaction.verify(trs, node.iAccount, function (err, trs) { expect(err).to.equal('Invalid math operator in multisignature keysgroup'); done(); }); }); it('should return error when multisignature keysgroup has an entry which is null', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, null], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, null], 1, 2); + trs.senderId = node.iAccount.address; - transaction.verify(trs, node.gAccount, function (err, trs) { + transaction.verify(trs, node.iAccount, function (err, trs) { expect(err).to.equal('Invalid member in keysgroup'); done(); }); }); it('should return error when multisignature keysgroup has an entry which is undefined', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, undefined], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, undefined], 1, 2); + trs.senderId = node.iAccount.address; - transaction.verify(trs, node.gAccount, function (err, trs) { + transaction.verify(trs, node.iAccount, function (err, trs) { expect(err).to.equal('Invalid member in keysgroup'); done(); }); }); it('should return error when multisignature keysgroup has an entry which is an integer', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, 12], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, 12], 1, 2); + trs.senderId = node.iAccount.address; - transaction.verify(trs, node.gAccount, function (err, trs) { + transaction.verify(trs, node.iAccount, function (err, trs) { expect(err).to.equal('Invalid member in keysgroup'); done(); }); }); it('should be okay for valid transaction', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); + trs.senderId = node.iAccount.address; - transaction.verify(trs, node.gAccount, function (err, trs) { + transaction.verify(trs, node.iAccount, function (err, trs) { expect(err).to.not.exist; done(); }); @@ -291,10 +291,10 @@ describe('multisignature', function () { it('should return error when min value is smaller than minimum acceptable value', function (done) { var min = constants.multisigConstraints.min.minimum - 1; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 1); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 1); trs.asset.multisignature.min = min; - multisignature.verify(trs, node.gAccount, function (err) { + multisignature.verify(trs, node.iAccount, function (err) { expect(err).to.equal('Invalid multisignature min. Must be between 1 and 15'); done(); }); @@ -302,59 +302,59 @@ describe('multisignature', function () { it('should return error when min value is greater than maximum acceptable value', function (done) { var min = constants.multisigConstraints.min.maximum + 1; - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, min); + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, min); - multisignature.verify(trs, node.gAccount, function (err) { + multisignature.verify(trs, node.iAccount, function (err) { expect(err).to.equal('Invalid multisignature min. Must be between 1 and 15'); done(); }); }); it('should return error when multisignature keysgroup has an entry which does not start with + character', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '-' + multiSigAccount2.publicKey], 1, 2); + trs.senderId = node.iAccount.address; - multisignature.verify(trs, node.gAccount, function (err, trs) { + multisignature.verify(trs, node.iAccount, function (err, trs) { expect(err).to.equal('Invalid math operator in multisignature keysgroup'); done(); }); }); it('should return error when multisignature keysgroup has an entry which is null', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, null], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, null], 1, 2); + trs.senderId = node.iAccount.address; - multisignature.verify(trs, node.gAccount, function (err, trs) { + multisignature.verify(trs, node.iAccount, function (err, trs) { expect(err).to.equal('Invalid member in keysgroup'); done(); }); }); it('should return error when multisignature keysgroup has an entry which is undefined', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, undefined], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, undefined], 1, 2); + trs.senderId = node.iAccount.address; - multisignature.verify(trs, node.gAccount, function (err, trs) { + multisignature.verify(trs, node.iAccount, function (err, trs) { expect(err).to.equal('Invalid member in keysgroup'); done(); }); }); it('should return error when multisignature keysgroup has an entry which is an integer', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, 12], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, 12], 1, 2); + trs.senderId = node.iAccount.address; - multisignature.verify(trs, node.gAccount, function (err, trs) { + multisignature.verify(trs, node.iAccount, function (err, trs) { expect(err).to.equal('Invalid member in keysgroup'); done(); }); }); it('should be okay for valid transaction', function (done) { - var trs = node.lisk.multisignature.createMultisignature(node.gAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); - trs.senderId = node.gAccount.address; + var trs = node.lisk.multisignature.createMultisignature(node.iAccount.password, null, ['+' + multiSigAccount1.publicKey, '+' + multiSigAccount2.publicKey], 1, 2); + trs.senderId = node.iAccount.address; - multisignature.verify(trs, node.gAccount, function (err, trs) { + multisignature.verify(trs, node.iAccount, function (err, trs) { expect(err).to.not.exist; done(); }); diff --git a/test/unit/logic/transaction.js b/test/unit/logic/transaction.js index e8744cc7..fe605512 100644 --- a/test/unit/logic/transaction.js +++ b/test/unit/logic/transaction.js @@ -31,7 +31,7 @@ var State = require('../../../logic/state.js'); var validPassword = 'rally clean ladder crane gadget century timber jealous shine scorpion beauty salon'; var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); -var senderHash = crypto.createHash('sha256').update(node.gAccount.password, 'utf8').digest(); +var senderHash = crypto.createHash('sha256').update(node.iAccount.password, 'utf8').digest(); var senderKeypair = ed.makeKeypair(senderHash); let validSender = { diff --git a/test/unit/logic/transfer.js b/test/unit/logic/transfer.js index 28300410..cefc8be6 100644 --- a/test/unit/logic/transfer.js +++ b/test/unit/logic/transfer.js @@ -22,7 +22,7 @@ var DelegateModule = require('../../../modules/delegates.js'); var validPassword = 'robust weapon course unknown head trial pencil latin acid'; var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); -var senderHash = crypto.createHash('sha256').update(node.gAccount.password, 'utf8').digest(); +var senderHash = crypto.createHash('sha256').update(node.iAccount.password, 'utf8').digest(); var senderKeypair = ed.makeKeypair(senderHash); var validSender = { diff --git a/test/unit/logic/vote.js b/test/unit/logic/vote.js index 38ce6bb0..f2ba24ed 100644 --- a/test/unit/logic/vote.js +++ b/test/unit/logic/vote.js @@ -260,7 +260,7 @@ describe('vote', function () { describe('verify', function () { it('should return error when receipientId and sender id are different', function (done) { var trs = _.cloneDeep(validTransaction); - trs.recipientId = node.gAccount.address; + trs.recipientId = node.iAccount.address; vote.verify(trs, validSender, function (err) { expect(err).to.equal('Invalid recipient'); done(); @@ -308,7 +308,7 @@ describe('vote', function () { it('should return error when removing vote for delegate sender has not voted', function (done) { var trs = _.cloneDeep(validTransaction); - trs.asset.votes = ['-' + node.gAccount.publicKey]; + trs.asset.votes = ['-' + node.iAccount.publicKey]; vote.verify(trs, validSender, function (err) { expect(err).to.equal('Failed to remove vote, account has not voted for this delegate'); done(); @@ -419,7 +419,7 @@ describe('vote', function () { it('should return err when account is not a delegate', function (done) { var trs = _.cloneDeep(validTransaction); - trs.asset.votes = ['+' + node.gAccount.publicKey]; + trs.asset.votes = ['+' + node.iAccount.publicKey]; vote.checkConfirmedDelegates(trs, function (err) { expect(err).to.equal('Delegate not found'); done(); @@ -618,7 +618,7 @@ describe('vote', function () { it('should return error when votes array is longer than maximum acceptable', function () { var trs = _.cloneDeep(validTransaction); trs.asset.votes = Array.apply(null, Array(constants.maxVotesPerTransaction + 1)).map(function () { - return '+' + node.gAccount.publicKey; + return '+' + node.iAccount.publicKey; }); expect(function () { vote.objectNormalize.call(transaction, trs); From 3244b6f82f39ce0d4cdee4cacaebaecdebdbd87f Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 7 Sep 2021 20:41:40 +0300 Subject: [PATCH 14/67] Tests for transactions-signatures --- test/api/peer.transactions.signatures.js | 156 +++++++++++++---------- test/node.js | 8 ++ 2 files changed, 95 insertions(+), 69 deletions(-) diff --git a/test/api/peer.transactions.signatures.js b/test/api/peer.transactions.signatures.js index 326f6d34..a4ede50d 100644 --- a/test/api/peer.transactions.signatures.js +++ b/test/api/peer.transactions.signatures.js @@ -5,7 +5,6 @@ var node = require('./../node.js'); var account = node.randomAccount(); var account2 = node.randomAccount(); -var account3 = node.randomAccount(); function postTransaction (transaction, done) { node.post('/peer/transactions', { @@ -15,13 +14,18 @@ function postTransaction (transaction, done) { }); } +function postSignatureTransaction (transaction, done) { + node.put('/api/signatures', transaction, function (err, res) { + done(err, res); + }); +} + function sendLISK (params, done) { var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + keyPair: node.createKeypairFromPassphrase(params.secret), + amount: params.amount, + recipientId: params.recipientId }); - var transaction = node.lisk.transaction.createTransaction(params.recipientId, params.amount, params.secret); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -43,26 +47,30 @@ describe('POST /peer/transactions', function () { }); }); - it('using undefined transaction.asset', function (done) { - var transaction = node.lisk.signature.createSignature(node.randomAccount().password, node.randomAccount().password); + // createSignatureTransaction doesn't work as ADAMANT doesn't use second signatures + // it('using undefined transaction.asset', function (done) { + // var transaction = node.lisk.signature.createSignature(node.randomAccount().password, node.randomAccount().password); - delete transaction.asset; + // delete transaction.asset; - postTransaction(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('message').to.contain('Invalid transaction body'); - done(); - }); - }); + // postTransaction(transaction, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.not.ok; + // node.expect(res.body).to.have.property('message').to.contain('Invalid transaction body'); + // done(); + // }); + // }); describe('when account has no funds', function () { it('should fail', function (done) { - var transaction = node.lisk.signature.createSignature(node.randomAccount().password, node.randomAccount().password); + var transaction = { + secret: account.password, + secondSecret: account.secondPassword + }; - postTransaction(transaction, function (err, res) { + postSignatureTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('message').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + node.expect(res.body).to.have.property('error').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); done(); }); }); @@ -79,12 +87,20 @@ describe('POST /peer/transactions', function () { }); it('should be ok', function (done) { - var transaction = node.lisk.signature.createSignature(account.password, account.secondPassword); - transaction.fee = node.fees.secondPasswordFee; - - postTransaction(transaction, function (err, res) { + // var transaction = node.createSignatureTransaction({ + // keyPair: account.keypair, + // secondKeypair: account2.keypair, + // secret: account.secondPassword, + // secondSecret: account.secondPassword + // }); + var transaction = { + secret: account.password, + secondSecret: account.secondPassword + }; + + postSignatureTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + // node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); done(); }); }); @@ -99,27 +115,27 @@ describe('POST /peer/transactions', function () { }); }); - it('when account does not have one should fail', function (done) { - var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address - }); - var transaction = node.lisk.transaction.createTransaction('1L', 1, node.iAccount.password, account.secondPassword); - - postTransaction(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.not.ok; - done(); - }); - }); + // Sending tokens with second signature doesn't work as ADAMANT doesn't use second signatures + // it('when account does not have one should fail', function (done) { + // var transaction = node.createSendTransaction({ + // keyPair: account.keypair, + // amount: 1, + // recipientId: account2.address + // }); + // var transaction = node.lisk.transaction.createTransaction('1L', 1, node.iAccount.password, account.secondPassword); + + // postTransaction(transaction, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.not.ok; + // done(); + // }); + // }); it('using blank second passphrase should fail', function (done) { var transaction = node.createSendTransaction({ keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address + amount: 1, + recipientId: account2.address }); - var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, ''); postTransaction(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -128,36 +144,38 @@ describe('POST /peer/transactions', function () { }); }); - it('using fake second signature should fail', function (done) { - var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address - }); - var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, account.secondPassword); - transaction.signSignature = crypto.randomBytes(64).toString('hex'); - transaction.id = node.lisk.crypto.getId(transaction); - - postTransaction(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('message').to.equal('Failed to verify second signature'); - done(); - }); - }); - - it('using valid second passphrase should be ok', function (done) { - var transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: randomAccount.address - }); - var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, account.secondPassword); - - postTransaction(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); - done(); - }); - }); + // Sending tokens with second signature doesn't work as ADAMANT doesn't use second signatures + // it('using fake second signature should fail', function (done) { + // var transaction = node.createSendTransaction({ + // keyPair: account.keypair, + // amount: 1, + // recipientId: account2.address + // }); + // var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, account.secondPassword); + // transaction.signSignature = crypto.randomBytes(64).toString('hex'); + // transaction.id = node.lisk.crypto.getId(transaction); + + // postTransaction(transaction, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.not.ok; + // node.expect(res.body).to.have.property('message').to.equal('Failed to verify second signature'); + // done(); + // }); + // }); + + // Sending tokens with second signature doesn't work as ADAMANT doesn't use second signatures + // it('using valid second passphrase should be ok', function (done) { + // var transaction = node.createSendTransaction({ + // keyPair: account.keypair, + // amount: 1, + // recipientId: account2.address + // }); + // var transaction = node.lisk.transaction.createTransaction('1L', 1, account.password, account.secondPassword); + + // postTransaction(transaction, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.ok; + // node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + // done(); + // }); + // }); }); }); diff --git a/test/node.js b/test/node.js index 2d85e67d..134cd68c 100644 --- a/test/node.js +++ b/test/node.js @@ -197,14 +197,22 @@ node.createDelegateTransaction = function (data) { return transaction; }; +// createSignatureTransaction doesn't work as ADAMANT doesn't use second signatures node.createSignatureTransaction = function (data) { data.transactionType = transactionTypes.SIGNATURE; let transaction = this.createBasicTransaction(data); transaction.asset = {}; transaction.recipientId= null; transaction.publicKey = data.keyPair.publicKey.toString('hex'); + transaction.keypair = data.keyPair; + transaction.secondKeypair = data.secondKeypair; + // transaction.secret = data.secret; + // transaction.secondSecret = data.secret; transaction.signature = this.transactionSign(transaction, data.keyPair); transaction.id = this.getId(transaction); + transaction.fee = node.fees.secondPasswordFee; + delete transaction.keyPair; + delete transaction.secondKeypair; return transaction; }; From ae58443e5381d3d87549853b7781b6f39f5ef681 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Tue, 7 Sep 2021 20:50:44 +0300 Subject: [PATCH 15/67] Fix tests for accounts --- test/api/accounts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/api/accounts.js b/test/api/accounts.js index 07a27ad0..1575bbd2 100644 --- a/test/api/accounts.js +++ b/test/api/accounts.js @@ -101,7 +101,7 @@ describe('GET /api/accounts/getBalance?address=', function () { } it('using known address should be ok', function (done) { - getBalance(node.iAccount.address, function (err, res) { + getBalance(node.gAccount.address, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('balance').that.is.a('string'); node.expect(res.body).to.have.property('unconfirmedBalance').that.is.a('string'); From ab9a2f0f2b6c8ec224d3d1cd76c031c0909b5e4f Mon Sep 17 00:00:00 2001 From: adamant-al Date: Wed, 8 Sep 2021 13:21:04 +0300 Subject: [PATCH 16/67] Fix tests for delegates --- test/api/delegates.js | 7 ++++--- test/node.js | 16 +++++++--------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/test/api/delegates.js b/test/api/delegates.js index 37878acd..4a5858a8 100644 --- a/test/api/delegates.js +++ b/test/api/delegates.js @@ -85,9 +85,10 @@ describe('PUT /api/accounts/delegates with funds', function () { before(function (done) { sendADM({ secret: node.iAccount.password, - amount: node.LISK, + amount: node.randomLISK(), recipientId: account.address }, function (err, res) { + console.log('res.body', res.body); node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('transactionId'); node.expect(res.body.transactionId).to.be.not.empty; @@ -267,7 +268,7 @@ describe('PUT /api/delegates with funds', function () { beforeEach(function (done) { sendADM({ secret: node.iAccount.password, - amount: node.LISK, + amount: node.randomLISK(), recipientId: account.address }, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -767,7 +768,7 @@ describe('GET /api/delegates/voters', function () { before(function (done) { sendADM({ secret: node.iAccount.password, - amount: node.LISK, + amount: node.randomLISK(), recipientId: account.address }, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; diff --git a/test/node.js b/test/node.js index 134cd68c..694fe111 100644 --- a/test/node.js +++ b/test/node.js @@ -33,8 +33,9 @@ node.supertest = require('supertest'); require('colors'); // Node configuration -// node.baseUrl = 'http://' + node.config.address + ':' + node.config.port; -node.baseUrl = 'http://' + node.config.peers.list[1].ip + ':' + node.config.peers.list[1].port; +node.baseUrl = 'http://' + node.config.address + ':' + node.config.port; +// Note: using not a localhost-node can break tests where PUT requests are used, or involving cache +// node.baseUrl = 'http://' + node.config.peers.list[2].ip + ':' + node.config.peers.list[2].port; node.api = node.supertest(node.baseUrl); node.normalizer = 100000000; // Use this to convert LISK amount to normal value @@ -137,8 +138,10 @@ if (process.env.SILENT === 'true') { node.debug = console.log; } -// Random LSK amount -node.LISK = Math.floor(Math.random() * (100000 * 100000000)) + 1; +// Returns random LSK amount +node.randomLISK = function () { + return Math.floor(Math.random() * (10000 * 100000000)) + (1000 * 100000000); +}; // Returns a random delegate name node.randomDelegateName = function () { @@ -462,11 +465,6 @@ node.getId = function (trs) { return id; }; -// Returns random LSK amount -node.randomLISK = function () { - return Math.floor(Math.random() * (10000 * 100000000)) + (1000 * 100000000); -}; - // Returns current block height node.getHeight = function (cb) { var request = node.popsicle.get(node.baseUrl + '/api/blocks/getHeight'); From 6bdd94fc94a5cd2b47f866dd7fc1a07a20471186 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Wed, 8 Sep 2021 14:41:09 +0300 Subject: [PATCH 17/67] Add notRandomAccount for tests, add notes for createPassPhraseHash --- logic/transaction.js | 1 + modules/multisignatures.js | 6 ++++++ test/api/loader.js | 2 +- test/api/multisignatures.js | 9 +++++---- test/node.js | 16 ++++++++++++++++ test/unit/logic/multisignature.js | 2 ++ test/unit/logic/transaction.js | 5 +++++ test/unit/logic/transfer.js | 3 +++ test/unit/logic/vote.js | 2 ++ 9 files changed, 41 insertions(+), 5 deletions(-) diff --git a/logic/transaction.js b/logic/transaction.js index e79e1121..5b8d3ca0 100644 --- a/logic/transaction.js +++ b/logic/transaction.js @@ -198,6 +198,7 @@ Transaction.prototype.sign = function (keypair, trs) { */ Transaction.prototype.multisign = function (keypair, trs) { var bytes = this.getBytes(trs, true, true); + // TODO: check put here if we need to use createPassPhraseHash instead (probably not) var hash = crypto.createHash('sha256').update(bytes).digest(); return this.scope.ed.sign(hash, keypair).toString('hex'); }; diff --git a/modules/multisignatures.js b/modules/multisignatures.js index 41d7d95a..c7209cf7 100644 --- a/modules/multisignatures.js +++ b/modules/multisignatures.js @@ -428,6 +428,8 @@ Multisignatures.prototype.shared = { } scope.hash = crypto.createHash('sha256').update(req.body.secret, 'utf8').digest(); + // TODO: use createPassPhraseHash — Correct one + // scope.hash = library.ed.createPassPhraseHash(req.body.secret); scope.keypair = library.ed.makeKeypair(scope.hash); if (req.body.publicKey) { @@ -499,6 +501,8 @@ Multisignatures.prototype.shared = { }, addMultisignature: function (seriesCb) { scope.hash = crypto.createHash('sha256').update(req.body.secret, 'utf8').digest(); + // TODO: use createPassPhraseHash — Correct one + // scope.hash = library.ed.createPassPhraseHash(req.body.secret); scope.keypair = library.ed.makeKeypair(scope.hash); if (req.body.publicKey) { @@ -524,6 +528,8 @@ Multisignatures.prototype.shared = { if (account.secondSignature) { scope.secondHash = crypto.createHash('sha256').update(req.body.secondSecret, 'utf8').digest(); + // TODO: use createPassPhraseHash — Correct one + // scope.secondHash = library.ed.createPassPhraseHash(req.body.secondSecret); scope.secondKeypair = library.ed.makeKeypair(scope.secondHash); } diff --git a/test/api/loader.js b/test/api/loader.js index 3bd54b51..1b087b78 100644 --- a/test/api/loader.js +++ b/test/api/loader.js @@ -21,7 +21,7 @@ describe('GET /api/loader/status/sync', function () { node.expect(res.body).to.have.property('blocks').to.be.a('number'); node.expect(res.body).to.have.property('height').to.be.a('number'); node.expect(res.body).to.have.property('broadhash').to.be.a('string'); - node.expect(res.body).to.not.have.property('consensus'); // Indicates forced forging + // node.expect(res.body).to.not.have.property('consensus'); // Indicates forced forging done(); }); }); diff --git a/test/api/multisignatures.js b/test/api/multisignatures.js index a45d228c..5ee628b9 100644 --- a/test/api/multisignatures.js +++ b/test/api/multisignatures.js @@ -7,7 +7,8 @@ var constants = require('../../helpers/constants.js'); var totalMembers = 15; var requiredSignatures = 15; -var multisigAccount = node.randomAccount(); +// var multisigAccount = node.randomAccount(); +var multisigAccount = node.notRandomAccount(); var accounts = []; for (var i = 0; i < totalMembers; i++) { @@ -83,7 +84,7 @@ var Keys; function makeKeysGroup () { var keysgroup = []; for (var i = 0; i < totalMembers; i++) { - var member = '+' + accounts[i].publicKey; + var member = '+' + accounts[i].publicKeyHex; //publicKey keysgroup.push(member); } return keysgroup; @@ -150,7 +151,7 @@ describe('PUT /api/multisignatures', function () { it('using sender in the keysgroup should fail', function (done) { validParams.keysgroup.pop(); - validParams.keysgroup.push('+' + multisigAccount.publicKey); + validParams.keysgroup.push('+' + multisigAccount.publicKeyHex); //publicKey node.put('/api/multisignatures', validParams, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -333,7 +334,7 @@ describe('PUT /api/multisignatures', function () { }); it('using invalid passphrase should fail', function (done) { - validParams.secret = multisigAccount.password + 'inv4lid'; + validParams.secret = multisigAccount.password + 'invalid'; node.put('/api/multisignatures', validParams, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; diff --git a/test/node.js b/test/node.js index 694fe111..8947c5ba 100644 --- a/test/node.js +++ b/test/node.js @@ -687,6 +687,22 @@ node.randomAccount = function () { return account; }; +// Returns a basic random account +node.notRandomAccount = function () { + var account = { + balance: '1000' + }; + account.password ='drive hurt august domain soccer forum dial more borrow neglect child reopen'; + const keypair = node.createKeypairFromPassphrase(account.password); + account.publicKey = keypair.publicKey; + account.publicKeyHex = keypair.publicKey.toString('hex'); + node.expect(account).to.have.property('publicKeyHex').to.equal('59c55fe82772db642ed12dcb19206f8f761c2de50eb0de4b37c96a23867c7768'); + account.address = node.createAddressFromPublicKey(keypair.publicKey); + node.expect(account).to.have.property('address').to.equal('U7519306946775275717'); + account.keypair = keypair; + return account; +}; + // Returns an extended random account node.randomTxAccount = function () { return node._.defaults(node.randomAccount(), { diff --git a/test/unit/logic/multisignature.js b/test/unit/logic/multisignature.js index 5bb9c73c..bee7639c 100644 --- a/test/unit/logic/multisignature.js +++ b/test/unit/logic/multisignature.js @@ -21,6 +21,7 @@ var AccountModule = require('../../../modules/accounts.js'); var Multisignature = require('../../../logic/multisignature.js'); var validPassword = 'robust weapon course unknown head trial pencil latin acid'; +// Fix here to library.ed.createPassPhraseHash() var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); var validSender = { @@ -30,6 +31,7 @@ var validSender = { balance: '10000000000000000' }; +// Fix here to library.ed.createPassPhraseHash() var senderHash = crypto.createHash('sha256').update(validSender.password, 'utf8').digest(); var senderKeypair = ed.makeKeypair(senderHash); diff --git a/test/unit/logic/transaction.js b/test/unit/logic/transaction.js index fe605512..e08c4923 100644 --- a/test/unit/logic/transaction.js +++ b/test/unit/logic/transaction.js @@ -29,8 +29,10 @@ var Chat = require('../../../logic/chat.js'); var State = require('../../../logic/state.js'); var validPassword = 'rally clean ladder crane gadget century timber jealous shine scorpion beauty salon'; +// Fix here to library.ed.createPassPhraseHash() var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); +// Fix here to library.ed.createPassPhraseHash() var senderHash = crypto.createHash('sha256').update(node.iAccount.password, 'utf8').digest(); var senderKeypair = ed.makeKeypair(senderHash); @@ -63,6 +65,7 @@ let marketDelegate = _.defaults({ secret: 'rally clean ladder crane gadget century timber jealous shine scorpion beauty salon' },validSender); +// Fix here to library.ed.createPassPhraseHash() const marketDelegateHash = crypto.createHash('sha256').update(marketDelegate.secret, 'utf8').digest(); const marketDelegateKeypair = ed.makeKeypair(marketDelegateHash); @@ -77,6 +80,7 @@ const genesis = _.defaults({ secret: 'neck want coast appear army smile palm major crumble upper void warm', balance: 0 },validSender); +// Fix here to library.ed.createPassPhraseHash() const genesisHash = crypto.createHash('sha256').update(genesis.secret, 'utf8').digest(); const genesisKeypair = ed.makeKeypair(genesisHash); @@ -171,6 +175,7 @@ var testSender = _.defaults({ u_balance: 10000000000000, balance: 100000000000000 },validSender); +// Fix here to library.ed.createPassPhraseHash() const testSenderHash = node.accounts.createPassPhraseHash(testSender.secret); //crypto.createHash('sha256').update(testSender.secret, 'utf8').digest(); const testSenderKeypair = node.accounts.makeKeypair(testSenderHash); var validUnconfirmedTrs = { diff --git a/test/unit/logic/transfer.js b/test/unit/logic/transfer.js index cefc8be6..edb06443 100644 --- a/test/unit/logic/transfer.js +++ b/test/unit/logic/transfer.js @@ -20,8 +20,10 @@ var AccountModule = require('../../../modules/accounts.js'); var DelegateModule = require('../../../modules/delegates.js'); var validPassword = 'robust weapon course unknown head trial pencil latin acid'; +// Fix here to library.ed.createPassPhraseHash() var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); +// Fix here to library.ed.createPassPhraseHash() var senderHash = crypto.createHash('sha256').update(node.iAccount.password, 'utf8').digest(); var senderKeypair = ed.makeKeypair(senderHash); @@ -99,6 +101,7 @@ var testSender = _.defaults({ u_balance: 1000000000000000000, balance: 1000000000000000000 },validSender); +// Fix here to library.ed.createPassPhraseHash() const testSenderHash = crypto.createHash('sha256').update(testSender.secret, 'utf8').digest(); const testSenderKeypair = ed.makeKeypair(testSenderHash); var validUnconfirmedTrs = { diff --git a/test/unit/logic/vote.js b/test/unit/logic/vote.js index f2ba24ed..03b658af 100644 --- a/test/unit/logic/vote.js +++ b/test/unit/logic/vote.js @@ -24,6 +24,7 @@ var AccountModule = require('../../../modules/accounts.js'); var DelegateModule = require('../../../modules/delegates.js'); var validPassword = 'robust weapon course unknown head trial pencil latin acid'; +// Fix here to library.ed.createPassPhraseHash() var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); var validSender = { @@ -37,6 +38,7 @@ var validSender = { }; +// Fix here to library.ed.createPassPhraseHash() var senderHash = crypto.createHash('sha256').update(validSender.password, 'utf8').digest(); var senderKeypair = ed.makeKeypair(senderHash); From 5f9fe7c7649d1fe7c2d0c8022bef53b93c328f9a Mon Sep 17 00:00:00 2001 From: adamant-al Date: Wed, 8 Sep 2021 16:15:14 +0300 Subject: [PATCH 18/67] Turn off tests for multisignatures --- test/api/multisignatures.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/api/multisignatures.js b/test/api/multisignatures.js index 5ee628b9..6a2ea430 100644 --- a/test/api/multisignatures.js +++ b/test/api/multisignatures.js @@ -1,3 +1,6 @@ +// Multisignatures tests are disabled currently + +/* 'use strict'; var async = require('async'); @@ -7,8 +10,8 @@ var constants = require('../../helpers/constants.js'); var totalMembers = 15; var requiredSignatures = 15; -// var multisigAccount = node.randomAccount(); -var multisigAccount = node.notRandomAccount(); +var multisigAccount = node.randomAccount(); +// var multisigAccount = node.notRandomAccount(); var accounts = []; for (var i = 0; i < totalMembers; i++) { @@ -779,3 +782,4 @@ describe('POST /api/multisignatures/sign (regular account)', function () { }); }); }); +*/ From 04f4a4821abc0fc72f38f93282eb929392a5b62d Mon Sep 17 00:00:00 2001 From: adamant-al Date: Wed, 8 Sep 2021 16:27:54 +0300 Subject: [PATCH 19/67] Fix peer-blocks --- test/api/peer.blocks.js | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/test/api/peer.blocks.js b/test/api/peer.blocks.js index a6d05ebb..ac6b8a2d 100644 --- a/test/api/peer.blocks.js +++ b/test/api/peer.blocks.js @@ -3,24 +3,25 @@ var node = require('./../node.js'); var genesisblock = require('../../test/genesisBlock.json'); // use testnet genesisBlock +// api/blocks/get?id=18267398587476633612 var testBlock = { - id: '2807833455815592401', - version: 0, - timestamp: 39997040, - height: 1258, - previousBlock: '3863141986505461614', - numberOfTransactions: 0, - transactions: [], - totalAmount: 0, - totalFee: 0, - reward: 0, - payloadLength: 0, - payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', - generatorPublicKey: 'bf9f5cfc548d29983cc0dfa5c4ec47c66c31df0f87aa669869678996902ab47f', - generatorId: '9950029393097476480L', - blockSignature: 'd54ac91d2f712f408e16ff5057f7ceaa2e3a1ad4bde759e1025b16ec48bdd8ea1d3adaf5e8b94ef205f9f365f6ebae0f178a3cb3f6354c28e74ba7a05fce600c', - confirmations: 2, - totalForged: '0' + id: '18267398587476633612', + version: 0, + timestamp: 126725875, + height: 105080, + previousBlock: '4479835370871360804', + numberOfTransactions: 16, + transactions: [], // Added manually, an endpoint doesn't return transactions property + totalAmount: 8395608909063, + totalFee: 800000000, + reward: 0, + payloadLength: 1872, + payloadHash: 'dd8ec39220738f0d70c1441216cfb725abb52cb0c279c8fc121ebbfb5b029642', + generatorPublicKey: '4abe42f0153eee29d49a17788ed8f5e562a71c086d0ba563b635abc093318d3d', + generatorId: 'U7195757346097283386', + blockSignature: '58ad2fd7ae4b3cf3ea74c5a583a8b78c844134519f8c048b01eae69bac49d8f3e71892eeed019c615c3b9e4d9ab457f2757a3196d3b248816055c54b2637e103', + confirmations: 1929, + totalForged: '800000000' }; describe('GET /peer/blocks', function () { @@ -229,7 +230,7 @@ describe('POST /peer/blocks', function () { .end(function (err, res) { node.debug('> Response:'.grey, JSON.stringify(res.body)); node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('blockId').to.equal('2807833455815592401'); + node.expect(res.body).to.have.property('blockId').to.equal('18267398587476633612'); done(); }); }); From df444be92dcd298edba00125a74847cd7c7bd286 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Wed, 8 Sep 2021 17:14:14 +0300 Subject: [PATCH 20/67] Fix tests for peer-signatures --- test/api/peer.signatures.js | 396 ++++++++++++++++++++---------------- 1 file changed, 216 insertions(+), 180 deletions(-) diff --git a/test/api/peer.signatures.js b/test/api/peer.signatures.js index 3b365cfe..9ccc7217 100644 --- a/test/api/peer.signatures.js +++ b/test/api/peer.signatures.js @@ -3,6 +3,31 @@ var node = require('./../node.js'); var packageJSON = require('./../../package.json'); +var owner = node.randomAccount(); +var coSigner1 = node.randomAccount(); +var coSigner2 = node.randomAccount(); + +function postTransaction (transaction, done) { + node.post('/peer/transactions', { + transaction: transaction + }, done); +} + +function postTransactions (transactions, done) { + node.post('/peer/transactions', { + transactions: transactions + }, done); +} + +function postSignature (transaction, signature, done) { + node.post('/peer/signatures', { + signature: { + transaction: transaction.id, + signature: signature + } + }, done); +} + describe('GET /peer/signatures', function () { it('using incorrect nethash in headers should fail', function (done) { @@ -44,29 +69,18 @@ describe('POST /peer/signatures', function () { var validParams; - // var transaction = node.lisk.transaction.createTransaction('1L', 1, node.iAccount.password); - - var transaction = { - t_id: '17190511997607511181', - b_height: 981, - t_blockId: '6438017970172540087', - t_type: 0, - t_timestamp: 33363661, - t_senderPublicKey: 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', - m_recipientPublicKey: null, - t_senderId: 'U810656636599221322', - t_recipientId: 'U7771441689362721578', - t_amount: 490000000000000, - t_fee: 10000000, - t_signature: '85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01', - confirmations: 8343 - }; + var randomAccount = node.randomAccount(); + var transaction = node.createSendTransaction({ + keyPair: node.iAccount.keypair, + amount: 1, + recipientId: randomAccount.address + }); beforeEach(function (done) { validParams = { signature: { - signature: transaction.t_signature, - transaction: transaction.t_id + signature: transaction.signature, + transaction: transaction.id } }; done(); @@ -108,174 +122,196 @@ describe('POST /peer/signatures', function () { }); }); - it('using unprocessable signature should fail', function (done) { - // validParams.signature.id = '1'; + it('using unprocessable signature should fail', function (done) { + validParams.signature.transaction = '1'; - node.post('/peer/signatures', validParams) - .end(function (err, res) { - node.debug('> Response:'.grey, JSON.stringify(res.body)); - node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('message').to.equal('Error processing signature: Transaction not found'); - done(); - }); - }); - - it('using processable signature should be ok'); + node.post('/peer/signatures', validParams) + .end(function (err, res) { + node.debug('> Response:'.grey, JSON.stringify(res.body)); + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Error processing signature: Transaction not found'); + done(); + }); + }); - // describe('creating a new multisignature account', function () { - // - // var transaction; - // - // // Fund accounts - // before(function (done) { - // var transactions = []; - // - // node.async.eachSeries([owner, coSigner1, coSigner2], function (account, eachSeriesCb) { - // transactions.push( - // node.lisk.transaction.createTransaction(account.address, 100000000000, node.iAccount.password) - // ); - // eachSeriesCb(); - // }, function (err) { - // postTransactions(transactions, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // node.onNewBlock(function (err) { - // done(); - // }); - // }); - // }); - // }); - // - // // Create multisignature group - // before(function (done) { - // var keysgroup = ['+' + coSigner1.publicKey, '+' + coSigner2.publicKey]; - // var lifetime = 72; - // var min = 2; - // - // transaction = node.lisk.multisignature.createMultisignature(owner.password, null, keysgroup, lifetime, min); - // - // postTransactions([transaction], function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // node.onNewBlock(function (err) { - // done(); - // }); - // }); - // }); - // - // it('using processable signature for owner should fail', function (done) { - // var signature = node.lisk.multisignature.signTransaction(transaction, owner.password); - // - // postSignature(transaction, signature, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.not.ok; - // node.expect(res.body).to.have.property('message').to.equal('Error processing signature: Failed to verify signature'); - // done(); - // }); - // }); - // - // it('using processable signature for coSigner1 should be ok', function (done) { - // var signature = node.lisk.multisignature.signTransaction(transaction, coSigner1.password); - // - // postSignature(transaction, signature, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // done(); - // }); - // }); - // - // it('using processable signature for coSigner1 should not confirm the transaction', function (done) { - // node.onNewBlock(function (err) { - // node.onNewBlock(function (err) { - // node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.not.ok; - // done(); - // }); - // }); - // }); - // }); - // - // it('using processable signature for coSigner2 should be ok', function (done) { - // var signature = node.lisk.multisignature.signTransaction(transaction, coSigner2.password); - // - // postSignature(transaction, signature, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // done(); - // }); - // }); - // - // it('using processable signature for coSigner2 should confirm the transaction', function (done) { + // Don't check /peer/signatures + // it('using processable signature should be ok', function (done) { + // postTransaction(transaction, function (err, res) { + // node.expect(res.body).to.have.property('success').to.be.ok; // node.onNewBlock(function (err) { - // node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { + // node.post('/peer/signatures', validParams) + // .end(function (err, res) { + // node.debug('> Response:'.grey, JSON.stringify(res.body)); // node.expect(res.body).to.have.property('success').to.be.ok; - // node.expect(res.body).to.have.property('transaction'); - // node.expect(res.body.transaction).to.have.property('id').to.equal(transaction.id); // done(); // }); // }); // }); // }); - // - // describe('sending transaction from multisignature account', function () { - // - // var transaction; - // - // before(function (done) { - // node.onNewBlock(done); - // }); - // - // // Send transaction - // before(function (done) { - // transaction = node.lisk.multisignature.createTransaction('1L', 1, owner.password); - // - // postTransaction(transaction, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // node.onNewBlock(function (err) { - // done(); - // }); - // }); - // }); - // - // it('using processable signature for coSigner1 should be ok', function (done) { - // var signature = node.lisk.multisignature.signTransaction(transaction, coSigner1.password); - // - // postSignature(transaction, signature, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // done(); - // }); - // }); - // - // it('using processable signature for coSigner1 should not confirm the transaction', function (done) { - // node.onNewBlock(function (err) { - // node.onNewBlock(function (err) { - // node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.not.ok; - // done(); - // }); - // }); - // }); - // }); - // - // it('using processable signature for coSigner2 should be ok', function (done) { - // var signature = node.lisk.multisignature.signTransaction(transaction, coSigner2.password); - // - // postSignature(transaction, signature, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // done(); - // }); - // }); - // - // it('using processable signature for coSigner2 should confirm the transaction', function (done) { - // node.onNewBlock(function (err) { - // node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // node.expect(res.body).to.have.property('transaction'); - // node.expect(res.body.transaction).to.have.property('id').to.equal(transaction.id); - // done(); - // }); - // }); - // }); - // }); - // - // describe('using multiple signatures', function () { - // it('with unprocessable signature should fail'); - // - // it('with processable signature should be ok'); - // }); + + // Multisignatures tests are disabled currently + + /* + describe('creating a new multisignature account', function () { + + var transaction; + + // Fund accounts + before(function (done) { + var transactions = []; + + node.async.eachSeries([owner, coSigner1, coSigner2], function (account, eachSeriesCb) { + transactions.push( + node.createSendTransaction({ + keyPair: node.gAccount.keypair, + amount: 1, + recipientId: account.address + }) + ); + eachSeriesCb(); + }, function (err) { + postTransactions(transactions, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(function (err) { + done(); + }); + }); + }); + }); + + // Create multisignature group + before(function (done) { + var keysgroup = ['+' + coSigner1.publicKey, '+' + coSigner2.publicKey]; + var lifetime = 72; + var min = 2; + + transaction = node.lisk.multisignature.createMultisignature(owner.password, null, keysgroup, lifetime, min); + + postTransactions([transaction], function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(function (err) { + done(); + }); + }); + }); + + it('using processable signature for owner should fail', function (done) { + var signature = node.lisk.multisignature.signTransaction(transaction, owner.password); + + postSignature(transaction, signature, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('message').to.equal('Error processing signature: Failed to verify signature'); + done(); + }); + }); + + it('using processable signature for coSigner1 should be ok', function (done) { + var signature = node.lisk.multisignature.signTransaction(transaction, coSigner1.password); + + postSignature(transaction, signature, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + done(); + }); + }); + + it('using processable signature for coSigner1 should not confirm the transaction', function (done) { + node.onNewBlock(function (err) { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + }); + }); + + it('using processable signature for coSigner2 should be ok', function (done) { + var signature = node.lisk.multisignature.signTransaction(transaction, coSigner2.password); + + postSignature(transaction, signature, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + done(); + }); + }); + + it('using processable signature for coSigner2 should confirm the transaction', function (done) { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction'); + node.expect(res.body.transaction).to.have.property('id').to.equal(transaction.id); + done(); + }); + }); + }); + }); + + describe('sending transaction from multisignature account', function () { + + var transaction; + + before(function (done) { + node.onNewBlock(done); + }); + + // Send transaction + before(function (done) { + transaction = node.lisk.multisignature.createTransaction('1L', 1, owner.password); + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(function (err) { + done(); + }); + }); + }); + + it('using processable signature for coSigner1 should be ok', function (done) { + var signature = node.lisk.multisignature.signTransaction(transaction, coSigner1.password); + + postSignature(transaction, signature, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + done(); + }); + }); + + it('using processable signature for coSigner1 should not confirm the transaction', function (done) { + node.onNewBlock(function (err) { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + done(); + }); + }); + }); + }); + + it('using processable signature for coSigner2 should be ok', function (done) { + var signature = node.lisk.multisignature.signTransaction(transaction, coSigner2.password); + + postSignature(transaction, signature, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + done(); + }); + }); + + it('using processable signature for coSigner2 should confirm the transaction', function (done) { + node.onNewBlock(function (err) { + node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction'); + node.expect(res.body.transaction).to.have.property('id').to.equal(transaction.id); + done(); + }); + }); + }); + }); + + describe('using multiple signatures', function () { + it('with unprocessable signature should fail'); + + it('with processable signature should be ok'); + }); + */ + }); From 991dd3985a3c90c574f892cb175bc9a587294131 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Wed, 8 Sep 2021 17:19:17 +0300 Subject: [PATCH 21/67] Disable tests for peer.transactions.multisignatures --- test/api/peer.transactions.multisignatures.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/api/peer.transactions.multisignatures.js b/test/api/peer.transactions.multisignatures.js index 17dcaa7e..03ef934d 100644 --- a/test/api/peer.transactions.multisignatures.js +++ b/test/api/peer.transactions.multisignatures.js @@ -1,3 +1,6 @@ +// Multisignatures tests are disabled currently + +/* 'use strict'; var crypto = require('crypto'); @@ -81,3 +84,4 @@ describe('POST /peer/transactions', function () { }); }); }); +*/ From 5b7da23e7c8d400e777ba6ae1bbe5cd877b631b7 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Thu, 9 Sep 2021 01:32:14 +0300 Subject: [PATCH 22/67] Fix tests for peer.transactions.votes --- test/api/peer.transactions.votes.js | 230 +++++++++++++++------------- test/config.json | 4 +- test/node.js | 9 +- 3 files changed, 132 insertions(+), 111 deletions(-) diff --git a/test/api/peer.transactions.votes.js b/test/api/peer.transactions.votes.js index 4993a84d..0f029a69 100644 --- a/test/api/peer.transactions.votes.js +++ b/test/api/peer.transactions.votes.js @@ -27,18 +27,20 @@ function getVotes (address, done) { function postVotes (params, done) { var count = 0; - var blocksToWait = Math.ceil(params.delegates.length / node.constants.maxTxsPerBlock); + var blocksToWait = Math.ceil(params.delegates.length / node.constants.maxTxsPerBlock) + 12; node.async.eachSeries(params.delegates, function (delegate, eachCb) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, votes: [params.action + delegate] - }); - transaction.fee = node.fees.voteFee; + }); - postVote(transaction, function (err, res) { - params.voteCb(err, res); - return eachCb(); + // Don't sent requests too often — a node can miss some of them + node.waitMilliSeconds(600, function () { + postVote(transaction, function (err, res) { + params.voteCb(err, res); + return eachCb(); + }); }); }, function (err) { node.waitForBlocks(blocksToWait, function (err) { @@ -64,11 +66,10 @@ function sendADM (params, done) { function registerDelegate (account, done) { account.username = node.randomDelegateName().toLowerCase(); - let transaction = node.createDelegateTransaction({ - username: account.username, - keyPair: account.keypair - }); - transaction.fee = node.fees.delegateRegistrationFee; + let transaction = node.createDelegateTransaction({ + username: account.username, + keyPair: account.keypair + }); node.post('/peer/transactions', { transaction: transaction }, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -83,7 +84,7 @@ describe('POST /peer/transactions', function () { before(function (done) { sendADM({ secret: node.iAccount.password, - amount: 50000000000000, + amount: 2000000000000, // 20k ADM recipientId: account.address }, done); }); @@ -130,11 +131,10 @@ describe('POST /peer/transactions', function () { }); it('using undefined transaction.asset', function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`+${delegate}`] - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`+${delegate}`] + }); delete transaction.asset; @@ -146,11 +146,10 @@ describe('POST /peer/transactions', function () { }); it('using transaction.asset.votes containing invalid vote type', function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [0] - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [0] + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -160,11 +159,10 @@ describe('POST /peer/transactions', function () { }); it('using transaction.asset.votes containing invalid vote format', function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`@${delegate}`] - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`@${delegate}`] + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -174,11 +172,10 @@ describe('POST /peer/transactions', function () { }); it('using transaction.asset.votes containing invalid vote length', function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`+${delegate}z`] - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`+${delegate}z`] + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -188,11 +185,10 @@ describe('POST /peer/transactions', function () { }); it('using transaction.asset.votes containing manipulated vote', function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: ['+8a6d629685b18e17e5f534065bad4984a8aa6b499c5783c3e65f61779e6da06czz'] - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: ['+8a6d629685b18e17e5f534065bad4984a8aa6b499c5783c3e65f61779e6da06czz'] + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -204,11 +200,10 @@ describe('POST /peer/transactions', function () { it('voting twice for a delegate should fail', function (done) { node.async.series([ function (seriesCb) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`+${delegate}`] - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`+${delegate}`] + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; return seriesCb(); @@ -218,11 +213,10 @@ describe('POST /peer/transactions', function () { setTimeout(seriesCb, 1000); }, function (seriesCb) { - let transaction2 = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`+${delegate}`] - }); - transaction2.fee = node.fees.voteFee; + let transaction2 = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`+${delegate}`] + }); postVote(transaction2, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; return seriesCb(); @@ -232,11 +226,10 @@ describe('POST /peer/transactions', function () { return node.onNewBlock(seriesCb); }, function (seriesCb) { - let transaction2 = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`+${delegate}`] - }); - transaction2.fee = node.fees.voteFee; + let transaction2 = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`+${delegate}`] + }); postVote(transaction2, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; return seriesCb(); @@ -254,60 +247,63 @@ describe('POST /peer/transactions', function () { }); it('removing votes from a delegate should be ok', function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`-${delegate}`] - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`-${delegate}`] + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); node.onNewBlock(function (err) { + getVotes(account.address, function (err, res) { + node.expect(res.body).to.have.property('delegates').that.has.lengthOf(0); + }); return done(err); }); }); }); - it(['voting for ', constants.maxVotesPerTransaction, 'delegates at once should be ok'].join(' '), function (done) { - // return '+' + delegate; - // })); - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: delegates.slice(0, constants.maxVotesPerTransaction).map(x => `+${x}`) - }); - transaction.fee = node.fees.voteFee; + it(['voting for', constants.maxVotesPerTransaction, 'delegates at once should be ok'].join(' '), function (done) { + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: delegates.slice(0, constants.maxVotesPerTransaction).map(x => `+${x}`) + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); node.onNewBlock(function (err) { + getVotes(account.address, function (err, res) { + node.expect(res.body).to.have.property('delegates').that.has.lengthOf(constants.maxVotesPerTransaction); + }); return done(err); }); }); }); it(['removing votes from', constants.maxVotesPerTransaction, 'delegates at once should be ok'].join(' '), function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: delegates.slice(0, constants.maxVotesPerTransaction).map(x => `-${x}`) - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: delegates.slice(0, constants.maxVotesPerTransaction).map(x => `-${x}`) + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); node.onNewBlock(function (err) { + getVotes(account.address, function (err, res) { + node.expect(res.body).to.have.property('delegates').that.has.lengthOf(0); + }); return done(err); }); }); }); it(['voting for', constants.maxVotesPerTransaction + 1, 'delegates at once should fail'].join(' '), function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: delegates.slice(0, constants.maxVotesPerTransaction + 1).map(x => `+${x}`) - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: delegates.slice(0, constants.maxVotesPerTransaction + 1).map(x => `+${x}`) + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -330,12 +326,18 @@ describe('POST /peer/transactions', function () { }, done); }); + it('votes count must be 101 now', function (done) { + getVotes(account.address, function (err, res) { + node.expect(res.body).to.have.property('delegates').that.has.lengthOf(101); + done(); + }); + }); + it(['removing votes from', constants.maxVotesPerTransaction + 1, 'delegates at once should fail'].join(' '), function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: delegates.slice(0, constants.maxVotesPerTransaction + 1).map(x => `-${x}`) - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: delegates.slice(0, constants.maxVotesPerTransaction + 1).map(x => `-${x}`) + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -357,6 +359,13 @@ describe('POST /peer/transactions', function () { } }, done); }); + + it('votes count must be 0 now', function (done) { + getVotes(account.address, function (err, res) { + node.expect(res.body).to.have.property('delegates').that.has.lengthOf(0); + done(); + }); + }); }); describe('POST /peer/transactions after registering a new delegate', function () { @@ -374,7 +383,7 @@ describe('POST /peer/transactions after registering a new delegate', function () before(function (done) { sendADM({ secret: node.iAccount.password, - amount: 5000000000000, + amount: 1500000000000, // 15k ADM recipientId: account.address }, done); }); @@ -384,11 +393,10 @@ describe('POST /peer/transactions after registering a new delegate', function () }); it('voting for self should be ok', function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`+${account.publicKey.toString('hex')}`] - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`+${account.publicKey.toString('hex')}`] + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; @@ -420,15 +428,23 @@ describe('POST /peer/transactions after registering a new delegate', function () } }, seriesCb); }, + function (seriesCb) { + return node.onNewBlock(seriesCb); + }, + function (seriesCb) { + getVotes(account.address, function (err, res) { + node.expect(res.body).to.have.property('delegates').that.has.lengthOf(77); + seriesCb(err); + }); + }, function (seriesCb) { var slicedDelegates = delegates.slice(-25); node.expect(slicedDelegates).to.have.lengthOf(25); - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: slicedDelegates.map(x => `+${x}`) - }); - transaction.fee = node.fees.voteFee; + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: slicedDelegates.map(x => `+${x}`) + }); postVote(transaction, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; @@ -447,20 +463,18 @@ describe('POST /peer/transactions after registering a new delegate', function () }); }); - it('removing vote from self should be ok', function (done) { - let transaction = node.createVoteTransaction({ - keyPair: account.keypair, - votes: [`-${account.publicKey.toString('hex')}`] - }); - transaction.fee = node.fees.voteFee; - - postVote(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); - node.onNewBlock(function (err) { - return done(err); - }); - }); - }); + it('removing vote from self should be ok', function (done) { + let transaction = node.createVoteTransaction({ + keyPair: account.keypair, + votes: [`-${account.publicKey.toString('hex')}`] + }); + postVote(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + node.onNewBlock(function (err) { + return done(err); + }); + }); + }); }); diff --git a/test/config.json b/test/config.json index 57084cc9..49424861 100644 --- a/test/config.json +++ b/test/config.json @@ -75,11 +75,11 @@ } }, "broadcasts": { - "broadcastInterval": 5000, + "broadcastInterval": 1500, "broadcastLimit": 20, "parallelLimit": 20, "releaseLimit": 25, - "relayLimit": 2 + "relayLimit": 3 }, "transactions": { "maxTxsPerQueue": 1000 diff --git a/test/node.js b/test/node.js index 8947c5ba..0b641d41 100644 --- a/test/node.js +++ b/test/node.js @@ -35,6 +35,7 @@ require('colors'); // Node configuration node.baseUrl = 'http://' + node.config.address + ':' + node.config.port; // Note: using not a localhost-node can break tests where PUT requests are used, or involving cache +// When high load, remote node can accept PUT request and return success:true, but not actually broadcast a transaction // node.baseUrl = 'http://' + node.config.peers.list[2].ip + ':' + node.config.peers.list[2].port; node.api = node.supertest(node.baseUrl); @@ -253,6 +254,7 @@ node.createVoteTransaction = function (data) { transaction.recipientId= transaction.senderId; transaction.signature = this.transactionSign(transaction, data.keyPair); transaction.id = this.getId(transaction); + transaction.fee = node.fees.voteFee; return transaction; }; @@ -504,11 +506,16 @@ node.onNewBlock = function (cb) { if (err) { return cb(err); } else { - node.waitForNewBlock(height, 2, cb); + node.waitForNewBlock(height, 3, cb); } }); }; +// Waits for (ms) milliseconds +node.waitMilliSeconds = function (ms, cb) { + setTimeout(cb, ms); +}; + // Waits for (n) blocks to be created node.waitForBlocks = function (blocksToWait, cb) { node.getHeight(function (err, height) { From e8e1bd710a2ac9f633bf1d310295e0ce3237fdbc Mon Sep 17 00:00:00 2001 From: adamant-al Date: Thu, 9 Sep 2021 10:00:59 +0300 Subject: [PATCH 23/67] Fix tests for signatures --- test/api/signatures.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/test/api/signatures.js b/test/api/signatures.js index acf55e8d..d049ac6b 100644 --- a/test/api/signatures.js +++ b/test/api/signatures.js @@ -42,6 +42,7 @@ before(function (done) { setTimeout(function () { sendLISK(account2, done); }, 2000); + describe('PUT /api/transactions from account with second signature enabled', function () { before(function (done) { @@ -115,7 +116,7 @@ describe('PUT /api/signatures', function () { putSignature(validParams, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('error').to.match(/Account does not have enough ADM: U[0-9]+ balance: 0/); + node.expect(res.body).to.have.property('error').to.match(/API error: Mnemonic string is invalid: invalid/); done(); }); }); @@ -125,7 +126,7 @@ describe('PUT /api/signatures', function () { putSignature(validParams, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; - node.expect(res.body).to.have.property('error'); + node.expect(res.body).to.have.property('error').to.match(/Missing required property: secondSecret/); done(); }); }); @@ -135,7 +136,7 @@ describe('PUT /api/signatures', function () { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('transaction').that.is.an('object'); node.expect(res.body.transaction).to.have.property('type').to.equal(node.txTypes.SIGNATURE); - node.expect(res.body.transaction).to.have.property('senderPublicKey').to.equal(account.publicKey); + node.expect(res.body.transaction).to.have.property('senderPublicKey').to.equal(account.publicKeyHex); node.expect(res.body.transaction).to.have.property('senderId').to.equal(account.address); node.expect(res.body.transaction).to.have.property('fee').to.equal(node.fees.secondPasswordFee); done(); From 86e66ec12a7bca858f45da8dd27c3f445cfa2734 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Thu, 9 Sep 2021 10:29:06 +0300 Subject: [PATCH 24/67] Fix tests for transactions --- test/api/transactions.js | 298 +++++++++++++++++++-------------------- 1 file changed, 148 insertions(+), 150 deletions(-) diff --git a/test/api/transactions.js b/test/api/transactions.js index e59a95be..494b1f5b 100644 --- a/test/api/transactions.js +++ b/test/api/transactions.js @@ -35,7 +35,7 @@ function putTransaction (params, done) { } function postTransaction (params, done) { - node.post('/api/transactions', params, done); + node.post('/api/transactions', params, done); } function sendADM (account, amount, done) { @@ -63,9 +63,9 @@ function sendADM (account, amount, done) { } function sendADM2voter (params, done) { - node.put('/api/transactions/', params, function (err, res) { - done(err, res); - }); + node.put('/api/transactions/', params, function (err, res) { + done(err, res); + }); } before(function (done) { @@ -82,15 +82,13 @@ before(function (done) { before(function (done) { setTimeout(function () { - // Send 20 LSK - sendADM(account2, 20*100000000, done); + sendADM(account2, 20 * 100000000, done); }, 2000); }); before(function (done) { setTimeout(function () { - // Send 100 LSK - sendADM(account2, 100*100000000, done); + sendADM(account2, 100 * 100000000, done); }, 2000); }); @@ -234,8 +232,8 @@ describe('GET /api/transactions', function () { var limit = 10; var offset = 0; var orderBy = 'amount:asc'; - var minAmount = 20*100000000; - var maxAmount = constants.maxAmount/10000000; + var minAmount = 20 * 100000000; + var maxAmount = constants.maxAmount / 10000000; var params = [ 'minAmount=' + minAmount, @@ -250,7 +248,7 @@ describe('GET /api/transactions', function () { node.expect(res.body).to.have.property('transactions').that.is.an('array'); node.expect(res.body.transactions).to.have.length.within(2, limit); node.expect(res.body.transactions[0].amount).to.be.equal(minAmount); - node.expect(res.body.transactions[res.body.transactions.length-1].amount).to.be.equal(maxAmount); + node.expect(res.body.transactions[res.body.transactions.length - 1].amount).to.be.equal(maxAmount); for (var i = 0; i < res.body.transactions.length; i++) { if (res.body.transactions[i + 1]) { node.expect(res.body.transactions[i].amount).to.be.at.most(res.body.transactions[i + 1].amount); @@ -280,7 +278,7 @@ describe('GET /api/transactions', function () { node.expect(res.body).to.have.property('transactions').that.is.an('array'); node.expect(res.body.transactions).to.have.length.within(2, limit); node.expect(res.body.transactions[0].fee).to.be.equal(minFee); - node.expect(res.body.transactions[res.body.transactions.length-1].fee).to.be.equal(maxFee); + node.expect(res.body.transactions[res.body.transactions.length - 1].fee).to.be.equal(maxFee); for (var i = 0; i < res.body.transactions.length; i++) { if (res.body.transactions[i + 1]) { node.expect(res.body.transactions[i].fee).to.be.at.most(res.body.transactions[i + 1].fee); @@ -424,7 +422,7 @@ describe('GET /api/transactions', function () { }); it('using array-like types should be ok', function (done) { - const types = [node.txTypes.VOTE,node.txTypes.DELEGATE]; + const types = [node.txTypes.VOTE, node.txTypes.DELEGATE]; const params = 'types=' + types.join(','); node.get('/api/transactions?' + params, function (err, res) { @@ -460,7 +458,7 @@ describe('GET /api/transactions', function () { node.get('/api/transactions', function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('transactions').that.is.an('array'); - const transactions = res.body.transactions.sort((x,y) => y.amount - x.amount); + const transactions = res.body.transactions.sort((x, y) => y.amount - x.amount); for (var i = 0; i < transactions.length; i++) { if (transactions[i + 1]) { node.expect(transactions[i].amount).to.be.at.least(transactions[i + 1].amount); @@ -547,7 +545,7 @@ describe('GET /api/transactions', function () { node.expect(res.body).to.have.property('success').to.be.not.ok; node.expect(res.body).to.have.property('error'); done(); - }); + }); }); it('using completely invalid fields should fail', function (done) { @@ -593,7 +591,7 @@ describe('GET /api/transactions', function () { var dividedIndices = res.body.transactions.reduce(function (memo, peer, index) { memo[peer[sortField] === null ? 'nullIndices' : 'notNullIndices'].push(index); return memo; - }, {notNullIndices: [], nullIndices: []}); + }, { notNullIndices: [], nullIndices: [] }); if (dividedIndices.nullIndices.length && dividedIndices.notNullIndices.length) { var ascOrder = function (a, b) { return a - b; }; @@ -920,123 +918,123 @@ describe('PUT /api/transactions', function () { describe('POST /api/transactions', function () { - var account4 = node.randomAccount(); - var transaction; - - var accountModule; - - var attachTransferAsset = function (transaction, accountLogic, rounds, done) { - modulesLoader.initModuleWithDb(AccountModule, function (err, __accountModule) { - var transfer = new Transfer(); - transfer.bind(__accountModule, rounds); - transaction.attachAssetType(transactionTypes.SEND, transfer); - accountModule = __accountModule; - done(); - }, { - logic: { - account: accountLogic, - transaction: transaction - } - }); - }; - - before(function (done) { - sendADM2voter({ - secret: node.iAccount.password, - amount: 500000000000, - recipientId: account4.address - }, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId'); - node.expect(res.body.transactionId).to.be.not.empty; - }); - async.auto({ - rounds: function (cb) { - modulesLoader.initModule(Rounds, modulesLoader.scope,cb); - }, - accountLogic: function (cb) { - modulesLoader.initLogicWithDb(AccountLogic, cb); - }, - transaction: ['accountLogic', function (result, cb) { - modulesLoader.initLogicWithDb(Transaction, cb, { - ed: require('../../helpers/ed'), - account: result.accountLogic - }); - }] - }, function (err, result) { - transaction = result.transaction; - transaction.bindModules(result); - attachTransferAsset(transaction, result.accountLogic, result.rounds, done); - transaction.attachAssetType(transactionTypes.CHAT_MESSAGE, new Chat()); - transaction.attachAssetType(transactionTypes.STATE, new State()); - }); - }); - - beforeEach(function (done) { - node.onNewBlock(function (err) { - done(); - }); - }); + var account4 = node.randomAccount(); + var transaction; + + var accountModule; + + var attachTransferAsset = function (transaction, accountLogic, rounds, done) { + modulesLoader.initModuleWithDb(AccountModule, function (err, __accountModule) { + var transfer = new Transfer(); + transfer.bind(__accountModule, rounds); + transaction.attachAssetType(transactionTypes.SEND, transfer); + accountModule = __accountModule; + done(); + }, { + logic: { + account: accountLogic, + transaction: transaction + } + }); + }; + + before(function (done) { + sendADM2voter({ + secret: node.iAccount.password, + amount: 500000000000, + recipientId: account4.address + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId'); + node.expect(res.body.transactionId).to.be.not.empty; + }); + async.auto({ + rounds: function (cb) { + modulesLoader.initModule(Rounds, modulesLoader.scope, cb); + }, + accountLogic: function (cb) { + modulesLoader.initLogicWithDb(AccountLogic, cb); + }, + transaction: ['accountLogic', function (result, cb) { + modulesLoader.initLogicWithDb(Transaction, cb, { + ed: require('../../helpers/ed'), + account: result.accountLogic + }); + }] + }, function (err, result) { + transaction = result.transaction; + transaction.bindModules(result); + attachTransferAsset(transaction, result.accountLogic, result.rounds, done); + transaction.attachAssetType(transactionTypes.CHAT_MESSAGE, new Chat()); + transaction.attachAssetType(transactionTypes.STATE, new State()); + }); + }); + + beforeEach(function (done) { + node.onNewBlock(function (err) { + done(); + }); + }); it('should be OK for a normal transaction', function (done) { - var amountToSend = 100000000; - var expectedFee = node.expectedFee(amountToSend); + var amountToSend = 100000000; + var expectedFee = node.expectedFee(amountToSend); - postTransaction({ - secret: account.password, - amount: amountToSend, - recipientId: account2.address, + postTransaction({ + secret: account.password, + amount: amountToSend, + recipientId: account2.address, type: node.txTypes.SEND - }, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').that.is.not.empty; - transactionList.push({ - 'sender': account.address, - 'recipient': account2.address, - 'grossSent': (amountToSend + expectedFee) / node.normalizer, - 'fee': expectedFee / node.normalizer, - 'netSent': amountToSend / node.normalizer, - 'txId': res.body.transactionId, - 'type': node.txTypes.SEND - }); - done(); - }); - }); + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + transactionList.push({ + 'sender': account.address, + 'recipient': account2.address, + 'grossSent': (amountToSend + expectedFee) / node.normalizer, + 'fee': expectedFee / node.normalizer, + 'netSent': amountToSend / node.normalizer, + 'txId': res.body.transactionId, + 'type': node.txTypes.SEND + }); + done(); + }); + }); it('should be OK for a vote transaction', function (done) { - postTransaction({ - secret: account4.password, - delegates: ['+' + node.eAccount.publicKey], - type: node.txTypes.VOTE, - }, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transaction').that.is.an('object'); - node.expect(res.body.transaction.type).to.equal(node.txTypes.VOTE); - node.expect(res.body.transaction.amount).to.equal(0); - node.expect(res.body.transaction.senderPublicKey).to.equal(account4.publicKey.toString('hex')); - node.expect(res.body.transaction.fee).to.equal(node.fees.voteFee); - done(); - }); - }); + postTransaction({ + secret: account4.password, + delegates: ['+' + node.eAccount.publicKey], + type: node.txTypes.VOTE, + }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction').that.is.an('object'); + node.expect(res.body.transaction.type).to.equal(node.txTypes.VOTE); + node.expect(res.body.transaction.amount).to.equal(0); + node.expect(res.body.transaction.senderPublicKey).to.equal(account4.publicKey.toString('hex')); + node.expect(res.body.transaction.fee).to.equal(node.fees.voteFee); + done(); + }); + }); it('should be OK for a register delegate transaction', function (done) { account4.username = node.randomDelegateName(); - postTransaction({ username: account4.username, secret: account4.password, type: node.txTypes.DELEGATE}, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transaction').that.is.an('object'); - node.expect(res.body.transaction.fee).to.equal(node.fees.delegateRegistrationFee); - node.expect(res.body.transaction).to.have.property('asset').that.is.an('object'); - node.expect(res.body.transaction.asset.delegate.username).to.equal(account4.username.toLowerCase()); - node.expect(res.body.transaction.asset.delegate.publicKey).to.equal(account4.publicKey.toString('hex')); - node.expect(res.body.transaction.type).to.equal(node.txTypes.DELEGATE); - node.expect(res.body.transaction.amount).to.equal(0); - done(); - }); - }); + postTransaction({ username: account4.username, secret: account4.password, type: node.txTypes.DELEGATE }, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction').that.is.an('object'); + node.expect(res.body.transaction.fee).to.equal(node.fees.delegateRegistrationFee); + node.expect(res.body.transaction).to.have.property('asset').that.is.an('object'); + node.expect(res.body.transaction.asset.delegate.username).to.equal(account4.username.toLowerCase()); + node.expect(res.body.transaction.asset.delegate.publicKey).to.equal(account4.publicKey.toString('hex')); + node.expect(res.body.transaction.type).to.equal(node.txTypes.DELEGATE); + node.expect(res.body.transaction.amount).to.equal(0); + done(); + }); + }); it('should be OK for chat message transaction', function (done) { - let recipient = node.randomAccount(); + let recipient = node.randomAccount(); let trs = { recipientId: recipient.address, senderPublicKey: account4.publicKey.toString('hex'), @@ -1044,10 +1042,10 @@ describe('POST /api/transactions', function () { type: node.txTypes.CHAT_MESSAGE, amount: 0, asset: { - chat : { - message: 'hello, world!', - own_message: '', - type: 1 + chat: { + message: 'hello, world!', + own_message: '', + type: 1 } }, timestamp: Math.floor((Date.now() - constants.epochTime.getTime()) / 1000) @@ -1055,35 +1053,35 @@ describe('POST /api/transactions', function () { trs.signature = transaction.sign(account4.keypair, trs); postTransaction({ transaction: trs }, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId'); - done(); - }); - }); + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId'); + done(); + }); + }); it('should be OK for state transaction', function (done) { let recipient = node.randomAccount(); - let trs = { - recipientId: recipient.address, - senderPublicKey: account4.publicKey.toString('hex'), - senderId: account4.address, - type: node.txTypes.STATE, - amount: 0, - asset: { - state : { - key: 'testkey', - value: 'testValue', - type: 0 - } - }, - timestamp: Math.floor((Date.now() - constants.epochTime.getTime()) / 1000) - }; - trs.signature = transaction.sign(account4.keypair, trs); + let trs = { + recipientId: recipient.address, + senderPublicKey: account4.publicKey.toString('hex'), + senderId: account4.address, + type: node.txTypes.STATE, + amount: 0, + asset: { + state: { + key: 'testkey', + value: 'testValue', + type: 0 + } + }, + timestamp: Math.floor((Date.now() - constants.epochTime.getTime()) / 1000) + }; + trs.signature = transaction.sign(account4.keypair, trs); postTransaction({ transaction: trs }, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId'); + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId'); done(); - }); + }); - }); + }); }); From fdc247f68e37573c64885d322025bf1d91d27d26 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Thu, 9 Sep 2021 10:35:16 +0300 Subject: [PATCH 25/67] Turn of multisignature tests --- test/unit/logic/multisignature.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/test/unit/logic/multisignature.js b/test/unit/logic/multisignature.js index bee7639c..c7a5e452 100644 --- a/test/unit/logic/multisignature.js +++ b/test/unit/logic/multisignature.js @@ -1,4 +1,7 @@ -'use strict';/*eslint*/ +// Multisignatures tests are disabled currently + +/* +'use strict'; var node = require('./../../node.js'); var ed = require('../../../helpers/ed'); @@ -363,3 +366,4 @@ describe('multisignature', function () { }); }); }); +*/ From 1f60ae1b01bc475875dae0b15611f64bc71852e1 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Thu, 9 Sep 2021 19:35:01 +0300 Subject: [PATCH 26/67] Fix tests for transaction --- test/node.js | 3 +- test/unit/logic/peers.js | 2 +- test/unit/logic/transaction.js | 270 +++++++++++++------------------ test/unit/schema/transactions.js | 10 +- 4 files changed, 122 insertions(+), 163 deletions(-) diff --git a/test/node.js b/test/node.js index 0b641d41..be246297 100644 --- a/test/node.js +++ b/test/node.js @@ -94,7 +94,7 @@ node.testSender = _.defaults({ },validSender); -node.marketDelegate = _.defaults({ +node.kindDelegate = _.defaults({ address: 'U12559234133690317086', publicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', isDelegate: 1, @@ -107,7 +107,6 @@ node.createKeypairFromPassphrase = function (passphrase) { }; // Existing delegate account -// TODO: replace me with a market delegate node.eAccount = { address: 'U12559234133690317086', publicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', diff --git a/test/unit/logic/peers.js b/test/unit/logic/peers.js index 118bd7fb..0509fa12 100644 --- a/test/unit/logic/peers.js +++ b/test/unit/logic/peers.js @@ -173,7 +173,7 @@ describe('peers', function () { removeAll(); }); - it('should insert peer with different ips', function () { + it('should insert peer with different IPs', function () { removeAll(); peers.upsert(randomPeer); diff --git a/test/unit/logic/transaction.js b/test/unit/logic/transaction.js index e08c4923..77d04055 100644 --- a/test/unit/logic/transaction.js +++ b/test/unit/logic/transaction.js @@ -8,7 +8,7 @@ var async = require('async'); // var chai = require('chai'); var expect = require('chai').expect; -var _ = require('lodash'); +var _ = require('lodash'); var transactionTypes = require('../../../helpers/transactionTypes'); var slots = require('../../../helpers/slots'); @@ -22,34 +22,27 @@ var Vote = require('../../../logic/vote.js'); var Transfer = require('../../../logic/transfer.js'); var Delegate = require('../../../logic/delegate.js'); var Signature = require('../../../logic/signature.js'); -// var Multisignature = require('../../../logic/multisignature.js'); +var Multisignature = require('../../../logic/multisignature.js'); var InTransfer = require('../../../logic/inTransfer.js'); var OutTransfer = require('../../../logic/outTransfer.js'); var Chat = require('../../../logic/chat.js'); var State = require('../../../logic/state.js'); +// valid keypair sample (market delegate's passphrase) var validPassword = 'rally clean ladder crane gadget century timber jealous shine scorpion beauty salon'; -// Fix here to library.ed.createPassPhraseHash() -var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); - -// Fix here to library.ed.createPassPhraseHash() -var senderHash = crypto.createHash('sha256').update(node.iAccount.password, 'utf8').digest(); -var senderKeypair = ed.makeKeypair(senderHash); +var validHash = ed.createPassPhraseHash(validPassword); +var validKeypair = ed.makeKeypair(validHash); +// stub for a valid sender let validSender = { username: null, isDelegate: 0, secondSignature: 0, - // address: 'U810656636599221322', - // publicKey: 'f4011a1360ac2769e066c789acaaeffa9d707690d4d3f6085a7d52756fbc30d0', secondPublicKey: null, - // balance: 9850458911801508, - // u_balance: 9850458911801508, vote: 0, multisignatures: null, multimin: 0, multilifetime: 0, - // blockId: '8505659485551877884', nameexist: 0, producedblocks: 0, missedblocks: 0, @@ -58,87 +51,70 @@ let validSender = { virgin: 0 }; -let marketDelegate = _.defaults({ +// valid sender to test transactions (kind delegate) +var testSender = _.defaults({ address: 'U12559234133690317086', publicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', - isDelegate: 1, - secret: 'rally clean ladder crane gadget century timber jealous shine scorpion beauty salon' -},validSender); - -// Fix here to library.ed.createPassPhraseHash() -const marketDelegateHash = crypto.createHash('sha256').update(marketDelegate.secret, 'utf8').digest(); -const marketDelegateKeypair = ed.makeKeypair(marketDelegateHash); - -const validRecipient = _.defaults({ - address: 'U7771441689362721578', - publicKey: 'd3a3c26c3906080689d0c2ccd3df30f2f4797c881e21a92aa4579bc68744581f' -},validSender); + secret: 'weather play vibrant large edge clean notable april fire smoke drift hidden', + u_balance: 10000000000000, + balance: 100000000000000 +}, validSender); +const testSenderHash = node.accounts.createPassPhraseHash(testSender.secret); +const testSenderKeypair = node.accounts.makeKeypair(testSenderHash); +// genesis account const genesis = _.defaults({ address: 'U15365455923155964650', publicKey: 'b80bb6459608dcdeb9a98d1f2b0111b2bf11e53ef2933e6769bb0198e3a97aae', secret: 'neck want coast appear army smile palm major crumble upper void warm', balance: 0 -},validSender); -// Fix here to library.ed.createPassPhraseHash() -const genesisHash = crypto.createHash('sha256').update(genesis.secret, 'utf8').digest(); +}, validSender); +const genesisHash = ed.createPassPhraseHash(genesis.secret); const genesisKeypair = ed.makeKeypair(genesisHash); -var validTransactionData = { +// valid new tx sample from a test sender +var validUnconfirmedTrs = { type: 0, - amount: 8067474861277, - sender: marketDelegate, - senderId: marketDelegate.address, - recipientId: validRecipient.address, - fee: 10000000, - keypair: marketDelegateKeypair, - senderPublicKey: marketDelegate.publicKey, - timestamp: 0 + amount: 100, + senderId: testSender.address, + senderPublicKey: testSender.publicKey, + recipientId: 'U7771441689362721578', + fee: 50000000, + timestamp: 1000, + asset: {} }; -// validTransactionData.signature = transaction.sign(marketDelegateKeypair, validTransactionData); - -var validTransaction = { - id: '8413713814903125448', - rowId: 133, - blockId: '1523428076558779496', +// valid new tx sample from a test sender, but with keypair +var validTransactionData = { type: 0, - timestamp: 33363661, - senderPublicKey: 'f4011a1360ac2769e066c789acaaeffa9d707690d4d3f6085a7d52756fbc30d0', - senderId: 'U6416794499161724697', - recipientId: 'U13030924027576053821', - amount: 100000000, + amount: 8067474861277, + keypair: testSenderKeypair, + sender: testSender, + senderId: testSender.address, + senderPublicKey: testSender.publicKey, + recipientId: 'U7771441689362721578', fee: 50000000, - signature: '85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01', - signSignature: null, - requesterPublicKey: null, - signatures: null, - asset: {}, + timestamp: 1000 }; -// from genesis to ico -var existedTransaction = { - id: '8787084714365585523', - blockId: '6438017970172540087', - type: 0, - sender: genesis, - senderPublicKey: genesis.publicKey, - senderId: genesis.address, - recipientId: 'U2509016256839651561', - amount: 7350000000000000, - fee: 50000000, - signature: 'b824bb51bc5a7f1a134e95445d8cd24ca15d49594d2c28c8711a941cdcbf98d405cd9b5d81c4a31e10a57262920136f20d114d956b423d3210bcf46486667500', - asset: {}, - timestamp: 0 +// valid tx sample, got from api endpoint (from genesis to devs) +var validTransaction = { + id: '17190511997607511181', + blockId: '6438017970172540087', + type: 0, + block_timestamp: null, + timestamp: 0, + senderPublicKey: 'b80bb6459608dcdeb9a98d1f2b0111b2bf11e53ef2933e6769bb0198e3a97aae', + senderId: 'U15365455923155964650', + recipientId: 'U9781760580710719871', + amount: 490000000000000, + fee: 0, + signature: '85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01', + signatures: [], + asset: {} }; -// var genesisAcc = { ...validSender, -// ...{ -// address: 'U15365455923155964650', -// publicKey: 'b80bbmarketDelegate6459608dcdeb9a98d1f2b0111b2bf11e53ef2933e6769bb0198e3a97aae' -// } -// }; - +// valid raw tx sample (same) var rawValidTransaction = { t_id: '17190511997607511181', b_height: 981, @@ -150,45 +126,25 @@ var rawValidTransaction = { t_senderId: 'U810656636599221322', t_recipientId: 'U7771441689362721578', t_amount: 490000000000000, - t_fee: 10000000, + t_fee: 0, t_signature: '85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01', confirmations: 8343 }; +// from genesis to devs var genesisTrs = { type: 0, amount: 490000000000000, fee: 0, timestamp: 0, - recipientId: 'U7771441689362721578', - senderId: 'U810656636599221322', - senderPublicKey: 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', + recipientId: 'U9781760580710719871', + senderId: 'U15365455923155964650', + senderPublicKey: 'b80bb6459608dcdeb9a98d1f2b0111b2bf11e53ef2933e6769bb0198e3a97aae', signature: '85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01', blockId: '6438017970172540087', id: '17190511997607511181' }; -var testSender = _.defaults({ - address: 'U12559234133690317086', - publicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', - secret: 'weather play vibrant large edge clean notable april fire smoke drift hidden', - u_balance: 10000000000000, - balance: 100000000000000 -},validSender); -// Fix here to library.ed.createPassPhraseHash() -const testSenderHash = node.accounts.createPassPhraseHash(testSender.secret); //crypto.createHash('sha256').update(testSender.secret, 'utf8').digest(); -const testSenderKeypair = node.accounts.makeKeypair(testSenderHash); -var validUnconfirmedTrs = { - type: 0, - amount: 100, - senderPublicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', - senderId: 'U12559234133690317086', - timestamp: 0, - asset: {}, - recipientId: 'U7771441689362721578', - fee: 50000000 -}; - describe('transaction', function () { @@ -213,7 +169,7 @@ describe('transaction', function () { before(function (done) { async.auto({ rounds: function (cb) { - modulesLoader.initModule(Rounds, modulesLoader.scope,cb); + modulesLoader.initModule(Rounds, modulesLoader.scope, cb); }, accountLogic: function (cb) { modulesLoader.initLogicWithDb(AccountLogic, cb); @@ -227,7 +183,7 @@ describe('transaction', function () { }, function (err, result) { transaction = result.transaction; transaction.bindModules(result); - attachTransferAsset(transaction, result.accountLogic, result.rounds, done); + attachTransferAsset(transaction, result.accountLogic, result.rounds, done); }); }); @@ -270,16 +226,16 @@ describe('transaction', function () { expect(appliedLogic).to.be.an.instanceof(Delegate); appliedLogic = transaction.attachAssetType(transactionTypes.SIGNATURE, new Signature()); expect(appliedLogic).to.be.an.instanceof(Signature); - // appliedLogic = transaction.attachAssetType(transactionTypes.MULTI, new Multisignature()); - // expect(appliedLogic).to.be.an.instanceof(Multisignature); - appliedLogic = transaction.attachAssetType(transactionTypes.IN_TRANSFER, new InTransfer()); + appliedLogic = transaction.attachAssetType(transactionTypes.MULTI, new Multisignature()); + expect(appliedLogic).to.be.an.instanceof(Multisignature); + appliedLogic = transaction.attachAssetType(transactionTypes.IN_TRANSFER, new InTransfer()); expect(appliedLogic).to.be.an.instanceof(InTransfer); appliedLogic = transaction.attachAssetType(transactionTypes.OUT_TRANSFER, new OutTransfer()); expect(appliedLogic).to.be.an.instanceof(OutTransfer); - appliedLogic = transaction.attachAssetType(transactionTypes.CHAT_MESSAGE, new Chat()); - expect(appliedLogic).to.be.an.instanceof(Chat); - appliedLogic = transaction.attachAssetType(transactionTypes.STATE, new State()); - expect(appliedLogic).to.be.an.instanceof(State); + appliedLogic = transaction.attachAssetType(transactionTypes.CHAT_MESSAGE, new Chat()); + expect(appliedLogic).to.be.an.instanceof(Chat); + appliedLogic = transaction.attachAssetType(transactionTypes.STATE, new State()); + expect(appliedLogic).to.be.an.instanceof(State); return transaction; }); @@ -301,7 +257,10 @@ describe('transaction', function () { }); it('should sign transaction', function () { - expect(transaction.sign(genesisKeypair, existedTransaction)).to.be.a('string').which.is.equal('33bfe35fbe231fcb8895e5440a0f5d33beb1d17a16cdc8ea0e78a65c1e9beff8bf918775b6955d97b06b73942440d13ff375fe95ab5635e2177f995a3d269b09'); + var notSignedTx = _.cloneDeep(validTransaction); + delete notSignedTx.signature; + // expect(transaction.sign(genesisKeypair, validTransaction)).to.be.a('string').which.is.equal('85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01'); + expect(transaction.sign(genesisKeypair, notSignedTx)).to.be.a('string').which.is.equal('85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01'); }); }); @@ -312,7 +271,7 @@ describe('transaction', function () { // }); // // it('should multisign the transaction', function () { - // expect(transaction.multisign(senderKeypair, validTransaction)).to.equal(validTransaction.signature); + // expect(transaction.multisign(testSenderKeypair, validTransaction)).to.equal(validTransaction.signature); // }); // }); @@ -323,7 +282,7 @@ describe('transaction', function () { }); it('should generate the id of the trs', function () { - expect(transaction.getId(existedTransaction)).to.be.a('string').which.is.equal(existedTransaction.id); + expect(transaction.getId(genesisTrs)).to.be.a('string').which.is.equal(genesisTrs.id); }); it('should update id if a field in trs value changes', function () { @@ -342,12 +301,12 @@ describe('transaction', function () { it('should return hash for trs', function () { var trs = validTransaction; - var expectedHash = 'a74da7ebf7ce42f20d260157a50b0f202a0eea3e89c24dcf1d0a870fb7e80d61'; + var expectedHash = '8d847c2495f790ee1f203c572f998b02376c37be57a8853bbbdcbc882d07b639'; expect(transaction.getHash(trs).toString('hex')).to.be.a('string').which.is.equal(expectedHash); }); it('should update hash if a field is trs value changes', function () { - var originalTrsHash = '5164ef55fccefddf72360ea6e05f19eed7c8d2653c5069df4db899c47246dd2f'; + var originalTrsHash = '8d847c2495f790ee1f203c572f998b02376c37be57a8853bbbdcbc882d07b639'; var trs = _.cloneDeep(validTransaction); trs.amount = 4000; expect(transaction.getHash(trs).toString('hex')).to.not.equal(originalTrsHash); @@ -411,7 +370,7 @@ describe('transaction', function () { }); it('should return count of trs in db with trs id', function (done) { - transaction.countById(existedTransaction, function (err, count) { + transaction.countById(validTransaction, function (err, count) { expect(err).to.not.exist; expect(count).to.be.equal(1); done(); @@ -459,9 +418,9 @@ describe('transaction', function () { }); it('should return error when sender has insufficiant balance', function () { - var amount = '49000000000000000000000'; + var amount = '49000000000000000000000'; var balanceKey = 'balance'; - let sender = _.cloneDeep(marketDelegate); + let sender = _.cloneDeep(testSender); sender.balance = 0; var res = transaction.checkBalance(amount, balanceKey, validUnconfirmedTrs, sender); expect(res.exceeded).to.equal(true); @@ -469,10 +428,10 @@ describe('transaction', function () { }); it('should be okay if insufficient balance from genesis account', function () { - var amount = '999823366072900'; + var amount = '999823366072900'; var balanceKey = 'balance'; - let sender = _.cloneDeep(genesis); - sender.balance = 0; + let sender = _.cloneDeep(genesis); + sender.balance = 0; var res = transaction.checkBalance(amount, balanceKey, genesisTrs, sender); expect(res.exceeded).to.equal(false); expect(res.error).to.not.exist; @@ -521,7 +480,7 @@ describe('transaction', function () { }); it('should process the transaction', function (done) { - transaction.process(existedTransaction, genesis, function (err, res) { + transaction.process(genesisTrs, genesis, function (err, res) { expect(err).to.not.be.ok; expect(res).to.be.an('object'); expect(res.senderId).to.be.a('string').which.is.equal(genesis.address); @@ -532,12 +491,12 @@ describe('transaction', function () { describe('verify', function () { - function createAndProcess (trsData, sender, cb) { + function createAndProcess(trsData, sender, cb) { var trs = transaction.create(trsData); transaction.process(trs, sender, function (err, __trs) { expect(err).to.not.exist; expect(__trs).to.be.an('object'); - cb(__trs); trs.senderId = sender.address; + cb(__trs); trs.senderId = sender.address; }); } @@ -594,8 +553,8 @@ describe('transaction', function () { // }); it('should return error when trs sender publicKey and sender public key are different', function (done) { - var trs = _.cloneDeep(existedTransaction); - var invalidPublicKey = '01389197bbaf1afb0acd47bbfeabb34aca80fb372a8f694a1c0716b3398db746'; + var trs = _.cloneDeep(validTransaction); + var invalidPublicKey = '01389197bbaf1afb0acd47bbfeabb34aca80fb372a8f694a1c0716b3398db746'; trs.senderPublicKey = invalidPublicKey; transaction.verify(trs, genesis, {}, function (err) { @@ -605,7 +564,7 @@ describe('transaction', function () { }); it('should be impossible to send the money from genesis account', function (done) { - var trs = transaction.create(validTransactionData); + var trs = transaction.create(validTransactionData); trs.senderId = 'U15365455923155964650'; trs.senderPublicKey = 'b80bb6459608dcdeb9a98d1f2b0111b2bf11e53ef2933e6769bb0198e3a97aae'; var vs = _.cloneDeep(validSender); @@ -618,7 +577,7 @@ describe('transaction', function () { }); it('should return error on different sender address in trs and sender', function (done) { - var trs = _.cloneDeep(existedTransaction); + var trs = _.cloneDeep(validTransaction); trs.senderId = 'U2581762640681118072'; transaction.verify(trs, genesis, {}, function (err) { @@ -642,9 +601,9 @@ describe('transaction', function () { // }); it('should return error when signature is not correct', function (done) { - var trs = _.cloneDeep(existedTransaction); + var trs = _.cloneDeep(validTransaction); // valid keypair is a different account - trs.signature = transaction.sign(marketDelegateKeypair, trs); + trs.signature = transaction.sign(testSenderKeypair, trs); transaction.verify(trs, genesis, {}, function (err) { expect(err).to.include('Failed to verify signature'); done(); @@ -657,7 +616,7 @@ describe('transaction', function () { // vs.multisignatures = [validKeypair.publicKey.toString('hex')]; // delete trs.signature; // trs.signatures = Array.apply(null, Array(2)).map(function () { return transaction.sign(validKeypair, trs); }); - // trs.signature = transaction.sign(senderKeypair, trs); + // trs.signature = transaction.sign(testSenderKeypair, trs); // transaction.verify(trs, vs, {}, function (err) { // expect(err).to.equal('Encountered duplicate signature in transaction'); // done(); @@ -670,7 +629,7 @@ describe('transaction', function () { // vs.multisignatures = [validKeypair.publicKey.toString('hex')]; // trs.requesterPublicKey = validKeypair.publicKey.toString('hex'); // delete trs.signature; - // // using validKeypair as opposed to senderKeypair + // // using validKeypair as opposed to testSenderKeypair // trs.signatures = [transaction.sign(validKeypair, trs)]; // trs.signature = transaction.sign(validKeypair, trs); // transaction.verify(trs, vs, {}, function (err) { @@ -684,7 +643,7 @@ describe('transaction', function () { // var vs = _.cloneDeep(validSender); // vs.multisignatures = [validKeypair.publicKey.toString('hex')]; // delete trs.signature; - // trs.signature = transaction.sign(senderKeypair, trs); + // trs.signature = transaction.sign(testSenderKeypair, trs); // trs.signatures = [transaction.multisign(validKeypair, trs)]; // transaction.verify(trs, vs, {}, function (err) { // expect(err).to.not.exist; @@ -728,7 +687,7 @@ describe('transaction', function () { // }); it('should throw return error transaction fee is incorrect', function (done) { - var trs = _.cloneDeep(existedTransaction); + var trs = _.cloneDeep(genesisTrs); trs.fee = -100; transaction.verify(trs, genesis, {}, function (err) { expect(err).to.include('Invalid transaction fee'); @@ -738,7 +697,7 @@ describe('transaction', function () { it('should verify transaction with correct fee (without data field)', function (done) { let trs = _.cloneDeep(validUnconfirmedTrs); - trs.signature = transaction.sign(testSenderKeypair, trs); + trs.signature = transaction.sign(testSenderKeypair, trs); transaction.verify(trs, testSender, {}, function (err) { expect(err).to.not.exist; done(); @@ -747,7 +706,7 @@ describe('transaction', function () { it('should return error when transaction amount is invalid', function (done) { var trsData = _.cloneDeep(validUnconfirmedTrs); - trsData.amount = node.constants.totalAmount + 10; + trsData.amount = node.constants.totalAmount + 10; trsData.signature = transaction.sign(testSenderKeypair, trsData); transaction.verify(trsData, testSender, {}, function (err) { expect(err).to.include('Invalid transaction amount'); @@ -822,7 +781,7 @@ describe('transaction', function () { var trs = _.cloneDeep(validTransactionData); // change trs value trs.amount = 1001; - expect(transaction.verifySignature(trs, marketDelegate.publicKey, trs.signature)).to.equal(false); + expect(transaction.verifySignature(trs, testSender.publicKey, trs.signature)).to.equal(false); }); it('should return false if signature not provided', function () { @@ -831,7 +790,7 @@ describe('transaction', function () { }); it('should return valid signature for correct trs', function () { - var trs = existedTransaction; + var trs = genesisTrs; expect(transaction.verifySignature(trs, genesis.publicKey, trs.signature)).to.equal(true); }); @@ -877,8 +836,8 @@ describe('transaction', function () { }); it('should be okay for valid bytes', function () { - var trsBytes = transaction.getBytes(existedTransaction, true, true); - var res = transaction.verifyBytes(trsBytes, existedTransaction.senderPublicKey, existedTransaction.signature); + var trsBytes = transaction.getBytes(genesisTrs, true, true); + var res = transaction.verifyBytes(trsBytes, genesisTrs.senderPublicKey, genesisTrs.signature); expect(res).to.equal(true); }); }); @@ -889,8 +848,8 @@ describe('transaction', function () { height: 1 }; - function undoTransaction (trs, sender, done) { - transaction.undo(trs, dummyBlock, sender, done); + function undoTransaction(trs, sender, done) { + transaction.undo(trs, dummyBlock, sender, done); } it('should throw an error with no param', function () { @@ -898,14 +857,14 @@ describe('transaction', function () { }); it('should be okay with valid params', function (done) { - var trs = existedTransaction; + var trs = validTransaction; transaction.apply(trs, dummyBlock, genesis, done); }); it('should return error on if balance is low', function (done) { var trs = _.cloneDeep(validTransactionData); trs.amount = '9850458911801908'; - let sender = _.cloneDeep(marketDelegate); + let sender = _.cloneDeep(testSender); sender.balance = 0; transaction.apply(trs, dummyBlock, sender, function (err) { expect(err).to.include('Account does not have enough '); @@ -914,12 +873,12 @@ describe('transaction', function () { }); it('should subtract balance from sender account on valid transaction', function (done) { - accountModule.getAccount({publicKey: validUnconfirmedTrs.senderPublicKey}, function (err, accountBefore) { + accountModule.getAccount({ publicKey: validUnconfirmedTrs.senderPublicKey }, function (err, accountBefore) { var amount = new bignum(validUnconfirmedTrs.amount.toString()).plus(validUnconfirmedTrs.fee.toString()); var balanceBefore = new bignum(accountBefore.balance.toString()); transaction.apply(validUnconfirmedTrs, dummyBlock, testSender, function (err) { - accountModule.getAccount({publicKey: validUnconfirmedTrs.senderPublicKey}, function (err, accountAfter) { + accountModule.getAccount({ publicKey: validUnconfirmedTrs.senderPublicKey }, function (err, accountAfter) { expect(err).to.not.exist; var balanceAfter = new bignum(accountAfter.balance.toString()); expect(balanceAfter.plus(amount).toString()).to.equal(balanceBefore.toString()); @@ -936,7 +895,7 @@ describe('transaction', function () { height: 1 }; - function applyTransaction (trs, sender, done) { + function applyTransaction(trs, sender, done) { transaction.apply(trs, dummyBlock, sender, done); } @@ -950,11 +909,11 @@ describe('transaction', function () { var amount = new bignum(trs.amount.toString()).plus(trs.fee.toString()); delete trs.recipientId; - accountModule.getAccount({publicKey: trs.senderPublicKey}, function (err, accountBefore) { + accountModule.getAccount({ publicKey: trs.senderPublicKey }, function (err, accountBefore) { var balanceBefore = new bignum(accountBefore.balance.toString()); transaction.undo(trs, dummyBlock, testSender, function (err) { - accountModule.getAccount({publicKey: trs.senderPublicKey}, function (err, accountAfter) { + accountModule.getAccount({ publicKey: trs.senderPublicKey }, function (err, accountAfter) { var balanceAfter = new bignum(accountAfter.balance.toString()); expect(balanceBefore.plus(amount.mul(2)).toString()).to.not.equal(balanceAfter.toString()); @@ -969,11 +928,11 @@ describe('transaction', function () { var trs = validUnconfirmedTrs; var amount = new bignum(trs.amount.toString()).plus(trs.fee.toString()); - accountModule.getAccount({publicKey: trs.senderPublicKey}, function (err, accountBefore) { + accountModule.getAccount({ publicKey: trs.senderPublicKey }, function (err, accountBefore) { var balanceBefore = new bignum(accountBefore.balance.toString()); transaction.undo(trs, dummyBlock, testSender, function (err) { - accountModule.getAccount({publicKey: trs.senderPublicKey}, function (err, accountAfter) { + accountModule.getAccount({ publicKey: trs.senderPublicKey }, function (err, accountAfter) { expect(err).to.not.exist; var balanceAfter = new bignum(accountAfter.balance.toString()); @@ -987,8 +946,8 @@ describe('transaction', function () { describe('applyUnconfirmed', function () { - function undoUnconfirmedTransaction (trs, sender, done) { - transaction.undoUnconfirmed(trs, sender, done); + function undoUnconfirmedTransaction(trs, sender, done) { + transaction.undoUnconfirmed(trs, sender, done); } it('should throw an error with no param', function () { @@ -1020,7 +979,7 @@ describe('transaction', function () { describe('undoUnconfirmed', function () { - function applyUnconfirmedTransaction (trs, sender, done) { + function applyUnconfirmedTransaction(trs, sender, done) { transaction.applyUnconfirmed(trs, sender, done); } @@ -1033,7 +992,7 @@ describe('transaction', function () { transaction.undoUnconfirmed(validUnconfirmedTrs, testSender, function (err) { expect(err).to.not.exist; applyUnconfirmedTransaction(validUnconfirmedTrs, testSender, done); - }); + }); }); }); @@ -1056,7 +1015,7 @@ describe('transaction', function () { var vs = _.cloneDeep(validSender); vs.multisignatures = [validKeypair.publicKey.toString('hex')]; delete trs.signature; - trs.signature = transaction.sign(senderKeypair, trs); + trs.signature = transaction.sign(testSenderKeypair, trs); trs.signatures = [transaction.multisign(validKeypair, trs)]; var savePromise = transaction.dbSave(trs); expect(savePromise).to.be.an('Array'); @@ -1150,6 +1109,7 @@ describe('transaction', function () { 'id', 'height', 'blockId', + 'block_timestamp', 'type', 'timestamp', 'senderPublicKey', diff --git a/test/unit/schema/transactions.js b/test/unit/schema/transactions.js index 407a3f11..82218ab8 100644 --- a/test/unit/schema/transactions.js +++ b/test/unit/schema/transactions.js @@ -41,13 +41,13 @@ describe('transactions', function () { senderPublicKey: node.testSender.publicKey, ownerPublicKey: node.testSender.publicKey, ownerAddress: node.testSender.address, - recipientId: node.marketDelegate.address, + recipientId: node.kindDelegate.address, amount: 100, fee: 20, - senderPublicKeys: [node.testSender.publicKey, node.marketDelegate.publicKey], - recipientPublicKeys: [node.testSender.publicKey, node.marketDelegate.publicKey], - senderIds: [node.testSender.address, node.marketDelegate.address], - recipientIds: [node.testSender.address, node.marketDelegate.address], + senderPublicKeys: [node.testSender.publicKey, node.kindDelegate.publicKey], + recipientPublicKeys: [node.testSender.publicKey, node.kindDelegate.publicKey], + senderIds: [node.testSender.address, node.kindDelegate.address], + recipientIds: [node.testSender.address, node.kindDelegate.address], fromHeight: 1, toHeight: 2, fromTimestamp: 0, From 9e4ab40acb6b4602a60caef3a05429362149571e Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 10 Sep 2021 13:14:54 +0300 Subject: [PATCH 27/67] Fix tests for transaction (2) --- test/unit/logic/transaction.js | 317 +++++++++++++++++---------------- 1 file changed, 161 insertions(+), 156 deletions(-) diff --git a/test/unit/logic/transaction.js b/test/unit/logic/transaction.js index 77d04055..78898dec 100644 --- a/test/unit/logic/transaction.js +++ b/test/unit/logic/transaction.js @@ -259,21 +259,24 @@ describe('transaction', function () { it('should sign transaction', function () { var notSignedTx = _.cloneDeep(validTransaction); delete notSignedTx.signature; - // expect(transaction.sign(genesisKeypair, validTransaction)).to.be.a('string').which.is.equal('85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01'); - expect(transaction.sign(genesisKeypair, notSignedTx)).to.be.a('string').which.is.equal('85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01'); + expect(transaction.sign(genesisKeypair, notSignedTx)).to.be.a('string').which.is.equal(validTransaction.signature); }); }); - // describe('multisign', function () { - // - // it('should throw an error with no param', function () { - // expect(transaction.multisign).to.throw(); - // }); - // - // it('should multisign the transaction', function () { - // expect(transaction.multisign(testSenderKeypair, validTransaction)).to.equal(validTransaction.signature); - // }); - // }); + // Multisignatures tests are disabled currently + + /* + describe('multisign', function () { + + it('should throw an error with no param', function () { + expect(transaction.multisign).to.throw(); + }); + + it('should multisign the transaction', function () { + expect(transaction.multisign(testSenderKeypair, validTransaction)).to.equal(validTransaction.signature); + }); + }); + */ describe('getId', function () { @@ -325,19 +328,13 @@ describe('transaction', function () { expect(firstCalculation.equals(secondCalculation)).to.be.ok; }); - // it('should return same result of getBytes using /logic/transaction and lisk-js package (without data field)', function () { - // var trsBytesFromLogic = transaction.getBytes(validTransaction); - // var trsBytesFromLiskJs = node.lisk.crypto.getBytes(validTransaction); - // expect(trsBytesFromLogic.equals(trsBytesFromLiskJs)).to.be.ok; - // }); - it('should skip signature, second signature for getting bytes', function () { var trsBytes = transaction.getBytes(validTransaction, true); expect(trsBytes.length).to.equal(53); }); }); - describe('ready', function () { + describe('transaction.ready', function () { it('should throw an error with no param', function () { expect(transaction.ready).to.throw(); @@ -417,7 +414,7 @@ describe('transaction', function () { expect(transaction.checkBalance).to.throw(); }); - it('should return error when sender has insufficiant balance', function () { + it('should return error when sender has insufficient balance', function () { var amount = '49000000000000000000000'; var balanceKey = 'balance'; let sender = _.cloneDeep(testSender); @@ -447,7 +444,7 @@ describe('transaction', function () { }); }); - describe('process', function () { + describe('transaction.process', function () { it('should throw an error with no param', function () { expect(transaction.process).to.throw(); @@ -489,15 +486,15 @@ describe('transaction', function () { }); }); - describe('verify', function () { + describe('transaction.verify', function () { - function createAndProcess(trsData, sender, cb) { + function createAndProcess (trsData, sender, cb) { var trs = transaction.create(trsData); transaction.process(trs, sender, function (err, __trs) { expect(err).to.not.exist; expect(__trs).to.be.an('object'); - cb(__trs); trs.senderId = sender.address; - + cb(__trs); + trs.senderId = sender.address; }); } @@ -518,39 +515,42 @@ describe('transaction', function () { }); }); + // Second signature tests are disabled currently + // it('should return error when missing sender second signature', function (done) { - // var trs = _.cloneDeep(validTransaction); - // var vs = _.cloneDeep(validSender); + // var trs = _.cloneDeep(validUnconfirmedTrs); + // trs.signSignature = [transaction.sign(testSenderKeypair, trs)]; + // var vs = _.cloneDeep(testSender); // vs.secondSignature = '839eba0f811554b9f935e39a68b3078f90bea22c5424d3ad16630f027a48362f78349ddc3948360045d6460404f5bc8e25b662d4fd09e60c89453776962df40d'; - // + // transaction.verify(trs, vs, {}, function (err) { // expect(err).to.include('Missing sender second signature'); // done(); // }); // }); - // it('should return error when sender does not have a second signature', function (done) { - // var trs = _.cloneDeep(validTransaction); - // trs.signSignature = [transaction.sign(validKeypair, trs)]; - // - // transaction.verify(trs, validSender, {}, function (err) { - // expect(err).to.include('Sender does not have a second signature'); - // done(); - // }); - // }); - // - // it('should return error when requester does not have a second signature', function (done) { - // var trs = _.cloneDeep(validTransaction); - // var dummyRequester = { - // secondSignature : 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f' - // }; - // trs.requesterPublicKey = '839eba0f811554b9f935e39a68b3078f90bea22c5424d3ad16630f027a48362f78349ddc3948360045d6460404f5bc8e25b662d4fd09e60c89453776962df40d'; - // - // transaction.verify(trs, validSender, dummyRequester, function (err) { - // expect(err).to.include('Missing requester second signature'); - // done(); - // }); - // }); + it('should return error when sender does not have a second signature', function (done) { + var trs = _.cloneDeep(validTransaction); + trs.signSignature = [transaction.sign(validKeypair, trs)]; + + transaction.verify(trs, validSender, {}, function (err) { + expect(err).to.include('Sender does not have a second signature'); + done(); + }); + }); + + it('should return error when requester does not have a second signature', function (done) { + var trs = _.cloneDeep(validTransaction); + var dummyRequester = { + secondSignature : 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f' + }; + trs.requesterPublicKey = '839eba0f811554b9f935e39a68b3078f90bea22c5424d3ad16630f027a48362f78349ddc3948360045d6460404f5bc8e25b662d4fd09e60c89453776962df40d'; + + transaction.verify(trs, validSender, dummyRequester, function (err) { + expect(err).to.include('Missing requester second signature'); + done(); + }); + }); it('should return error when trs sender publicKey and sender public key are different', function (done) { var trs = _.cloneDeep(validTransaction); @@ -586,23 +586,27 @@ describe('transaction', function () { }); }); - // it('should return error when Account does not belong to multisignature group', function (done) { - // var trs = _.cloneDeep(validTransaction); - // var vs = _.cloneDeep(validSender); - // // Different publicKey for multisignature account - // vs.multisignatures = [node.eAccount.publicKey]; - // trs.requesterPublicKey = validKeypair.publicKey.toString('hex'); - // delete trs.signature; - // trs.signature = transaction.sign(validKeypair, trs); - // transaction.verify(trs, vs, {}, function (err) { - // expect(err).to.equal('Account does not belong to multisignature group'); - // done(); - // }); - // }); + // Multisignatures tests are disabled currently + + /* + it('should return error when Account does not belong to multisignature group', function (done) { + var trs = _.cloneDeep(validTransaction); + var vs = _.cloneDeep(validSender); + // Different publicKey for multisignature account + vs.multisignatures = [node.eAccount.publicKey]; + trs.requesterPublicKey = validKeypair.publicKey.toString('hex'); + delete trs.signature; + trs.signature = transaction.sign(validKeypair, trs); + transaction.verify(trs, vs, {}, function (err) { + expect(err).to.equal('Account does not belong to multisignature group'); + done(); + }); + }); + */ it('should return error when signature is not correct', function (done) { var trs = _.cloneDeep(validTransaction); - // valid keypair is a different account + // testSenderKeypair is for a different account trs.signature = transaction.sign(testSenderKeypair, trs); transaction.verify(trs, genesis, {}, function (err) { expect(err).to.include('Failed to verify signature'); @@ -610,81 +614,83 @@ describe('transaction', function () { }); }); - // it('should return error when duplicate signature in transaction', function (done) { - // var trs = _.cloneDeep(validTransaction); - // var vs = _.cloneDeep(validSender); - // vs.multisignatures = [validKeypair.publicKey.toString('hex')]; - // delete trs.signature; - // trs.signatures = Array.apply(null, Array(2)).map(function () { return transaction.sign(validKeypair, trs); }); - // trs.signature = transaction.sign(testSenderKeypair, trs); - // transaction.verify(trs, vs, {}, function (err) { - // expect(err).to.equal('Encountered duplicate signature in transaction'); - // done(); - // }); - // }); + // Multisignatures tests are disabled currently - // it('should return error when failed to verify multisignature', function (done) { - // var trs = _.cloneDeep(validTransaction); - // var vs = _.cloneDeep(validSender); - // vs.multisignatures = [validKeypair.publicKey.toString('hex')]; - // trs.requesterPublicKey = validKeypair.publicKey.toString('hex'); - // delete trs.signature; - // // using validKeypair as opposed to testSenderKeypair - // trs.signatures = [transaction.sign(validKeypair, trs)]; - // trs.signature = transaction.sign(validKeypair, trs); - // transaction.verify(trs, vs, {}, function (err) { - // expect(err).to.equal('Failed to verify multisignature'); - // done(); - // }); - // }); - // - // it('should be okay with valid multisignature', function (done) { - // var trs = _.cloneDeep(validTransaction); - // var vs = _.cloneDeep(validSender); - // vs.multisignatures = [validKeypair.publicKey.toString('hex')]; - // delete trs.signature; - // trs.signature = transaction.sign(testSenderKeypair, trs); - // trs.signatures = [transaction.multisign(validKeypair, trs)]; - // transaction.verify(trs, vs, {}, function (err) { - // expect(err).to.not.exist; - // done(); - // }); - // }); - // - // it('should return error when second signature is invalid', function (done) { - // var vs = _.cloneDeep(validSender); - // vs.secondPublicKey = validKeypair.publicKey.toString('hex'); - // vs.secondSignature = 1; - // - // var trsData = _.cloneDeep(validTransactionData); - // trsData.sender = vs; - // trsData.secondKeypair = validKeypair; - // createAndProcess(trsData, validSender, function (trs) { - // trs.signSignature = '7af5f0ee2c4d4c83d6980a46efe31befca41f7aa8cda5f7b4c2850e4942d923af058561a6a3312005ddee566244346bdbccf004bc8e2c84e653f9825c20be008'; - // transaction.verify(trs, vs, function (err) { - // expect(err).to.equal('Failed to verify second signature'); - // done(); - // }); - // }); - // }); - // - // it('should be okay for valid second signature', function (done) { - // var sender = _.cloneDeep(validSender); - // sender.secondPublicKey = validKeypair.publicKey.toString('hex'); - // sender.secondSignature = 1; - // - // var trsData = _.cloneDeep(validTransactionData); - // trsData.sender = sender; - // trsData.secondKeypair = validKeypair; - // createAndProcess(trsData, validSender, function (trs) { - // transaction.verify(trs, validSender, {}, function (err) { - // transaction.verify(trs, sender, function (err) { - // expect(err).to.not.exist; - // done(); - // }); - // }); - // }); - // }); + /* + it('should return error when duplicate signature in transaction', function (done) { + var trs = _.cloneDeep(validTransaction); + var vs = _.cloneDeep(validSender); + vs.multisignatures = [validKeypair.publicKey.toString('hex')]; + delete trs.signature; + trs.signatures = Array.apply(null, Array(2)).map(function () { return transaction.sign(validKeypair, trs); }); + trs.signature = transaction.sign(testSenderKeypair, trs); + transaction.verify(trs, vs, {}, function (err) { + expect(err).to.equal('Encountered duplicate signature in transaction'); + done(); + }); + }); + + it('should return error when failed to verify multisignature', function (done) { + var trs = _.cloneDeep(validTransaction); + var vs = _.cloneDeep(validSender); + vs.multisignatures = [validKeypair.publicKey.toString('hex')]; + trs.requesterPublicKey = validKeypair.publicKey.toString('hex'); + delete trs.signature; + // using validKeypair as opposed to testSenderKeypair + trs.signatures = [transaction.sign(validKeypair, trs)]; + trs.signature = transaction.sign(validKeypair, trs); + transaction.verify(trs, vs, {}, function (err) { + expect(err).to.equal('Failed to verify multisignature'); + done(); + }); + }); + + it('should be okay with valid multisignature', function (done) { + var trs = _.cloneDeep(validTransaction); + var vs = _.cloneDeep(validSender); + vs.multisignatures = [validKeypair.publicKey.toString('hex')]; + delete trs.signature; + trs.signature = transaction.sign(testSenderKeypair, trs); + trs.signatures = [transaction.multisign(validKeypair, trs)]; + transaction.verify(trs, vs, {}, function (err) { + expect(err).to.not.exist; + done(); + }); + }); + */ + + it('should return error when second signature is invalid', function (done) { + var vs = _.cloneDeep(validSender); + vs.secondPublicKey = validKeypair.publicKey.toString('hex'); + vs.secondSignature = 1; + + var trsData = _.cloneDeep(validTransactionData); + createAndProcess(trsData, validSender, function (trs) { + trs.signSignature = '7af5f0ee2c4d4c83d6980a46efe31befca41f7aa8cda5f7b4c2850e4942d923af058561a6a3312005ddee566244346bdbccf004bc8e2c84e653f9825c20be008'; + transaction.verify(trs, vs, function (err) { + expect(err).to.equal('Failed to verify second signature'); + done(); + }); + }); + }); + + it('should be okay for valid second signature', function (done) { + var sender = _.cloneDeep(testSender); + sender.secondPublicKey = validKeypair.publicKey.toString('hex'); + sender.secondSignature = 1; + + var trsData = _.cloneDeep(validTransactionData); + trsData.sender = sender; + trsData.secondKeypair = validKeypair; + createAndProcess(trsData, testSender, function (trs) { + transaction.verify(trs, testSender, {}, function (err) { + transaction.verify(trs, sender, function (err) { + expect(err).to.not.exist; + done(); + }); + }); + }); + }); it('should throw return error transaction fee is incorrect', function (done) { var trs = _.cloneDeep(genesisTrs); @@ -779,7 +785,6 @@ describe('transaction', function () { it('should return false if trs is changed', function () { var trs = _.cloneDeep(validTransactionData); - // change trs value trs.amount = 1001; expect(transaction.verifySignature(trs, testSender.publicKey, trs.signature)).to.equal(false); }); @@ -803,17 +808,17 @@ describe('transaction', function () { }); }); - // describe('verifySecondSignature', function () { - // - // it('should throw an error with no param', function () { - // expect(transaction.verifySecondSignature).to.throw(); - // }); - // - // it('should verify the second signature correctly', function () { - // var signature = transaction.sign(validKeypair, validTransaction); - // expect(transaction.verifySecondSignature(validTransaction, validKeypair.publicKey.toString('hex'), signature)).to.equal(true); - // }); - // }); + describe('verifySecondSignature', function () { + + it('should throw an error with no param', function () { + expect(transaction.verifySecondSignature).to.throw(); + }); + + it('should verify the second signature correctly', function () { + var signature = transaction.sign(validKeypair, validTransaction); + expect(transaction.verifySecondSignature(validTransaction, validKeypair.publicKey.toString('hex'), signature)).to.equal(true); + }); + }); describe('verifyBytes', function () { @@ -827,7 +832,7 @@ describe('transaction', function () { expect(transaction.verifyBytes(trsBytes, invalidPublicKey, validTransaction.signature)).to.equal(false); }); - it('should throw when publickey is not in the right format', function () { + it('should throw when public key is not in the right format', function () { var trsBytes = transaction.getBytes(validTransaction); var invalidPublicKey = 'iddb0e15a44b0fdc6ff291be28d8c98f5551d0cd9218d749e30ddb87c6e31ca9'; expect(function () { @@ -842,13 +847,13 @@ describe('transaction', function () { }); }); - describe('apply', function () { + describe('transaction.apply', function () { var dummyBlock = { id: '9314232245035524467', height: 1 }; - function undoTransaction(trs, sender, done) { + function undoTransaction (trs, sender, done) { transaction.undo(trs, dummyBlock, sender, done); } @@ -895,7 +900,7 @@ describe('transaction', function () { height: 1 }; - function applyTransaction(trs, sender, done) { + function applyTransaction (trs, sender, done) { transaction.apply(trs, dummyBlock, sender, done); } @@ -946,7 +951,7 @@ describe('transaction', function () { describe('applyUnconfirmed', function () { - function undoUnconfirmedTransaction(trs, sender, done) { + function undoUnconfirmedTransaction (trs, sender, done) { transaction.undoUnconfirmed(trs, sender, done); } @@ -979,7 +984,7 @@ describe('transaction', function () { describe('undoUnconfirmed', function () { - function applyUnconfirmedTransaction(trs, sender, done) { + function applyUnconfirmedTransaction (trs, sender, done) { transaction.applyUnconfirmed(trs, sender, done); } From da6524c731aa15af868c8f62e608f6421dd3f167 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 10 Sep 2021 13:32:20 +0300 Subject: [PATCH 28/67] Fix tests for transfer --- test/unit/logic/transfer.js | 172 +++++++++++++++++------------------- 1 file changed, 82 insertions(+), 90 deletions(-) diff --git a/test/unit/logic/transfer.js b/test/unit/logic/transfer.js index edb06443..b5af7f14 100644 --- a/test/unit/logic/transfer.js +++ b/test/unit/logic/transfer.js @@ -19,28 +19,21 @@ var AccountLogic = require('../../../logic/account.js'); var AccountModule = require('../../../modules/accounts.js'); var DelegateModule = require('../../../modules/delegates.js'); -var validPassword = 'robust weapon course unknown head trial pencil latin acid'; -// Fix here to library.ed.createPassPhraseHash() -var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); +// valid keypair sample (market delegate's passphrase) +var validPassword = 'rally clean ladder crane gadget century timber jealous shine scorpion beauty salon'; +var validHash = ed.createPassPhraseHash(validPassword); +var validKeypair = ed.makeKeypair(validHash); -// Fix here to library.ed.createPassPhraseHash() -var senderHash = crypto.createHash('sha256').update(node.iAccount.password, 'utf8').digest(); -var senderKeypair = ed.makeKeypair(senderHash); - -var validSender = { +// stub for a valid sender +let validSender = { username: null, isDelegate: 0, secondSignature: 0, - address: '16313739661670634666L', - publicKey: 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', secondPublicKey: null, - balance: 9850458911801508, - u_balance: 9850458911801508, vote: 0, multisignatures: null, multimin: 0, multilifetime: 0, - blockId: '8505659485551877884', nameexist: 0, producedblocks: 0, missedblocks: 0, @@ -49,71 +42,66 @@ var validSender = { virgin: 0 }; -var validTransactionData = { +// valid sender to test transactions (kind delegate) +validSender = _.defaults({ + address: 'U12559234133690317086', + publicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', + secret: 'weather play vibrant large edge clean notable april fire smoke drift hidden', + u_balance: 10000000000000, + balance: 100000000000000 +}, validSender); + +// valid sender to test transactions (kind delegate) +var testSender = _.defaults({ + address: 'U12559234133690317086', + publicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', + secret: 'weather play vibrant large edge clean notable april fire smoke drift hidden', + u_balance: 10000000000000, + balance: 100000000000000 +}, validSender); +const testSenderHash = node.accounts.createPassPhraseHash(testSender.secret); +const testSenderKeypair = node.accounts.makeKeypair(testSenderHash); + +// valid new tx sample from a test sender +var validUnconfirmedTrs = { type: 0, - amount: 8067474861277, - sender: validSender, - senderId: '16313739661670634666L', - recipientId: '2460251951231579923L', - fee: 10000000, - keypair: senderKeypair, - publicKey: 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', + amount: 100, + senderId: testSender.address, + senderPublicKey: testSender.publicKey, + recipientId: 'U7771441689362721578', + fee: 50000000, + timestamp: 1000, + asset: {} }; -var validTransaction = { - id: '16140284222734558289', - rowId: 133, - blockId: '1462190441827192029', +// valid new tx sample from a test sender, but with keypair +var validTransactionData = { type: 0, - timestamp: 33363661, - senderPublicKey: 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', - senderId: '16313739661670634666L', - recipientId: '2460251951231579923L', amount: 8067474861277, - fee: 10000000, - signature: '0c5e9ed74fc64ca5940a45025f7386fc40cc7f495ca48490d2c7e9fb636cbe8046e1a5ce031ff5d84f7bf753f9e4307c6c3dedcc9756844177093dd46ccade06', - signSignature: null, - requesterPublicKey: null, - signatures: null, - asset: {}, + keypair: testSenderKeypair, + sender: testSender, + senderId: testSender.address, + senderPublicKey: testSender.publicKey, + recipientId: 'U7771441689362721578', + fee: 50000000, + timestamp: 1000 }; -var rawValidTransaction = { - t_id: '16140284222734558289', - b_height: 981, - t_blockId: '1462190441827192029', - t_type: 0, - t_timestamp: 33363661, - t_senderPublicKey: 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', - m_recipientPublicKey: null, - t_senderId: '16313739661670634666L', - t_recipientId: '2460251951231579923L', - t_amount: 8067474861277, - t_fee: 10000000, - t_signature: '0c5e9ed74fc64ca5940a45025f7386fc40cc7f495ca48490d2c7e9fb636cbe8046e1a5ce031ff5d84f7bf753f9e4307c6c3dedcc9756844177093dd46ccade06', - confirmations: 8343 -}; - -var testSender = _.defaults({ - address: 'U12559234133690317086', - publicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', - secret: 'weather play vibrant large edge clean notable april fire smoke drift hidden', - u_balance: 1000000000000000000, - balance: 1000000000000000000 -},validSender); -// Fix here to library.ed.createPassPhraseHash() -const testSenderHash = crypto.createHash('sha256').update(testSender.secret, 'utf8').digest(); -const testSenderKeypair = ed.makeKeypair(testSenderHash); -var validUnconfirmedTrs = { - type: 0, - amount: 100, - senderPublicKey: 'd365e59c9880bd5d97c78475010eb6d96c7a3949140cda7e667f9513218f9089', - senderId: 'U12559234133690317086', - timestamp: 0, - asset: {}, - recipientId: 'U7771441689362721578', - fee: 10000000, - signature: '6029db8004f1e208f9ead403260c15a5bbf4f874336e9fc7e34c771588e366f1727145b86184256c8bd496b1e7ef6f1359565fc2d68d5480bc131fdc859f800b' +// valid tx sample, got from api endpoint (from genesis to devs) +var validTransaction = { + id: '17190511997607511181', + blockId: '6438017970172540087', + type: 0, + block_timestamp: null, + timestamp: 0, + senderPublicKey: 'b80bb6459608dcdeb9a98d1f2b0111b2bf11e53ef2933e6769bb0198e3a97aae', + senderId: 'U15365455923155964650', + recipientId: 'U9781760580710719871', + amount: 490000000000000, + fee: 0, + signature: '85dc703a2b82698193ecbd86fd7aff1b057dfeb86e2a390ef42c1998bf1e9269c0048f42285e208a1e14a63843defbabece1bc96730f317f0cc16e23bb1b4d01', + signatures: [], + asset: {} }; @@ -241,7 +229,7 @@ describe('transfer', function () { transfer.undo.call(transaction, trs, dummyBlock, sender, done); } - it('should return error if recipientid is not set', function (done) { + it('should return error if recipientId is not set', function (done) { var trs = _.cloneDeep(validTransaction); delete trs.recipientId; transfer.apply.call(transaction, trs, dummyBlock, validSender, function (err) { @@ -284,7 +272,7 @@ describe('transfer', function () { transfer.apply.call(transaction, trs, dummyBlock, sender, done); } - it('should return error if recipientid is not set', function (done) { + it('should return error if recipientId is not set', function (done) { var trs = _.cloneDeep(validTransaction); delete trs.recipientId; transfer.undo.call(transaction, trs, dummyBlock, validSender, function (err) { @@ -354,22 +342,26 @@ describe('transfer', function () { expect(transfer.ready(validTransaction, validSender)).to.equal(true); }); - // it('should return false for multi signature transaction with less signatures', function () { - // var trs = _.cloneDeep(validTransaction); - // var vs = _.cloneDeep(validSender); - // vs.multisignatures = [validKeypair.publicKey.toString('hex')]; - // expect(transaction.ready(trs, vs)).to.equal(false); - // }); - - // it('should return true for multi signature transaction with alteast min signatures', function () { - // var trs = _.cloneDeep(validTransaction); - // var vs = _.cloneDeep(validSender); - // vs.multisignatures = [validKeypair.publicKey.toString('hex')]; - // vs.multimin = 1; - // delete trs.signature; - // trs.signature = transaction.sign(senderKeypair, trs); - // trs.signatures = [transaction.multisign(validKeypair, trs)]; - // expect(transaction.ready(trs, vs)).to.equal(true); - // }); + // Multisignatures tests are disabled currently + + /* + it('should return false for multi signature transaction with less signatures', function () { + var trs = _.cloneDeep(validTransaction); + var vs = _.cloneDeep(validSender); + vs.multisignatures = [validKeypair.publicKey.toString('hex')]; + expect(transaction.ready(trs, vs)).to.equal(false); + }); + + it('should return true for multi signature transaction with at least min signatures', function () { + var trs = _.cloneDeep(validTransaction); + var vs = _.cloneDeep(validSender); + vs.multisignatures = [validKeypair.publicKey.toString('hex')]; + vs.multimin = 1; + delete trs.signature; + trs.signature = transaction.sign(senderKeypair, trs); + trs.signatures = [transaction.multisign(validKeypair, trs)]; + expect(transaction.ready(trs, vs)).to.equal(true); + }); + */ }); }); From d49464f7e8a7e02f51963825ae15dba85c2f54bc Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 10 Sep 2021 13:38:02 +0300 Subject: [PATCH 29/67] Fix tests for vote --- test/unit/logic/vote.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/unit/logic/vote.js b/test/unit/logic/vote.js index 03b658af..13a76226 100644 --- a/test/unit/logic/vote.js +++ b/test/unit/logic/vote.js @@ -23,9 +23,10 @@ var AccountLogic = require('../../../logic/account.js'); var AccountModule = require('../../../modules/accounts.js'); var DelegateModule = require('../../../modules/delegates.js'); -var validPassword = 'robust weapon course unknown head trial pencil latin acid'; -// Fix here to library.ed.createPassPhraseHash() -var validKeypair = ed.makeKeypair(crypto.createHash('sha256').update(validPassword, 'utf8').digest()); +// valid keypair sample (market delegate's passphrase) +var validPassword = 'rally clean ladder crane gadget century timber jealous shine scorpion beauty salon'; +var validHash = ed.createPassPhraseHash(validPassword); +var validKeypair = ed.makeKeypair(validHash); var validSender = { balance: 8067474861277, @@ -35,11 +36,9 @@ var validSender = { publicKey: 'f4011a1360ac2769e066c789acaaeffa9d707690d4d3f6085a7d52756fbc30d0', multimin: 0, address: 'U810656636599221322' - }; -// Fix here to library.ed.createPassPhraseHash() -var senderHash = crypto.createHash('sha256').update(validSender.password, 'utf8').digest(); +var senderHash = ed.createPassPhraseHash(validSender.password); var senderKeypair = ed.makeKeypair(senderHash); var transactionVotes = [ @@ -93,6 +92,7 @@ describe('vote', function () { 'd3a3c26c3906080689d0c2ccd3df30f2f4797c881e21a92aa4579bc68744581f', '2deabea717a9e9054e3759e3041b84409dd6195c74d9d7736e0cd8442c000f5a' ]; + function addVotes (votes, done) { var trs = _.clone(validTransaction); trs.asset.votes = votes; @@ -260,7 +260,7 @@ describe('vote', function () { }); describe('verify', function () { - it('should return error when receipientId and sender id are different', function (done) { + it('should return error when recipientId and sender id are different', function (done) { var trs = _.cloneDeep(validTransaction); trs.recipientId = node.iAccount.address; vote.verify(trs, validSender, function (err) { From 2310b442e74d7861934fd1eee787c6b81ac6c2ac Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 10 Sep 2021 14:15:25 +0300 Subject: [PATCH 30/67] Fix tests for verify --- test/unit/modules/blocks/verify.js | 86 +++++++++++++++--------------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/test/unit/modules/blocks/verify.js b/test/unit/modules/blocks/verify.js index 511280e3..8cd2491f 100644 --- a/test/unit/modules/blocks/verify.js +++ b/test/unit/modules/blocks/verify.js @@ -7,7 +7,7 @@ var exceptions = require('../../../../helpers/exceptions.js'); var previousBlock = { blockSignature: 'a74cd53bebf9cf003cfd5fed8c053e1b64660e89a654078ff3341348145bbb0f34d1bde4a254b139ebae03117b346a2aab77fc8607eed9c7431db5eb4d4cbe0b', - generatorPublicKey:'377bfcc233fdba3039d9fbb8c7d8d97e1087d52941e5661b9c55b59c57f8fafe', + generatorPublicKey: '377bfcc233fdba3039d9fbb8c7d8d97e1087d52941e5661b9c55b59c57f8fafe', height: 42394, id: '1553572419982003786', numberOfTransactions: 0, @@ -40,35 +40,35 @@ var validBlock = { }; var blockRewardInvalid = { - blockSignature: '08d70794b3fd90be5d14fd02f512c56485d4bac071ccf98188833242a7d84dfd9c98bc3cf6b7eecb6231dc94da82a275002d1913f60809e98d64f9892e98d303', - generatorPublicKey: '747d370dc479a7d684e3b61d8c75716f3bc91afcf9e5d3eeaeb557753d757ac4', - numberOfTransactions: 0, - payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', - payloadLength: 0, - previousBlock: '1553572419982003786', - reward: 0, - timestamp: 39674950, - totalAmount: 0, - totalFee: 0, - transactions: [], - version: 0, - id: '10000428847403166564' + blockSignature: '08d70794b3fd90be5d14fd02f512c56485d4bac071ccf98188833242a7d84dfd9c98bc3cf6b7eecb6231dc94da82a275002d1913f60809e98d64f9892e98d303', + generatorPublicKey: '747d370dc479a7d684e3b61d8c75716f3bc91afcf9e5d3eeaeb557753d757ac4', + numberOfTransactions: 0, + payloadHash: 'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855', + payloadLength: 0, + previousBlock: '1553572419982003786', + reward: 0, + timestamp: 39674950, + totalAmount: 0, + totalFee: 0, + transactions: [], + version: 0, + id: '10000428847403166564' }; var validBlockWithPayload = { - blockSignature: '25ea76424044e76a47ab2f1854d553f3aa24437f37af7acbabeb50ce27c42f340ad890103d1c96862224dbd4590c787cf47497131214842c57a0cc8801366e0a', - generatorPublicKey: '7c7b92b7d2159e5652bc942fdb9d6dbee77d1b120f488960966ce0850d819b05', - numberOfTransactions: 3, + blockSignature: '25ea76424044e76a47ab2f1854d553f3aa24437f37af7acbabeb50ce27c42f340ad890103d1c96862224dbd4590c787cf47497131214842c57a0cc8801366e0a', + generatorPublicKey: '7c7b92b7d2159e5652bc942fdb9d6dbee77d1b120f488960966ce0850d819b05', + numberOfTransactions: 3, height: 24134, - payloadHash: '81de7bd1606eaca88b8f835b11682668afba47439a5468fce5288b5b7b6280d4', - payloadLength: 364, - previousBlock: '8741947515519892818', - reward: 0, - timestamp: 39555010, - totalAmount: 0, - totalFee: 300000, - transactions: [ - { + payloadHash: '81de7bd1606eaca88b8f835b11682668afba47439a5468fce5288b5b7b6280d4', + payloadLength: 364, + previousBlock: '8741947515519892818', + reward: 0, + timestamp: 39555010, + totalAmount: 0, + totalFee: 300000, + transactions: [ + { type: 8, amount: 0, fee: 100000, @@ -85,8 +85,8 @@ var validBlockWithPayload = { } } ], - version: 0, - id: '15642998233669588601' + version: 0, + id: '15642998233669588601' }; describe('blocks/verify', function () { @@ -105,16 +105,16 @@ describe('blocks/verify', function () { blockLogic = __blockLogic; modulesLoader.initModules([ - {blocks: require('../../../../modules/blocks')}, - {accounts: require('../../../../modules/accounts')}, - {delegates: require('../../../../modules/delegates')}, - {transactions: require('../../../../modules/transactions')}, - {transport: require('../../../../modules/transport')}, - {system: require('../../../../modules/system')}, + { blocks: require('../../../../modules/blocks') }, + { accounts: require('../../../../modules/accounts') }, + { delegates: require('../../../../modules/delegates') }, + { transactions: require('../../../../modules/transactions') }, + { transport: require('../../../../modules/transport') }, + { system: require('../../../../modules/system') }, ], [ - {'block': require('../../../../logic/block')}, - {'transaction': require('../../../../logic/transaction')}, - {'account': require('../../../../logic/account')}, + { 'block': require('../../../../logic/block') }, + { 'transaction': require('../../../../logic/transaction') }, + { 'account': require('../../../../logic/account') }, ], {}, function (err, __modules) { if (err) { return done(err); @@ -127,7 +127,7 @@ describe('blocks/verify', function () { blocks = __modules.blocks; blocksVerify = __modules.blocks.verify; accounts = __modules.accounts; - delegates = __modules.delegates; + // delegates = __modules.delegates; done(); }); @@ -416,8 +416,8 @@ describe('blocks/verify', function () { function testVerifyBlockSlot (functionName) { it('should fail when block timestamp is less than previousBlock timestamp', function () { var timestamp = validBlock.timestamp; - validBlock.timestamp = 32578350; - + validBlock.timestamp = timestamp - 1000; + // validBlock.timestamp = 32578350; var result = blocksVerify[functionName](validBlock); expect(result.verified).to.be.false; @@ -425,7 +425,7 @@ describe('blocks/verify', function () { expect(result.errors[0]).to.equal('Invalid block timestamp'); expect(result.errors[1]).to.equal('Failed to verify block signature'); - validBlock.timestamp = timestamp; + validBlock.timestamp = timestamp; }); } @@ -447,9 +447,9 @@ describe('blocks/verify', function () { describe('calling verifyPayload()', testVerifyPayload.bind(null, 'verifyReceipt')); - describe.skip('calling verifyForkOne()', testVerifyForkOne); + describe('calling verifyForkOne()', testVerifyForkOne.bind(null, 'verifyBlock')); - describe.skip('calling verifyBlockSlot()', testVerifyBlockSlot); + describe('calling verifyBlockSlot()', testVerifyBlockSlot.bind(null, 'verifyBlock')); }); describe('verifyBlock() when block is valid', testValid.bind(null, 'verifyBlock')); From d4d4af9072cca9b2dffb6f137775a76947ec37f1 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 10 Sep 2021 14:23:04 +0300 Subject: [PATCH 31/67] Fix tests for schema/multisignatures --- test/unit/modules/blocks/verify.js | 2 +- test/unit/schema/dapp.js | 4 ++++ test/unit/schema/multisignatures.js | 9 ++++++--- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/test/unit/modules/blocks/verify.js b/test/unit/modules/blocks/verify.js index 8cd2491f..6212736e 100644 --- a/test/unit/modules/blocks/verify.js +++ b/test/unit/modules/blocks/verify.js @@ -89,7 +89,7 @@ var validBlockWithPayload = { id: '15642998233669588601' }; -describe('blocks/verify', function () { +describe('blocks/verify (one may fail with Cannot read property sockets of undefined)', function () { var blocksVerify; var blocks; diff --git a/test/unit/schema/dapp.js b/test/unit/schema/dapp.js index 0edabb84..fe60a6fc 100644 --- a/test/unit/schema/dapp.js +++ b/test/unit/schema/dapp.js @@ -7,6 +7,8 @@ var validator = new ZSchema(); describe('dapp', function () { // TODO: Add tests for other dapps schemas + + /* describe('put', function () { it('tests for schema'); }); @@ -43,6 +45,8 @@ describe('dapp', function () { it('tests for schema'); }); + */ + describe('launch', function () { var testBody; diff --git a/test/unit/schema/multisignatures.js b/test/unit/schema/multisignatures.js index 697983a4..f02c4089 100644 --- a/test/unit/schema/multisignatures.js +++ b/test/unit/schema/multisignatures.js @@ -9,6 +9,8 @@ var validator = new ZSchema(); describe('multisignatures', function () { // TODO: Add tests for other multisignature schemas + + /* describe('getAccounts', function () { it('tests for schema'); }); @@ -20,15 +22,16 @@ describe('multisignatures', function () { describe('sign', function () { it('tests for schema'); }); + */ describe('addMultisignatures', function () { var testBody; beforeEach(function () { - var secret = node.randomAccount().password; + var account = node.randomAccount(); testBody = { - secret: secret, - publicKey: node.lisk.crypto.getKeys(secret).publicKey, + secret: account.password, + publicKey: account.publicKeyHex, min: 2, lifetime: 1, keysgroup: Array.apply(null, Array(4)).map(function () { return '+' + node.randomAccount().publicKey;}) From 40f8a71732334b6767e830fc4103c7ec0265647b Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 10 Sep 2021 14:36:44 +0300 Subject: [PATCH 32/67] Tests fixed --- test/unit/schema/transactions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/unit/schema/transactions.js b/test/unit/schema/transactions.js index 82218ab8..d4c9bea1 100644 --- a/test/unit/schema/transactions.js +++ b/test/unit/schema/transactions.js @@ -10,6 +10,8 @@ var validator = new ZSchema(); describe('transactions', function () { // TODO: Add tests for other transaction schemas + + /* describe('getTransaction', function () { it('tests for schema'); }); @@ -25,15 +27,13 @@ describe('transactions', function () { describe('addTransactions', function () { it('tests for schema'); }); + */ describe('getTransactions', function () { // TODO: Add tests for other schemas properties var testBody; beforeEach(function () { - // var account1PublicKey = node.randomAccount().publicKey; - // var account2PublicKey = node.randomAccount().publicKey; - testBody = { blockId: '1465651642158264047', type: 0, From 79076cb1a59e2b5fc0dca290f79e95aeba0b1bce Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 10 Sep 2021 17:12:27 +0300 Subject: [PATCH 33/67] Fix tests for chatrooms --- package.json | 2 +- test/api/chatrooms.js | 919 +++++++++++++++++++++--------------------- test/api/delegates.js | 14 +- 3 files changed, 471 insertions(+), 464 deletions(-) diff --git a/package.json b/package.json index ba6329e7..1d618acd 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "fetchCoverage": "./node_modules/.bin/grunt exec:fetchCoverage --verbose", "jsdoc": "jsdoc -c docs/conf.json --verbose --pedantic", "server-docs": "npm run jsdoc && http-server docs/jsdoc/", - "fasttest": "./node_modules/.bin/mocha --exclude test/unit/logic/blockReward.js --exclude test/unit/sql/blockRewards.js --exclude test/api/delegates.js --exclude test/api/peer.transactions.stress.js --exclude test/api/peer.transactions.votes.js test/unit/**/* test/api/**/*" + "fasttest": "./node_modules/.bin/mocha --exclude test/unit/sql/blockRewards.js --exclude test/api/delegates.js --exclude test/api/peer.transactions.stress.js --exclude test/api/peer.transactions.votes.js test/unit/**/* test/api/**/*" }, "author": "ADAMANT Tech Labs , Lisk Foundation , lightcurve GmbH ", "license": "GPL-3.0", diff --git a/test/api/chatrooms.js b/test/api/chatrooms.js index a10d0729..06a49834 100644 --- a/test/api/chatrooms.js +++ b/test/api/chatrooms.js @@ -5,472 +5,479 @@ const Mnemonic = require('bitcore-mnemonic'); const _ = require('lodash'); function sendADM (params, done) { - node.put('/api/transactions/', params, function (err, res) { - done(err, res); - }); + node.put('/api/transactions/', params, function (err, res) { + done(err, res); + }); } function postMessage (transaction, done) { - node.post('/api/transactions', { transaction: transaction }, done); + node.post('/api/transactions', { transaction: transaction }, done); } function getChats (senderId, done, params) { - const args = _.keys(params).map((key) => `${key}=${params[key]}`); - node.get( `/api/chatrooms/${senderId}${args.length > 0 ? '?'+args.join('&') : ''}`, done); + const args = _.keys(params).map((key) => `${key}=${params[key]}`); + node.get(`/api/chatrooms/${senderId}${args.length > 0 ? '?' + args.join('&') : ''}`, done); } function getMessages (authorId, companionId, done, params) { - const args = _.keys(params).map((key) => `${key}=${params[key]}`); - node.get( `/api/chatrooms/${authorId}/${companionId}${args.length > 0 ? '?'+args.join('&') : ''}`, done); + const args = _.keys(params).map((key) => `${key}=${params[key]}`); + node.get(`/api/chatrooms/${authorId}/${companionId}${args.length > 0 ? '?' + args.join('&') : ''}`, done); } describe('GET /api/chatrooms/:ID/:ID', function () { - const sender = node.randomAccount(); - const recipient1 = node.randomAccount(); - const recipient2 = node.randomAccount(); - - // send ADM to message sender - before(function (done) { - sendADM({ - secret: node.iAccount.password, - amount: node.fees.messageFee*3+node.fees.transactionFee*2, - recipientId: sender.address - }, function () { - done(); - }); - }); - - // send ADM to recipient1 - before(function (done) { - sendADM({ - secret: node.iAccount.password, - amount: node.fees.messageFee, - recipientId: recipient1.address - }, function () { - done(); - }); - }); - - // send ADM to recipient2 - before(function (done) { - sendADM({ - secret: node.iAccount.password, - amount: node.fees.messageFee, - recipientId: recipient2.address - }, function () { - done(); - }); - }); - - before(function (done) { - node.onNewBlock(function () { - done(); - }); - }); - - // send a message from a sender to recipient1 - before(function (done) { - const transaction = node.createChatTransaction({ - keyPair: sender.keypair, - recipientId: recipient1.address, - message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), - own_message: '', - type: 1 - }); - postMessage(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').that.is.not.empty; - done(); - }); - }); - - // send a message from a recipient1 to recipient2 - before(function (done) { - const transaction = node.createChatTransaction({ - keyPair: recipient1.keypair, - recipientId: recipient2.address, - message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), - own_message: '', - type: 1 - }); - postMessage(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').that.is.not.empty; - done(); - }); - }); - - // send a message from a recipient2 to recipient1 - before(function (done) { - const transaction = node.createChatTransaction({ - keyPair: recipient2.keypair, - recipientId: recipient1.address, - message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), - own_message: '', - type: 1 - }); - postMessage(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').that.is.not.empty; - done(); - }); - }); - - before(function (done) { - node.onNewBlock(function () { - done(); - }); - }); - - // send a message from a sender to recipient2 - before(function (done) { - const transaction = node.createChatTransaction({ - keyPair: sender.keypair, - recipientId: recipient2.address, - message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), - own_message: '', - type: 1 - }); - postMessage(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').that.is.not.empty; - done(); - }); - }); - - before(function (done) { - node.onNewBlock(function () { - done(); - }); - }); - - // send a second message from a sender to recipient1 - before(function (done) { - const transaction = node.createChatTransaction({ - keyPair: sender.keypair, - recipientId: recipient1.address, - message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), - own_message: '', - type: 1 - }); - postMessage(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').that.is.not.empty; - done(); - }); - }); - - // send ADM to message sender - before(function (done) { - sendADM({ - secret: sender.password, - amount: node.fees.transactionFee, - recipientId: recipient1.address - }, function () { - done(); - }); - }); - - before(function (done) { - node.onNewBlock(function () { - done(); - }); - }); - - it('should return the chats list for a valid transaction', function (done) { - getChats(sender.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('chats').to.have.lengthOf(2); - for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.chats[i].participants[0].address).to.equal(sender.address); - node.expect(res.body.chats[i].participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.chats[i].participants[1].publicKey).to.not.equal(null); - node.expect(res.body.chats[i]).to.have.property('lastTransaction').to.be.an('object'); - node.expect(res.body.chats[i].lastTransaction.timestamp).to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction.fee).to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction.amount).to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction).to.have.property('asset').to.be.an('object'); - node.expect(res.body.chats[i].lastTransaction.asset).to.have.property('chat').to.be.an('object'); - node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('message').to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('own_message').to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('type').to.not.equal(null); - } - done(); - }); - }); - - it('should return the chats list for a valid transaction for recipient1', function (done) { - getChats(recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('chats').to.have.lengthOf(2); - for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.chats[i].participants[0].publicKey).to.not.equal(null); - node.expect(res.body.chats[i].participants[1].publicKey).to.not.equal(null); - node.expect(res.body.chats[i]).to.have.property('lastTransaction').to.be.an('object'); - node.expect(res.body.chats[i].lastTransaction.timestamp).to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction.fee).to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction.amount).to.not.equal(null); - } - done(); - }, { orderBy: 'timestamp:desc'}); - }); - - it('should return the chats list for a valid transaction for recipient2', function (done) { - getChats(recipient2.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('chats').to.have.lengthOf(2); - for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.chats[i].participants[0].publicKey).to.not.equal(null); - node.expect(res.body.chats[i].participants[1].publicKey).to.not.equal(null); - node.expect(res.body.chats[i]).to.have.property('lastTransaction').to.be.an('object'); - node.expect(res.body.chats[i].lastTransaction.timestamp).to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction.fee).to.not.equal(null); - node.expect(res.body.chats[i].lastTransaction.amount).to.not.equal(null); - } - done(); - }); - }); - - it('should return the chats list for a valid transaction with limit', function (done) { - getChats(sender.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('chats').to.have.lengthOf(1); - for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - for (let y = 0; y < res.body.chats[i].participants.length; y++) { - node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); - } - } - done(); - }, { limit: 1 }); - }); - - it('should return the chats list for a valid transaction with offset', function (done) { - getChats(sender.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('chats').to.have.lengthOf(1); - for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - for (let y = 0; y < res.body.chats[i].participants.length; y++) { - node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); - } - } - done(); - }, { offset: 1 }); - }); - - it('should return the chats list for a valid transaction with orderBy=timestamp:desc', function (done) { - getChats(sender.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('chats').to.have.lengthOf(2); - for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - for (let y = 0; y < res.body.chats[i].participants.length; y++) { - node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); - } - } - done(); - }, { orderBy: 'timestamp:desc' }); - }); - - it('should return the chats list for a valid transaction with orderBy=timestamp:asc', function (done) { - getChats(sender.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('chats').to.have.lengthOf(2); - for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - for (let y = 0; y < res.body.chats[i].participants.length; y++) { - node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); - } - } - done(); - }, { orderBy: 'timestamp:asc' }); - }); - - it('should return the chats list for a valid transaction with sender and recipient chats', function (done) { - getChats(recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('chats').to.have.lengthOf(2); - for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - for (let y = 0; y < res.body.chats[i].participants.length; y++) { - node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); - } - } - done(); - }); - }); - - it('should return the messages list for a valid transaction', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(2); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }); - }); - - it('should return the messages list for a valid transaction with a limit', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(1); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - limit: 1 - }); - }); - - it('should return the messages list for a valid transaction with an offset', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(1); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - offset: 1 - }); - }); - - it('should return the messages list for a valid transaction with an orderBy=timestamp:desc', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(2); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - orderBy: 'timestamp:desc' - }); - }); - - it('should return the messages list for a valid transaction with an orderBy=timestamp:asc', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('2'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(2); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - orderBy: 'timestamp:asc' - }); - }); - - it('should return the messages list for a valid transaction with payments', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('3'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(3); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - withPayments: true - }); - }); - - it('should return the messages list for a valid transaction with payments with a limit', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('3'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(1); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - withPayments: true, - limit: 1 - }); - }); - - it('should return the messages list for a valid transaction with payments and with an offset', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('3'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(2); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - withPayments: true, - offset: 1 - }); - }); - - it('should return the messages list for a valid transaction with payments and with an orderBy=timestamp:desc', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('3'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(3); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - withPayments: true, - orderBy: 'timestamp:desc' - }); - }); - - it('should return the messages list for a valid transaction with payments and with an orderBy=timestamp:asc', function (done) { - getMessages(sender.address, recipient1.address, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('count').to.equal('3'); - node.expect(res.body).to.have.property('messages').to.have.lengthOf(3); - node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); - node.expect(res.body.participants[0].address).to.equal(sender.address); - node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); - node.expect(res.body.participants[1].address).to.equal(recipient1.address); - node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); - done(); - }, { - withPayments: true, - orderBy: 'timestamp:asc' - }); - }); + const sender = node.randomAccount(); + const recipient1 = node.randomAccount(); + const recipient2 = node.randomAccount(); + + // send ADM to message sender + before(function (done) { + sendADM({ + secret: node.iAccount.password, + amount: node.fees.messageFee * 3 + node.fees.transactionFee * 2, + recipientId: sender.address + }, function () { + done(); + }); + }); + + // send ADM to recipient1 + before(function (done) { + sendADM({ + secret: node.iAccount.password, + amount: node.fees.messageFee, + recipientId: recipient1.address + }, function () { + done(); + }); + }); + + // send ADM to recipient2 + before(function (done) { + sendADM({ + secret: node.iAccount.password, + amount: node.fees.messageFee, + recipientId: recipient2.address + }, function () { + done(); + }); + }); + + before(function (done) { + node.onNewBlock(function () { + done(); + }); + }); + + // send a message from a sender to recipient1 + before(function (done) { + const transaction = node.createChatTransaction({ + keyPair: sender.keypair, + recipientId: recipient1.address, + message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), + own_message: '', + type: 1 + }); + postMessage(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + done(); + }); + }); + + // send a message from a recipient1 to recipient2 + before(function (done) { + const transaction = node.createChatTransaction({ + keyPair: recipient1.keypair, + recipientId: recipient2.address, + message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), + own_message: '', + type: 1 + }); + postMessage(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + done(); + }); + }); + + // send a message from a recipient2 to recipient1 + before(function (done) { + const transaction = node.createChatTransaction({ + keyPair: recipient2.keypair, + recipientId: recipient1.address, + message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), + own_message: '', + type: 1 + }); + postMessage(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + done(); + }); + }); + + before(function (done) { + node.onNewBlock(function () { + done(); + }); + }); + + // send a message from a sender to recipient2 + before(function (done) { + const transaction = node.createChatTransaction({ + keyPair: sender.keypair, + recipientId: recipient2.address, + message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), + own_message: '', + type: 1 + }); + postMessage(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + done(); + }); + }); + + before(function (done) { + node.onNewBlock(function () { + done(); + }); + }); + + // send a second message from a sender to recipient1 + before(function (done) { + const transaction = node.createChatTransaction({ + keyPair: sender.keypair, + recipientId: recipient1.address, + message: new Mnemonic(Mnemonic.Words.ENGLISH).toString(), + own_message: '', + type: 1 + }); + postMessage(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').that.is.not.empty; + done(); + }); + }); + + // send ADM to message sender + before(function (done) { + sendADM({ + secret: sender.password, + amount: node.fees.transactionFee, + recipientId: recipient1.address + }, function () { + done(); + }); + }); + + before(function (done) { + node.onNewBlock(function () { + done(); + }); + }); + + it('should return the chat list for sender with no parameters', function (done) { + getChats(sender.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); // 2 chats and 1 direct transfer from iAccount + node.expect(res.body).to.have.property('chats').to.have.lengthOf(3); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + if (res.body.chats[i].participants[0].address !== 'U5338684603617333081') { + node.expect(res.body.chats[i].participants[0].address).to.equal(sender.address); + node.expect(res.body.chats[i].participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.chats[i].lastTransaction.asset).to.have.property('chat').to.be.an('object'); + node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('message').to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('own_message').to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('type').to.not.equal(null); + } else { + node.expect(res.body.chats[i].participants[0].address).to.equal(node.iAccount.address); + node.expect(res.body.chats[i].participants[0].publicKey).to.equal(node.iAccount.publicKey); + node.expect(res.body.chats[i].participants[1].address).to.equal(sender.address); + node.expect(res.body.chats[i].participants[1].publicKey).to.equal(sender.publicKey.toString('hex')); + } + node.expect(res.body.chats[i].participants[1].publicKey).to.not.equal(null); + node.expect(res.body.chats[i]).to.have.property('lastTransaction').to.be.an('object'); + node.expect(res.body.chats[i].lastTransaction.timestamp).to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction.fee).to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction.amount).to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction).to.have.property('asset').to.be.an('object'); + } + done(); + }); + }); + + it('should return the chat list for recipient1', function (done) { + getChats(recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); // 2 chats and 1 direct transfer from iAccount + node.expect(res.body).to.have.property('chats').to.have.lengthOf(3); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.chats[i].participants[0].publicKey).to.not.equal(null); + node.expect(res.body.chats[i].participants[1].publicKey).to.not.equal(null); + node.expect(res.body.chats[i]).to.have.property('lastTransaction').to.be.an('object'); + node.expect(res.body.chats[i].lastTransaction.timestamp).to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction.fee).to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction.amount).to.not.equal(null); + } + done(); + }, { orderBy: 'timestamp:desc' }); + }); + + it('should return the chat list for recipient2', function (done) { + getChats(recipient2.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); // 2 chats and 1 direct transfer from iAccount + node.expect(res.body).to.have.property('chats').to.have.lengthOf(3); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.chats[i].participants[0].publicKey).to.not.equal(null); + node.expect(res.body.chats[i].participants[1].publicKey).to.not.equal(null); + node.expect(res.body.chats[i]).to.have.property('lastTransaction').to.be.an('object'); + node.expect(res.body.chats[i].lastTransaction.timestamp).to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction.fee).to.not.equal(null); + node.expect(res.body.chats[i].lastTransaction.amount).to.not.equal(null); + } + done(); + }); + }); + + it('should return the chat list for sender with limit', function (done) { + getChats(sender.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('chats').to.have.lengthOf(1); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + for (let y = 0; y < res.body.chats[i].participants.length; y++) { + node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); + } + } + done(); + }, { limit: 1 }); + }); + + it('should return the chat list for sender with offset', function (done) { + getChats(sender.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('chats').to.have.lengthOf(2); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + for (let y = 0; y < res.body.chats[i].participants.length; y++) { + node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); + } + } + done(); + }, { offset: 1 }); + }); + + it('should return the chat list for sender with orderBy=timestamp:desc', function (done) { + getChats(sender.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('chats').to.have.lengthOf(3); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + for (let y = 0; y < res.body.chats[i].participants.length; y++) { + node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); + } + } + done(); + }, { orderBy: 'timestamp:desc' }); + }); + + it('should return the chat list for sender with orderBy=timestamp:asc', function (done) { + getChats(sender.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('chats').to.have.lengthOf(3); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + for (let y = 0; y < res.body.chats[i].participants.length; y++) { + node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); + } + } + done(); + }, { orderBy: 'timestamp:asc' }); + }); + + it('should return the chat list for recipient1', function (done) { + getChats(recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('chats').to.have.lengthOf(3); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + for (let y = 0; y < res.body.chats[i].participants.length; y++) { + node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); + } + } + done(); + }); + }); + + it('should return the messages between sender and recipient1', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); // 2 messages and 1 direct transfer + node.expect(res.body).to.have.property('messages').to.have.lengthOf(3); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }); + }); + + it('should return the messages between sender and recipient1 with a limit', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(1); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + limit: 1 + }); + }); + + it('should return the messages between sender and recipient1 with an offset', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(2); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + offset: 1 + }); + }); + + it('should return the messages between sender and recipient1 with an orderBy=timestamp:desc', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(3); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + orderBy: 'timestamp:desc' + }); + }); + + it('should return the messages between sender and recipient1 with an orderBy=timestamp:asc', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(3); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + orderBy: 'timestamp:asc' + }); + }); + + it('should return the messages between sender and recipient1 without direct transfers', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('2'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(2); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + withoutDirectTransfers: true + }); + }); + + it('should return the messages between sender and recipient1 without direct transfers with a limit', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('2'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(1); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + withoutDirectTransfers: true, + limit: 1 + }); + }); + + it('should return the messages between sender and recipient1 without direct transfers with an offset', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('2'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(1); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + withoutDirectTransfers: true, + offset: 1 + }); + }); + + it('should return the messages between sender and recipient1 without direct transfers with an orderBy=timestamp:desc', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('2'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(2); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + withoutDirectTransfers: true, + orderBy: 'timestamp:desc' + }); + }); + + it('should return the messages between sender and recipient1 without direct transfers with an orderBy=timestamp:asc', function (done) { + getMessages(sender.address, recipient1.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('2'); + node.expect(res.body).to.have.property('messages').to.have.lengthOf(2); + node.expect(res.body).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.participants[0].address).to.equal(sender.address); + node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); + node.expect(res.body.participants[1].address).to.equal(recipient1.address); + node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + done(); + }, { + withoutDirectTransfers: true, + orderBy: 'timestamp:asc' + }); + }); }); diff --git a/test/api/delegates.js b/test/api/delegates.js index 4a5858a8..d3b87bbf 100644 --- a/test/api/delegates.js +++ b/test/api/delegates.js @@ -196,7 +196,7 @@ describe('PUT /api/accounts/delegates with funds', function () { }); }); - it('when upvoting using a blank pasphrase should fail', function (done) { + it('when upvoting using a blank passphrase should fail', function (done) { putAccountsDelegates({ secret: '', delegates: ['+' + node.eAccount.publicKey] @@ -207,7 +207,7 @@ describe('PUT /api/accounts/delegates with funds', function () { }); }); - it('when downvoting using a blank pasphrase should fail', function (done) { + it('when downvoting using a blank passphrase should fail', function (done) { putAccountsDelegates({ secret: '', delegates: ['-' + node.eAccount.publicKey] @@ -280,7 +280,7 @@ describe('PUT /api/delegates with funds', function () { }); }); - it('using blank pasphrase should fail', function (done) { + it('using blank passphrase should fail', function (done) { validParams.secret = ''; putDelegates(validParams, function (err, res) { @@ -290,7 +290,7 @@ describe('PUT /api/delegates with funds', function () { }); }); - it('using invalid pasphrase should fail', function (done) { + it('using invalid passphrase should fail', function (done) { validParams.secret = []; putDelegates(validParams, function (err, res) { @@ -933,7 +933,7 @@ describe('GET /api/delegates/voters', function () { // }); // }); // -// it('using critera == "lo" should return 2 delegates', function (done) { +// it('using criteria == "lo" should return 2 delegates', function (done) { // var q = 'lo'; // // node.get('/api/delegates/search?q=' + q, function (err, res) { @@ -944,7 +944,7 @@ describe('GET /api/delegates/voters', function () { // }); // }); // -// it('using critera == "love" should return 1 delegate', function (done) { +// it('using criteria == "love" should return 1 delegate', function (done) { // var q = 'love'; // // node.get('/api/delegates/search?q=' + q, function (err, res) { @@ -955,7 +955,7 @@ describe('GET /api/delegates/voters', function () { // }); // }); // -// it('using critera == "genesis_101" should have all properties', function (done) { +// it('using criteria == "genesis_101" should have all properties', function (done) { // var q = 'genesis_101'; // // node.get('/api/delegates/search?q=' + q, function (err, res) { From 41e7cd8a9e2eb179cdc00e9058be8cbc08c8a944 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Fri, 10 Sep 2021 18:14:08 +0300 Subject: [PATCH 34/67] Add chatrooms tests for timestamps --- test/api/chatrooms.js | 83 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/test/api/chatrooms.js b/test/api/chatrooms.js index 06a49834..2004069b 100644 --- a/test/api/chatrooms.js +++ b/test/api/chatrooms.js @@ -84,6 +84,12 @@ describe('GET /api/chatrooms/:ID/:ID', function () { }); }); + before(function (done) { + node.onNewBlock(function () { + done(); + }); + }); + // send a message from a recipient1 to recipient2 before(function (done) { const transaction = node.createChatTransaction({ @@ -100,6 +106,12 @@ describe('GET /api/chatrooms/:ID/:ID', function () { }); }); + before(function (done) { + node.onNewBlock(function () { + done(); + }); + }); + // send a message from a recipient2 to recipient1 before(function (done) { const transaction = node.createChatTransaction({ @@ -138,6 +150,17 @@ describe('GET /api/chatrooms/:ID/:ID', function () { }); }); + // send ADM from sender to recipient1 + before(function (done) { + sendADM({ + secret: sender.password, + amount: node.fees.transactionFee, + recipientId: recipient1.address + }, function () { + done(); + }); + }); + before(function (done) { node.onNewBlock(function () { done(); @@ -160,17 +183,6 @@ describe('GET /api/chatrooms/:ID/:ID', function () { }); }); - // send ADM to message sender - before(function (done) { - sendADM({ - secret: sender.password, - amount: node.fees.transactionFee, - recipientId: recipient1.address - }, function () { - done(); - }); - }); - before(function (done) { node.onNewBlock(function () { done(); @@ -184,14 +196,14 @@ describe('GET /api/chatrooms/:ID/:ID', function () { node.expect(res.body).to.have.property('chats').to.have.lengthOf(3); for (let i = 0; i < res.body.chats.length; i++) { node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); - if (res.body.chats[i].participants[0].address !== 'U5338684603617333081') { + if (res.body.chats[i].participants[0].address !== node.iAccount.address) { // if it's a message node.expect(res.body.chats[i].participants[0].address).to.equal(sender.address); node.expect(res.body.chats[i].participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); node.expect(res.body.chats[i].lastTransaction.asset).to.have.property('chat').to.be.an('object'); node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('message').to.not.equal(null); node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('own_message').to.not.equal(null); node.expect(res.body.chats[i].lastTransaction.asset.chat).to.have.property('type').to.not.equal(null); - } else { + } else { // if it is a direct transfer from node.iAccount.address node.expect(res.body.chats[i].participants[0].address).to.equal(node.iAccount.address); node.expect(res.body.chats[i].participants[0].publicKey).to.equal(node.iAccount.publicKey); node.expect(res.body.chats[i].participants[1].address).to.equal(sender.address); @@ -222,6 +234,10 @@ describe('GET /api/chatrooms/:ID/:ID', function () { node.expect(res.body.chats[i].lastTransaction.fee).to.not.equal(null); node.expect(res.body.chats[i].lastTransaction.amount).to.not.equal(null); } + let pTimestamp = res.body.chats[0].lastTransaction.timestamp; + for (let i = 1; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i].lastTransaction).to.have.property('timestamp').to.be.below(pTimestamp); + } done(); }, { orderBy: 'timestamp:desc' }); }); @@ -274,17 +290,36 @@ describe('GET /api/chatrooms/:ID/:ID', function () { }, { offset: 1 }); }); + it('should return the chat list for sender with both limit and offset', function (done) { + getChats(sender.address, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('count').to.equal('3'); + node.expect(res.body).to.have.property('chats').to.have.lengthOf(1); + for (let i = 0; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + for (let y = 0; y < res.body.chats[i].participants.length; y++) { + node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); + } + } + done(); + }, { limit: 1, offset: 1 }); + }); + it('should return the chat list for sender with orderBy=timestamp:desc', function (done) { getChats(sender.address, function (err, res) { node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('count').to.equal('3'); node.expect(res.body).to.have.property('chats').to.have.lengthOf(3); for (let i = 0; i < res.body.chats.length; i++) { - node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); + node.expect(res.body.chats[i]).to.have.property('participants').to.have.lengthOf(2); for (let y = 0; y < res.body.chats[i].participants.length; y++) { node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); } } + let pTimestamp = res.body.chats[0].lastTransaction.timestamp; + for (let i = 1; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i].lastTransaction).to.have.property('timestamp').to.be.below(pTimestamp); + } done(); }, { orderBy: 'timestamp:desc' }); }); @@ -300,6 +335,10 @@ describe('GET /api/chatrooms/:ID/:ID', function () { node.expect(res.body.chats[i].participants[y].publicKey).to.not.equal(null); } } + let pTimestamp = res.body.chats[0].lastTransaction.timestamp; + for (let i = 1; i < res.body.chats.length; i++) { + node.expect(res.body.chats[i].lastTransaction).to.have.property('timestamp').to.be.above(pTimestamp); + } done(); }, { orderBy: 'timestamp:asc' }); }); @@ -375,6 +414,10 @@ describe('GET /api/chatrooms/:ID/:ID', function () { node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); node.expect(res.body.participants[1].address).to.equal(recipient1.address); node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + let pTimestamp = res.body.messages[0].timestamp; + for (let i = 1; i < res.body.messages.length; i++) { + node.expect(res.body.messages[i]).to.have.property('timestamp').to.be.below(pTimestamp); + } done(); }, { orderBy: 'timestamp:desc' @@ -391,6 +434,10 @@ describe('GET /api/chatrooms/:ID/:ID', function () { node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); node.expect(res.body.participants[1].address).to.equal(recipient1.address); node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + let pTimestamp = res.body.messages[0].timestamp; + for (let i = 1; i < res.body.messages.length; i++) { + node.expect(res.body.messages[i]).to.have.property('timestamp').to.be.above(pTimestamp); + } done(); }, { orderBy: 'timestamp:asc' @@ -457,6 +504,10 @@ describe('GET /api/chatrooms/:ID/:ID', function () { node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); node.expect(res.body.participants[1].address).to.equal(recipient1.address); node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + let pTimestamp = res.body.messages[0].timestamp; + for (let i = 1; i < res.body.messages.length; i++) { + node.expect(res.body.messages[i]).to.have.property('timestamp').to.be.below(pTimestamp); + } done(); }, { withoutDirectTransfers: true, @@ -474,6 +525,10 @@ describe('GET /api/chatrooms/:ID/:ID', function () { node.expect(res.body.participants[0].publicKey).to.equal(sender.publicKey.toString('hex')); node.expect(res.body.participants[1].address).to.equal(recipient1.address); node.expect(res.body.participants[1].publicKey).to.equal(recipient1.publicKey.toString('hex')); + let pTimestamp = res.body.messages[0].timestamp; + for (let i = 1; i < res.body.messages.length; i++) { + node.expect(res.body.messages[i]).to.have.property('timestamp').to.be.above(pTimestamp); + } done(); }, { withoutDirectTransfers: true, From c02bba31fc098d48b6ee0a29d588b853d6c823a9 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Sat, 11 Sep 2021 11:28:20 +0300 Subject: [PATCH 35/67] Fix tests for delegates --- test/api/delegates.js | 640 ++++++++++++++++++++---------------------- 1 file changed, 310 insertions(+), 330 deletions(-) diff --git a/test/api/delegates.js b/test/api/delegates.js index d3b87bbf..346b0955 100644 --- a/test/api/delegates.js +++ b/test/api/delegates.js @@ -88,7 +88,6 @@ describe('PUT /api/accounts/delegates with funds', function () { amount: node.randomLISK(), recipientId: account.address }, function (err, res) { - console.log('res.body', res.body); node.expect(res.body).to.have.property('success').to.be.ok; node.expect(res.body).to.have.property('transactionId'); node.expect(res.body.transactionId).to.be.not.empty; @@ -103,7 +102,7 @@ describe('PUT /api/accounts/delegates with funds', function () { }); it('when upvoting same delegate multiple times should fail', function (done) { - var votedDelegate = Array.apply(null, Array(2)).map(function () { return '+' + node.eAccount.publicKey;}); + var votedDelegate = Array.apply(null, Array(2)).map(function () { return '+' + node.eAccount.publicKey; }); putAccountsDelegates({ secret: account.password, @@ -116,7 +115,7 @@ describe('PUT /api/accounts/delegates with funds', function () { }); it('when downvoting same delegate multiple times should fail', function (done) { - var votedDelegate = Array.apply(null, Array(2)).map(function () { return '-' + node.eAccount.publicKey;}); + var votedDelegate = Array.apply(null, Array(2)).map(function () { return '-' + node.eAccount.publicKey; }); putAccountsDelegates({ secret: account.password, @@ -429,7 +428,7 @@ describe('GET /api/delegates (cache)', function () { orderBy = 'unknown:asc'; params = 'orderBy=' + orderBy; - node.get(url+ params, function (err, res) { + node.get(url + params, function (err, res) { node.expect(res.body).to.have.property('success').to.be.not.ok; node.expect(res.body).to.have.property('error').to.equal('Invalid sort field'); cache.getJsonForKey(url + params, function (err, res) { @@ -550,40 +549,60 @@ describe('GET /api/delegates', function () { }); }); - // it('using orderBy == "vote:asc" should be ok', function (done) { - // var orderBy = 'vote:asc'; - // var params = 'orderBy=' + orderBy; - // - // node.get('/api/delegates?' + params, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // node.expect(res.body).to.have.property('delegates').that.is.an('array'); - // node.expect(res.body.delegates).to.have.lengthOf(101); - // for (var i = 0; i < res.body.delegates.length; i++) { - // if (res.body.delegates[i + 1] != null) { - // node.expect(res.body.delegates[i].vote).to.be.at.most(res.body.delegates[i + 1].vote); - // } - // } - // done(); - // }); - // }); - - // it('using orderBy == "vote:desc" should be ok', function (done) { - // var orderBy = 'vote:desc'; - // var params = 'orderBy=' + orderBy; - // - // node.get('/api/delegates?' + params, function (err, res) { - // node.expect(res.body).to.have.property('success').to.be.ok; - // node.expect(res.body).to.have.property('delegates').that.is.an('array'); - // node.expect(res.body.delegates).to.have.lengthOf(101); - // const delegates = res.body.delegates.sort((x,y) => parseInt(y.vote)-parseInt(x.vote)); - // for (var i = delegates.length-1; i > 0; i--) { - // if (delegates[i - 1] != null) { - // node.expect(delegates[i].vote).to.be.at.least(delegates[i - 1].vote); - // } - // } - // done(); - // }); - // }); + it('using orderBy == "vote:asc" should be ok', function (done) { + var orderBy = 'vote:asc'; + var params = 'orderBy=' + orderBy; + + node.get('/api/delegates?' + params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.lengthOf(101); + for (var i = 0; i < res.body.delegates.length; i++) { + if (res.body.delegates[i + 1]) { + node.expect(Number(res.body.delegates[i].vote)).to.be.at.most(Number(res.body.delegates[i + 1].vote)); + } + } + done(); + }); + }); + + it('using orderBy == "vote:desc" should be ok', function (done) { + var orderBy = 'vote:desc'; + var params = 'orderBy=' + orderBy; + + node.get('/api/delegates?' + params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.lengthOf(101); + for (var i = 0; i < res.body.delegates.length; i++) { + if (res.body.delegates[i + 1]) { + node.expect(Number(res.body.delegates[i].vote)).to.be.at.least(Number(res.body.delegates[i + 1].vote)); + } + } + done(); + }); + }); + + // Sorting via votesWeight is not yet implemented + + /* + it('using orderBy == "votesWeight:asc" should be ok', function (done) { + var orderBy = 'votesWeight:asc'; + var params = 'orderBy=' + orderBy; + + node.get('/api/delegates?' + params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.lengthOf(101); + for (var i = 0; i < res.body.delegates.length; i++) { + if (res.body.delegates[i + 1]) { + node.expect(Number(res.body.delegates[i].votesWeight)).to.be.at.most(Number(res.body.delegates[i + 1].votesWeight)); + } + } + done(); + }); + }); + */ it('using orderBy == "username:asc" should be ok', function (done) { var orderBy = 'username:asc'; @@ -733,7 +752,7 @@ describe('GET /api/delegates', function () { var dividedIndices = res.body.delegates.reduce(function (memo, peer, index) { memo[peer[sortField] === null ? 'nullIndices' : 'notNullIndices'].push(index); return memo; - }, {notNullIndices: [], nullIndices: []}); + }, { notNullIndices: [], nullIndices: [] }); if (dividedIndices.nullIndices.length && dividedIndices.notNullIndices.length) { var ascOrder = function (a, b) { return a - b; }; @@ -832,296 +851,257 @@ describe('GET /api/delegates/voters', function () { }); }); -// describe('GET /api/delegates/search', function () { -// -// const accounts = Array.from(Array(101)).map(() => node.randomAccount()); -// -// before(function (done) { -// for (let i = 0; i < 101; i++) { -// const account = accounts[i]; -// sendADM({ -// secret: "echo indoor minute album notice pear prosper situate alcohol vintage athlete crouch", -// amount: node.constants.fees.delegate, -// recipientId: account.address -// }, (err, res) => { -// node.expect(res.body).to.have.property('success'); -// node.waitForBlocks(2, () => { -// const params = { -// secret: account.password, -// username: `genesis_${i+1}` -// }; -// putDelegates(params, (err, res) => { -// node.expect(res.body).to.have.property('success'); -// }); -// }); -// }); -// } -// done(); -// }); -// -// before(function (done) { -// node.waitForBlocks(101, done); -// }); -// -// // before(function (done) { -// // accounts.forEach((account,i) => { -// // -// // }); -// // // node.onNewBlock(done); -// // done(); -// // }); -// // -// // before(function (done) { -// // node.waitForBlocks(101, done); -// // }); -// -// it('using no criteria should fail', function (done) { -// node.get('/api/delegates/search', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using blank criteria should fail', function (done) { -// var q = ''; -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using wildcard criteria should be ok', function (done) { -// var q = '%'; // 1 character -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// done(); -// }); -// }); -// -// it('using criteria with length == 1 should be ok', function (done) { -// var q = 'g'; // 1 character -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// done(); -// }); -// }); -// -// it('using criteria with length == 20 should be ok', function (done) { -// var q = 'genesis_123456789012'; // 20 characters -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// done(); -// }); -// }); -// -// it('using criteria with length > 20 should fail', function (done) { -// var q = 'genesis_1234567890123'; // 21 characters -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using criteria == "lo" should return 2 delegates', function (done) { -// var q = 'lo'; -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// node.expect(res.body.delegates).to.have.length(2); -// done(); -// }); -// }); -// -// it('using criteria == "love" should return 1 delegate', function (done) { -// var q = 'love'; -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// node.expect(res.body.delegates).to.have.length(1); -// done(); -// }); -// }); -// -// it('using criteria == "genesis_101" should have all properties', function (done) { -// var q = 'genesis_101'; -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// node.expect(res.body.delegates).to.have.length(1); -// node.expect(res.body.delegates[0]).to.have.property('rank').that.is.an('number'); -// node.expect(res.body.delegates[0]).to.have.property('username').that.is.an('string'); -// node.expect(res.body.delegates[0]).to.have.property('address').that.is.an('string'); -// node.expect(res.body.delegates[0]).to.have.property('publicKey').that.is.an('string'); -// node.expect(res.body.delegates[0]).to.have.property('vote').that.is.an('string'); -// node.expect(res.body.delegates[0]).to.have.property('producedblocks').that.is.an('number'); -// node.expect(res.body.delegates[0]).to.have.property('missedblocks').that.is.an('number'); -// node.expect(res.body.delegates[0]).to.have.property('approval').that.is.an('number'); -// node.expect(res.body.delegates[0]).to.have.property('productivity').that.is.an('number'); -// node.expect(res.body.delegates[0]).to.have.property('voters_cnt').that.is.an('number'); -// node.expect(res.body.delegates[0]).to.have.property('register_timestamp').that.is.an('number'); -// done(); -// }); -// }); -// -// it('using no limit should be ok', function (done) { -// var q = 'genesis_'; -// -// node.get('/api/delegates/search?q=' + q, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// node.expect(res.body.delegates).to.have.length(101); -// done(); -// }); -// }); -// -// it('using string limit should fail', function (done) { -// var q = 'genesis_'; -// var limit = 'one'; -// -// node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using limit == -100 should fail', function (done) { -// var q = 'genesis_'; -// var limit = -100; -// -// node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using limit == -1 should fail', function (done) { -// var q = 'genesis_'; -// var limit = -1; -// -// node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using limit == 0 should fail', function (done) { -// var q = 'genesis_'; -// var limit = 0; -// -// node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using limit == 1 should be ok', function (done) { -// var q = 'genesis_'; -// var limit = 1; -// -// node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.ok; -// node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// node.expect(res.body.delegates).to.have.length(1); -// done(); -// }); -// }); -// -// // it('using limit == 1000 should be ok', function (done) { -// // var q = 'genesis_'; -// // var limit = 1000; -// // -// // node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { -// // node.expect(res.body).to.have.property('success').to.be.ok; -// // node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// // node.expect(res.body.delegates).to.have.length(101); -// // done(); -// // }); -// // }); -// -// it('using limit > 1000 should fail', function (done) { -// var q = 'genesis_'; -// var limit = 1001; -// -// node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// it('using orderBy == "unknown:asc" should fail', function (done) { -// var q = 'genesis_'; -// -// node.get('/api/delegates/search?q=' + q + '&orderBy=unknown:asc', function (err, res) { -// node.expect(res.body).to.have.property('success').to.be.not.ok; -// node.expect(res.body).to.have.property('error'); -// done(); -// }); -// }); -// -// // it('using no orderBy should be ordered by ascending username', function (done) { -// // var q = 'genesis_'; -// // -// // node.get('/api/delegates/search?q=' + q, function (err, res) { -// // node.expect(res.body).to.have.property('success').to.be.ok; -// // node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// // node.expect(res.body.delegates).to.have.length(101); -// // node.expect(res.body.delegates[0]).to.have.property('username'); -// // node.expect(res.body.delegates[0].username).to.equal('genesis_1'); -// // node.expect(res.body.delegates[24]).to.have.property('username'); -// // node.expect(res.body.delegates[24].username).to.equal('genesis_3'); -// // done(); -// // }); -// // }); -// // -// // it('using orderBy == "username:asc" should be ordered by ascending username', function (done) { -// // var q = 'genesis_'; -// // -// // node.get('/api/delegates/search?q=' + q + '&orderBy=username:asc', function (err, res) { -// // node.expect(res.body).to.have.property('success').to.be.ok; -// // node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// // node.expect(res.body.delegates).to.have.length(101); -// // node.expect(res.body.delegates[0]).to.have.property('username'); -// // node.expect(res.body.delegates[0].username).to.equal('genesis_1'); -// // node.expect(res.body.delegates[24]).to.have.property('username'); -// // node.expect(res.body.delegates[24].username).to.equal('genesis_3'); -// // done(); -// // }); -// // }); -// // -// // it('using orderBy == "username:desc" should be ordered by descending username', function (done) { -// // var q = 'genesis_'; -// // -// // node.get('/api/delegates/search?q=' + q + '&orderBy=username:desc', function (err, res) { -// // node.expect(res.body).to.have.property('success').to.be.ok; -// // node.expect(res.body).to.have.property('delegates').that.is.an('array'); -// // node.expect(res.body.delegates).to.have.length(101); -// // node.expect(res.body.delegates[0]).to.have.property('username'); -// // node.expect(res.body.delegates[0].username).to.equal('genesis_99'); -// // node.expect(res.body.delegates[24]).to.have.property('username'); -// // node.expect(res.body.delegates[24].username).to.equal('genesis_77'); -// // done(); -// // }); -// // }); -// }); +describe('GET /api/delegates/search', function () { + + const accounts = Array.from(Array(101)).map(() => node.randomAccount()); + + it('using no criteria should fail', function (done) { + node.get('/api/delegates/search', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using blank criteria should fail', function (done) { + var q = ''; + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using wildcard criteria should be ok', function (done) { + var q = '%'; // 1 character + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + done(); + }); + }); + + it('using criteria with length == 1 should be ok', function (done) { + var q = 'g'; // 1 character + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + done(); + }); + }); + + it('using criteria with length == 20 should be ok', function (done) { + var q = 'genesis_123456789012'; // 20 characters + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + done(); + }); + }); + + it('using criteria with length > 20 should fail', function (done) { + var q = 'genesis_1234567890123'; // 21 characters + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using criteria == "lo" should return 2 delegates', function (done) { + var q = 'lo'; + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.length(2); + done(); + }); + }); + + it('using criteria == "love" should return 1 delegate', function (done) { + var q = 'love'; + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.length(1); + done(); + }); + }); + + it('using criteria == "market" should have all properties', function (done) { + var q = 'market'; + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.length(1); + node.expect(res.body.delegates[0]).to.have.property('rank').that.is.an('number'); + node.expect(res.body.delegates[0]).to.have.property('username').that.is.an('string'); + node.expect(res.body.delegates[0]).to.have.property('address').that.is.an('string'); + node.expect(res.body.delegates[0]).to.have.property('publicKey').that.is.an('string'); + node.expect(res.body.delegates[0]).to.have.property('vote').that.is.an('string'); + node.expect(res.body.delegates[0]).to.have.property('producedblocks').that.is.an('number'); + node.expect(res.body.delegates[0]).to.have.property('missedblocks').that.is.an('number'); + node.expect(res.body.delegates[0]).to.have.property('approval').that.is.an('number'); + node.expect(res.body.delegates[0]).to.have.property('productivity').that.is.an('number'); + node.expect(res.body.delegates[0]).to.have.property('voters_cnt').that.is.an('number'); + node.expect(res.body.delegates[0]).to.have.property('register_timestamp').that.is.an('number'); + done(); + }); + }); + + it('using no limit should be ok', function (done) { + var q = '%'; + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.length(101); + done(); + }); + }); + + it('using string limit should fail', function (done) { + var q = '%'; + var limit = 'one'; + + node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using limit == -100 should fail', function (done) { + var q = '%'; + var limit = -100; + + node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using limit == -1 should fail', function (done) { + var q = '%'; + var limit = -1; + + node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using limit == 0 should fail', function (done) { + var q = '%'; + var limit = 0; + + node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using limit == 1 should be ok', function (done) { + var q = '%'; + var limit = 1; + + node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.length(1); + done(); + }); + }); + + it('using limit == 1000 should be ok', function (done) { + var q = '%'; + var limit = 1000; + + node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates.length).to.be.at.least(101); + done(); + }); + }); + + it('using limit > 1000 should fail', function (done) { + var q = '%'; + var limit = 1001; + + node.get('/api/delegates/search?q=' + q + '&limit=' + limit, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using orderBy == "unknown:asc" should fail', function (done) { + var q = '%'; + + node.get('/api/delegates/search?q=' + q + '&orderBy=unknown:asc', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.not.ok; + node.expect(res.body).to.have.property('error'); + done(); + }); + }); + + it('using no orderBy should be ordered by ascending username', function (done) { + var q = '%'; + + node.get('/api/delegates/search?q=' + q, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.length(101); + node.expect(res.body.delegates[0]).to.have.property('username'); + node.expect(res.body.delegates[0].username).to.be.at.most(res.body.delegates[1].username); + node.expect(res.body.delegates[24]).to.have.property('username'); + node.expect(res.body.delegates[24].username).to.be.at.most(res.body.delegates[25].username); + done(); + }); + }); + + it('using orderBy == "username:asc" should be ordered by ascending username', function (done) { + var q = '%'; + + node.get('/api/delegates/search?q=' + q + '&orderBy=username:asc', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.length(101); + node.expect(res.body.delegates[0]).to.have.property('username'); + node.expect(res.body.delegates[0].username).to.be.at.most(res.body.delegates[1].username); + node.expect(res.body.delegates[24]).to.have.property('username'); + node.expect(res.body.delegates[24].username).to.be.at.most(res.body.delegates[25].username); + done(); + }); + }); + + it('using orderBy == "username:desc" should be ordered by descending username', function (done) { + var q = '%'; + + node.get('/api/delegates/search?q=' + q + '&orderBy=username:desc', function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('delegates').that.is.an('array'); + node.expect(res.body.delegates).to.have.length(101); + node.expect(res.body.delegates[0]).to.have.property('username'); + node.expect(res.body.delegates[0].username).to.be.at.least(res.body.delegates[1].username); + node.expect(res.body.delegates[24]).to.have.property('username'); + node.expect(res.body.delegates[24].username).to.be.at.least(res.body.delegates[25].username); + done(); + }); + }); +}); describe('GET /api/delegates/forging/status', function () { it('using no params should be ok', function (done) { @@ -1236,7 +1216,7 @@ describe('POST /api/delegates/forging/enable', function () { done(); }); } else { - done(); + done(); } }); }); From ce1507fd6296a386a86d8cebbd1454cc9dddde1a Mon Sep 17 00:00:00 2001 From: adamant-al Date: Sat, 11 Sep 2021 12:44:19 +0300 Subject: [PATCH 36/67] Fix tests for peer.transactions --- test/api/peer.transactions.stress.js | 231 ++++++++++++++------------- 1 file changed, 116 insertions(+), 115 deletions(-) diff --git a/test/api/peer.transactions.stress.js b/test/api/peer.transactions.stress.js index c95142bd..94d63919 100644 --- a/test/api/peer.transactions.stress.js +++ b/test/api/peer.transactions.stress.js @@ -3,134 +3,135 @@ var node = require('./../node.js'); function postTransaction (transaction, done) { - node.post('/peer/transactions', { - transaction: transaction - }, done); + node.post('/peer/transactions', { + transaction: transaction + }, done); } function postTransactions (transactions, done) { - node.post('/peer/transactions', { - transactions: transactions - }, done); + node.post('/peer/transactions', { + transactions: transactions + }, done); } function sendADM (params, done) { - node.put('/api/transactions', params, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.onNewBlock(function (err) { - return done(err, res); - }); + node.put('/api/transactions', params, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(function (err) { + return done(err, res); }); + }); } describe('POST /peer/transactions', function () { - describe('sending 1000 bundled transfers to random addresses', function () { - - var transactions = []; - var maximum = 1000; - var count = 1; - const account = node.randomAccount(); - - before(function (done) { - sendADM({ - secret: node.iAccount.password, - amount: 5000000000*2000, - recipientId: account.address - },function () { - node.async.doUntil(function (next) { - var bundled = []; - - for (var i = 0; i < node.config.broadcasts.releaseLimit; i++) { - const recipient = node.randomAccount(); - let transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: recipient.address - }); - transaction.fee = node.fees.transactionFee; - - transactions.push(transaction); - bundled.push(transaction); - count++; - } - - postTransactions(bundled, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - next(); - }); - }, function () { - return (count >= maximum); - }, function (err) { - done(err); - }); + describe('sending 100 bundled transfers to random addresses', function () { + + var transactions = []; + var maximum = 100; + var count = 1; + const account = node.randomAccount(); + + before(function (done) { + sendADM({ + secret: node.iAccount.password, + amount: 5000000000 * 2000, + recipientId: account.address + }, function () { + node.async.doUntil(function (next) { + var bundled = []; + + for (var i = 0; i < node.config.broadcasts.releaseLimit; i++) { + const recipient = node.randomAccount(); + let transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: recipient.address }); + transaction.fee = node.fees.transactionFee; + + transactions.push(transaction); + bundled.push(transaction); + count++; + } - }); - - it('should confirm all transactions', function (done) { - var blocksToWait = Math.ceil(maximum / node.constants.maxTxsPerBlock); - node.waitForBlocks(blocksToWait, function (err) { - node.async.eachSeries(transactions, function (transaction, eachSeriesCb) { - node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transaction').that.is.an('object'); - return setImmediate(eachSeriesCb); - }); - }, done); - }); - }).timeout(500000); - }); - - describe('sending 1000 single transfers to random addresses', function () { - - var transactions = []; - var maximum = 1000; - var count = 1; - const account = node.randomAccount(); - - before(function (done) { - sendADM({ - secret: node.iAccount.password, - amount: 5000000000*2000, - recipientId: account.address - }, function () { - node.async.doUntil(function (next) { - const recipient = node.randomAccount(); - let transaction = node.createSendTransaction({ - keyPair: account.keypair, - amount: 100000000, - recipientId: recipient.address - }); - transaction.fee = node.fees.transactionFee; - - postTransaction(transaction, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); - transactions.push(transaction); - count++; - next(); - }); - }, function () { - return (count >= maximum); - }, function (err) { - done(err); - }); + postTransactions(bundled, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.onNewBlock(function (err) { + next(); }); - }); - - it('should confirm all transactions', function (done) { - var blocksToWait = Math.ceil(maximum / node.constants.maxTxsPerBlock); - node.waitForBlocks(blocksToWait, function (err) { - node.async.eachSeries(transactions, function (transaction, eachSeriesCb) { - node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { - node.expect(res.body).to.have.property('success').to.be.ok; - node.expect(res.body).to.have.property('transaction').that.is.an('object'); - return setImmediate(eachSeriesCb); - }); - }, done); - }); - }).timeout(500000); - }); + }); + }, function () { + return (count >= maximum); + }, function (err) { + done(err); + }); + }); + }); + + it('should confirm all bundled transactions', function (done) { + var blocksToWait = Math.ceil(maximum / node.constants.maxTxsPerBlock); + node.waitForBlocks(blocksToWait, function (err) { + node.async.eachSeries(transactions, function (transaction, eachSeriesCb) { + node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction').that.is.an('object'); + return setImmediate(eachSeriesCb); + }); + }, done); + }); + }).timeout(500000); + }); + + describe('sending 100 single transfers to random addresses', function () { + + var transactions = []; + var maximum = 100; + var count = 1; + const account = node.randomAccount(); + + before(function (done) { + sendADM({ + secret: node.iAccount.password, + amount: 5000000000 * 2000, + recipientId: account.address + }, function () { + node.async.doUntil(function (next) { + const recipient = node.randomAccount(); + let transaction = node.createSendTransaction({ + keyPair: account.keypair, + amount: 100000000, + recipientId: recipient.address + }); + transaction.fee = node.fees.transactionFee; + + postTransaction(transaction, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transactionId').to.equal(transaction.id); + transactions.push(transaction); + count++; + next(); + }); + }, function () { + return (count >= maximum); + }, function (err) { + done(err); + }); + }); + }); + + it('should confirm all single transactions', function (done) { + var blocksToWait = Math.ceil(maximum / node.constants.maxTxsPerBlock); + node.waitForBlocks(blocksToWait, function (err) { + node.async.eachSeries(transactions, function (transaction, eachSeriesCb) { + node.get('/api/transactions/get?id=' + transaction.id, function (err, res) { + node.expect(res.body).to.have.property('success').to.be.ok; + node.expect(res.body).to.have.property('transaction').that.is.an('object'); + return setImmediate(eachSeriesCb); + }); + }, done); + }); + }).timeout(500000); + }); }); From ca4f4e3b8b79a77526bb8a3dc0901c2637cb99f8 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Sat, 11 Sep 2021 16:23:30 +0300 Subject: [PATCH 37/67] Tune scripts --- Gruntfile.js | 8 ++++---- package.json | 10 ++++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 5ec5030f..698960c7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -15,12 +15,12 @@ module.exports = function (grunt) { 'app.js' ]; - var today = moment().format('HH:mm:ss DD/MM/YYYY'); + var today = moment().format('YYYY-MM-DD HH:mm:ss'); var config = require('./config.json'); var release_dir = __dirname + '/release/'; - var version_dir = release_dir + config.version; + var version_dir = release_dir + 'current'; var maxBufferSize = require('buffer').kMaxLength - 1; @@ -100,7 +100,7 @@ module.exports = function (grunt) { level: 6 }, files: [ - { expand: true, cwd: release_dir, src: [config.version + '/**'], dest: './' } + { expand: true, cwd: release_dir, src: ['current' + '/**'], dest: './' } ] } }, @@ -132,7 +132,7 @@ module.exports = function (grunt) { grunt.registerTask('default', ['release']); grunt.registerTask('release', ['exec:folder', 'obfuscator', 'exec:package', 'exec:build', 'compress']); - grunt.registerTask('jenkins', ['exec:coverageSingle']); + grunt.registerTask('test-single', ['exec:coverageSingle']); grunt.registerTask('eslint-nofix', ['eslint']); grunt.registerTask('test', ['eslint', 'exec:coverage']); diff --git a/package.json b/package.json index 1d618acd..c1d4edd6 100644 --- a/package.json +++ b/package.json @@ -5,13 +5,15 @@ "scripts": { "start": "node app.js", "start:testnet": "node app.js --config test/config.json --genesis test/genesisBlock.json", - "test": "./node_modules/.bin/grunt test --verbose", - "jenkins": "./node_modules/.bin/grunt jenkins --verbose", + "test:full": "./node_modules/.bin/grunt test --verbose", + "test:single": "./node_modules/.bin/grunt test-single --verbose", + "test:fast": "./node_modules/.bin/mocha --exclude test/unit/sql/blockRewards.js --exclude test/api/delegates.js --exclude test/api/peer.transactions.stress.js --exclude test/api/peer.transactions.votes.js test/unit/**/* test/api/**/*", + "test:all": "./node_modules/.bin/mocha test/unit/**/* test/api/**/*", "eslint": "./node_modules/.bin/grunt eslint-nofix --verbose", + "eslint:fix": "./node_modules/.bin/grunt eslint-fix --verbose", "fetchCoverage": "./node_modules/.bin/grunt exec:fetchCoverage --verbose", "jsdoc": "jsdoc -c docs/conf.json --verbose --pedantic", - "server-docs": "npm run jsdoc && http-server docs/jsdoc/", - "fasttest": "./node_modules/.bin/mocha --exclude test/unit/sql/blockRewards.js --exclude test/api/delegates.js --exclude test/api/peer.transactions.stress.js --exclude test/api/peer.transactions.votes.js test/unit/**/* test/api/**/*" + "server-docs": "npm run jsdoc && http-server docs/jsdoc/" }, "author": "ADAMANT Tech Labs , Lisk Foundation , lightcurve GmbH ", "license": "GPL-3.0", From 9c5e70aa1aeeacef8a6be5e4c6ef93d8ada3be50 Mon Sep 17 00:00:00 2001 From: adamant-al Date: Sat, 11 Sep 2021 16:44:16 +0300 Subject: [PATCH 38/67] Updat grunt & eslint --- .eslintignore | 1 - .eslintrc.json | 17 ++++++++++------- Gruntfile.js | 2 +- package.json | 14 +++++++------- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.eslintignore b/.eslintignore index e7d0d019..16bad264 100644 --- a/.eslintignore +++ b/.eslintignore @@ -10,5 +10,4 @@ tmp public/node_modules public/bower_components public/static -test/lisk-js helpers/bignum.js diff --git a/.eslintrc.json b/.eslintrc.json index 5105b53a..00f7f6ef 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,7 +1,15 @@ { + "env": { + "commonjs": true, + "es2021": true, + "browser": true, + "node": true + }, + "extends": [ + "google" + ], "parserOptions": { - "ecmaVersion": 5, - "sourceType": "module" + "ecmaVersion": 12 }, "rules": { "semi": "error", @@ -22,10 +30,6 @@ "no-mixed-requires": "off", "no-new-require": "off" }, - "env": { - "browser": true, - "node": true - }, "globals": { "it": true, "describe": true, @@ -35,5 +39,4 @@ "afterEach": true }, "plugins": [] - } diff --git a/Gruntfile.js b/Gruntfile.js index 698960c7..f63ab447 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -125,7 +125,7 @@ module.exports = function (grunt) { grunt.loadTasks('tasks'); - grunt.loadNpmTasks('grunt-obfuscator'); + grunt.loadNpmTasks('grunt-contrib-obfuscator'); grunt.loadNpmTasks('grunt-exec'); grunt.loadNpmTasks('grunt-contrib-compress'); grunt.loadNpmTasks('grunt-eslint'); diff --git a/package.json b/package.json index c1d4edd6..25d6f4aa 100644 --- a/package.json +++ b/package.json @@ -67,17 +67,17 @@ "coveralls": "=2.11.16", "crypto-browserify": "=3.11.0", "csv": "=1.1.1", + "eslint-config-google": "^0.14.0", "faker": "=3.1.0", - "grunt": "=1.0.1", - "grunt-cli": "=1.2.0", - "grunt-contrib-compress": "=1.4.1", - "grunt-eslint": "=19.0.0", - "grunt-exec": "=1.0.1", - "grunt-obfuscator": "=0.1.0", + "grunt": "^1.4.1", + "grunt-cli": "^1.4.3", + "grunt-contrib-compress": "^2.0.0", + "grunt-eslint": "^23.0.0", + "grunt-exec": "^3.0.0", + "grunt-contrib-obfuscator": "^8.0.0", "istanbul": "=0.4.5", "istanbul-middleware": "=0.2.2", "jsdoc": "^3.4.3", - "jsdox": "=0.4.10", "mocha": "=5.2.0", "moment": "=2.19.3", "sinon": "=1.17.7", From e6114b98bf0f98424ccfb4f4547ec402bf538e1f Mon Sep 17 00:00:00 2001 From: adamant-al Date: Sat, 11 Sep 2021 17:06:06 +0300 Subject: [PATCH 39/67] Replace tabs with spaces --- .eslintrc.json | 9 + api/http/accounts.js | 64 +- api/http/blocks.js | 64 +- api/http/chatrooms.js | 4 +- api/http/chats.js | 10 +- api/http/dapps.js | 78 +- api/http/delegates.js | 82 +- api/http/loader.js | 26 +- api/http/multisignatures.js | 24 +- api/http/node.js | 12 +- api/http/peers.js | 24 +- api/http/server.js | 48 +- api/http/signatures.js | 16 +- api/http/states.js | 6 +- api/http/transport.js | 188 +- app.js | 1274 ++++---- helpers/RoundChanges.js | 40 +- helpers/bignum.js | 150 +- helpers/cache.js | 48 +- helpers/checkIpInList.js | 82 +- helpers/config.js | 54 +- helpers/constants.js | 132 +- helpers/dappCategories.js | 26 +- helpers/dappTypes.js | 4 +- helpers/database.js | 346 +-- helpers/diff.js | 104 +- helpers/ed.js | 14 +- helpers/exceptions.js | 52 +- helpers/git.js | 16 +- helpers/httpApi.js | 342 +-- helpers/inserts.js | 74 +- helpers/jobsQueue.js | 28 +- helpers/json-schema/field.js | 2 +- helpers/json-schema/validator.js | 386 +-- helpers/orderBy.js | 110 +- helpers/request-limiter.js | 60 +- helpers/router.js | 78 +- helpers/sandbox.js | 12 +- helpers/sequence.js | 82 +- helpers/slots.js | 174 +- helpers/transactionTypes.js | 30 +- helpers/validator/field.js | 246 +- helpers/validator/utils.js | 38 +- helpers/validator/validator.js | 260 +- helpers/z_schema-express.js | 24 +- helpers/z_schema.js | 132 +- modules/blocks.js | 218 +- modules/blocks/api.js | 444 +-- modules/blocks/chain.js | 884 +++--- modules/blocks/process.js | 828 ++--- modules/blocks/utils.js | 496 +-- modules/blocks/verify.js | 520 ++-- modules/cache.js | 212 +- modules/crypto.js | 8 +- modules/dapps.js | 2726 ++++++++--------- modules/delegates.js | 1528 ++++----- modules/loader.js | 1238 ++++---- modules/multisignatures.js | 976 +++--- modules/node.js | 86 +- modules/peers.js | 990 +++--- modules/rounds.js | 486 +-- modules/server.js | 18 +- modules/signatures.js | 286 +- modules/sql.js | 384 +-- modules/system.js | 184 +- modules/transport.js | 1082 +++---- package.json | 1 + schema/accounts.js | 228 +- schema/blocks.js | 172 +- schema/chats.js | 468 +-- schema/config.js | 612 ++-- schema/dapps.js | 578 ++-- schema/delegates.js | 294 +- schema/loader.js | 48 +- schema/multisignatures.js | 170 +- schema/peers.js | 242 +- schema/signatures.js | 50 +- schema/states.js | 26 +- schema/transactions.js | 496 +-- schema/transport.js | 222 +- sql/chats.js | 28 +- sql/dapps.js | 60 +- sql/loader.js | 16 +- .../20170321001337_createRoundsFeesTable.sql | 154 +- .../20170403001337_calculateBlocksRewards.sql | 176 +- ...2001337_recreateCalculateBlocksRewards.sql | 244 +- sql/multisignatures.js | 2 +- sql/rounds.js | 40 +- sql/states.js | 36 +- sql/system.js | 2 +- sql/transport.js | 2 +- test/api/accounts.js | 778 ++--- test/api/blocks.js | 686 ++--- test/api/dapps.js | 2514 +++++++-------- test/api/delegates.js | 2718 ++++++++-------- test/api/loader.js | 34 +- test/api/multisignatures.js | 1430 ++++----- test/api/peer.blocks.js | 402 +-- test/api/peer.js | 182 +- test/api/peer.signatures.js | 556 ++-- test/api/peer.transactions.collision.js | 132 +- test/api/peer.transactions.delegates.js | 342 +-- test/api/peer.transactions.main.js | 506 +-- test/api/peer.transactions.multisignatures.js | 120 +- test/api/peer.transactions.signatures.js | 254 +- test/api/peer.transactions.votes.js | 888 +++--- test/api/peers.js | 1018 +++--- test/api/signatures.js | 192 +- test/api/transactions.js | 1968 ++++++------ test/sql/blockRewards.js | 10 +- 110 files changed, 18888 insertions(+), 18878 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 00f7f6ef..ec44b75e 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -12,6 +12,15 @@ "ecmaVersion": 12 }, "rules": { + "max-len": ["error", + { "code": 125, + "ignoreTrailingComments": true, + "ignoreUrls": true, + "ignoreStrings": true, + "ignoreTemplateLiterals": true, + "ignoreRegExpLiterals": true + }], + "require-jsdoc": ["off"], "semi": "error", "no-eq-null": "off", "indent": ["off", 4], diff --git a/api/http/accounts.js b/api/http/accounts.js index dce8ec96..c615da72 100644 --- a/api/http/accounts.js +++ b/api/http/accounts.js @@ -8,18 +8,18 @@ var schema = require('../../schema/accounts.js'); * Binds api with modules and creates common url. * - End point: `/api/accounts` * - Public API: - - post /open - - post /new - - get /getBalance - - get /getPublicKey - - post /generatePublicKey - - get /delegates - - get /delegates/fee - - put /delegates - - post /delegates - - get / + - post /open + - post /new + - get /getBalance + - get /getPublicKey + - post /generatePublicKey + - get /delegates + - get /delegates/fee + - put /delegates + - post /delegates + - get / * - Private API: - * - get /count + * - get /count * @memberof module:accounts * @requires helpers/Router * @requires helpers/httpApi @@ -30,34 +30,34 @@ var schema = require('../../schema/accounts.js'); function AccountsHttpApi (accountsModule, app) { - var router = new Router(); + var router = new Router(); - router.map(accountsModule.shared, { - 'post /open': 'open', + router.map(accountsModule.shared, { + 'post /open': 'open', 'post /new': 'new', - 'get /getBalance': 'getBalance', - 'get /getPublicKey': 'getPublickey', - 'post /generatePublicKey': 'generatePublicKey', - 'get /delegates': 'getDelegates', - 'get /delegates/fee': 'getDelegatesFee', - 'put /delegates': 'addDelegates', + 'get /getBalance': 'getBalance', + 'get /getPublicKey': 'getPublickey', + 'post /generatePublicKey': 'generatePublicKey', + 'get /delegates': 'getDelegates', + 'get /delegates/fee': 'getDelegatesFee', + 'put /delegates': 'addDelegates', 'post /delegates': 'voteForDelegates', - 'get /': 'getAccount' - }); + 'get /': 'getAccount' + }); - router.map(accountsModule.internal, { - 'get /count': 'count' - }); + router.map(accountsModule.internal, { + 'get /count': 'count' + }); - if (process.env.DEBUG && process.env.DEBUG.toUpperCase() === 'TRUE') { - router.map(accountsModule.internal, {'get /getAllAccounts': 'getAllAccounts'}); - } + if (process.env.DEBUG && process.env.DEBUG.toUpperCase() === 'TRUE') { + router.map(accountsModule.internal, {'get /getAllAccounts': 'getAllAccounts'}); + } - if (process.env.TOP && process.env.TOP.toUpperCase() === 'TRUE') { - router.get('/top', httpApi.middleware.sanitize('query', schema.top, accountsModule.internal.top)); - } + if (process.env.TOP && process.env.TOP.toUpperCase() === 'TRUE') { + router.get('/top', httpApi.middleware.sanitize('query', schema.top, accountsModule.internal.top)); + } - httpApi.registerEndpoint('/api/accounts', app, router, accountsModule.isLoaded); + httpApi.registerEndpoint('/api/accounts', app, router, accountsModule.isLoaded); } module.exports = AccountsHttpApi; diff --git a/api/http/blocks.js b/api/http/blocks.js index 799ab474..14e194b0 100644 --- a/api/http/blocks.js +++ b/api/http/blocks.js @@ -7,18 +7,18 @@ var httpApi = require('../../helpers/httpApi'); * Binds api with modules and creates common url. * - End point: `/api/blocks` * - Public API: - * - get /get - * - get / - * - get /getBroadhash - * - get /getEpoch - * - get /getHeight - * - get /getNethash - * - get /getFee - * - get /getFees - * - get /getMilestone - * - get /getReward - * - get /getSupply - * - get /getStatus + * - get /get + * - get / + * - get /getBroadhash + * - get /getEpoch + * - get /getHeight + * - get /getNethash + * - get /getFee + * - get /getFees + * - get /getMilestone + * - get /getReward + * - get /getSupply + * - get /getStatus * @memberof module:blocks * @requires helpers/Router * @requires helpers/httpApi @@ -29,29 +29,29 @@ var httpApi = require('../../helpers/httpApi'); // Constructor function BlocksHttpApi (blocksModule, app, logger, cache) { - var router = new Router(); + var router = new Router(); - // attach a middlware to endpoints - router.attachMiddlwareForUrls(httpApi.middleware.useCache.bind(null, logger, cache), [ - 'get /' - ]); + // attach a middlware to endpoints + router.attachMiddlwareForUrls(httpApi.middleware.useCache.bind(null, logger, cache), [ + 'get /' + ]); - router.map(blocksModule.shared, { - 'get /get': 'getBlock', - 'get /': 'getBlocks', - 'get /getBroadhash': 'getBroadhash', - 'get /getEpoch': 'getEpoch', - 'get /getHeight': 'getHeight', - 'get /getNethash': 'getNethash', - 'get /getFee': 'getFee', - 'get /getFees': 'getFees', - 'get /getMilestone': 'getMilestone', - 'get /getReward': 'getReward', - 'get /getSupply': 'getSupply', - 'get /getStatus': 'getStatus' - }); + router.map(blocksModule.shared, { + 'get /get': 'getBlock', + 'get /': 'getBlocks', + 'get /getBroadhash': 'getBroadhash', + 'get /getEpoch': 'getEpoch', + 'get /getHeight': 'getHeight', + 'get /getNethash': 'getNethash', + 'get /getFee': 'getFee', + 'get /getFees': 'getFees', + 'get /getMilestone': 'getMilestone', + 'get /getReward': 'getReward', + 'get /getSupply': 'getSupply', + 'get /getStatus': 'getStatus' + }); - httpApi.registerEndpoint('/api/blocks', app, router, blocksModule.isLoaded); + httpApi.registerEndpoint('/api/blocks', app, router, blocksModule.isLoaded); } module.exports = BlocksHttpApi; diff --git a/api/http/chatrooms.js b/api/http/chatrooms.js index a216a331..3c7a3de6 100644 --- a/api/http/chatrooms.js +++ b/api/http/chatrooms.js @@ -8,8 +8,8 @@ const httpApi = require('../../helpers/httpApi'); * - End point: `/api/chatrooms` * * - Sanitized - * - get /:ID - * - get /:ID/:ID + * - get /:ID + * - get /:ID/:ID * @memberof module:chatrooms * @requires helpers/Router * @requires helpers/httpApi diff --git a/api/http/chats.js b/api/http/chats.js index 7d57f2c8..a9e0ca43 100644 --- a/api/http/chats.js +++ b/api/http/chats.js @@ -8,13 +8,13 @@ var schema = require('../../schema/dapps'); * Binds api with modules and creates common url. * - End point: `/api/chats` * - Private API: - * - post /normalize - * - post /finalize + * - post /normalize + * - post /finalize * * - Sanitized - * - get / - * - put / - * - get /get + * - get / + * - put / + * - get /get * @memberof module:chats * @requires helpers/Router * @requires helpers/httpApi diff --git a/api/http/dapps.js b/api/http/dapps.js index fa0f4159..60f076b7 100644 --- a/api/http/dapps.js +++ b/api/http/dapps.js @@ -8,25 +8,25 @@ var schema = require('../../schema/dapps'); * Binds api with modules and creates common url. * - End point: `/api/dapps` * - Private API: - * - get /categories - * - get /installed - * - get /installedIds - * - get /ismasterpasswordenabled - * - get /installing - * - get /uninstalling - * - get /launched - * - post /launch - * - put /transaction - * - put /withdrawal - * + * - get /categories + * - get /installed + * - get /installedIds + * - get /ismasterpasswordenabled + * - get /installing + * - get /uninstalling + * - get /launched + * - post /launch + * - put /transaction + * - put /withdrawal + * * - Sanitized - * - get / - * - put / - * - get /get - * - get /search - * - post /install - * - post /uninstall - * - post /stop + * - get / + * - put / + * - get /get + * - get /search + * - post /install + * - post /uninstall + * - post /stop * @memberof module:dapps * @requires helpers/Router * @requires helpers/httpApi @@ -37,30 +37,30 @@ var schema = require('../../schema/dapps'); // Constructor function DappsHttpApi (dappsModule, app) { - var router = new Router(); + var router = new Router(); - router.map(dappsModule.internal, { - 'get /categories': 'categories', - 'get /installed': 'installed', - 'get /installedIds': 'installedIds', - 'get /ismasterpasswordenabled': 'isMasterPasswordEnabled', - 'get /installing': 'installing', - 'get /uninstalling': 'uninstalling', - 'get /launched': 'launched', - 'post /launch': 'launch', - 'put /transaction': 'addTransactions', - 'put /withdrawal': 'sendWithdrawal' - }); + router.map(dappsModule.internal, { + 'get /categories': 'categories', + 'get /installed': 'installed', + 'get /installedIds': 'installedIds', + 'get /ismasterpasswordenabled': 'isMasterPasswordEnabled', + 'get /installing': 'installing', + 'get /uninstalling': 'uninstalling', + 'get /launched': 'launched', + 'post /launch': 'launch', + 'put /transaction': 'addTransactions', + 'put /withdrawal': 'sendWithdrawal' + }); - router.get('/', httpApi.middleware.sanitize('query', schema.list, dappsModule.internal.list)); - router.put('/', httpApi.middleware.sanitize('body', schema.put, dappsModule.internal.put)); - router.get('/get', httpApi.middleware.sanitize('query', schema.get, dappsModule.internal.get)); - router.get('/search', httpApi.middleware.sanitize('query', schema.search, dappsModule.internal.search)); - router.post('/install', httpApi.middleware.sanitize('body', schema.install, dappsModule.internal.install)); - router.post('/uninstall', httpApi.middleware.sanitize('body', schema.uninstall, dappsModule.internal.uninstall)); - router.post('/stop', httpApi.middleware.sanitize('body', schema.stop, dappsModule.internal.stop)); + router.get('/', httpApi.middleware.sanitize('query', schema.list, dappsModule.internal.list)); + router.put('/', httpApi.middleware.sanitize('body', schema.put, dappsModule.internal.put)); + router.get('/get', httpApi.middleware.sanitize('query', schema.get, dappsModule.internal.get)); + router.get('/search', httpApi.middleware.sanitize('query', schema.search, dappsModule.internal.search)); + router.post('/install', httpApi.middleware.sanitize('body', schema.install, dappsModule.internal.install)); + router.post('/uninstall', httpApi.middleware.sanitize('body', schema.uninstall, dappsModule.internal.uninstall)); + router.post('/stop', httpApi.middleware.sanitize('body', schema.stop, dappsModule.internal.stop)); - httpApi.registerEndpoint('/api/dapps', app, router, dappsModule.isLoaded); + httpApi.registerEndpoint('/api/dapps', app, router, dappsModule.isLoaded); } module.exports = DappsHttpApi; diff --git a/api/http/delegates.js b/api/http/delegates.js index b9685e87..f76c2cf7 100644 --- a/api/http/delegates.js +++ b/api/http/delegates.js @@ -7,23 +7,23 @@ var httpApi = require('../../helpers/httpApi'); * Binds api with modules and creates common url. * - End point: `/api/delegates` * - Public API: - - get /count - - get /search - - get /voters - - get /get - - get / - - get /fee - - get /forging/getForgedByAccount - - put / - - post / - - get /getNextForgers + - get /count + - get /search + - get /voters + - get /get + - get / + - get /fee + - get /forging/getForgedByAccount + - put / + - post / + - get /getNextForgers * - Private API: - * - post /forging/enable - * - post /forging/disable - * - get /forging/status + * - post /forging/enable + * - post /forging/disable + * - get /forging/status * - Debug API: - * - get /forging/disableAll - * - get /forging/enableAll + * - get /forging/disableAll + * - get /forging/enableAll * @memberof module:delegates * @requires helpers/Router * @requires helpers/httpApi @@ -34,38 +34,38 @@ var httpApi = require('../../helpers/httpApi'); // Constructor function DelegatesHttpApi (delegatesModule, app, logger, cache) { - var router = new Router(); + var router = new Router(); - // attach a middlware to endpoints - router.attachMiddlwareForUrls(httpApi.middleware.useCache.bind(null, logger, cache), ['get /']); + // attach a middlware to endpoints + router.attachMiddlwareForUrls(httpApi.middleware.useCache.bind(null, logger, cache), ['get /']); - router.map(delegatesModule.shared, { - 'get /count': 'count', - 'get /search': 'search', - 'get /voters': 'getVoters', - 'get /get': 'getDelegate', - 'get /': 'getDelegates', - 'get /fee': 'getFee', - 'get /forging/getForgedByAccount': 'getForgedByAccount', - 'put /': 'addDelegate', + router.map(delegatesModule.shared, { + 'get /count': 'count', + 'get /search': 'search', + 'get /voters': 'getVoters', + 'get /get': 'getDelegate', + 'get /': 'getDelegates', + 'get /fee': 'getFee', + 'get /forging/getForgedByAccount': 'getForgedByAccount', + 'put /': 'addDelegate', 'post /': 'registerDelegate', - 'get /getNextForgers': 'getNextForgers' - }); + 'get /getNextForgers': 'getNextForgers' + }); - router.map(delegatesModule.internal, { - 'post /forging/enable': 'forgingEnable', - 'post /forging/disable': 'forgingDisable', - 'get /forging/status': 'forgingStatus' - }); + router.map(delegatesModule.internal, { + 'post /forging/enable': 'forgingEnable', + 'post /forging/disable': 'forgingDisable', + 'get /forging/status': 'forgingStatus' + }); - if (process.env.DEBUG) { - router.map(delegatesModule.internal, { - 'get /forging/disableAll': 'forgingDisableAll', - 'get /forging/enableAll': 'forgingEnableAll' - }); - } + if (process.env.DEBUG) { + router.map(delegatesModule.internal, { + 'get /forging/disableAll': 'forgingDisableAll', + 'get /forging/enableAll': 'forgingEnableAll' + }); + } - httpApi.registerEndpoint('/api/delegates', app, router, delegatesModule.isLoaded); + httpApi.registerEndpoint('/api/delegates', app, router, delegatesModule.isLoaded); } module.exports = DelegatesHttpApi; diff --git a/api/http/loader.js b/api/http/loader.js index 8b8caa1f..09b7c017 100644 --- a/api/http/loader.js +++ b/api/http/loader.js @@ -6,10 +6,10 @@ var httpApi = require('../../helpers/httpApi'); * Binds api with modules and creates common url. * - End point: `/api/loader` * - Public API: - * - get /status - * - get /status/sync + * - get /status + * - get /status/sync * - Private API: - * - get /status/ping + * - get /status/ping * @memberof module:loader * @requires helpers/Router * @requires helpers/httpApi @@ -20,19 +20,19 @@ var httpApi = require('../../helpers/httpApi'); // Constructor function LoaderHttpApi (loaderModule, app) { - var router = new Router(); + var router = new Router(); - router.map(loaderModule.shared, { - 'get /status': 'status', - 'get /status/sync': 'sync' - }); + router.map(loaderModule.shared, { + 'get /status': 'status', + 'get /status/sync': 'sync' + }); - router.get('/status/ping', function (req, res) { - var status = loaderModule.internal.statusPing(); - return res.status(status ? 200 : 503).json({success: status}); - }); + router.get('/status/ping', function (req, res) { + var status = loaderModule.internal.statusPing(); + return res.status(status ? 200 : 503).json({success: status}); + }); - httpApi.registerEndpoint('/api/loader', app, router, loaderModule.isLoaded); + httpApi.registerEndpoint('/api/loader', app, router, loaderModule.isLoaded); } module.exports = LoaderHttpApi; diff --git a/api/http/multisignatures.js b/api/http/multisignatures.js index 84f38ec2..910f05db 100644 --- a/api/http/multisignatures.js +++ b/api/http/multisignatures.js @@ -7,10 +7,10 @@ var httpApi = require('../../helpers/httpApi'); * Binds api with modules and creates common url. * - End point: `/api/multisignatures` * - Public API: - * - get /pending - * - post /sign - * - put / - * - get /accounts + * - get /pending + * - post /sign + * - put / + * - get /accounts * @memberof module:multisignatures * @requires helpers/Router * @requires helpers/httpApi @@ -22,16 +22,16 @@ var httpApi = require('../../helpers/httpApi'); // Constructor function MultisignaturesHttpApi (mutlisignaturesModule, app) { - var router = new Router(); + var router = new Router(); - router.map(mutlisignaturesModule.shared, { - 'get /pending': 'pending', - 'post /sign': 'sign', - 'put /': 'addMultisignature', - 'get /accounts': 'getAccounts' - }); + router.map(mutlisignaturesModule.shared, { + 'get /pending': 'pending', + 'post /sign': 'sign', + 'put /': 'addMultisignature', + 'get /accounts': 'getAccounts' + }); - httpApi.registerEndpoint('/api/multisignatures', app, router, mutlisignaturesModule.isLoaded); + httpApi.registerEndpoint('/api/multisignatures', app, router, mutlisignaturesModule.isLoaded); } module.exports = MultisignaturesHttpApi; diff --git a/api/http/node.js b/api/http/node.js index 0bcb8f13..949aaf1d 100644 --- a/api/http/node.js +++ b/api/http/node.js @@ -8,7 +8,7 @@ var schema = require('../../schema/node.js'); * Binds api with modules and creates common url. * - End point: `/api/node` * - Public API: - - get /status + - get /status * @memberof module:node * @requires helpers/Router * @requires helpers/httpApi @@ -19,14 +19,14 @@ var schema = require('../../schema/node.js'); function NodeHttpApi (nodeModule, app) { - var router = new Router(); + var router = new Router(); - router.map(nodeModule.shared, { - 'get /status': 'getStatus', - }); + router.map(nodeModule.shared, { + 'get /status': 'getStatus', + }); - httpApi.registerEndpoint('/api/node', app, router, nodeModule.isLoaded); + httpApi.registerEndpoint('/api/node', app, router, nodeModule.isLoaded); } module.exports = NodeHttpApi; diff --git a/api/http/peers.js b/api/http/peers.js index f8604f53..e2fe3bc0 100644 --- a/api/http/peers.js +++ b/api/http/peers.js @@ -7,10 +7,10 @@ var httpApi = require('../../helpers/httpApi'); * Binds api with modules and creates common url. * - End point: `/api/peers` * - Public API: - * - get / - * - get /version - * - get /get - * - get /count + * - get / + * - get /version + * - get /get + * - get /count * @memberof module:peers * @requires helpers/Router * @requires helpers/httpApi @@ -21,16 +21,16 @@ var httpApi = require('../../helpers/httpApi'); // Constructor function PeersHttpApi (peersModule, app) { - var router = new Router(); + var router = new Router(); - router.map(peersModule.shared, { - 'get /': 'getPeers', - 'get /version': 'version', - 'get /get': 'getPeer', - 'get /count': 'count' - }); + router.map(peersModule.shared, { + 'get /': 'getPeers', + 'get /version': 'version', + 'get /get': 'getPeer', + 'get /count': 'count' + }); - httpApi.registerEndpoint('/api/peers', app, router, peersModule.isLoaded); + httpApi.registerEndpoint('/api/peers', app, router, peersModule.isLoaded); } module.exports = PeersHttpApi; diff --git a/api/http/server.js b/api/http/server.js index d8c73cfe..85616bf4 100644 --- a/api/http/server.js +++ b/api/http/server.js @@ -6,7 +6,7 @@ var httpApi = require('../../helpers/httpApi'); /** * Renders main page wallet from public folder. * - Public API: - * - get / + * - get / * @memberof module:server * @requires helpers/Router * @requires helpers/httpApi @@ -17,29 +17,29 @@ var httpApi = require('../../helpers/httpApi'); // Constructor function ServerHttpApi (serverModule, app) { - var router = new Router(); - - router.use(function (req, res, next) { - if (serverModule.areModulesReady()) { return next(); } - res.status(500).send({success: false, error: 'Blockchain is loading'}); - }); - - router.get('/', function (req, res) { - if (serverModule.isLoaded()) { - res.render('wallet.html', {layout: false}); - } else { - res.render('loading.html'); - } - }); - - router.use(function (req, res, next) { - if (req.url.indexOf('/api/') === -1 && req.url.indexOf('/peer/') === -1) { - return res.redirect('/'); - } - next(); - }); - - app.use('/', router); + var router = new Router(); + + router.use(function (req, res, next) { + if (serverModule.areModulesReady()) { return next(); } + res.status(500).send({success: false, error: 'Blockchain is loading'}); + }); + + router.get('/', function (req, res) { + if (serverModule.isLoaded()) { + res.render('wallet.html', {layout: false}); + } else { + res.render('loading.html'); + } + }); + + router.use(function (req, res, next) { + if (req.url.indexOf('/api/') === -1 && req.url.indexOf('/peer/') === -1) { + return res.redirect('/'); + } + next(); + }); + + app.use('/', router); } module.exports = ServerHttpApi; diff --git a/api/http/signatures.js b/api/http/signatures.js index e76db162..13e0ef69 100644 --- a/api/http/signatures.js +++ b/api/http/signatures.js @@ -7,8 +7,8 @@ var httpApi = require('../../helpers/httpApi'); * Binds api with modules and creates common url. * - End point: `/api/signatures` * - Public API: - * - get /fee - * - put / + * - get /fee + * - put / * @memberof module:signatures * @requires helpers/Router * @requires helpers/httpApi @@ -19,14 +19,14 @@ var httpApi = require('../../helpers/httpApi'); // Constructor function SignaturesHttpApi (signaturesModule, app) { - var router = new Router(); + var router = new Router(); - router.map(signaturesModule.shared, { - 'get /fee': 'getFee', - 'put /': 'addSignature' - }); + router.map(signaturesModule.shared, { + 'get /fee': 'getFee', + 'put /': 'addSignature' + }); - httpApi.registerEndpoint('/api/signatures', app, router, signaturesModule.isLoaded); + httpApi.registerEndpoint('/api/signatures', app, router, signaturesModule.isLoaded); } module.exports = SignaturesHttpApi; diff --git a/api/http/states.js b/api/http/states.js index 2dd98228..f60f95a9 100644 --- a/api/http/states.js +++ b/api/http/states.js @@ -8,11 +8,11 @@ var httpApi = require('../../helpers/httpApi'); * Binds api with modules and creates common url. * - End point: `/api/states` * - Private API: - * - post /normalize - * - post /finalize + * - post /normalize + * - post /finalize * * - Sanitized - * - get /get + * - get /get * @memberof module:states * @requires helpers/Router * @requires helpers/httpApi diff --git a/api/http/transport.js b/api/http/transport.js index 3b192e8a..786a2f3f 100644 --- a/api/http/transport.js +++ b/api/http/transport.js @@ -8,18 +8,18 @@ var schema = require('../../schema/transport'); * Binds api with modules and creates common url. * - End point: `/peer` * - Private API: - * - get /blocks/common - * - get /blocks - * - get /list - * - get /height - * - get /ping - * - get /signatures - * - get /transactions - * - post /dapp/message - * - post /dapp/request - * - post /blocks - * - post /signatures - * - post /transactions + * - get /blocks/common + * - get /blocks + * - get /list + * - get /height + * - get /ping + * - get /signatures + * - get /transactions + * - post /dapp/message + * - post /dapp/request + * - post /blocks + * - post /signatures + * - post /transactions * @memberof module:transport * @requires helpers/Router * @requires helpers/httpApi @@ -31,88 +31,88 @@ var schema = require('../../schema/transport'); // Constructor function TransportHttpApi (transportModule, app, logger, cache) { - var router = new Router(); - - router.use(httpApi.middleware.attachResponseHeaders.bind(null, transportModule.headers)); - router.use(httpApi.middleware.blockchainReady.bind(null, transportModule.isLoaded)); - - router.use(handshakeMiddleware); - - router.get('/blocks/common', getCommonBlocksMiddleware); - router.get('/blocks', httpApi.middleware.sanitize('query', schema.blocks, transportModule.internal.blocks)); - - router.map(transportModule.internal, { - 'get /list': 'list', - 'get /height': 'height', - 'get /ping': 'ping', - 'get /signatures': 'getSignatures', - 'get /transactions': 'getTransactions', - 'post /dapp/message': 'postDappMessage', - 'post /dapp/request': 'postDappRequest' - - }); - - // Custom parameters internal functions - router.post('/blocks', function (req, res) { - transportModule.internal.postBlock(req.body.block, req.peer, req.method + ' ' + req.url, httpApi.respond.bind(null, res)); - }); - - router.post('/signatures', function (req, res) { - transportModule.internal.postSignatures({signatures: req.body.signatures, signature: req.body.signature}, httpApi.respond.bind(null, res)); - }); - - router.post('/transactions', function (req, res) { - transportModule.internal.postTransactions({ - transactions: req.body.transactions, - transaction: req.body.transaction - }, req.peer, req.method + ' ' + req.url, httpApi.respond.bind(null, res)); - }); - - router.use(httpApi.middleware.notFound); - - app.use('/peer', router); - - function handshakeMiddleware (req, res, next) { - transportModule.internal.handshake(req.ip, req.headers.port, req.headers, validateHeaders, function (err, peer) { - if (err) { - return res.status(500).send(err); - } - - req.peer = peer; - - if (req.body && req.body.dappid) { - req.peer.dappid = req.body.dappid; - } - return next(); - }); - - function validateHeaders (headers, cb) { - return req.sanitize(headers, schema.headers, function (err, report, sanitized) { - if (err) { - return cb(err.toString()); - } else if (!report.isValid) { - return cb(report.issues); - } - - return cb(); - }); - } - } - - function getCommonBlocksMiddleware (req, res, next) { - req.sanitize(req.query, schema.commonBlock, function (err, report, query) { - if (err) { - logger.debug('Common block request validation failed', {err: err.toString(), req: req.query}); - return next(err); - } - if (!report.isValid) { - logger.debug('Common block request validation failed', {err: report, req: req.query}); - return res.json({success: false, error: report.issues}); - } - - return transportModule.internal.blocksCommon(query.ids, req.peer, req.method + ' ' + req.url, httpApi.respond.bind(null, res)); - }); - } + var router = new Router(); + + router.use(httpApi.middleware.attachResponseHeaders.bind(null, transportModule.headers)); + router.use(httpApi.middleware.blockchainReady.bind(null, transportModule.isLoaded)); + + router.use(handshakeMiddleware); + + router.get('/blocks/common', getCommonBlocksMiddleware); + router.get('/blocks', httpApi.middleware.sanitize('query', schema.blocks, transportModule.internal.blocks)); + + router.map(transportModule.internal, { + 'get /list': 'list', + 'get /height': 'height', + 'get /ping': 'ping', + 'get /signatures': 'getSignatures', + 'get /transactions': 'getTransactions', + 'post /dapp/message': 'postDappMessage', + 'post /dapp/request': 'postDappRequest' + + }); + + // Custom parameters internal functions + router.post('/blocks', function (req, res) { + transportModule.internal.postBlock(req.body.block, req.peer, req.method + ' ' + req.url, httpApi.respond.bind(null, res)); + }); + + router.post('/signatures', function (req, res) { + transportModule.internal.postSignatures({signatures: req.body.signatures, signature: req.body.signature}, httpApi.respond.bind(null, res)); + }); + + router.post('/transactions', function (req, res) { + transportModule.internal.postTransactions({ + transactions: req.body.transactions, + transaction: req.body.transaction + }, req.peer, req.method + ' ' + req.url, httpApi.respond.bind(null, res)); + }); + + router.use(httpApi.middleware.notFound); + + app.use('/peer', router); + + function handshakeMiddleware (req, res, next) { + transportModule.internal.handshake(req.ip, req.headers.port, req.headers, validateHeaders, function (err, peer) { + if (err) { + return res.status(500).send(err); + } + + req.peer = peer; + + if (req.body && req.body.dappid) { + req.peer.dappid = req.body.dappid; + } + return next(); + }); + + function validateHeaders (headers, cb) { + return req.sanitize(headers, schema.headers, function (err, report, sanitized) { + if (err) { + return cb(err.toString()); + } else if (!report.isValid) { + return cb(report.issues); + } + + return cb(); + }); + } + } + + function getCommonBlocksMiddleware (req, res, next) { + req.sanitize(req.query, schema.commonBlock, function (err, report, query) { + if (err) { + logger.debug('Common block request validation failed', {err: err.toString(), req: req.query}); + return next(err); + } + if (!report.isValid) { + logger.debug('Common block request validation failed', {err: report, req: req.query}); + return res.json({success: false, error: report.issues}); + } + + return transportModule.internal.blocksCommon(query.ids, req.peer, req.method + ' ' + req.url, httpApi.respond.bind(null, res)); + }); + } } module.exports = TransportHttpApi; diff --git a/app.js b/app.js index 8c48846c..7a910f1d 100644 --- a/app.js +++ b/app.js @@ -48,22 +48,22 @@ var versionBuild = fs.readFileSync(path.join(__dirname, 'build'), 'utf8'); var lastCommit = ''; if (typeof gc !== 'undefined') { - setInterval(function () { - // eslint-disable-next-line no-undef - gc(); - }, 60000); + setInterval(function () { + // eslint-disable-next-line no-undef + gc(); + }, 60000); } program - .version(packageJson.version) - .option('-c, --config ', 'config.json file path') - .option('-g, --genesis ', 'genesisBlock.json file path') - .option('-p, --port ', 'listening port number') - .option('-a, --address ', 'listening host name or ip') - .option('-x, --peers [peers...]', 'peers list') - .option('-l, --log ', 'log level') - .option('-s, --snapshot ', 'verify snapshot') - .parse(process.argv); + .version(packageJson.version) + .option('-c, --config ', 'config.json file path') + .option('-g, --genesis ', 'genesisBlock.json file path') + .option('-p, --port ', 'listening port number') + .option('-a, --address ', 'listening host name or ip') + .option('-x, --peers [peers...]', 'peers list') + .option('-l, --log ', 'log level') + .option('-s, --snapshot ', 'verify snapshot') + .parse(process.argv); /** * @property {object} - The default list of configuration options. Can be updated by CLI. @@ -73,39 +73,39 @@ var appConfig = require('./helpers/config.js')(program.config); var genesisblock = require(path.resolve(process.cwd(), (program.genesis || 'genesisBlock.json'))); if (program.port) { - appConfig.port = program.port; + appConfig.port = program.port; } if (program.address) { - appConfig.address = program.address; + appConfig.address = program.address; } if (program.peers) { - if (typeof program.peers === 'string') { - appConfig.peers.list = program.peers.split(',').map(function (peer) { - peer = peer.split(':'); - return { - ip: peer.shift(), - port: peer.shift() || appConfig.port - }; - }); - } else { - appConfig.peers.list = []; - } + if (typeof program.peers === 'string') { + appConfig.peers.list = program.peers.split(',').map(function (peer) { + peer = peer.split(':'); + return { + ip: peer.shift(), + port: peer.shift() || appConfig.port + }; + }); + } else { + appConfig.peers.list = []; + } } if (program.log) { - appConfig.consoleLogLevel = program.log; + appConfig.consoleLogLevel = program.log; } if (program.snapshot) { - appConfig.loading.snapshot = Math.abs( - Math.floor(program.snapshot) - ); + appConfig.loading.snapshot = Math.abs( + Math.floor(program.snapshot) + ); } if (process.env.NODE_ENV === 'test') { - appConfig.coverage = true; + appConfig.coverage = true; } // Define top endpoint availability @@ -120,49 +120,49 @@ process.env.TOP = appConfig.topAccounts; * @property {object} api - `api/http` folder content. */ var config = { - db: appConfig.db, - cache: appConfig.redis, - cacheEnabled: appConfig.cacheEnabled, - modules: { - server: './modules/server.js', - accounts: './modules/accounts.js', - transactions: './modules/transactions.js', - blocks: './modules/blocks.js', - signatures: './modules/signatures.js', - transport: './modules/transport.js', - loader: './modules/loader.js', - system: './modules/system.js', - peers: './modules/peers.js', - delegates: './modules/delegates.js', - rounds: './modules/rounds.js', - multisignatures: './modules/multisignatures.js', - dapps: './modules/dapps.js', + db: appConfig.db, + cache: appConfig.redis, + cacheEnabled: appConfig.cacheEnabled, + modules: { + server: './modules/server.js', + accounts: './modules/accounts.js', + transactions: './modules/transactions.js', + blocks: './modules/blocks.js', + signatures: './modules/signatures.js', + transport: './modules/transport.js', + loader: './modules/loader.js', + system: './modules/system.js', + peers: './modules/peers.js', + delegates: './modules/delegates.js', + rounds: './modules/rounds.js', + multisignatures: './modules/multisignatures.js', + dapps: './modules/dapps.js', chats: './modules/chats.js', - chatrooms: './modules/chatrooms.js', + chatrooms: './modules/chatrooms.js', states: './modules/states.js', - node: './modules/node.js', - chats: './modules/chats.js', - crypto: './modules/crypto.js', - sql: './modules/sql.js', - cache: './modules/cache.js' - }, - api: { - accounts: { http: './api/http/accounts.js' }, - blocks: { http: './api/http/blocks.js' }, - dapps: { http: './api/http/dapps.js' }, + node: './modules/node.js', + chats: './modules/chats.js', + crypto: './modules/crypto.js', + sql: './modules/sql.js', + cache: './modules/cache.js' + }, + api: { + accounts: { http: './api/http/accounts.js' }, + blocks: { http: './api/http/blocks.js' }, + dapps: { http: './api/http/dapps.js' }, chats: { http: './api/http/chats.js' }, - chatrooms: { http: './api/http/chatrooms.js' }, + chatrooms: { http: './api/http/chatrooms.js' }, states: { http: './api/http/states.js' }, node: { http: './api/http/node.js' }, - delegates: { http: './api/http/delegates.js' }, - loader: { http: './api/http/loader.js' }, - multisignatures: { http: './api/http/multisignatures.js' }, - peers: { http: './api/http/peers.js' }, - server: { http: './api/http/server.js' }, - signatures: { http: './api/http/signatures.js' }, - transactions: { http: './api/http/transactions.js' }, - transport: { http: './api/http/transport.js' } - } + delegates: { http: './api/http/delegates.js' }, + loader: { http: './api/http/loader.js' }, + multisignatures: { http: './api/http/multisignatures.js' }, + peers: { http: './api/http/peers.js' }, + server: { http: './api/http/server.js' }, + signatures: { http: './api/http/signatures.js' }, + transactions: { http: './api/http/transactions.js' }, + transport: { http: './api/http/transport.js' } + } }; /** @@ -171,16 +171,16 @@ var config = { * @property {object} - Logger instance. */ var logger = new Logger({ - echo: appConfig.consoleLogLevel, - errorLevel: appConfig.fileLogLevel, - filename: appConfig.logFileName + echo: appConfig.consoleLogLevel, + errorLevel: appConfig.fileLogLevel, + filename: appConfig.logFileName }); // Trying to get last git commit try { - lastCommit = git.getLastCommit(); + lastCommit = git.getLastCommit(); } catch (err) { - logger.debug('Cannot get last git commit', err.message); + logger.debug('Cannot get last git commit', err.message); } /** @@ -190,566 +190,566 @@ try { var d = require('domain').create(); d.on('error', function (err) { - logger.fatal('Domain master', { - message: err.message, - stack: err.stack - }); - process.exit(0); + logger.fatal('Domain master', { + message: err.message, + stack: err.stack + }); + process.exit(0); }); // runs domain d.run(function () { - var modules = []; - async.auto({ - /** - * Loads `payloadHash` and generate dapp password if it is empty and required. - * Then updates config.json with new random password. - * @method config - * @param {nodeStyleCallback} cb - Callback function with the mutated `appConfig`. - * @throws {Error} If failed to assign nethash from genesis block. - */ - config: function (cb) { - try { - appConfig.nethash = Buffer.from(genesisblock.payloadHash, 'hex').toString('hex'); - } catch (e) { - logger.error('Failed to assign nethash from genesis block'); - throw Error(e); - } - - if (appConfig.dapp.masterrequired && !appConfig.dapp.masterpassword) { - var randomstring = require('randomstring'); - - appConfig.dapp.masterpassword = randomstring.generate({ - length: 12, - readable: true, - charset: 'alphanumeric' - }); - - if (appConfig.loading.snapshot != null) { - delete appConfig.loading.snapshot; - } - - fs.writeFileSync('./config.json', JSON.stringify(appConfig, null, 4)); - cb(null, appConfig); - } else { - cb(null, appConfig); - } - }, - logger: function (cb) { - cb(null, logger); - }, - - build: function (cb) { - cb(null, versionBuild); - }, - - /** - * Returns hash of last git commit. - * @method lastCommit - * @param {nodeStyleCallback} cb - Callback function with Hash of last git commit. - */ - lastCommit: function (cb) { - cb(null, lastCommit); - }, - - genesisblock: function (cb) { - cb(null, { - block: genesisblock - }); - }, + var modules = []; + async.auto({ + /** + * Loads `payloadHash` and generate dapp password if it is empty and required. + * Then updates config.json with new random password. + * @method config + * @param {nodeStyleCallback} cb - Callback function with the mutated `appConfig`. + * @throws {Error} If failed to assign nethash from genesis block. + */ + config: function (cb) { + try { + appConfig.nethash = Buffer.from(genesisblock.payloadHash, 'hex').toString('hex'); + } catch (e) { + logger.error('Failed to assign nethash from genesis block'); + throw Error(e); + } + + if (appConfig.dapp.masterrequired && !appConfig.dapp.masterpassword) { + var randomstring = require('randomstring'); + + appConfig.dapp.masterpassword = randomstring.generate({ + length: 12, + readable: true, + charset: 'alphanumeric' + }); + + if (appConfig.loading.snapshot != null) { + delete appConfig.loading.snapshot; + } + + fs.writeFileSync('./config.json', JSON.stringify(appConfig, null, 4)); + cb(null, appConfig); + } else { + cb(null, appConfig); + } + }, + logger: function (cb) { + cb(null, logger); + }, + + build: function (cb) { + cb(null, versionBuild); + }, + + /** + * Returns hash of last git commit. + * @method lastCommit + * @param {nodeStyleCallback} cb - Callback function with Hash of last git commit. + */ + lastCommit: function (cb) { + cb(null, lastCommit); + }, + + genesisblock: function (cb) { + cb(null, { + block: genesisblock + }); + }, packageJson: function (cb) { cb(null, packageJson); }, - public: function (cb) { - cb(null, path.join(__dirname, 'public')); - }, - - schema: function (cb) { - cb(null, new z_schema()); - }, - - /** - * ws client PWA, - * @method clientWs - * @param {object} wsconfig - config from ws client PWA, - * @param {nodeStyleCallback} cb - Callback function with created Method: - * `emit`. - */ - clientWs: ['config', function (scope, cb) { - var ClientWs = require('./modules/clientWs'); - cb(null, new ClientWs(scope.config.wsClient, logger)); - }], - /** - * Once config is completed, creates app, http & https servers & sockets with express. - * @method network - * @param {object} scope - The results from current execution, - * at least will contain the required elements. - * @param {nodeStyleCallback} cb - Callback function with created Object: - * `{express, app, server, io, https, https_io}`. - */ - network: ['config', function (scope, cb) { - var express = require('express'); - var compression = require('compression'); - var cors = require('cors'); - var app = express(); - - if (appConfig.coverage) { - var im = require('istanbul-middleware'); - logger.debug('Hook loader for coverage - do not use in production environment!'); - im.hookLoader(__dirname); - app.use('/coverage', im.createHandler()); - } - - require('./helpers/request-limiter')(app, appConfig); - - app.use(compression({ - level: 9 - })); - app.use(cors()); - app.options('*', cors()); - - var server = require('http').createServer(app); - var io = require('socket.io')(server); - - var privateKey, certificate, https, https_io; - - if (scope.config.ssl.enabled) { - privateKey = fs.readFileSync(scope.config.ssl.options.key); - certificate = fs.readFileSync(scope.config.ssl.options.cert); - - https = require('https').createServer({ - key: privateKey, - cert: certificate, - ciphers: 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:' + 'ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA256:HIGH:' + '!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!SRP:!CAMELLIA' - }, app); - - https_io = require('socket.io')(https); - } - - cb(null, { - express: express, - app: app, - server: server, - io: io, - https: https, - https_io: https_io - }); - }], - - dbSequence: ['logger', function (scope, cb) { - var sequence = new Sequence({ - onWarning: function (current, limit) { - scope.logger.warn('DB queue', current); - } - }); - cb(null, sequence); - }], - - sequence: ['logger', function (scope, cb) { - var sequence = new Sequence({ - onWarning: function (current, limit) { - scope.logger.warn('Main queue', current); - } - }); - cb(null, sequence); - }], - - balancesSequence: ['logger', function (scope, cb) { - var sequence = new Sequence({ - onWarning: function (current, limit) { - scope.logger.warn('Balance queue', current); - } - }); - cb(null, sequence); - }], - - /** - * Once config, public, genesisblock, logger, build and network are completed, - * adds configuration to `network.app`. - * @method connect - * @param {object} scope - The results from current execution, - * at least will contain the required elements. - * @param {function} cb - Callback function. - */ - connect: ['config', 'public', 'genesisblock', 'logger', 'build', 'network', function (scope, cb) { - var path = require('path'); - var bodyParser = require('body-parser'); - var methodOverride = require('method-override'); - var queryParser = require('express-query-int'); - var randomString = require('randomstring'); - - scope.nonce = randomString.generate(16); - scope.network.app.engine('html', require('ejs').renderFile); - scope.network.app.use(require('express-domain-middleware')); - scope.network.app.set('view engine', 'ejs'); - scope.network.app.set('views', path.join(__dirname, 'public')); - scope.network.app.use(scope.network.express.static(path.join(__dirname, 'public'))); - scope.network.app.use(bodyParser.raw({ - limit: '2mb' - })); - scope.network.app.use(bodyParser.urlencoded({ - extended: true, - limit: '2mb', - parameterLimit: 5000 - })); - scope.network.app.use(bodyParser.json({ - limit: '2mb' - })); - scope.network.app.use(methodOverride()); - - var ignore = ['id', 'name', 'lastBlockId', 'blockId', 'transactionId', 'address', 'recipientId', 'senderId', 'previousBlock']; - - scope.network.app.use(queryParser({ - parser: function (value, radix, name) { - if (ignore.indexOf(name) >= 0) { - return value; - } - - // Ignore conditional fields for transactions list - if (/^.+?:(blockId|recipientId|senderId)$/.test(name)) { - return value; - } - - /*eslint-disable eqeqeq */ - if (isNaN(value) || parseInt(value) != value || isNaN(parseInt(value, radix))) { - return value; - } - /*eslint-enable eqeqeq */ - return parseInt(value); - } - })); - - scope.network.app.use(require('./helpers/z_schema-express.js')(scope.schema)); - - scope.network.app.use(httpApi.middleware.logClientConnections.bind(null, scope.logger)); - - /* Instruct browser to deny display of ,