From 9a8358eac907b33068be50e0daa2116ff6cc5f50 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Fri, 16 Jun 2023 01:02:10 -0600 Subject: [PATCH 1/6] fix: don't silence fatal or unknown (non-warning) errors --- lib/services/dashd.js | 36 +++++++++++++++++----- test/services/dashd.unit.js | 61 ++++++++++++++++++++++++++++++++----- 2 files changed, 83 insertions(+), 14 deletions(-) diff --git a/lib/services/dashd.js b/lib/services/dashd.js index adc2d12bc..01ca4ca35 100644 --- a/lib/services/dashd.js +++ b/lib/services/dashd.js @@ -21,6 +21,17 @@ var utils = require('../utils'); var Service = require('../service'); var rawtxTopicBuffer = new Buffer('7261777478', 'hex'); var rawtxlockTopicBuffer = new Buffer('72617774786c6f636b', 'hex'); + +function isNonFatalError(err) { + if (err.code === Dash.E_RPC_IN_WARMUP) { + log.warn(err?.message); + return true; + } + + // will throw instead of retrying + return false; +} + /** * Provides a friendly event driven API to dashd in Node.js. Manages starting and * stopping dashd as a child process for application support, as well as connecting @@ -77,6 +88,7 @@ Dash.DEFAULT_SPAWN_RESTART_TIME = 5000; Dash.DEFAULT_SPAWN_STOP_TIME = 10000; Dash.DEFAULT_TRY_ALL_INTERVAL = 1000; Dash.DEFAULT_REINDEX_INTERVAL = 10000; +Dash.DEFAULT_START_RETRY_TIMES = 60; Dash.DEFAULT_START_RETRY_INTERVAL = 5000; Dash.DEFAULT_TIP_UPDATE_INTERVAL = 15000; Dash.DEFAULT_TRANSACTION_CONCURRENCY = 5; @@ -96,6 +108,7 @@ Dash.DEFAULT_CONFIG_SETTINGS = { rpcpassword: 'local321', uacomment: 'dashcore' }; +Dash.E_RPC_IN_WARMUP = -28; Dash.prototype._initDefaults = function(options) { /* jshint maxcomplexity: 15 */ @@ -113,6 +126,7 @@ Dash.prototype._initDefaults = function(options) { // try all interval this.tryAllInterval = options.tryAllInterval || Dash.DEFAULT_TRY_ALL_INTERVAL; + this.startRetryTimes = options.startRetryTimes || Dash.DEFAULT_START_RETRY_TIMES; this.startRetryInterval = options.startRetryInterval || Dash.DEFAULT_START_RETRY_INTERVAL; // rpc limits @@ -856,11 +870,9 @@ Dash.prototype._checkReindex = function(node, callback) { Dash.prototype._loadTipFromNode = function(node, callback) { var self = this; node.client.getBestBlockHash(function(err, response) { - if (err && err.code === -28) { - log.warn(err.message); - return callback(self._wrapRPCError(err)); - } else if (err) { - return callback(self._wrapRPCError(err)); + if (err) { + callback(self._wrapRPCError(err)); + return; } node.client.getBlock(response.result, function(err, response) { if (err) { @@ -963,7 +975,12 @@ Dash.prototype._spawnChildProcess = function(callback) { var exitShutdown = false; - async.retry({times: 60, interval: self.startRetryInterval}, function(done) { + var retryOpts = { + times: self.startRetryTimes, + interval: self.startRetryInterval, + errorFilter: isNonFatalError, + }; + async.retry(retryOpts, function (done) { if (self.node.stopping) { exitShutdown = true; return done(); @@ -1008,7 +1025,12 @@ Dash.prototype._connectProcess = function(config, callback) { var node = {}; var exitShutdown = false; - async.retry({times: 60, interval: self.startRetryInterval}, function(done) { + var retryOpts = { + times: self.startRetryTimes, + interval: self.startRetryInterval, + errorFilter: isNonFatalError, + }; + async.retry(retryOpts, function(done) { if (self.node.stopping) { exitShutdown = true; return done(); diff --git a/test/services/dashd.unit.js b/test/services/dashd.unit.js index 4bc07bf18..22eb397dd 100644 --- a/test/services/dashd.unit.js +++ b/test/services/dashd.unit.js @@ -38,6 +38,11 @@ describe('Dash Service', function() { } }; + var RPC_IN_WARMUP_ERROR = new Error('Verifying blocks...'); + Object.assign(RPC_IN_WARMUP_ERROR, { + code: DashService.E_RPC_IN_WARMUP + }) + describe('@constructor', function() { it('will create an instance', function() { var dashd = new DashService(baseConfig); @@ -1592,9 +1597,9 @@ describe('Dash Service', function() { done(); }); }); - it('will log when error is RPC_IN_WARMUP', function(done) { + it('will throw when error is RPC_IN_WARMUP outside of retry', function(done) { var dashd = new DashService(baseConfig); - var getBestBlockHash = sinon.stub().callsArgWith(0, {code: -28, message: 'Verifying blocks...'}); + var getBestBlockHash = sinon.stub().callsArgWith(0, RPC_IN_WARMUP_ERROR); var node = { client: { getBestBlockHash: getBestBlockHash @@ -1602,7 +1607,7 @@ describe('Dash Service', function() { }; dashd._loadTipFromNode(node, function(err) { err.should.be.instanceof(Error); - log.warn.callCount.should.equal(1); + log.warn.callCount.should.equal(0); done(); }); }); @@ -1968,7 +1973,7 @@ describe('Dash Service', function() { process.emit('exit', 1); }); }); - it('will give error after 60 retries', function(done) { + it('will give error after 60 retries of RPC_IN_WARMUP warning', function(done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); var TestDashService = proxyquire('../../lib/services/dashd', { @@ -1992,13 +1997,44 @@ describe('Dash Service', function() { dashd.spawn.config.rpcpassword = 'password'; dashd.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001'; dashd.spawn.config.zmqpubrawtxlock = 'tcp://127.0.0.1:30001'; - dashd._loadTipFromNode = sinon.stub().callsArgWith(1, new Error('test')); + dashd._loadTipFromNode = sinon.stub().callsArgWith(1, RPC_IN_WARMUP_ERROR); dashd._spawnChildProcess(function(err) { dashd._loadTipFromNode.callCount.should.equal(60); err.should.be.instanceof(Error); done(); }); }); + it('will give error WITHOUT retrying for fatal and unknown errors', function(done) { + var process = new EventEmitter(); + var spawn = sinon.stub().returns(process); + var TestDashService = proxyquire('../../lib/services/dashd', { + fs: { + readFileSync: readFileSync + }, + child_process: { + spawn: spawn + } + }); + var dashd = new TestDashService(baseConfig); + dashd.startRetryInterval = 1; + dashd._loadSpawnConfiguration = sinon.stub(); + dashd.spawn = {}; + dashd.spawn.exec = 'testexec'; + dashd.spawn.configPath = 'testdir/dash.conf'; + dashd.spawn.datadir = 'testdir'; + dashd.spawn.config = {}; + dashd.spawn.config.rpcport = 20001; + dashd.spawn.config.rpcuser = 'dash'; + dashd.spawn.config.rpcpassword = 'password'; + dashd.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001'; + dashd.spawn.config.zmqpubrawtxlock = 'tcp://127.0.0.1:30001'; + dashd._loadTipFromNode = sinon.stub().callsArgWith(1, new Error('test')); + dashd._spawnChildProcess(function(err) { + dashd._loadTipFromNode.callCount.should.equal(1); + err.should.be.instanceof(Error); + done(); + }); + }); it('will give error from check reindex', function(done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); @@ -2058,9 +2094,9 @@ describe('Dash Service', function() { done(); }); }); - it('will give error from loadTipFromNode after 60 retries', function(done) { + it('will give error for warnings from loadTipFromNode after 60 retries', function(done) { var dashd = new DashService(baseConfig); - dashd._loadTipFromNode = sinon.stub().callsArgWith(1, new Error('test')); + dashd._loadTipFromNode = sinon.stub().callsArgWith(1, RPC_IN_WARMUP_ERROR); dashd.startRetryInterval = 1; var config = {}; dashd._connectProcess(config, function(err) { @@ -2069,6 +2105,17 @@ describe('Dash Service', function() { done(); }); }); + it('will immediately fail from loadTipFromNode for fatal and unknown errors', function(done) { + var dashd = new DashService(baseConfig); + dashd._loadTipFromNode = sinon.stub().callsArgWith(1, new Error('test')); + dashd.startRetryInterval = 1; + var config = {}; + dashd._connectProcess(config, function(err) { + err.should.be.instanceof(Error); + dashd._loadTipFromNode.callCount.should.equal(1); + done(); + }); + }); it('will init zmq/rpc on node', function(done) { var dashd = new DashService(baseConfig); dashd._initZmqSubSocket = sinon.stub(); From 8e4da2494c56249290201ad3c5b126df5d113faf Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 19 Jun 2023 22:32:29 -0600 Subject: [PATCH 2/6] Chore: set .jshintrc.latedef = "nofunc" (for browsers and node) --- .jshintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.jshintrc b/.jshintrc index 1b7ebf23f..20492464e 100644 --- a/.jshintrc +++ b/.jshintrc @@ -9,7 +9,7 @@ "freeze": true, "immed": true, "indent": 2, - "latedef": true, + "latedef": "nofunc", "newcap": false, "noarg": true, "node": true, From edcc4df2133eba7024bef5621c6f5fee45554baf Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 19 Jun 2023 23:37:58 -0600 Subject: [PATCH 3/6] Chore: bump .jshintrc.esversion to 11 (the dashd suite relies on node v18) --- .jshintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.jshintrc b/.jshintrc index 20492464e..df33758a7 100644 --- a/.jshintrc +++ b/.jshintrc @@ -1,11 +1,11 @@ { + "esversion": 11, "bitwise": false, "browser": true, "camelcase": false, "curly": true, "devel": false, "eqeqeq": true, - "esnext": true, "freeze": true, "immed": true, "indent": 2, From 3374cdefc7a6a1855fb17b2f9fc5f5eb2118ea1a Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 19 Jun 2023 23:48:17 -0600 Subject: [PATCH 4/6] Chore: bump tests to node v18 (to allow use of WebCrypto) --- .github/workflows/test_and_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test_and_release.yml b/.github/workflows/test_and_release.yml index 6b64e4c1b..49f148384 100644 --- a/.github/workflows/test_and_release.yml +++ b/.github/workflows/test_and_release.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-node@v2 with: - node-version: '12' + node-version: '18' - name: Enable NPM cache uses: actions/cache@v2 From 8b3d4e58492a1847f936b8cfacff590f1c0bc200 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 20 Jun 2023 00:13:28 -0600 Subject: [PATCH 5/6] Chore: enforce style rules with 'npm run fmt' --- .editorconfig | 9 +++++++++ .github/workflows/test_and_release.yml | 3 +++ .jshintrc | 25 ++++++++++--------------- .prettierrc.json | 3 +++ package.json | 1 + 5 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 .editorconfig create mode 100644 .prettierrc.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..1b24c0ca6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +trim_trailing_whitespace = true +insert_final_newline = true +end_of_line = lf diff --git a/.github/workflows/test_and_release.yml b/.github/workflows/test_and_release.yml index 49f148384..1a186bd7f 100644 --- a/.github/workflows/test_and_release.yml +++ b/.github/workflows/test_and_release.yml @@ -39,6 +39,9 @@ jobs: - name: Run jshint run: npm run jshint + - name: Run fmt + run: npm run fmt + - name: Run tests run: npm run test diff --git a/.jshintrc b/.jshintrc index df33758a7..d570493ad 100644 --- a/.jshintrc +++ b/.jshintrc @@ -8,35 +8,30 @@ "eqeqeq": true, "freeze": true, "immed": true, - "indent": 2, "latedef": "nofunc", + "laxbreak": true, "newcap": false, "noarg": true, "node": true, "noempty": true, "nonew": true, - "quotmark": "single", "regexp": true, - "smarttabs": false, "strict": true, - "trailing": true, "undef": true, "unused": true, "maxparams": 5, "maxstatements": 17, "maxcomplexity": 10, "maxdepth": 3, - "maxlen": 120, - "multistr": true, "predef": [ - "after", - "afterEach", - "before", - "beforeEach", - "describe", - "exports", - "it", - "module", - "require" + "after", + "afterEach", + "before", + "beforeEach", + "describe", + "exports", + "it", + "module", + "require" ] } diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 000000000..963354f23 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "printWidth": 120 +} diff --git a/package.json b/package.json index f2fc83485..bef7b92c9 100644 --- a/package.json +++ b/package.json @@ -31,6 +31,7 @@ }, "scripts": { "test": "mocha -R spec --recursive", + "fmt": "npx -p prettier@2.x -- prettier -w '**/*.{js,md}'", "regtest": "./regtest/regtest", "jshint": "jshint --reporter=node_modules/jshint-stylish ./lib", "coverage": "istanbul cover _mocha -- --recursive", From 62c994d368b555585a590213ea1dcc3033cd6751 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Tue, 20 Jun 2023 00:35:36 -0600 Subject: [PATCH 6/6] chore: 'npm run fmt' to apply style rules --- README.md | 29 +- benchmarks/index.js | 245 +- docs/bus.md | 9 +- docs/development.md | 27 +- docs/node.md | 29 +- docs/scaffold.md | 7 + docs/services.md | 14 +- docs/services/dashd.md | 139 +- docs/services/web.md | 18 +- docs/upgrade.md | 23 +- index.js | 38 +- lib/bus.js | 18 +- lib/cli/daemon.js | 18 +- lib/cli/dashcore.js | 62 +- lib/cli/dashcored.js | 64 +- lib/cli/main.js | 108 +- lib/errors.js | 10 +- lib/index.js | 4 +- lib/logger.js | 28 +- lib/node.js | 94 +- lib/scaffold/add.js | 57 +- lib/scaffold/call-method.js | 35 +- lib/scaffold/create.js | 140 +- lib/scaffold/default-base-config.js | 20 +- lib/scaffold/default-config.js | 42 +- lib/scaffold/find-config.js | 22 +- lib/scaffold/remove.js | 65 +- lib/scaffold/start.js | 104 +- lib/service.js | 24 +- lib/services/dashd.js | 1585 +++--- lib/services/web.js | 140 +- lib/utils.js | 18 +- regtest/cluster.js | 224 +- regtest/dashd.js | 313 +- regtest/node.js | 504 +- regtest/p2p.js | 189 +- test/bus.integration.js | 95 +- test/bus.unit.js | 118 +- test/index.unit.js | 10 +- test/logger.unit.js | 79 +- test/node.unit.js | 355 +- test/scaffold/add.integration.js | 177 +- test/scaffold/call-method.unit.js | 68 +- test/scaffold/create.integration.js | 198 +- .../default-base-config.integration.js | 32 +- test/scaffold/default-config.integration.js | 137 +- test/scaffold/find-config.integration.js | 78 +- test/scaffold/remove.integration.js | 183 +- test/scaffold/start.integration.js | 113 +- test/scaffold/start.unit.js | 221 +- test/services/dashd.unit.js | 4618 +++++++++-------- test/services/web.unit.js | 323 +- test/utils.unit.js | 116 +- 53 files changed, 5702 insertions(+), 5685 deletions(-) diff --git a/README.md b/README.md index ba3cc429d..eb23edace 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -Dashcore Node -============ +# Dashcore Node A Dash full node for building applications and services with Node.js. A node is extensible and can be configured to run additional services. At the minimum a node has an interface to [Dash Core (dashd) v0.13.0](https://github.com/dashpay/dash/tree/v0.13.0.x) for more advanced address queries. Additional services can be enabled to make a node more useful such as exposing new APIs, running a block explorer and wallet service. @@ -23,6 +22,7 @@ Some plugins are available : - Insight-UI : `./bin/dashcore-node addservice @dashevo/insight-ui` You also might want to add these index to your dash.conf file : + ``` -addressindex -timestampindex @@ -36,25 +36,25 @@ npm install @dashevo/dashcore-node ``` ```javascript -const dashcore = require('@dashevo/dashcore-node'); -const config = require('./dashcore-node.json'); +const dashcore = require("@dashevo/dashcore-node"); +const config = require("./dashcore-node.json"); let node = dashcore.scaffold.start({ path: "", config: config }); -node.on('ready', function () { - console.log("Dash core started"); - - node.services.dashd.on('tx', function(txData) { - let tx = new dashcore.lib.Transaction(txData); - console.log(tx); - }); +node.on("ready", function () { + console.log("Dash core started"); + + node.services.dashd.on("tx", function (txData) { + let tx = new dashcore.lib.Transaction(txData); + console.log(tx); + }); }); ``` ## Prerequisites -- Dash Core (dashd) (v0.13.0) with support for additional indexing *(see above)* +- Dash Core (dashd) (v0.13.0) with support for additional indexing _(see above)_ - Node.js v8+ -- ZeroMQ *(libzmq3-dev for Ubuntu/Debian or zeromq on OSX)* +- ZeroMQ _(libzmq3-dev for Ubuntu/Debian or zeromq on OSX)_ - ~50GB of disk storage - ~1GB of RAM @@ -95,7 +95,6 @@ There are several add-on services available to extend the functionality of Bitco - [Bus](docs/bus.md) - Overview of the event bus constructor - [Release Process](docs/release.md) - Information about verifying a release and the release process. - ## Setting up dev environment (with Insight) Prerequisite : Having a dashd node already runing `dashd --daemon`. @@ -105,6 +104,7 @@ Insight-api (optional) : `git clone https://github.com/dashevo/insight-api -b de Insight-UI (optional) : `git clone https://github.com/dashevo/insight-ui -b develop` Install them : + ``` cd dashcore-node && npm install \ && cd ../insight-ui && npm install \ @@ -112,6 +112,7 @@ cd dashcore-node && npm install \ ``` Symbolic linking in parent folder : + ``` npm link ../insight-api npm link ../insight-ui diff --git a/benchmarks/index.js b/benchmarks/index.js index 671673c34..f4dcc370f 100644 --- a/benchmarks/index.js +++ b/benchmarks/index.js @@ -1,169 +1,170 @@ -'use strict'; +"use strict"; -var benchmark = require('benchmark'); -var dashdRPC = require('@dashevo/dashd-rpc'); -var async = require('async'); +var benchmark = require("benchmark"); +var dashdRPC = require("@dashevo/dashd-rpc"); +var async = require("async"); var maxTime = 20; -console.log('Dash Service native interface vs. Dash JSON RPC interface'); -console.log('----------------------------------------------------------------------'); +console.log("Dash Service native interface vs. Dash JSON RPC interface"); +console.log("----------------------------------------------------------------------"); // To run the benchmarks a fully synced Dash Core directory is needed. The RPC comands // can be modified to match the settings in dash.conf. var fixtureData = { blockHashes: [ - '00000000fa7a4acea40e5d0591d64faf48fd862fa3561d111d967fc3a6a94177', - '000000000017e9e0afc4bc55339f60ffffb9cbe883f7348a9fbc198a486d5488', - '000000000019ddb889b534c5d85fca2c91a73feef6fd775cd228dea45353bae1', - '0000000000977ac3d9f5261efc88a3c2d25af92a91350750d00ad67744fa8d03' + "00000000fa7a4acea40e5d0591d64faf48fd862fa3561d111d967fc3a6a94177", + "000000000017e9e0afc4bc55339f60ffffb9cbe883f7348a9fbc198a486d5488", + "000000000019ddb889b534c5d85fca2c91a73feef6fd775cd228dea45353bae1", + "0000000000977ac3d9f5261efc88a3c2d25af92a91350750d00ad67744fa8d03", ], txHashes: [ - '5523b432c1bd6c101bee704ad6c560fd09aefc483f8a4998df6741feaa74e6eb', - 'ff48393e7731507c789cfa9cbfae045b10e023ce34ace699a63cdad88c8b43f8', - '5d35c5eebf704877badd0a131b0a86588041997d40dbee8ccff21ca5b7e5e333', - '88842f2cf9d8659c3434f6bc0c515e22d87f33e864e504d2d7117163a572a3aa', - ] + "5523b432c1bd6c101bee704ad6c560fd09aefc483f8a4998df6741feaa74e6eb", + "ff48393e7731507c789cfa9cbfae045b10e023ce34ace699a63cdad88c8b43f8", + "5d35c5eebf704877badd0a131b0a86588041997d40dbee8ccff21ca5b7e5e333", + "88842f2cf9d8659c3434f6bc0c515e22d87f33e864e504d2d7117163a572a3aa", + ], }; -var dashd = require('../').services.Dash({ +var dashd = require("../").services.Dash({ node: { - datadir: process.env.HOME + '/.dash', + datadir: process.env.HOME + "/.dash", network: { - name: 'testnet' - } - } + name: "testnet", + }, + }, }); -dashd.on('error', function(err) { +dashd.on("error", function (err) { console.error(err.message); }); -dashd.start(function(err) { +dashd.start(function (err) { if (err) { throw err; } - console.log('Dash Core started'); + console.log("Dash Core started"); }); -dashd.on('ready', function() { - - console.log('Dash Core ready'); +dashd.on("ready", function () { + console.log("Dash Core ready"); var client = new dashdRPC({ - host: 'localhost', + host: "localhost", port: 18332, - user: 'dash', - pass: 'local321' + user: "dash", + pass: "local321", }); - async.series([ - function(next) { - - var c = 0; - var hashesLength = fixtureData.blockHashes.length; - var txLength = fixtureData.txHashes.length; + async.series( + [ + function (next) { + var c = 0; + var hashesLength = fixtureData.blockHashes.length; + var txLength = fixtureData.txHashes.length; - function dashdGetBlockNative(deffered) { - if (c >= hashesLength) { - c = 0; - } - var hash = fixtureData.blockHashes[c]; - dashd.getBlock(hash, function(err, block) { - if (err) { - throw err; + function dashdGetBlockNative(deffered) { + if (c >= hashesLength) { + c = 0; } - deffered.resolve(); - }); - c++; - } - - function dashdGetBlockJsonRpc(deffered) { - if (c >= hashesLength) { - c = 0; + var hash = fixtureData.blockHashes[c]; + dashd.getBlock(hash, function (err, block) { + if (err) { + throw err; + } + deffered.resolve(); + }); + c++; } - var hash = fixtureData.blockHashes[c]; - client.getBlock(hash, false, function(err, block) { - if (err) { - throw err; - } - deffered.resolve(); - }); - c++; - } - function dashGetTransactionNative(deffered) { - if (c >= txLength) { - c = 0; - } - var hash = fixtureData.txHashes[c]; - dashd.getTransaction(hash, true, function(err, tx) { - if (err) { - throw err; + function dashdGetBlockJsonRpc(deffered) { + if (c >= hashesLength) { + c = 0; } - deffered.resolve(); - }); - c++; - } + var hash = fixtureData.blockHashes[c]; + client.getBlock(hash, false, function (err, block) { + if (err) { + throw err; + } + deffered.resolve(); + }); + c++; + } - function dashGetTransactionJsonRpc(deffered) { - if (c >= txLength) { - c = 0; + function dashGetTransactionNative(deffered) { + if (c >= txLength) { + c = 0; + } + var hash = fixtureData.txHashes[c]; + dashd.getTransaction(hash, true, function (err, tx) { + if (err) { + throw err; + } + deffered.resolve(); + }); + c++; } - var hash = fixtureData.txHashes[c]; - client.getRawTransaction(hash, function(err, tx) { - if (err) { - throw err; + + function dashGetTransactionJsonRpc(deffered) { + if (c >= txLength) { + c = 0; } - deffered.resolve(); - }); - c++; - } + var hash = fixtureData.txHashes[c]; + client.getRawTransaction(hash, function (err, tx) { + if (err) { + throw err; + } + deffered.resolve(); + }); + c++; + } - var suite = new benchmark.Suite(); + var suite = new benchmark.Suite(); - suite.add('dashd getblock (native)', dashdGetBlockNative, { - defer: true, - maxTime: maxTime - }); + suite.add("dashd getblock (native)", dashdGetBlockNative, { + defer: true, + maxTime: maxTime, + }); - suite.add('dashd getblock (json rpc)', dashdGetBlockJsonRpc, { - defer: true, - maxTime: maxTime - }); + suite.add("dashd getblock (json rpc)", dashdGetBlockJsonRpc, { + defer: true, + maxTime: maxTime, + }); - suite.add('dashd gettransaction (native)', dashGetTransactionNative, { - defer: true, - maxTime: maxTime - }); + suite.add("dashd gettransaction (native)", dashGetTransactionNative, { + defer: true, + maxTime: maxTime, + }); - suite.add('dashd gettransaction (json rpc)', dashGetTransactionJsonRpc, { - defer: true, - maxTime: maxTime - }); + suite.add("dashd gettransaction (json rpc)", dashGetTransactionJsonRpc, { + defer: true, + maxTime: maxTime, + }); - suite - .on('cycle', function(event) { - console.log(String(event.target)); - }) - .on('complete', function() { - console.log('Fastest is ' + this.filter('fastest').pluck('name')); - console.log('----------------------------------------------------------------------'); - next(); - }) - .run(); - } - ], function(err) { - if (err) { - throw err; - } - console.log('Finished'); - dashd.stop(function(err) { + suite + .on("cycle", function (event) { + console.log(String(event.target)); + }) + .on("complete", function () { + console.log("Fastest is " + this.filter("fastest").pluck("name")); + console.log("----------------------------------------------------------------------"); + next(); + }) + .run(); + }, + ], + function (err) { if (err) { - console.error('Fail to stop services: ' + err); - process.exit(1); + throw err; } - process.exit(0); - }); - }); + console.log("Finished"); + dashd.stop(function (err) { + if (err) { + console.error("Fail to stop services: " + err); + process.exit(1); + } + process.exit(0); + }); + } + ); }); diff --git a/docs/bus.md b/docs/bus.md index 8746d682c..8584bc02b 100644 --- a/docs/bus.md +++ b/docs/bus.md @@ -1,10 +1,10 @@ # Bus + The bus provides a way to subscribe to events from any of the services running. It's implemented abstract from transport specific implementation. The primary use of the bus in Bitcore Node is for subscribing to events via a web socket. ## Opening/Closing ```javascript - // a node is needed to be able to open a bus var node = new Node(configuration); @@ -18,13 +18,12 @@ bus.close(); ## Subscribing/Unsubscribing ```javascript - // subscribe to all transaction events -bus.subscribe('bitcoind/rawtransaction'); +bus.subscribe("bitcoind/rawtransaction"); // to subscribe to new block hashes -bus.subscribe('bitcoind/hashblock'); +bus.subscribe("bitcoind/hashblock"); // unsubscribe -bus.unsubscribe('bitcoind/rawtransaction'); +bus.unsubscribe("bitcoind/rawtransaction"); ``` diff --git a/docs/development.md b/docs/development.md index 048eb46a1..f8bfd8742 100644 --- a/docs/development.md +++ b/docs/development.md @@ -25,20 +25,22 @@ git clone git@github.com:/bitcoin.git git fetch origin : git checkout ``` -**Note**: See bitcoin documentation for building bitcoin on your platform. +**Note**: See bitcoin documentation for building bitcoin on your platform. ## Install Development Dependencies For Ubuntu: + ```bash sudo apt-get install libzmq3-dev sudo apt-get install build-essential ``` -**Note**: Make sure that libzmq-dev is not installed, it should be removed when installing libzmq3-dev. +**Note**: Make sure that libzmq-dev is not installed, it should be removed when installing libzmq3-dev. For Mac OS X: + ```bash brew install zeromq ``` @@ -51,10 +53,11 @@ npm install cd ../bitcore-node-dash npm install ``` + **Note**: If you get a message about not being able to download bitcoin distribution, you'll need to compile bitcoind from source, and setup your configuration to use that version. +We now will setup symlinks in `bitcore-node-dash` _(repeat this for any other modules you're planning on developing)_: -We now will setup symlinks in `bitcore-node-dash` *(repeat this for any other modules you're planning on developing)*: ```bash cd node_modules rm -rf bitcore-lib @@ -64,6 +67,7 @@ ln -s ~/bitcoind-rpc-dash ``` And if you're compiling or developing bitcoin: + ```bash cd ../bin ln -sf ~/bitcoin/src/bitcoind @@ -72,11 +76,13 @@ ln -sf ~/bitcoin/src/bitcoind ## Run Tests If you do not already have mocha installed: + ```bash npm install mocha -g ``` To run all test suites: + ```bash cd bitcore-node-dash npm run regtest @@ -84,11 +90,13 @@ npm run test ``` To run a specific unit test in watch mode: + ```bash mocha -w -R spec test/services/bitcoind.unit.js ``` To run a specific regtest: + ```bash mocha -R spec regtest/bitcoind.js ``` @@ -107,17 +115,12 @@ touch package.json ``` Edit `bitcore-node-dash.json` with something similar to: + ```json { "network": "livenet", "port": 3001, - "services": [ - "bitcoind", - "web", - "insight-api", - "insight-ui", - "" - ], + "services": ["bitcoind", "web", "insight-api", "insight-ui", ""], "servicesConfig": { "bitcoind": { "spawn": { @@ -142,6 +145,7 @@ ln -s ~/insight-ui ``` Make sure that the `/bitcoin.conf` has the necessary settings, for example: + ``` server=1 whitelist=127.0.0.1 @@ -157,6 +161,7 @@ rpcpassword=local321 ``` From within the `devnode` directory with the configuration file, start the node: + ```bash ../bitcore-node-dash/bin/bitcore-node-dash start -``` \ No newline at end of file +``` diff --git a/docs/node.md b/docs/node.md index 2d002aeb8..e8dedb82c 100644 --- a/docs/node.md +++ b/docs/node.md @@ -1,7 +1,9 @@ # Node + A node represents a collection of services that are loaded together. For more information about services, please see the [Services Documentation](services.md). ## API Documentation + - `start()` - Will start the node's services in the correct order based on the dependencies of a service. - `stop()` - Will stop the node's services. - `openBus()` - Will create a new event bus to subscribe to events. @@ -13,39 +15,38 @@ A node represents a collection of services that are loaded together. For more in ## Example Usage ```js - -var index = require('bitcore-node-dash'); +var index = require("bitcore-node-dash"); var Bitcoin = index.services.Bitcoin; var Node = index.Node; var configuration = { - datadir: '/home/user/.bitcoin', - network: 'testnet', + datadir: "/home/user/.bitcoin", + network: "testnet", services: [ { - name: 'bitcoind', + name: "bitcoind", module: Bitcoin, - config: {} - } - ] + config: {}, + }, + ], }; var node = new Node(configuration); -node.start(function() { - //start the node so the node.on('ready') is actually called. +node.start(function () { + //start the node so the node.on('ready') is actually called. }); -node.on('ready', function() { - console.log('Bitcoin Node Ready'); +node.on("ready", function () { + console.log("Bitcoin Node Ready"); }); -node.on('error', function(err) { +node.on("error", function (err) { console.error(err); }); // shutdown the node -node.stop(function() { +node.stop(function () { // the shutdown is complete }); ``` diff --git a/docs/scaffold.md b/docs/scaffold.md index 3af634565..76e87de61 100644 --- a/docs/scaffold.md +++ b/docs/scaffold.md @@ -1,20 +1,27 @@ # Scaffold + A collection of functions for creating, managing, starting, stopping and interacting with a Bitcore node. ## Install + This function will add a service to a node by installing the necessary dependencies and modifying the `bitcore-node-dash.json` configuration. ## Start + This function will load a configuration file `bitcore-node-dash.json` and instantiate and start a node based on the configuration. ## Find Config + This function will recursively find a configuration `bitcore-node-dash.json` file in parent directories and return the result. ## Default Config + This function will return a default configuration with the default services based on environment variables, and will default to using the standard `/home/user/.bitcoin` data directory. ## Uninstall + This function will remove a service from a node by uninstalling the necessary dependencies and modifying the `bitcore-node-dash.json` configuration. ## Call Method + This function will call an API method on a node via the JSON-RPC interface. diff --git a/docs/services.md b/docs/services.md index 6032e5743..ea2887d2d 100644 --- a/docs/services.md +++ b/docs/services.md @@ -1,5 +1,7 @@ # Services + Bitcore Node has a service module system that can start up additional services that can include additional: + - Blockchain indexes (e.g. querying balances for addresses) - API methods - HTTP routes @@ -9,9 +11,7 @@ The `bitcore-node-dash.json` file describes which services will load for a node: ```json { - "services": [ - "bitcoind", "web" - ] + "services": ["bitcoind", "web"] } ``` @@ -30,6 +30,7 @@ Services correspond with a Node.js module as described in 'package.json', for ex _Note:_ If you already have a bitcore-node-dash database, and you want to query data from previous blocks in the blockchain, you will need to reindex. Reindexing right now means deleting your bitcore-node-dash database and resyncing. ## Using Services Programmatically + If, instead, you would like to run a custom node, you can include services by including them in your configuration object when initializing a new node. ```js @@ -67,14 +68,16 @@ var myNode = new bitcore.Node({ Now that you've loaded your services you can access them via `myNode.services..`. For example if you wanted to check the balance of an address, you could access the address service like so. ```js -myNode.services.bitcoind.getAddressBalance('1HB5XMLmzFVj8ALj6mfBsbifRoD4miY36v', false, function(err, total) { +myNode.services.bitcoind.getAddressBalance("1HB5XMLmzFVj8ALj6mfBsbifRoD4miY36v", false, function (err, total) { console.log(total.balance); //Satoshi amount of this address }); ``` ## Writing a Service + A new service can be created by inheriting from `Node.Service` and implementing these methods and properties: -- `Service.dependencies` - An array of services that are needed, this will determine the order that services are started on the node. + +- `Service.dependencies` - An array of services that are needed, this will determine the order that services are started on the node. - `Service.prototype.start()` - Called to start up the service. - `Service.prototype.stop()` - Called to stop the service. - `Service.prototype.blockHandler()` - Will be called when a block is added or removed from the chain, and is useful for updating a database view/index. @@ -85,4 +88,3 @@ A new service can be created by inheriting from `Node.Service` and implementing The `package.json` for the service module can either export the `Node.Service` directly, or specify a specific module to load by including `"bitcoreNode": "lib/bitcore-node-dash.js"`. Please take a look at some of the existing services for implementation specifics. - diff --git a/docs/services/dashd.md b/docs/services/dashd.md index beb35790b..df65335a0 100644 --- a/docs/services/dashd.md +++ b/docs/services/dashd.md @@ -9,43 +9,41 @@ The configuration should include a "connect" configuration in "dashd". This defi ```json5 { // ... - "services": [ - "dashd" - ], - "servicesConfig": { - "dashd": { - "connect": [ + services: ["dashd"], + servicesConfig: { + dashd: { + connect: [ { - "rpchost": "127.0.0.1", - "rpcport": 30521, - "rpcuser": "dashrpc", - "rpcpassword": "local321", - "zmqpubrawtx": "tcp://127.0.0.1:30611" + rpchost: "127.0.0.1", + rpcport: 30521, + rpcuser: "dashrpc", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:30611", }, { - "rpchost": "127.0.0.1", - "rpcport": 30522, - "rpcuser": "dashrpc", - "rpcpassword": "local321", - "zmqpubrawtx": "tcp://127.0.0.1:30622" + rpchost: "127.0.0.1", + rpcport: 30522, + rpcuser: "dashrpc", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:30622", }, { - "rpchost": "127.0.0.1", - "rpcport": 30523, - "rpcuser": "dashrpc", - "rpcpassword": "local321", - "zmqpubrawtx": "tcp://127.0.0.1:30633" - } - ] - } - } + rpchost: "127.0.0.1", + rpcport: 30523, + rpcuser: "dashrpc", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:30633", + }, + ], + }, + }, } ``` **Note**: For detailed example configuration see [`regtest/cluster.js`](regtest/cluster.js) - ## API Documentation + Methods are available by directly interfacing with the service: ```js @@ -60,31 +58,31 @@ node.services.dashd. // gives the block hashes sorted from low to high within a range of timestamps var high = 1460393372; // Mon Apr 11 2016 12:49:25 GMT-0400 (EDT) var low = 1460306965; // Mon Apr 10 2016 12:49:25 GMT-0400 (EDT) -node.services.dashd.getBlockHashesByTimestamp(high, low, function(err, blockHashes) { +node.services.dashd.getBlockHashesByTimestamp(high, low, function (err, blockHashes) { //... }); // get the current tip of the chain -node.services.dashd.getBestBlockHash(function(err, blockHash) { +node.services.dashd.getBestBlockHash(function (err, blockHash) { //... -}) +}); ``` **Getting Synchronization and Node Status** ```js // gives a boolean if the daemon is fully synced (not the initial block download) -node.services.dashd.isSynced(function(err, synced) { +node.services.dashd.isSynced(function (err, synced) { //... -}) +}); // gives the current estimate of blockchain download as a percentage -node.services.dashd.syncPercentage(function(err, percent) { +node.services.dashd.syncPercentage(function (err, percent) { //... }); // gives information about the chain including total number of blocks -node.services.dashd.getInfo(function(err, info) { +node.services.dashd.getInfo(function (err, info) { //... }); ``` @@ -94,7 +92,7 @@ node.services.dashd.getInfo(function(err, info) { ```js // will generate a block for the "regtest" network (development purposes) var numberOfBlocks = 10; -node.services.dashd.generateBlock(numberOfBlocks, function(err, blockHashes) { +node.services.dashd.generateBlock(numberOfBlocks, function (err, blockHashes) { //... }); ``` @@ -136,8 +134,8 @@ node.services.dashd.getBlockOverview(blockHash, function(err, blockOverview) { Get a transaction asynchronously by reading it from disk: ```js -var txid = '3dba349df7225e071179256eea2195083cd89985124be3b05e48de509cf1e268'; -node.services.dashd.getRawTransaction(txid, function(err, transactionBuffer) { +var txid = "3dba349df7225e071179256eea2195083cd89985124be3b05e48de509cf1e268"; +node.services.dashd.getRawTransaction(txid, function (err, transactionBuffer) { if (err) { throw err; } @@ -145,12 +143,12 @@ node.services.dashd.getRawTransaction(txid, function(err, transactionBuffer) { }); // get a bitcore object of the transaction (as above) -node.services.dashd.getTransaction(txid, function(err, transaction) { +node.services.dashd.getTransaction(txid, function (err, transaction) { //... }); // retrieve the transaction with input values, fees, spent and block info -node.services.dashd.getDetailedTransaction(txid, function(err, transaction) { +node.services.dashd.getDetailedTransaction(txid, function (err, transaction) { //... }); ``` @@ -159,11 +157,11 @@ Send a transaction to the network: ```js var numberOfBlocks = 3; -node.services.dashd.estimateFee(numberOfBlocks, function(err, feesPerKilobyte) { +node.services.dashd.estimateFee(numberOfBlocks, function (err, feesPerKilobyte) { //... }); -node.services.dashd.sendTransaction(transaction.serialize(), function(err, hash) { +node.services.dashd.sendTransaction(transaction.serialize(), function (err, hash) { //... }); ``` @@ -175,8 +173,8 @@ node.services.dashd.sendTransaction(transaction.serialize(), function(err, hash) One of the most common uses will be to retrieve unspent outputs necessary to create a transaction, here is how to get the unspent outputs for an address: ```js -var address = 'yegvhonA7HaRvBqp57RVncFAuuqRbMQNXk'; -node.services.dashd.getAddressUnspentOutputs(address, options, function(err, unspentOutputs) { +var address = "yegvhonA7HaRvBqp57RVncFAuuqRbMQNXk"; +node.services.dashd.getAddressUnspentOutputs(address, options, function (err, unspentOutputs) { // see below }); ``` @@ -186,22 +184,22 @@ The `unspentOutputs` will have the format: ```js [ { - address: 'yegvhonA7HaRvBqp57RVncFAuuqRbMQNXk', - txid: '65e991800c93f8272c38f28366ca901d3bb9096d34598f2903c5578ec277c85d', + address: "yegvhonA7HaRvBqp57RVncFAuuqRbMQNXk", + txid: "65e991800c93f8272c38f28366ca901d3bb9096d34598f2903c5578ec277c85d", outputIndex: 1, height: 150, satoshis: 281250000, - script: '76a914c982406f087057a97456e48d335546ae8d93a03c88ac', - confirmations: 3 - } -] + script: "76a914c982406f087057a97456e48d335546ae8d93a03c88ac", + confirmations: 3, + }, +]; ``` **View Balances** ```js -var address = 'yTyBtDZp16HtS1jpNd1vD11y6LSyvm1XzX'; -node.services.dashd.getAddressBalance(address, options, function(err, balance) { +var address = "yTyBtDZp16HtS1jpNd1vD11y6LSyvm1XzX"; +node.services.dashd.getAddressBalance(address, options, function (err, balance) { // balance will be in satoshis with "received" and "balance" }); ``` @@ -211,13 +209,13 @@ node.services.dashd.getAddressBalance(address, options, function(err, balance) { This method will give history of an address limited by a range of block heights by using the "start" and "end" arguments. The "start" value is the more recent, and greater, block height. The "end" value is the older, and lesser, block height. This feature is most useful for synchronization as previous history can be omitted. Furthermore for large ranges of block heights, results can be paginated by using the "from" and "to" arguments. ```js -var addresses = ['yTyBtDZp16HtS1jpNd1vD11y6LSyvm1XzX']; +var addresses = ["yTyBtDZp16HtS1jpNd1vD11y6LSyvm1XzX"]; var options = { start: 345000, end: 344000, - queryMempool: true + queryMempool: true, }; -node.services.dashd.getAddressHistory(addresses, options, function(err, history) { +node.services.dashd.getAddressHistory(addresses, options, function (err, history) { // see below }); ``` @@ -245,12 +243,12 @@ The history format will be: **View Address Summary** ```js -var address = 'yTyBtDZp16HtS1jpNd1vD11y6LSyvm1XzX'; +var address = "yTyBtDZp16HtS1jpNd1vD11y6LSyvm1XzX"; var options = { - noTxList: false + noTxList: false, }; -node.services.dashd.getAddressSummary(address, options, function(err, summary) { +node.services.dashd.getAddressSummary(address, options, function (err, summary) { // see below }); ``` @@ -270,32 +268,35 @@ The `summary` will have the format (values are in satoshis): ] } ``` + **Notes**: -- `totalReceived` does not exclude change *(the amount of satoshis originating from the same address)* -- `unconfirmedBalance` is the delta that the unconfirmed transactions have on the total balance *(can be both positive and negative)* + +- `totalReceived` does not exclude change _(the amount of satoshis originating from the same address)_ +- `unconfirmedBalance` is the delta that the unconfirmed transactions have on the total balance _(can be both positive and negative)_ - `unconfirmedAppearances` is the total number of unconfirmed transactions - `appearances` is the total confirmed transactions -- `txids` Are sorted in block order with the most recent at the beginning. A maximum of 1000 *(default)* will be returned, the `from` and `to` options can be used to get further values. - +- `txids` Are sorted in block order with the most recent at the beginning. A maximum of 1000 _(default)_ will be returned, the `from` and `to` options can be used to get further values. ## Events + The Dash Service exposes two events via the Bus, and there are a few events that can be directly registered: ```js -node.services.dashd.on('tip', function(blockHash) { +node.services.dashd.on("tip", function (blockHash) { // a new block tip has been added, if there is a rapid update (with a second) this will not emit every tip update }); -node.services.dashd.on('tx', function(transactionBuffer) { +node.services.dashd.on("tx", function (transactionBuffer) { // a new transaction has entered the mempool }); -node.services.dashd.on('block', function(blockHash) { +node.services.dashd.on("block", function (blockHash) { // a new block has been added }); ``` For details on instantiating a bus for a node, see the [Bus Documentation](../bus.md). + - Name: `dashd/rawtransaction` - Name: `dashd/hashblock` - Name: `dashd/addresstxid`, Arguments: [address, address...] @@ -303,19 +304,19 @@ For details on instantiating a bus for a node, see the [Bus Documentation](../bu **Examples:** ```js -bus.subscribe('dashd/rawtransaction'); -bus.subscribe('dashd/hashblock'); -bus.subscribe('dashd/addresstxid', ['XxoNntPX7RNFKHUhuGNUthb1UQpYnKuCsk']); +bus.subscribe("dashd/rawtransaction"); +bus.subscribe("dashd/hashblock"); +bus.subscribe("dashd/addresstxid", ["XxoNntPX7RNFKHUhuGNUthb1UQpYnKuCsk"]); -bus.on('dashd/rawtransaction', function(transactionHex) { +bus.on("dashd/rawtransaction", function (transactionHex) { //... }); -bus.on('dashd/hashblock', function(blockhashHex) { +bus.on("dashd/hashblock", function (blockhashHex) { //... }); -bus.on('dashd/addresstxid', function(data) { +bus.on("dashd/addresstxid", function (data) { // data.address; // data.txid; }); diff --git a/docs/services/web.md b/docs/services/web.md index 613607116..255473428 100644 --- a/docs/services/web.md +++ b/docs/services/web.md @@ -1,4 +1,5 @@ # Web Service + The web service creates an express app which can be used by services for setting up web routes for API's, static content, web applications, etc. This allows users to interact with various bitcore node services over one http or https port. In order for your service to add routes, it must implement the `setupRoutes()` and `getRoutePrefix()` methods. @@ -6,22 +7,23 @@ In order for your service to add routes, it must implement the `setupRoutes()` a ## Example ```js -MyService.prototype.setupRoutes = function(app, express) { +MyService.prototype.setupRoutes = function (app, express) { // Set up routes - app.get('/hello', function(req, res) { - res.send('world'); + app.get("/hello", function (req, res) { + res.send("world"); }); // Serve static content - app.use('/static', express.static(__dirname + '/static')); + app.use("/static", express.static(__dirname + "/static")); }; -MyService.prototype.getRoutePrefix = function() { - return 'my-service' +MyService.prototype.getRoutePrefix = function () { + return "my-service"; }; ``` ## Configuring Web Service for HTTPS + You can run the web service over https by editing your bitcore node config, setting https to true and adding httpsOptions: ```json @@ -32,8 +34,6 @@ You can run the web service over https by editing your bitcore node config, sett "key": "path-to-private-key", "cert": "path-to-certificate" }, - "services": [ - "web" - ] + "services": ["web"] } ``` diff --git a/docs/upgrade.md b/docs/upgrade.md index 1b58fa9c7..3e84c6d50 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -8,7 +8,8 @@ This major upgrade includes changes to indexes, API methods and services. Please ### Indexes -Indexes include *more information* and are now also *faster*. Because of this a **reindex will be necessary** when upgrading as the address and database indexes are now a part of bitcoind with three new `bitcoin.conf` options: +Indexes include _more information_ and are now also _faster_. Because of this a **reindex will be necessary** when upgrading as the address and database indexes are now a part of bitcoind with three new `bitcoin.conf` options: + - `-addressindex` - `-timestampindex` - `-spentindex` @@ -17,33 +18,27 @@ To start reindexing add `reindex=1` during the **first startup only**. ### Configuration Options -- The `bitcoin.conf` file in will need to be updated to include additional indexes *(see below)*. +- The `bitcoin.conf` file in will need to be updated to include additional indexes _(see below)_. - The `datadir` option is now a part of `bitcoind` spawn configuration, and there is a new option to connect to multiple bitcoind processes (Please see [Bitcoin Service Docs](services/bitcoind.md) for more details). The services `db` and `address` are now a part of the `bitcoind` service. Here is how to update `bitcore-node-dash.json` configuration options: **Before**: + ```json { "datadir": "/home//.bitcoin", "network": "livenet", "port": 3001, - "services": [ - "address", - "bitcoind", - "db", - "web" - ] + "services": ["address", "bitcoind", "db", "web"] } ``` **After**: + ```json { "network": "livenet", "port": 3001, - "services": [ - "bitcoind", - "web" - ], + "services": ["bitcoind", "web"], "servicesConfig": { "bitcoind": { "spawn": { @@ -56,6 +51,7 @@ To start reindexing add `reindex=1` during the **first startup only**. ``` It will also be necessary to update `bitcoin.conf` settings, to include these fields: + ``` server=1 whitelist=127.0.0.1 @@ -73,5 +69,6 @@ rpcpassword= **Important**: Once changes have been made you'll also need to add the `reindex=1` option **only for the first startup** to regenerate the indexes. Once this is complete you should be able to remove the `bitcore-node-dash.db` directory with the old indexes. ### API and Service Changes + - Many API methods that were a part of the `db` and `address` services are now a part of the `bitcoind` service. Please see [Bitcoin Service Docs](docs/services/bitcoind.md) for more details. -- The `db` and `address` services are deprecated, most of the functionality still exists. Any services that were extending indexes with the `db` service, will need to manage chain state itself, or build the indexes within `bitcoind`. \ No newline at end of file +- The `db` and `address` services are deprecated, most of the functionality still exists. Any services that were extending indexes with the `db` service, will need to manage chain state itself, or build the indexes within `bitcoind`. diff --git a/index.js b/index.js index 6370f5bf4..a0497acb1 100644 --- a/index.js +++ b/index.js @@ -1,27 +1,27 @@ -'use strict'; +"use strict"; -module.exports = require('./lib'); -module.exports.Node = require('./lib/node'); -module.exports.Service = require('./lib/service'); -module.exports.errors = require('./lib/errors'); +module.exports = require("./lib"); +module.exports.Node = require("./lib/node"); +module.exports.Service = require("./lib/service"); +module.exports.errors = require("./lib/errors"); module.exports.services = {}; -module.exports.services.Dash = require('./lib/services/dashd'); -module.exports.services.Web = require('./lib/services/web'); +module.exports.services.Dash = require("./lib/services/dashd"); +module.exports.services.Web = require("./lib/services/web"); module.exports.scaffold = {}; -module.exports.scaffold.create = require('./lib/scaffold/create'); -module.exports.scaffold.add = require('./lib/scaffold/add'); -module.exports.scaffold.remove = require('./lib/scaffold/remove'); -module.exports.scaffold.start = require('./lib/scaffold/start'); -module.exports.scaffold.callMethod = require('./lib/scaffold/call-method'); -module.exports.scaffold.findConfig = require('./lib/scaffold/find-config'); -module.exports.scaffold.defaultConfig = require('./lib/scaffold/default-config'); +module.exports.scaffold.create = require("./lib/scaffold/create"); +module.exports.scaffold.add = require("./lib/scaffold/add"); +module.exports.scaffold.remove = require("./lib/scaffold/remove"); +module.exports.scaffold.start = require("./lib/scaffold/start"); +module.exports.scaffold.callMethod = require("./lib/scaffold/call-method"); +module.exports.scaffold.findConfig = require("./lib/scaffold/find-config"); +module.exports.scaffold.defaultConfig = require("./lib/scaffold/default-config"); module.exports.cli = {}; -module.exports.cli.main = require('./lib/cli/main'); -module.exports.cli.daemon = require('./lib/cli/daemon'); -module.exports.cli.dashcore = require('./lib/cli/dashcore'); -module.exports.cli.dashcored = require('./lib/cli/dashcored'); +module.exports.cli.main = require("./lib/cli/main"); +module.exports.cli.daemon = require("./lib/cli/daemon"); +module.exports.cli.dashcore = require("./lib/cli/dashcore"); +module.exports.cli.dashcored = require("./lib/cli/dashcored"); -module.exports.lib = require('@dashevo/dashcore-lib'); +module.exports.lib = require("@dashevo/dashcore-lib"); diff --git a/lib/bus.js b/lib/bus.js index d4f3bdd5f..c1aa0f79c 100644 --- a/lib/bus.js +++ b/lib/bus.js @@ -1,7 +1,7 @@ -'use strict'; +"use strict"; -var events = require('events'); -var util = require('util'); +var events = require("events"); +var util = require("util"); /** * The bus represents a connection to node, decoupled from the transport layer, that can @@ -24,10 +24,10 @@ util.inherits(Bus, events.EventEmitter); * first argument of this function. * @param {String} name - The name of the event */ -Bus.prototype.subscribe = function(name) { +Bus.prototype.subscribe = function (name) { var events = []; - for(var i in this.node.services) { + for (var i in this.node.services) { var service = this.node.services[i]; events = events.concat(service.getPublishEvents()); } @@ -46,10 +46,10 @@ Bus.prototype.subscribe = function(name) { * The inverse of the subscribe method. * @param {String} name - The name of the event */ -Bus.prototype.unsubscribe = function(name) { +Bus.prototype.unsubscribe = function (name) { var events = []; - for(var i in this.node.services) { + for (var i in this.node.services) { var service = this.node.services[i]; events = events.concat(service.getPublishEvents()); } @@ -67,10 +67,10 @@ Bus.prototype.unsubscribe = function(name) { /** * This function will unsubscribe all events. */ -Bus.prototype.close = function() { +Bus.prototype.close = function () { var events = []; - for(var i in this.node.services) { + for (var i in this.node.services) { var service = this.node.services[i]; events = events.concat(service.getPublishEvents()); } diff --git a/lib/cli/daemon.js b/lib/cli/daemon.js index 2cc89ada7..2c6ebc182 100644 --- a/lib/cli/daemon.js +++ b/lib/cli/daemon.js @@ -1,8 +1,8 @@ -'use strict'; +"use strict"; -var program = require('commander'); -var path = require('path'); -var dashcore = require('..'); +var program = require("commander"); +var path = require("path"); +var dashcore = require(".."); function main(servicesPath, additionalServices) { /* jshint maxstatements: 100 */ @@ -14,9 +14,9 @@ function main(servicesPath, additionalServices) { program .version(version) - .description('Start the current node') - .option('-c, --config ', 'Specify the directory with Dashcore Node configuration') - .option('-d, --daemon', 'Make dashcore a daemon (running in the background)'); + .description("Start the current node") + .option("-c, --config ", "Specify the directory with Dashcore Node configuration") + .option("-d, --daemon", "Make dashcore a daemon (running in the background)"); program.parse(process.argv); @@ -26,10 +26,10 @@ function main(servicesPath, additionalServices) { var configInfo = findConfig(program.config || process.cwd()); if (!configInfo) { configInfo = defaultConfig({ - additionalServices: additionalServices + additionalServices: additionalServices, }); } - if(program.daemon) { + if (program.daemon) { configInfo.config.daemon = true; } if (servicesPath) { diff --git a/lib/cli/dashcore.js b/lib/cli/dashcore.js index 6e99a1b1c..01b95b8a7 100644 --- a/lib/cli/dashcore.js +++ b/lib/cli/dashcore.js @@ -1,38 +1,40 @@ -'use strict'; +"use strict"; -var Liftoff = require('liftoff'); +var Liftoff = require("liftoff"); function main(parentServicesPath, additionalServices) { - var liftoff = new Liftoff({ - name: 'dashcore', - moduleName: 'dashcore-node', - configName: 'dashcore-node', - processTitle: 'dashcore' - }).on('require', function (name) { - console.log('Loading:', name); - }).on('requireFail', function (name, err) { - console.log('Unable to load:', name, err); - }).on('respawn', function (flags, child) { - console.log('Detected node flags:', flags); - console.log('Respawned to PID:', child.pid); - }); - - liftoff.launch({ - cwd: process.cwd() - }, function(env){ - - var node; - if (env.configPath && env.modulePath) { - node = require(env.modulePath); - node.cli.main(); - } else { - node = require('../../'); - node.cli.main(parentServicesPath, additionalServices); + name: "dashcore", + moduleName: "dashcore-node", + configName: "dashcore-node", + processTitle: "dashcore", + }) + .on("require", function (name) { + console.log("Loading:", name); + }) + .on("requireFail", function (name, err) { + console.log("Unable to load:", name, err); + }) + .on("respawn", function (flags, child) { + console.log("Detected node flags:", flags); + console.log("Respawned to PID:", child.pid); + }); + + liftoff.launch( + { + cwd: process.cwd(), + }, + function (env) { + var node; + if (env.configPath && env.modulePath) { + node = require(env.modulePath); + node.cli.main(); + } else { + node = require("../../"); + node.cli.main(parentServicesPath, additionalServices); + } } - - }); - + ); } module.exports = main; diff --git a/lib/cli/dashcored.js b/lib/cli/dashcored.js index 243263e97..6e693f211 100644 --- a/lib/cli/dashcored.js +++ b/lib/cli/dashcored.js @@ -1,39 +1,41 @@ -'use strict'; +"use strict"; -var Liftoff = require('liftoff'); +var Liftoff = require("liftoff"); function main(parentServicesPath, additionalServices) { - var liftoff = new Liftoff({ - name: 'dashcored', - moduleName: 'dashcore-node', - configName: 'dashcore-node', - processTitle: 'dashcored' - }).on('require', function (name) { - console.log('Loading:', name); - }).on('requireFail', function (name, err) { - console.log('Unable to load:', name, err); - }).on('respawn', function (flags, child) { - console.log('Detected node flags:', flags); - console.log('Respawned to PID:', child.pid); - }); - - liftoff.launch({ - cwd: process.cwd() - }, function(env){ - - var node; - - if (env.configPath && env.modulePath) { - node = require(env.modulePath); - node.cli.daemon(); - } else { - node = require('../../'); - node.cli.daemon(parentServicesPath, additionalServices); + name: "dashcored", + moduleName: "dashcore-node", + configName: "dashcore-node", + processTitle: "dashcored", + }) + .on("require", function (name) { + console.log("Loading:", name); + }) + .on("requireFail", function (name, err) { + console.log("Unable to load:", name, err); + }) + .on("respawn", function (flags, child) { + console.log("Detected node flags:", flags); + console.log("Respawned to PID:", child.pid); + }); + + liftoff.launch( + { + cwd: process.cwd(), + }, + function (env) { + var node; + + if (env.configPath && env.modulePath) { + node = require(env.modulePath); + node.cli.daemon(); + } else { + node = require("../../"); + node.cli.daemon(parentServicesPath, additionalServices); + } } - - }); - + ); } module.exports = main; diff --git a/lib/cli/main.js b/lib/cli/main.js index efe304770..abe0babe6 100644 --- a/lib/cli/main.js +++ b/lib/cli/main.js @@ -1,9 +1,9 @@ -'use strict'; +"use strict"; -var program = require('commander'); -var path = require('path'); -var dashcorenode = require('..'); -var utils = require('../utils'); +var program = require("commander"); +var path = require("path"); +var dashcorenode = require(".."); +var utils = require("../utils"); function main(servicesPath, additionalServices) { /* jshint maxstatements: 100 */ @@ -17,51 +17,50 @@ function main(servicesPath, additionalServices) { var findConfig = dashcorenode.scaffold.findConfig; var defaultConfig = dashcorenode.scaffold.defaultConfig; - program - .version(version); + program.version(version); program - .command('create ') - .description('Create a new node') - .option('-d, --datadir ', 'Specify the Dash database directory') - .option('-t, --testnet', 'Enable testnet as the network') - .action(function(dirname, cmd){ + .command("create ") + .description("Create a new node") + .option("-d, --datadir ", "Specify the Dash database directory") + .option("-t, --testnet", "Enable testnet as the network") + .action(function (dirname, cmd) { if (cmd.datadir) { cmd.datadir = path.resolve(process.cwd(), cmd.datadir); } var opts = { cwd: process.cwd(), dirname: dirname, - datadir: cmd.datadir || './data', - isGlobal: false + datadir: cmd.datadir || "./data", + isGlobal: false, }; if (cmd.testnet) { - opts.network = 'testnet'; + opts.network = "testnet"; } - create(opts, function(err) { + create(opts, function (err) { if (err) { throw err; } - console.log('Successfully created node in directory: ', dirname); + console.log("Successfully created node in directory: ", dirname); }); }); program - .command('start') - .description('Start the current node') - .option('-c, --config ', 'Specify the directory with Dashcore Node configuration') - .option('-d, --daemon', 'Make dashcore-node a daemon (running in the background)') - .action(function(cmd){ + .command("start") + .description("Start the current node") + .option("-c, --config ", "Specify the directory with Dashcore Node configuration") + .option("-d, --daemon", "Make dashcore-node a daemon (running in the background)") + .action(function (cmd) { if (cmd.config) { cmd.config = path.resolve(process.cwd(), cmd.config); } var configInfo = findConfig(cmd.config || process.cwd()); if (!configInfo) { configInfo = defaultConfig({ - additionalServices: additionalServices + additionalServices: additionalServices, }); } - if(cmd.daemon) { + if (cmd.daemon) { configInfo.config.daemon = true; } if (servicesPath) { @@ -71,72 +70,74 @@ function main(servicesPath, additionalServices) { }); program - .command('install ') - .description('Install a service for the current node') - .action(function(services){ + .command("install ") + .description("Install a service for the current node") + .action(function (services) { var configInfo = findConfig(process.cwd()); if (!configInfo) { - throw new Error('Could not find configuration, see `dashcore-node create --help`'); + throw new Error("Could not find configuration, see `dashcore-node create --help`"); } var opts = { path: configInfo.path, - services: services + services: services, }; - add(opts, function(err) { + add(opts, function (err) { if (err) { throw err; } - console.log('Successfully added services(s):', services.join(', ')); + console.log("Successfully added services(s):", services.join(", ")); }); - }).on('--help', function() { - console.log(' Examples:'); + }) + .on("--help", function () { + console.log(" Examples:"); console.log(); - console.log(' $ dashcore-node add wallet-service'); - console.log(' $ dashcore-node add insight-api'); + console.log(" $ dashcore-node add wallet-service"); + console.log(" $ dashcore-node add insight-api"); console.log(); }); program - .command('uninstall ') - .description('Uninstall a service for the current node') - .action(function(services){ + .command("uninstall ") + .description("Uninstall a service for the current node") + .action(function (services) { var configInfo = findConfig(process.cwd()); if (!configInfo) { - throw new Error('Could not find configuration, see `dashcore-node create --help`'); + throw new Error("Could not find configuration, see `dashcore-node create --help`"); } var opts = { path: configInfo.path, - services: services + services: services, }; - remove(opts, function(err) { + remove(opts, function (err) { if (err) { throw err; } - console.log('Successfully removed services(s):', services.join(', ')); + console.log("Successfully removed services(s):", services.join(", ")); }); - }).on('--help', function() { - console.log(' Examples:'); + }) + .on("--help", function () { + console.log(" Examples:"); console.log(); - console.log(' $ dashcore-node remove wallet-service'); - console.log(' $ dashcore-node remove insight-api'); + console.log(" $ dashcore-node remove wallet-service"); + console.log(" $ dashcore-node remove insight-api"); console.log(); }); program - .command('call [params...]') - .description('Call an API method') - .action(function(method, paramsArg) { + .command("call [params...]") + .description("Call an API method") + .action(function (method, paramsArg) { var params = utils.parseParamsWithJSON(paramsArg); var configInfo = findConfig(process.cwd()); if (!configInfo) { configInfo = defaultConfig(); } var options = { - protocol: 'http', - host: 'localhost', - port: configInfo.config.port + protocol: "http", + host: "localhost", + port: configInfo.config.port, }; - callMethod(options, method, params, function(err, data) { + callMethod(options, method, params, function (err, data) { if (err) { throw err; } @@ -149,7 +150,6 @@ function main(servicesPath, additionalServices) { if (process.argv.length === 2) { program.help(); } - } module.exports = main; diff --git a/lib/errors.js b/lib/errors.js index f42702fe9..76d5beaf9 100644 --- a/lib/errors.js +++ b/lib/errors.js @@ -1,12 +1,12 @@ -'use strict'; +"use strict"; -var createError = require('errno').create; +var createError = require("errno").create; -var DashcoreNodeError = createError('DashcoreNodeError'); +var DashcoreNodeError = createError("DashcoreNodeError"); -var RPCError = createError('RPCError', DashcoreNodeError); +var RPCError = createError("RPCError", DashcoreNodeError); module.exports = { Error: DashcoreNodeError, - RPCError: RPCError + RPCError: RPCError, }; diff --git a/lib/index.js b/lib/index.js index 4b02c98b7..9307773ed 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,3 +1,3 @@ -var Logger = require('./logger'); -module.exports.errors = require('./errors'); +var Logger = require("./logger"); +module.exports.errors = require("./errors"); module.exports.log = new Logger(); diff --git a/lib/logger.js b/lib/logger.js index 3434adfa0..6f105464c 100644 --- a/lib/logger.js +++ b/lib/logger.js @@ -1,8 +1,8 @@ -'use strict'; +"use strict"; -var dashcore = require('@dashevo/dashcore-lib'); +var dashcore = require("@dashevo/dashcore-lib"); var _ = dashcore.deps._; -var colors = require('colors/safe'); +var colors = require("colors/safe"); /** * Wraps console.log with some special magic @@ -21,47 +21,47 @@ Logger.DEFAULT_FORMATTING = true; * Prints an info message * #info */ -Logger.prototype.info = function() { - this._log.apply(this, ['blue', 'info'].concat(Array.prototype.slice.call(arguments))); +Logger.prototype.info = function () { + this._log.apply(this, ["blue", "info"].concat(Array.prototype.slice.call(arguments))); }; /** * Prints an error message * #error */ -Logger.prototype.error = function() { - this._log.apply(this, ['red', 'error'].concat(Array.prototype.slice.call(arguments))); +Logger.prototype.error = function () { + this._log.apply(this, ["red", "error"].concat(Array.prototype.slice.call(arguments))); }; /** * Prints an debug message * #debug */ -Logger.prototype.debug = function() { - this._log.apply(this, ['magenta', 'debug'].concat(Array.prototype.slice.call(arguments))); +Logger.prototype.debug = function () { + this._log.apply(this, ["magenta", "debug"].concat(Array.prototype.slice.call(arguments))); }; /** * Prints an warn message * #warn */ -Logger.prototype.warn = function() { - this._log.apply(this, ['yellow', 'warn'].concat(Array.prototype.slice.call(arguments))); +Logger.prototype.warn = function () { + this._log.apply(this, ["yellow", "warn"].concat(Array.prototype.slice.call(arguments))); }; /** * Proxies console.log with color and arg parsing magic * #_log */ -Logger.prototype._log = function(color) { +Logger.prototype._log = function (color) { var args = Array.prototype.slice.call(arguments); args = args.slice(1); var level = args.shift(); if (this.formatting) { var date = new Date(); - var typeString = colors[color].italic(level + ':'); - args[0] = '[' + date.toISOString() + ']' + ' ' + typeString + ' ' + args[0]; + var typeString = colors[color].italic(level + ":"); + args[0] = "[" + date.toISOString() + "]" + " " + typeString + " " + args[0]; } var fn = console[level] || console.log; fn.apply(console, args); diff --git a/lib/node.js b/lib/node.js index 0bee9966b..9292f01d3 100644 --- a/lib/node.js +++ b/lib/node.js @@ -1,16 +1,16 @@ -'use strict'; +"use strict"; -var util = require('util'); -var EventEmitter = require('events').EventEmitter; -var async = require('async'); -var dashcore = require('@dashevo/dashcore-lib'); +var util = require("util"); +var EventEmitter = require("events").EventEmitter; +var async = require("async"); +var dashcore = require("@dashevo/dashcore-lib"); var Networks = dashcore.Networks; var $ = dashcore.util.preconditions; var _ = dashcore.deps._; -var index = require('./'); +var index = require("./"); var log = index.log; -var Bus = require('./bus'); -var errors = require('./errors'); +var Bus = require("./bus"); +var errors = require("./errors"); /** * A node is a hub of services, and will manage starting and stopping the services in @@ -38,7 +38,7 @@ var errors = require('./errors'); */ function Node(config) { /* jshint maxstatements: 20 */ - if(!(this instanceof Node)) { + if (!(this instanceof Node)) { return new Node(config); } this.configPath = config.path; @@ -71,36 +71,36 @@ util.inherits(Node, EventEmitter); * @param {Object} config * @param {String} config.network - Possible options "testnet", "regtest" or "livenet" */ -Node.prototype._setNetwork = function(config) { - if (config.network === 'testnet') { - this.network = Networks.get('testnet'); - } else if (config.network === 'regtest') { +Node.prototype._setNetwork = function (config) { + if (config.network === "testnet") { + this.network = Networks.get("testnet"); + } else if (config.network === "regtest") { Networks.enableRegtest(); - this.network = Networks.get('regtest'); + this.network = Networks.get("regtest"); } else { this.network = Networks.defaultNetwork; } - $.checkState(this.network, 'Unrecognized network'); + $.checkState(this.network, "Unrecognized network"); }; /** * Will instantiate a new Bus for this node. * @returns {Bus} */ -Node.prototype.openBus = function(options) { +Node.prototype.openBus = function (options) { if (!options) { options = {}; } - return new Bus({node: this, remoteAddress: options.remoteAddress}); + return new Bus({ node: this, remoteAddress: options.remoteAddress }); }; /** * Will get an array of API method descriptions from all of the available services. * @returns {Array} */ -Node.prototype.getAllAPIMethods = function() { +Node.prototype.getAllAPIMethods = function () { var methods = []; - for(var i in this.services) { + for (var i in this.services) { var mod = this.services[i]; if (mod.getAPIMethods) { methods = methods.concat(mod.getAPIMethods()); @@ -113,7 +113,7 @@ Node.prototype.getAllAPIMethods = function() { * Will get an array of events from all of the available services. * @returns {Array} */ -Node.prototype.getAllPublishEvents = function() { +Node.prototype.getAllPublishEvents = function () { var events = []; for (var i in this.services) { var mod = this.services[i]; @@ -129,8 +129,7 @@ Node.prototype.getAllPublishEvents = function() { * based on the service's dependencies. * @returns {Array} */ -Node.prototype.getServiceOrder = function() { - +Node.prototype.getServiceOrder = function () { var services = this._unloadedServices; // organize data for sorting @@ -146,8 +145,7 @@ Node.prototype.getServiceOrder = function() { var stack = []; function addToStack(names) { - for(var i = 0; i < names.length; i++) { - + for (var i = 0; i < names.length; i++) { var name = names[i]; var service = servicesByName[name]; $.checkState(service, 'Required dependency "' + name + '" not available.'); @@ -156,11 +154,10 @@ Node.prototype.getServiceOrder = function() { addToStack(service.module.dependencies); // add to the stack if it hasn't been added - if(!stackNames[name]) { + if (!stackNames[name]) { stack.push(service); stackNames[name] = true; } - } } @@ -180,10 +177,10 @@ Node.prototype.getServiceOrder = function() { * @param {Function} callback - Called when the service is started * @private */ -Node.prototype._startService = function(serviceInfo, callback) { +Node.prototype._startService = function (serviceInfo, callback) { var self = this; - log.info('Starting ' + serviceInfo.name); // TODO: update service name in dashcore-node.json + log.info("Starting " + serviceInfo.name); // TODO: update service name in dashcore-node.json var config; if (serviceInfo.config) { @@ -202,7 +199,7 @@ Node.prototype._startService = function(serviceInfo, callback) { // include in loaded services self.services[serviceInfo.name] = service; - service.start(function(err) { + service.start(function (err) { if (err) { return callback(err); } @@ -211,7 +208,7 @@ Node.prototype._startService = function(serviceInfo, callback) { if (service.getAPIMethods) { var methodData = service.getAPIMethods(); var methodNameConflicts = []; - methodData.forEach(function(data) { + methodData.forEach(function (data) { var name = data[0]; var instance = data[1]; var method = data[2]; @@ -219,36 +216,33 @@ Node.prototype._startService = function(serviceInfo, callback) { if (self[name]) { methodNameConflicts.push(name); } else { - self[name] = function() { + self[name] = function () { return method.apply(instance, arguments); }; } }); if (methodNameConflicts.length > 0) { - return callback(new Error('Existing API method(s) exists: ' + methodNameConflicts.join(', '))); + return callback(new Error("Existing API method(s) exists: " + methodNameConflicts.join(", "))); } } callback(); - }); - }; -Node.prototype._logTitle = function() { +Node.prototype._logTitle = function () { if (this.configPath) { - log.info('Using config:', this.configPath); - log.info('Using network:', this.getNetworkName()); + log.info("Using config:", this.configPath); + log.info("Using network:", this.getNetworkName()); } }; - /** * Will start all running services in the order based on the dependency chain. * @param {Function} callback - Called when all services are started */ -Node.prototype.start = function(callback) { +Node.prototype.start = function (callback) { var self = this; var servicesOrder = this.getServiceOrder(); @@ -256,23 +250,23 @@ Node.prototype.start = function(callback) { async.eachSeries( servicesOrder, - function(service, next) { + function (service, next) { self._startService(service, next); }, - function(err) { + function (err) { if (err) { return callback(err); } - self.emit('ready'); + self.emit("ready"); callback(); } ); }; -Node.prototype.getNetworkName = function() { +Node.prototype.getNetworkName = function () { var network = this.network.name; if (this.network.regtestEnabled) { - network = 'regtest'; + network = "regtest"; } return network; }; @@ -282,22 +276,22 @@ Node.prototype.getNetworkName = function() { * were initially started. * @param {Function} callback - Called when all services are stopped */ -Node.prototype.stop = function(callback) { - log.info('Beginning shutdown'); +Node.prototype.stop = function (callback) { + log.info("Beginning shutdown"); var self = this; var services = this.getServiceOrder().reverse(); this.stopping = true; - this.emit('stopping'); + this.emit("stopping"); async.eachSeries( services, - function(service, next) { + function (service, next) { if (self.services[service.name]) { - log.info('Stopping ' + service.name); // TODO: update service name in dashcore-node.json + log.info("Stopping " + service.name); // TODO: update service name in dashcore-node.json self.services[service.name].stop(next); } else { - log.info('Stopping ' + service.name + ' (not started)'); // TODO: update service name in dashcore-node.json + log.info("Stopping " + service.name + " (not started)"); // TODO: update service name in dashcore-node.json setImmediate(next); } }, diff --git a/lib/scaffold/add.js b/lib/scaffold/add.js index fd8473913..e1a88075b 100644 --- a/lib/scaffold/add.js +++ b/lib/scaffold/add.js @@ -1,11 +1,11 @@ -'use strict'; +"use strict"; -var async = require('async'); -var fs = require('fs'); -var path = require('path'); -var spawn = require('child_process').spawn; -var dashcore = require('@dashevo/dashcore-lib'); -var utils = require('../utils'); +var async = require("async"); +var fs = require("fs"); +var path = require("path"); +var spawn = require("child_process").spawn; +var dashcore = require("@dashevo/dashcore-lib"); +var utils = require("../utils"); var $ = dashcore.util.preconditions; var _ = dashcore.deps._; @@ -15,19 +15,16 @@ var _ = dashcore.deps._; * @param {Function} done */ function addConfig(configFilePath, service, done) { - $.checkState(utils.isAbsolutePath(configFilePath), 'An absolute path is expected'); - fs.readFile(configFilePath, function(err, data) { + $.checkState(utils.isAbsolutePath(configFilePath), "An absolute path is expected"); + fs.readFile(configFilePath, function (err, data) { if (err) { return done(err); } var config = JSON.parse(data); - $.checkState( - Array.isArray(config.services), - 'Configuration file is expected to have a services array.' - ); + $.checkState(Array.isArray(config.services), "Configuration file is expected to have a services array."); config.services.push(service); config.services = _.uniq(config.services); - config.services.sort(function(a, b) { + config.services.sort(function (a, b) { return a > b; }); fs.writeFile(configFilePath, JSON.stringify(config, null, 2), done); @@ -40,20 +37,20 @@ function addConfig(configFilePath, service, done) { * @param {Function} done */ function addService(configDir, service, done) { - $.checkState(utils.isAbsolutePath(configDir), 'An absolute path is expected'); - var npm = spawn('npm', ['install', service, '--save'], {cwd: configDir}); + $.checkState(utils.isAbsolutePath(configDir), "An absolute path is expected"); + var npm = spawn("npm", ["install", service, "--save"], { cwd: configDir }); - npm.stdout.on('data', function(data) { + npm.stdout.on("data", function (data) { process.stdout.write(data); }); - npm.stderr.on('data', function(data) { + npm.stderr.on("data", function (data) { process.stderr.write(data); }); - npm.on('close', function(code) { + npm.on("close", function (code) { if (code !== 0) { - return done(new Error('There was an error installing service: ' + service)); + return done(new Error("There was an error installing service: " + service)); } else { return done(); } @@ -69,31 +66,26 @@ function addService(configDir, service, done) { function add(options, done) { $.checkArgument(_.isObject(options)); $.checkArgument(_.isFunction(done)); - $.checkArgument( - _.isString(options.path) && utils.isAbsolutePath(options.path), - 'An absolute path is expected' - ); + $.checkArgument(_.isString(options.path) && utils.isAbsolutePath(options.path), "An absolute path is expected"); $.checkArgument(Array.isArray(options.services)); var configPath = options.path; var services = options.services; - var dashcoreConfigPath = path.resolve(configPath, 'dashcore-node.json'); - var packagePath = path.resolve(configPath, 'package.json'); + var dashcoreConfigPath = path.resolve(configPath, "dashcore-node.json"); + var packagePath = path.resolve(configPath, "package.json"); if (!fs.existsSync(dashcoreConfigPath) || !fs.existsSync(packagePath)) { - return done( - new Error('Directory does not have a dashcore-node.json and/or package.json file.') - ); + return done(new Error("Directory does not have a dashcore-node.json and/or package.json file.")); } var oldPackage = JSON.parse(fs.readFileSync(packagePath)); async.eachSeries( services, - function(service, next) { + function (service, next) { // npm install --save - addService(configPath, service, function(err) { + addService(configPath, service, function (err) { if (err) { return next(err); } @@ -111,7 +103,8 @@ function add(options, done) { // add service to dashcore-node.json addConfig(dashcoreConfigPath, serviceName, next); }); - }, done + }, + done ); } diff --git a/lib/scaffold/call-method.js b/lib/scaffold/call-method.js index b5ca9ad66..6125d70ae 100644 --- a/lib/scaffold/call-method.js +++ b/lib/scaffold/call-method.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -var socketClient = require('socket.io-client'); +var socketClient = require("socket.io-client"); /** * Calls a remote node with a method and params @@ -10,34 +10,35 @@ var socketClient = require('socket.io-client'); * @param {Function} done - The callback function */ function callMethod(options, method, params, done) { - var host = options.host; var protocol = options.protocol; var port = options.port; - var url = protocol + '://' + host + ':' + port; + var url = protocol + "://" + host + ":" + port; var socketOptions = { reconnection: false, - connect_timeout: 5000 + connect_timeout: 5000, }; var socket = socketClient(url, socketOptions); - socket.on('connect', function(){ - socket.send({ - method: method, - params: params, - }, function(response) { - if (response.error) { - return done(new Error(response.error.message)); + socket.on("connect", function () { + socket.send( + { + method: method, + params: params, + }, + function (response) { + if (response.error) { + return done(new Error(response.error.message)); + } + socket.close(); + done(null, response.result); } - socket.close(); - done(null, response.result); - }); + ); }); - socket.on('connect_error', done); + socket.on("connect_error", done); return socket; - } module.exports = callMethod; diff --git a/lib/scaffold/create.js b/lib/scaffold/create.js index 936235d48..117ab14a5 100644 --- a/lib/scaffold/create.js +++ b/lib/scaffold/create.js @@ -1,26 +1,26 @@ -'use strict'; +"use strict"; -var spawn = require('child_process').spawn; -var dashcore = require('@dashevo/dashcore-lib'); -var async = require('async'); +var spawn = require("child_process").spawn; +var dashcore = require("@dashevo/dashcore-lib"); +var async = require("async"); var $ = dashcore.util.preconditions; var _ = dashcore.deps._; -var path = require('path'); -var packageFile = require('../../package.json'); -var fs = require('fs'); -var defaultBaseConfig = require('./default-base-config'); +var path = require("path"); +var packageFile = require("../../package.json"); +var fs = require("fs"); +var defaultBaseConfig = require("./default-base-config"); -var version = '^' + packageFile.version; +var version = "^" + packageFile.version; var BASE_PACKAGE = { - description: 'A full Dash node build with Dashcore', - repository: 'https://github.com/user/project', - license: 'MIT', - readme: 'README.md', + description: "A full Dash node build with Dashcore", + repository: "https://github.com/user/project", + license: "MIT", + readme: "README.md", dependencies: { - '@dashevo/dashcore-lib': '^' + dashcore.version, - '@dashevo/dashcore-node': version - } + "@dashevo/dashcore-lib": "^" + dashcore.version, + "@dashevo/dashcore-node": version, + }, }; /** @@ -29,7 +29,7 @@ var BASE_PACKAGE = { * @param {Function} done - The callback function called when finished */ function createDashDirectory(datadir, done) { - fs.mkdir(datadir, { recursive: true }, function(err) { + fs.mkdir(datadir, { recursive: true }, function (err) { if (err) { throw err; } @@ -50,7 +50,7 @@ function createDashDirectory(datadir, done) { * @param {Function} done - The callback function called when finished */ function createConfigDirectory(options, configDir, isGlobal, done) { - fs.mkdir(configDir, { recursive: true }, function(err) { + fs.mkdir(configDir, { recursive: true }, function (err) { if (err) { throw err; } @@ -60,15 +60,14 @@ function createConfigDirectory(options, configDir, isGlobal, done) { var configJSON = JSON.stringify(config, null, 2); var packageJSON = JSON.stringify(BASE_PACKAGE, null, 2); try { - fs.writeFileSync(configDir + '/dashcore-node.json', configJSON); + fs.writeFileSync(configDir + "/dashcore-node.json", configJSON); if (!isGlobal) { - fs.writeFileSync(configDir + '/package.json', packageJSON); + fs.writeFileSync(configDir + "/package.json", packageJSON); } - } catch(e) { + } catch (e) { done(e); } done(); - }); } @@ -100,54 +99,55 @@ function create(options, done) { var absConfigDir = path.resolve(cwd, dirname); var absDataDir = path.resolve(absConfigDir, datadir); - async.series([ - function(next) { - // Setup the the dashcore-node directory and configuration - if (!fs.existsSync(absConfigDir)) { - var createOptions = { - network: options.network, - datadir: datadir - }; - createConfigDirectory(createOptions, absConfigDir, isGlobal, next); - } else { - next(new Error('Directory "' + absConfigDir+ '" already exists.')); - } - }, - function(next) { - // Setup the Dash directory and configuration - if (!fs.existsSync(absDataDir)) { - createDashDirectory(absDataDir, next); - } else { - next(); - } - }, - function(next) { - // Install all of the necessary dependencies - if (!isGlobal) { - var npm = spawn('npm', ['install'], {cwd: absConfigDir}); - - npm.stdout.on('data', function (data) { - process.stdout.write(data); - }); - - npm.stderr.on('data', function (data) { - process.stderr.write(data); - }); - - npm.on('close', function (code) { - if (code !== 0) { - return next(new Error('There was an error installing dependencies.')); - } else { - return next(); - } - }); - - } else { - next(); - } - } - ], done); - + async.series( + [ + function (next) { + // Setup the the dashcore-node directory and configuration + if (!fs.existsSync(absConfigDir)) { + var createOptions = { + network: options.network, + datadir: datadir, + }; + createConfigDirectory(createOptions, absConfigDir, isGlobal, next); + } else { + next(new Error('Directory "' + absConfigDir + '" already exists.')); + } + }, + function (next) { + // Setup the Dash directory and configuration + if (!fs.existsSync(absDataDir)) { + createDashDirectory(absDataDir, next); + } else { + next(); + } + }, + function (next) { + // Install all of the necessary dependencies + if (!isGlobal) { + var npm = spawn("npm", ["install"], { cwd: absConfigDir }); + + npm.stdout.on("data", function (data) { + process.stdout.write(data); + }); + + npm.stderr.on("data", function (data) { + process.stderr.write(data); + }); + + npm.on("close", function (code) { + if (code !== 0) { + return next(new Error("There was an error installing dependencies.")); + } else { + return next(); + } + }); + } else { + next(); + } + }, + ], + done + ); } module.exports = create; diff --git a/lib/scaffold/default-base-config.js b/lib/scaffold/default-base-config.js index 96004e38c..001043c79 100644 --- a/lib/scaffold/default-base-config.js +++ b/lib/scaffold/default-base-config.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -var path = require('path'); +var path = require("path"); /** * Will return the path and default dashcore-node configuration on environment variables @@ -14,23 +14,23 @@ function getDefaultBaseConfig(options) { options = {}; } - var datadir = options.datadir || path.resolve(process.env.HOME, '.dash'); + var datadir = options.datadir || path.resolve(process.env.HOME, ".dash"); return { path: process.cwd(), config: { - network: options.network || 'livenet', + network: options.network || "livenet", port: 3001, - services: ['dashd', 'web'], + services: ["dashd", "web"], servicesConfig: { dashd: { spawn: { datadir: datadir, - exec: path.resolve(__dirname, datadir, 'dashd') - } - } - } - } + exec: path.resolve(__dirname, datadir, "dashd"), + }, + }, + }, + }, }; } diff --git a/lib/scaffold/default-config.js b/lib/scaffold/default-config.js index 1b4757371..968b18735 100644 --- a/lib/scaffold/default-config.js +++ b/lib/scaffold/default-config.js @@ -1,7 +1,7 @@ -'use strict'; +"use strict"; -var path = require('path'); -var fs = require('fs'); +var path = require("path"); +var fs = require("fs"); /** * Will return the path and default dashcore-node configuration. It will search for the @@ -16,52 +16,52 @@ function getDefaultConfig(options) { options = {}; } - var defaultPath = path.resolve(process.env.HOME, './.dashcore'); - var defaultConfigFile = path.resolve(defaultPath, './dashcore-node.json'); + var defaultPath = path.resolve(process.env.HOME, "./.dashcore"); + var defaultConfigFile = path.resolve(defaultPath, "./dashcore-node.json"); if (!fs.existsSync(defaultPath)) { fs.mkdirSync(defaultPath, { recursive: true }); } - var defaultServices = ['dashd', 'web']; + var defaultServices = ["dashd", "web"]; if (options.additionalServices) { defaultServices = defaultServices.concat(options.additionalServices); } if (!fs.existsSync(defaultConfigFile)) { - var defaultConfig = { - network: 'livenet', + network: "livenet", port: 3001, services: defaultServices, servicesConfig: { dashd: { - connect: [{ - rpchost: '127.0.0.1', - rpcport: 9998, - rpcuser: 'dash', - rpcpassword: 'local321', - zmqpubrawtx: 'tcp://127.0.0.1:28332' - }] - } - } + connect: [ + { + rpchost: "127.0.0.1", + rpcport: 9998, + rpcuser: "dash", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:28332", + }, + ], + }, + }, }; fs.writeFileSync(defaultConfigFile, JSON.stringify(defaultConfig, null, 2)); } - var defaultDataDir = path.resolve(defaultPath, './data'); + var defaultDataDir = path.resolve(defaultPath, "./data"); if (!fs.existsSync(defaultDataDir)) { fs.mkdirSync(defaultDataDir, { recursive: true }); } - var config = JSON.parse(fs.readFileSync(defaultConfigFile, 'utf-8')); + var config = JSON.parse(fs.readFileSync(defaultConfigFile, "utf-8")); return { path: defaultPath, - config: config + config: config, }; - } module.exports = getDefaultConfig; diff --git a/lib/scaffold/find-config.js b/lib/scaffold/find-config.js index 352f9aa46..0363d5582 100644 --- a/lib/scaffold/find-config.js +++ b/lib/scaffold/find-config.js @@ -1,29 +1,29 @@ -'use strict'; +"use strict"; -var dashcore = require('@dashevo/dashcore-lib'); +var dashcore = require("@dashevo/dashcore-lib"); var $ = dashcore.util.preconditions; var _ = dashcore.deps._; -var path = require('path'); -var fs = require('fs'); -var utils = require('../utils'); +var path = require("path"); +var fs = require("fs"); +var utils = require("../utils"); /** * Will return the path and dashcore-node configuration * @param {String} cwd - The absolute path to the current working directory */ function findConfig(cwd) { - $.checkArgument(_.isString(cwd), 'Argument should be a string'); - $.checkArgument(utils.isAbsolutePath(cwd), 'Argument should be an absolute path'); + $.checkArgument(_.isString(cwd), "Argument should be a string"); + $.checkArgument(utils.isAbsolutePath(cwd), "Argument should be an absolute path"); var directory = String(cwd); - while (!fs.existsSync(path.resolve(directory, 'dashcore-node.json'))) { - directory = path.resolve(directory, '../'); - if (directory === '/') { + while (!fs.existsSync(path.resolve(directory, "dashcore-node.json"))) { + directory = path.resolve(directory, "../"); + if (directory === "/") { return false; } } return { path: directory, - config: require(path.resolve(directory, 'dashcore-node.json')) + config: require(path.resolve(directory, "dashcore-node.json")), }; } diff --git a/lib/scaffold/remove.js b/lib/scaffold/remove.js index a872e7a81..eac6812f9 100644 --- a/lib/scaffold/remove.js +++ b/lib/scaffold/remove.js @@ -1,13 +1,13 @@ -'use strict'; +"use strict"; -var async = require('async'); -var fs = require('fs'); -var path = require('path'); -var spawn = require('child_process').spawn; -var dashcore = require('@dashevo/dashcore-lib'); +var async = require("async"); +var fs = require("fs"); +var path = require("path"); +var spawn = require("child_process").spawn; +var dashcore = require("@dashevo/dashcore-lib"); var $ = dashcore.util.preconditions; var _ = dashcore.deps._; -var utils = require('../utils'); +var utils = require("../utils"); /** * Will remove a service from dashcore-node.json @@ -16,16 +16,13 @@ var utils = require('../utils'); * @param {Function} done */ function removeConfig(configFilePath, service, done) { - $.checkArgument(utils.isAbsolutePath(configFilePath), 'An absolute path is expected'); - fs.readFile(configFilePath, function(err, data) { + $.checkArgument(utils.isAbsolutePath(configFilePath), "An absolute path is expected"); + fs.readFile(configFilePath, function (err, data) { if (err) { return done(err); } var config = JSON.parse(data); - $.checkState( - Array.isArray(config.services), - 'Configuration file is expected to have a services array.' - ); + $.checkState(Array.isArray(config.services), "Configuration file is expected to have a services array."); // remove the service from the configuration for (var i = 0; i < config.services.length; i++) { if (config.services[i] === service) { @@ -33,7 +30,7 @@ function removeConfig(configFilePath, service, done) { } } config.services = _.uniq(config.services); - config.services.sort(function(a, b) { + config.services.sort(function (a, b) { return a > b; }); fs.writeFile(configFilePath, JSON.stringify(config, null, 2), done); @@ -47,22 +44,22 @@ function removeConfig(configFilePath, service, done) { * @param {Function} done */ function uninstallService(configDir, service, done) { - $.checkArgument(utils.isAbsolutePath(configDir), 'An absolute path is expected'); - $.checkArgument(_.isString(service), 'A string is expected for the service argument'); + $.checkArgument(utils.isAbsolutePath(configDir), "An absolute path is expected"); + $.checkArgument(_.isString(service), "A string is expected for the service argument"); - var child = spawn('npm', ['uninstall', service, '--save'], {cwd: configDir}); + var child = spawn("npm", ["uninstall", service, "--save"], { cwd: configDir }); - child.stdout.on('data', function(data) { + child.stdout.on("data", function (data) { process.stdout.write(data); }); - child.stderr.on('data', function(data) { + child.stderr.on("data", function (data) { process.stderr.write(data); }); - child.on('close', function(code) { + child.on("close", function (code) { if (code !== 0) { - return done(new Error('There was an error uninstalling service(s): ' + service)); + return done(new Error("There was an error uninstalling service(s): " + service)); } else { return done(); } @@ -76,12 +73,10 @@ function uninstallService(configDir, service, done) { * @param {Function} done */ function removeService(configDir, service, done) { - $.checkArgument(utils.isAbsolutePath(configDir), 'An absolute path is expected'); - $.checkArgument(_.isString(service), 'A string is expected for the service argument'); + $.checkArgument(utils.isAbsolutePath(configDir), "An absolute path is expected"); + $.checkArgument(_.isString(service), "A string is expected for the service argument"); uninstallService(configDir, service, done); - - } /** @@ -94,36 +89,32 @@ function removeService(configDir, service, done) { function remove(options, done) { $.checkArgument(_.isObject(options)); $.checkArgument(_.isFunction(done)); - $.checkArgument( - _.isString(options.path) && utils.isAbsolutePath(options.path), - 'An absolute path is expected' - ); + $.checkArgument(_.isString(options.path) && utils.isAbsolutePath(options.path), "An absolute path is expected"); $.checkArgument(Array.isArray(options.services)); var configPath = options.path; var services = options.services; - var dashcoreConfigPath = path.resolve(configPath, 'dashcore-node.json'); - var packagePath = path.resolve(configPath, 'package.json'); + var dashcoreConfigPath = path.resolve(configPath, "dashcore-node.json"); + var packagePath = path.resolve(configPath, "package.json"); if (!fs.existsSync(dashcoreConfigPath) || !fs.existsSync(packagePath)) { - return done( - new Error('Directory does not have a dashcore-node.json and/or package.json file.') - ); + return done(new Error("Directory does not have a dashcore-node.json and/or package.json file.")); } async.eachSeries( services, - function(service, next) { + function (service, next) { // if the service is installed remove it - removeService(configPath, service, function(err) { + removeService(configPath, service, function (err) { if (err) { return next(err); } // remove service to dashcore-node.json removeConfig(dashcoreConfigPath, service, next); }); - }, done + }, + done ); } diff --git a/lib/scaffold/start.js b/lib/scaffold/start.js index 9ac4bd144..7f7f42282 100644 --- a/lib/scaffold/start.js +++ b/lib/scaffold/start.js @@ -1,14 +1,14 @@ -'use strict'; +"use strict"; -var path = require('path'); -var DashcoreNode = require('../node'); -var index = require('../'); -var dashcore = require('@dashevo/dashcore-lib'); +var path = require("path"); +var DashcoreNode = require("../node"); +var index = require("../"); +var dashcore = require("@dashevo/dashcore-lib"); var _ = dashcore.deps._; var log = index.log; var shuttingDown = false; -log.debug = function() {}; +log.debug = function () {}; /** * Checks for configuration options from version 2. This includes an "address" and @@ -16,34 +16,35 @@ log.debug = function() {}; */ function checkConfigVersion2(fullConfig) { var datadirUndefined = _.isUndefined(fullConfig.datadir); - var addressDefined = (fullConfig.services.indexOf('address') >= 0); - var dbDefined = (fullConfig.services.indexOf('db') >= 0); + var addressDefined = fullConfig.services.indexOf("address") >= 0; + var dbDefined = fullConfig.services.indexOf("db") >= 0; if (!datadirUndefined || addressDefined || dbDefined) { - - console.warn('\nConfiguration file is not compatible with this version. \n' + - 'A reindex for dashd is necessary for this upgrade with the "reindex=1" dash.conf option. \n' + - 'There are changes necessary in both dash.conf and dashcore-node.json. \n\n' + - 'To upgrade please see the details below and documentation at: \n' + - 'https://github.com/dashevo/dashcore-node/blob/dashd/docs/upgrade.md \n'); + console.warn( + "\nConfiguration file is not compatible with this version. \n" + + 'A reindex for dashd is necessary for this upgrade with the "reindex=1" dash.conf option. \n' + + "There are changes necessary in both dash.conf and dashcore-node.json. \n\n" + + "To upgrade please see the details below and documentation at: \n" + + "https://github.com/dashevo/dashcore-node/blob/dashd/docs/upgrade.md \n" + ); if (!datadirUndefined) { - console.warn('Please remove "datadir" and add it to the config at ' + fullConfig.path + ' with:'); + console.warn('Please remove "datadir" and add it to the config at ' + fullConfig.path + " with:"); var missingConfig = { servicesConfig: { dashd: { spawn: { datadir: fullConfig.datadir, - exec: path.resolve(__dirname, '../../bin/dashd') - } - } - } + exec: path.resolve(__dirname, "../../bin/dashd"), + }, + }, + }, }; - console.warn(JSON.stringify(missingConfig, null, 2) + '\n'); + console.warn(JSON.stringify(missingConfig, null, 2) + "\n"); } if (addressDefined || dbDefined) { - console.warn('Please remove "address" and/or "db" from "services" in: ' + fullConfig.path + '\n'); + console.warn('Please remove "address" and/or "db" from "services" in: ' + fullConfig.path + "\n"); } return true; @@ -76,7 +77,7 @@ function start(options) { servicesPath = options.path; // defaults to the same directory } - fullConfig.path = path.resolve(options.path, './dashcore-node.json'); + fullConfig.path = path.resolve(options.path, "./dashcore-node.json"); if (checkConfigVersion2(fullConfig)) { process.exit(1); @@ -89,17 +90,17 @@ function start(options) { // setup handlers for uncaught exceptions and ctrl+c start.registerExitHandlers(process, node); - node.on('ready', function() { - log.info('Dashcore Node ready'); + node.on("ready", function () { + log.info("Dashcore Node ready"); }); - node.on('error', function(err) { + node.on("error", function (err) { log.error(err); }); - node.start(function(err) { - if(err) { - log.error('Failed to start services'); + node.start(function (err) { + if (err) { + log.error("Failed to start services"); if (err.stack) { log.error(err.stack); } @@ -108,7 +109,6 @@ function start(options) { }); return node; - } /** @@ -117,10 +117,12 @@ function start(options) { */ function checkService(service) { // check that the service supports expected methods - if (!service.module.prototype || - !service.module.dependencies || - !service.module.prototype.start || - !service.module.prototype.stop) { + if ( + !service.module.prototype || + !service.module.dependencies || + !service.module.prototype.start || + !service.module.prototype.stop + ) { throw new Error( 'Could not load service "' + service.name + '" as it does not support necessary methods and properties.' ); @@ -136,14 +138,13 @@ function checkService(service) { function loadModule(req, service) { try { // first try in the built-in dashcore-node services directory - service.module = req(path.resolve(__dirname, '../services/' + service.name)); - } catch(e) { - + service.module = req(path.resolve(__dirname, "../services/" + service.name)); + } catch (e) { // check if the package.json specifies a specific file to use - var servicePackage = req(service.name + '/package.json'); + var servicePackage = req(service.name + "/package.json"); var serviceModule = service.name; if (servicePackage.dashcoreNode) { - serviceModule = service.name + '/' + servicePackage.dashcoreNode; + serviceModule = service.name + "/" + servicePackage.dashcoreNode; } service.module = req(serviceModule); } @@ -166,8 +167,7 @@ function loadModule(req, service) { * @returns {Array} */ function setupServices(req, servicesPath, config) { - - module.paths.push(path.resolve(servicesPath, './node_modules')); + module.paths.push(path.resolve(servicesPath, "./node_modules")); var services = []; if (config.services) { @@ -193,12 +193,12 @@ function setupServices(req, servicesPath, config) { * @param {Node} node - The Dashcore Node instance */ function cleanShutdown(_process, node) { - node.stop(function(err) { - if(err) { - log.error('Failed to stop services: ' + err); + node.stop(function (err) { + if (err) { + log.error("Failed to stop services: " + err); return _process.exit(1); } - log.info('Halted'); + log.info("Halted"); _process.exit(0); }); } @@ -211,16 +211,16 @@ function cleanShutdown(_process, node) { * @param {Object} _process - The Node.js process * @param {Node} node * @param {Error} error -*/ + */ function exitHandler(options, _process, node, err) { if (err) { - log.error('uncaught exception:', err); - if(err.stack) { + log.error("uncaught exception:", err); + if (err.stack) { log.error(err.stack); } - node.stop(function(err) { - if(err) { - log.error('Failed to stop services: ' + err); + node.stop(function (err) { + if (err) { + log.error("Failed to stop services: " + err); } _process.exit(-1); }); @@ -241,10 +241,10 @@ function exitHandler(options, _process, node, err) { */ function registerExitHandlers(_process, node) { //catches uncaught exceptions - _process.on('uncaughtException', exitHandler.bind(null, {exit:true}, _process, node)); + _process.on("uncaughtException", exitHandler.bind(null, { exit: true }, _process, node)); //catches ctrl+c event - _process.on('SIGINT', exitHandler.bind(null, {sigint:true}, _process, node)); + _process.on("SIGINT", exitHandler.bind(null, { sigint: true }, _process, node)); } module.exports = start; diff --git a/lib/service.js b/lib/service.js index cb3133fea..05b288a12 100644 --- a/lib/service.js +++ b/lib/service.js @@ -1,9 +1,9 @@ -'use strict'; +"use strict"; -var util = require('util'); -var EventEmitter = require('events').EventEmitter; +var util = require("util"); +var EventEmitter = require("events").EventEmitter; -var Service = function(options) { +var Service = function (options) { EventEmitter.call(this); this.node = options.node; @@ -23,9 +23,9 @@ Service.dependencies = []; * @param {Boolean} add - whether the block is being added or removed * @param {Function} callback - call with the leveldb database operations to perform */ -Service.prototype.blockHandler = function(block, add, callback) { +Service.prototype.blockHandler = function (block, add, callback) { // implement in the child class - setImmediate(function() { + setImmediate(function () { callback(null, []); }); }; @@ -34,7 +34,7 @@ Service.prototype.blockHandler = function(block, add, callback) { * the bus events available for subscription * @return {Array} an array of event info */ -Service.prototype.getPublishEvents = function() { +Service.prototype.getPublishEvents = function () { // Example: // return [ // ['eventname', this, this.subscribeEvent, this.unsubscribeEvent], @@ -46,7 +46,7 @@ Service.prototype.getPublishEvents = function() { * the API methods to expose * @return {Array} return array of methods */ -Service.prototype.getAPIMethods = function() { +Service.prototype.getAPIMethods = function () { // Example: // return [ // ['getData', this, this.getData, 1] @@ -63,14 +63,14 @@ Service.prototype.getAPIMethods = function() { /** * Function which is called when module is first initialized */ -Service.prototype.start = function(done) { +Service.prototype.start = function (done) { setImmediate(done); }; /** * Function to be called when dashcore-node is stopped */ -Service.prototype.stop = function(done) { +Service.prototype.stop = function (done) { setImmediate(done); }; @@ -78,11 +78,11 @@ Service.prototype.stop = function(done) { * Setup express routes * @param {Express} app */ -Service.prototype.setupRoutes = function() { +Service.prototype.setupRoutes = function () { // Setup express routes here }; -Service.prototype.getRoutePrefix = function() { +Service.prototype.getRoutePrefix = function () { return this.name; }; diff --git a/lib/services/dashd.js b/lib/services/dashd.js index 01ca4ca35..c1581765d 100644 --- a/lib/services/dashd.js +++ b/lib/services/dashd.js @@ -1,26 +1,26 @@ -'use strict'; - -var fs = require('fs'); -var path = require('path'); -var spawn = require('child_process').spawn; -var util = require('util'); -var dashcore = require('@dashevo/dashcore-lib'); -var zmq = require('zeromq'); -var async = require('async'); -var LRU = require('lru-cache'); -var DashdRPC = require('@dashevo/dashd-rpc'); +"use strict"; + +var fs = require("fs"); +var path = require("path"); +var spawn = require("child_process").spawn; +var util = require("util"); +var dashcore = require("@dashevo/dashcore-lib"); +var zmq = require("zeromq"); +var async = require("async"); +var LRU = require("lru-cache"); +var DashdRPC = require("@dashevo/dashd-rpc"); var $ = dashcore.util.preconditions; -var _ = dashcore.deps._; +var _ = dashcore.deps._; var Transaction = dashcore.Transaction; var Proposal = dashcore.GovObject.Proposal; -var index = require('../'); +var index = require("../"); var errors = index.errors; var log = index.log; -var utils = require('../utils'); -var Service = require('../service'); -var rawtxTopicBuffer = new Buffer('7261777478', 'hex'); -var rawtxlockTopicBuffer = new Buffer('72617774786c6f636b', 'hex'); +var utils = require("../utils"); +var Service = require("../service"); +var rawtxTopicBuffer = new Buffer("7261777478", "hex"); +var rawtxlockTopicBuffer = new Buffer("72617774786c6f636b", "hex"); function isNonFatalError(err) { if (err.code === Dash.E_RPC_IN_WARMUP) { @@ -70,7 +70,7 @@ function Dash(options) { // for testing purposes this._process = options.process || process; - this.on('error', function(err) { + this.on("error", function (err) { log.error(err.stack); }); } @@ -95,22 +95,22 @@ Dash.DEFAULT_TRANSACTION_CONCURRENCY = 5; Dash.DEFAULT_INSTANTSEND_FEE = 10000; Dash.DEFAULT_CONFIG_SETTINGS = { server: 1, - whitelist: '127.0.0.1', + whitelist: "127.0.0.1", txindex: 1, addressindex: 1, timestampindex: 1, spentindex: 1, - zmqpubrawtx: 'tcp://127.0.0.1:28332', - zmqpubrawtxlock: 'tcp://127.0.0.1:28332', - zmqpubhashblock: 'tcp://127.0.0.1:28332', - rpcallowip: '127.0.0.1', - rpcuser: 'dash', - rpcpassword: 'local321', - uacomment: 'dashcore' + zmqpubrawtx: "tcp://127.0.0.1:28332", + zmqpubrawtxlock: "tcp://127.0.0.1:28332", + zmqpubhashblock: "tcp://127.0.0.1:28332", + rpcallowip: "127.0.0.1", + rpcuser: "dash", + rpcpassword: "local321", + uacomment: "dashcore", }; Dash.E_RPC_IN_WARMUP = -28; -Dash.prototype._initDefaults = function(options) { +Dash.prototype._initDefaults = function (options) { /* jshint maxcomplexity: 15 */ // limits @@ -136,30 +136,29 @@ Dash.prototype._initDefaults = function(options) { this.zmqSubscribeProgress = options.zmqSubscribeProgress || Dash.DEFAULT_ZMQ_SUBSCRIBE_PROGRESS; }; -Dash.prototype._initCaches = function() { - +Dash.prototype._initCaches = function () { var CACHES = [ - {name:'utxos', lru:50000}, - {name:'txids', lru:50000}, - {name:'balance', lru:50000}, - {name:'summary', lru:50000}, - {name:'blockOverview', lru:144}, - {name:'transactionDetailed', lru:100000}, - {name:'masternodeList', lru:50000}, - {name:'sporksList', lru:50}, + { name: "utxos", lru: 50000 }, + { name: "txids", lru: 50000 }, + { name: "balance", lru: 50000 }, + { name: "summary", lru: 50000 }, + { name: "blockOverview", lru: 144 }, + { name: "transactionDetailed", lru: 100000 }, + { name: "masternodeList", lru: 50000 }, + { name: "sporksList", lru: 50 }, //governance - {name:'gov', lru:20}, + { name: "gov", lru: 20 }, //cache valid indefinitely - {name:'transaction', lru:100000}, - {name:'rawTransaction', lru:50000}, - {name:'block', lru:144}, - {name:'rawBlock', lru:72}, - {name:'blockHeader', lru:288} + { name: "transaction", lru: 100000 }, + { name: "rawTransaction", lru: 50000 }, + { name: "block", lru: 144 }, + { name: "rawBlock", lru: 72 }, + { name: "blockHeader", lru: 288 }, ]; var self = this; CACHES.forEach(function (el) { - self[el.name+'Cache']=LRU(el.lru); + self[el.name + "Cache"] = LRU(el.lru); }); // caches valid until there is a new block @@ -168,54 +167,53 @@ Dash.prototype._initCaches = function() { this.zmqKnownBlocks = LRU(50); this.lastTip = 0; this.lastTipTimeout = false; - }; -Dash.prototype._initClients = function() { +Dash.prototype._initClients = function () { var self = this; this.nodes = []; this.nodesIndex = 0; - Object.defineProperty(this, 'client', { - get: function() { + Object.defineProperty(this, "client", { + get: function () { var client = self.nodes[self.nodesIndex].client; self.nodesIndex = (self.nodesIndex + 1) % self.nodes.length; return client; }, enumerable: true, - configurable: false + configurable: false, }); }; /** * Called by Node to determine the available API methods. */ -Dash.prototype.getAPIMethods = function() { +Dash.prototype.getAPIMethods = function () { var methods = [ - ['getBlock', this, this.getBlock, 1], - ['getRawBlock', this, this.getRawBlock, 1], - ['getBlockHeader', this, this.getBlockHeader, 1], - ['getBlockHeaders', this, this.getBlockHeaders, 1], - ['getBlockOverview', this, this.getBlockOverview, 1], - ['getBlockHashesByTimestamp', this, this.getBlockHashesByTimestamp, 2], - ['getBestBlockHash', this, this.getBestBlockHash, 0], - ['getBestChainLock', this, this.getBestChainLock, 0], - ['getSpentInfo', this, this.getSpentInfo, 1], - ['getMNList', this, this.getMNList, 1], - ['getInfo', this, this.getInfo, 0], - ['syncPercentage', this, this.syncPercentage, 0], - ['isSynced', this, this.isSynced, 0], - ['getRawTransaction', this, this.getRawTransaction, 1], - ['getTransaction', this, this.getTransaction, 1], - ['getDetailedTransaction', this, this.getDetailedTransaction, 1], - ['sendTransaction', this, this.sendTransaction, 1], - ['estimateFee', this, this.estimateFee, 1], - ['getAddressTxids', this, this.getAddressTxids, 2], - ['getAddressBalance', this, this.getAddressBalance, 2], - ['getAddressUnspentOutputs', this, this.getAddressUnspentOutputs, 2], - ['getAddressUnspentOutputsPaginated', this, this.getAddressUnspentOutputsPaginated, 2], - ['getAddressHistory', this, this.getAddressHistory, 2], - ['getAddressSummary', this, this.getAddressSummary, 1], - ['generateBlock', this, this.generateBlock, 1] + ["getBlock", this, this.getBlock, 1], + ["getRawBlock", this, this.getRawBlock, 1], + ["getBlockHeader", this, this.getBlockHeader, 1], + ["getBlockHeaders", this, this.getBlockHeaders, 1], + ["getBlockOverview", this, this.getBlockOverview, 1], + ["getBlockHashesByTimestamp", this, this.getBlockHashesByTimestamp, 2], + ["getBestBlockHash", this, this.getBestBlockHash, 0], + ["getBestChainLock", this, this.getBestChainLock, 0], + ["getSpentInfo", this, this.getSpentInfo, 1], + ["getMNList", this, this.getMNList, 1], + ["getInfo", this, this.getInfo, 0], + ["syncPercentage", this, this.syncPercentage, 0], + ["isSynced", this, this.isSynced, 0], + ["getRawTransaction", this, this.getRawTransaction, 1], + ["getTransaction", this, this.getTransaction, 1], + ["getDetailedTransaction", this, this.getDetailedTransaction, 1], + ["sendTransaction", this, this.sendTransaction, 1], + ["estimateFee", this, this.estimateFee, 1], + ["getAddressTxids", this, this.getAddressTxids, 2], + ["getAddressBalance", this, this.getAddressBalance, 2], + ["getAddressUnspentOutputs", this, this.getAddressUnspentOutputs, 2], + ["getAddressUnspentOutputsPaginated", this, this.getAddressUnspentOutputsPaginated, 2], + ["getAddressHistory", this, this.getAddressHistory, 2], + ["getAddressSummary", this, this.getAddressSummary, 1], + ["generateBlock", this, this.generateBlock, 1], ]; return methods; }; @@ -223,53 +221,53 @@ Dash.prototype.getAPIMethods = function() { /** * Called by the Bus to determine the available events. */ -Dash.prototype.getPublishEvents = function() { +Dash.prototype.getPublishEvents = function () { return [ { - name: 'dashd/rawtransaction', + name: "dashd/rawtransaction", scope: this, - subscribe: this.subscribe.bind(this, 'rawtransaction'), - unsubscribe: this.unsubscribe.bind(this, 'rawtransaction') + subscribe: this.subscribe.bind(this, "rawtransaction"), + unsubscribe: this.unsubscribe.bind(this, "rawtransaction"), }, { - name: 'dashd/transactionlock', + name: "dashd/transactionlock", scope: this, - subscribe: this.subscribe.bind(this, 'transactionlock'), - unsubscribe: this.unsubscribe.bind(this, 'transactionlock') + subscribe: this.subscribe.bind(this, "transactionlock"), + unsubscribe: this.unsubscribe.bind(this, "transactionlock"), }, { - name: 'dashd/hashblock', + name: "dashd/hashblock", scope: this, - subscribe: this.subscribe.bind(this, 'hashblock'), - unsubscribe: this.unsubscribe.bind(this, 'hashblock') + subscribe: this.subscribe.bind(this, "hashblock"), + unsubscribe: this.unsubscribe.bind(this, "hashblock"), }, { - name: 'dashd/addresstxid', + name: "dashd/addresstxid", scope: this, subscribe: this.subscribeAddress.bind(this), - unsubscribe: this.unsubscribeAddress.bind(this) - } + unsubscribe: this.unsubscribeAddress.bind(this), + }, ]; }; -Dash.prototype.subscribe = function(name, emitter) { +Dash.prototype.subscribe = function (name, emitter) { this.subscriptions[name].push(emitter); - log.info(emitter.remoteAddress, 'subscribe:', 'dashd/' + name, 'total:', this.subscriptions[name].length); + log.info(emitter.remoteAddress, "subscribe:", "dashd/" + name, "total:", this.subscriptions[name].length); }; -Dash.prototype.unsubscribe = function(name, emitter) { +Dash.prototype.unsubscribe = function (name, emitter) { var index = this.subscriptions[name].indexOf(emitter); if (index > -1) { this.subscriptions[name].splice(index, 1); } - log.info(emitter.remoteAddress, 'unsubscribe:', 'dashd/' + name, 'total:', this.subscriptions[name].length); + log.info(emitter.remoteAddress, "unsubscribe:", "dashd/" + name, "total:", this.subscriptions[name].length); }; -Dash.prototype.subscribeAddress = function(emitter, addresses) { +Dash.prototype.subscribeAddress = function (emitter, addresses) { var self = this; function addAddress(addressStr) { - if(self.subscriptions.address[addressStr]) { + if (self.subscriptions.address[addressStr]) { var emitters = self.subscriptions.address[addressStr]; var index = emitters.indexOf(emitter); if (index === -1) { @@ -279,27 +277,27 @@ Dash.prototype.subscribeAddress = function(emitter, addresses) { self.subscriptions.address[addressStr] = [emitter]; } } - if(addresses){ - for(var i = 0; i < addresses.length; i++) { + if (addresses) { + for (var i = 0; i < addresses.length; i++) { if (dashcore.Address.isValid(addresses[i], this.node.network)) { addAddress(addresses[i]); } } } - log.info(emitter.remoteAddress, 'subscribe:', 'dashd/addresstxid', 'total:', _.size(this.subscriptions.address)); + log.info(emitter.remoteAddress, "subscribe:", "dashd/addresstxid", "total:", _.size(this.subscriptions.address)); }; -Dash.prototype.unsubscribeAddress = function(emitter, addresses) { +Dash.prototype.unsubscribeAddress = function (emitter, addresses) { var self = this; - if(!addresses) { + if (!addresses) { return this.unsubscribeAddressAll(emitter); } function removeAddress(addressStr) { var emitters = self.subscriptions.address[addressStr]; var index = emitters.indexOf(emitter); - if(index > -1) { + if (index > -1) { emitters.splice(index, 1); if (emitters.length === 0) { delete self.subscriptions.address[addressStr]; @@ -307,13 +305,13 @@ Dash.prototype.unsubscribeAddress = function(emitter, addresses) { } } - for(var i = 0; i < addresses.length; i++) { - if(this.subscriptions.address[addresses[i]]) { + for (var i = 0; i < addresses.length; i++) { + if (this.subscriptions.address[addresses[i]]) { removeAddress(addresses[i]); } } - log.info(emitter.remoteAddress, 'unsubscribe:', 'dashd/addresstxid', 'total:', _.size(this.subscriptions.address)); + log.info(emitter.remoteAddress, "unsubscribe:", "dashd/addresstxid", "total:", _.size(this.subscriptions.address)); }; /** @@ -321,37 +319,37 @@ Dash.prototype.unsubscribeAddress = function(emitter, addresses) { * @param {String} name - The name of the event * @param {EventEmitter} emitter - An instance of an event emitter */ -Dash.prototype.unsubscribeAddressAll = function(emitter) { - for(var hashHex in this.subscriptions.address) { +Dash.prototype.unsubscribeAddressAll = function (emitter) { + for (var hashHex in this.subscriptions.address) { var emitters = this.subscriptions.address[hashHex]; var index = emitters.indexOf(emitter); - if(index > -1) { + if (index > -1) { emitters.splice(index, 1); } if (emitters.length === 0) { delete this.subscriptions.address[hashHex]; } } - log.info(emitter.remoteAddress, 'unsubscribe:', 'dashd/addresstxid', 'total:', _.size(this.subscriptions.address)); + log.info(emitter.remoteAddress, "unsubscribe:", "dashd/addresstxid", "total:", _.size(this.subscriptions.address)); }; -Dash.prototype._getDefaultConfig = function() { - var config = ''; +Dash.prototype._getDefaultConfig = function () { + var config = ""; var defaults = Dash.DEFAULT_CONFIG_SETTINGS; - for(var key in defaults) { - config += key + '=' + defaults[key] + '\n'; + for (var key in defaults) { + config += key + "=" + defaults[key] + "\n"; } return config; }; -Dash.prototype._parseDashConf = function(configPath) { +Dash.prototype._parseDashConf = function (configPath) { var options = {}; var file = fs.readFileSync(configPath); - var unparsed = file.toString().split('\n'); - for(var i = 0; i < unparsed.length; i++) { + var unparsed = file.toString().split("\n"); + for (var i = 0; i < unparsed.length; i++) { var line = unparsed[i]; if (!line.match(/^\#/) && line.match(/\=/)) { - var option = line.split('='); + var option = line.split("="); var value; if (!Number.isNaN(Number(option[1]))) { value = Number(option[1]); @@ -364,7 +362,7 @@ Dash.prototype._parseDashConf = function(configPath) { return options; }; -Dash.prototype._expandRelativeDatadir = function() { +Dash.prototype._expandRelativeDatadir = function () { if (!utils.isAbsolutePath(this.options.spawn.datadir)) { $.checkState(this.node.configPath); $.checkState(utils.isAbsolutePath(this.node.configPath)); @@ -373,7 +371,7 @@ Dash.prototype._expandRelativeDatadir = function() { } }; -Dash.prototype._loadSpawnConfiguration = function(node) { +Dash.prototype._loadSpawnConfiguration = function (node) { /* jshint maxstatements: 25 */ $.checkArgument(this.options.spawn, 'Please specify "spawn" in dashd config options'); @@ -383,9 +381,9 @@ Dash.prototype._loadSpawnConfiguration = function(node) { this._expandRelativeDatadir(); var spawnOptions = this.options.spawn; - var configPath = path.resolve(spawnOptions.datadir, './dash.conf'); + var configPath = path.resolve(spawnOptions.datadir, "./dash.conf"); - log.info('Using Dash config file:', configPath); + log.info("Using Dash config file:", configPath); this.spawn = {}; this.spawn.datadir = this.options.spawn.datadir; @@ -413,29 +411,28 @@ Dash.prototype._loadSpawnConfiguration = function(node) { var spawnConfig = this.spawn.config; this._checkConfigIndexes(spawnConfig, node); - }; -Dash.prototype._checkConfigIndexes = function(spawnConfig, node) { +Dash.prototype._checkConfigIndexes = function (spawnConfig, node) { $.checkState( spawnConfig.txindex && spawnConfig.txindex === 1, '"txindex" option is required in order to use transaction query features of dashcore-node. ' + 'Please add "txindex=1" to your configuration and reindex an existing database if ' + - 'necessary with reindex=1' + "necessary with reindex=1" ); $.checkState( spawnConfig.addressindex && spawnConfig.addressindex === 1, '"addressindex" option is required in order to use address query features of dashcore-node. ' + 'Please add "addressindex=1" to your configuration and reindex an existing database if ' + - 'necessary with reindex=1' + "necessary with reindex=1" ); $.checkState( spawnConfig.spentindex && spawnConfig.spentindex === 1, '"spentindex" option is required in order to use spent info query features of dashcore-node. ' + 'Please add "spentindex=1" to your configuration and reindex an existing database if ' + - 'necessary with reindex=1' + "necessary with reindex=1" ); $.checkState( @@ -451,8 +448,8 @@ Dash.prototype._checkConfigIndexes = function(spawnConfig, node) { ); $.checkState( - spawnConfig.zmqpubrawtxlock, - '"zmqpubrawtxlock" option is required to get transaction locks from dashd. ' + + spawnConfig.zmqpubrawtxlock, + '"zmqpubrawtxlock" option is required to get transaction locks from dashd. ' + 'Please add "zmqpubrawtxlock=tcp://127.0.0.1:" to your configuration and restart' ); @@ -463,20 +460,22 @@ Dash.prototype._checkConfigIndexes = function(spawnConfig, node) { ); $.checkState( - (spawnConfig.zmqpubhashblock === spawnConfig.zmqpubrawtx), + spawnConfig.zmqpubhashblock === spawnConfig.zmqpubrawtx, '"zmqpubrawtx" and "zmqpubhashblock" are expected to the same host and port in dash.conf' ); if (spawnConfig.reindex && spawnConfig.reindex === 1) { - log.warn('Reindex option is currently enabled. This means that dashd is undergoing a reindex. ' + - 'The reindex flag will start the index from beginning every time the node is started, so it ' + - 'should be removed after the reindex has been initiated. Once the reindex is complete, the rest ' + - 'of dashcore-node services will start.'); + log.warn( + "Reindex option is currently enabled. This means that dashd is undergoing a reindex. " + + "The reindex flag will start the index from beginning every time the node is started, so it " + + "should be removed after the reindex has been initiated. Once the reindex is complete, the rest " + + "of dashcore-node services will start." + ); node._reindex = true; } }; -Dash.prototype._resetCaches = function() { +Dash.prototype._resetCaches = function () { this.transactionDetailedCache.reset(); this.utxosCache.reset(); this.txidsCache.reset(); @@ -485,8 +484,8 @@ Dash.prototype._resetCaches = function() { this.blockOverviewCache.reset(); this.masternodeListCache.reset(); this.sporksListCache.reset(); - this.govCache.del('info'); - this.govCache.del('count'); + this.govCache.del("info"); + this.govCache.del("count"); }; /** @@ -496,64 +495,63 @@ Dash.prototype._resetCaches = function() { * @param callback * @private */ -Dash.prototype._tryAllClients = function(func, callback) { +Dash.prototype._tryAllClients = function (func, callback) { var self = this; //Storing current node index into closure var nextClientToTry = this.nodesIndex; //Incrementing this.nodesIndex for proper round-robin this.nodesIndex = (this.nodesIndex + 1) % self.nodes.length; - var retry = function(done) { + var retry = function (done) { var client = self.nodes[nextClientToTry].client; nextClientToTry = (nextClientToTry + 1) % self.nodes.length; func(client, done); }; - async.retry({times: this.nodes.length, interval: this.tryAllInterval || 1000}, retry, callback); + async.retry({ times: this.nodes.length, interval: this.tryAllInterval || 1000 }, retry, callback); }; -Dash.prototype._wrapRPCError = function(errObj) { +Dash.prototype._wrapRPCError = function (errObj) { var err = new errors.RPCError(errObj.message); err.code = errObj.code; return err; }; -Dash.prototype._initChain = function(callback) { +Dash.prototype._initChain = function (callback) { var self = this; - self.client.getBestBlockHash(function(err, response) { + self.client.getBestBlockHash(function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } - self.client.getBlock(response.result, function(err, response) { + self.client.getBlock(response.result, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } self.height = response.result.height; - self.client.getBlockHash(0, function(err, response) { + self.client.getBlockHash(0, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } var blockhash = response.result; - self.getRawBlock(blockhash, function(err, blockBuffer) { + self.getRawBlock(blockhash, function (err, blockBuffer) { if (err) { return callback(err); } self.genesisBuffer = blockBuffer; - self.emit('ready'); - log.info('Dash Daemon Ready'); + self.emit("ready"); + log.info("Dash Daemon Ready"); callback(); }); }); - }); }); }; -Dash.prototype._getDefaultConf = function() { +Dash.prototype._getDefaultConf = function () { var networkOptions = { - rpcport: 9998 + rpcport: 9998, }; if (this.node.network === dashcore.Networks.testnet) { networkOptions.rpcport = 19998; @@ -561,48 +559,47 @@ Dash.prototype._getDefaultConf = function() { return networkOptions; }; -Dash.prototype._getNetworkConfigPath = function() { +Dash.prototype._getNetworkConfigPath = function () { var networkPath; if (this.node.network === dashcore.Networks.testnet) { - networkPath = 'testnet3/dash.conf'; + networkPath = "testnet3/dash.conf"; if (this.node.network.regtestEnabled) { - networkPath = 'regtest/dash.conf'; + networkPath = "regtest/dash.conf"; } } return networkPath; }; -Dash.prototype._getNetworkOption = function() { +Dash.prototype._getNetworkOption = function () { var networkOption; if (this.node.network === dashcore.Networks.testnet) { - networkOption = '--testnet'; + networkOption = "--testnet"; if (this.node.network.regtestEnabled) { - networkOption = '--regtest'; + networkOption = "--regtest"; } } return networkOption; }; -Dash.prototype._zmqBlockHandler = function(node, message) { +Dash.prototype._zmqBlockHandler = function (node, message) { var self = this; // Update the current chain tip self._rapidProtectedUpdateTip(node, message); // Notify block subscribers - var id = message.toString('binary'); + var id = message.toString("binary"); if (!self.zmqKnownBlocks.get(id)) { self.zmqKnownBlocks.set(id, true); - self.emit('block', message); + self.emit("block", message); for (var i = 0; i < this.subscriptions.hashblock.length; i++) { - this.subscriptions.hashblock[i].emit('dashd/hashblock', message.toString('hex')); + this.subscriptions.hashblock[i].emit("dashd/hashblock", message.toString("hex")); } } - }; -Dash.prototype._rapidProtectedUpdateTip = function(node, message) { +Dash.prototype._rapidProtectedUpdateTip = function (node, message) { var self = this; // Prevent a rapid succession of tip updates @@ -611,49 +608,49 @@ Dash.prototype._rapidProtectedUpdateTip = function(node, message) { self._updateTip(node, message); } else { clearTimeout(self.lastTipTimeout); - self.lastTipTimeout = setTimeout(function() { + self.lastTipTimeout = setTimeout(function () { self._updateTip(node, message); }, 1000); } }; -Dash.prototype._updateTip = function(node, message) { +Dash.prototype._updateTip = function (node, message) { var self = this; - var hex = message.toString('hex'); + var hex = message.toString("hex"); if (hex !== self.tiphash) { - self.tiphash = message.toString('hex'); + self.tiphash = message.toString("hex"); // reset block valid caches self._resetCaches(); - node.client.getBlock(self.tiphash, function(err, response) { + node.client.getBlock(self.tiphash, function (err, response) { if (err) { var error = self._wrapRPCError(err); - self.emit('error', error); + self.emit("error", error); } else { self.height = response.result.height; $.checkState(self.height >= 0); - self.emit('tip', self.height); + self.emit("tip", self.height); } }); - if(!self.node.stopping) { - self.syncPercentage(function(err, percentage) { + if (!self.node.stopping) { + self.syncPercentage(function (err, percentage) { if (err) { - self.emit('error', err); + self.emit("error", err); } else { if (Math.round(percentage) >= 100) { - self.emit('synced', self.height); + self.emit("synced", self.height); } - log.info('Dash Height:', self.height, 'Percentage:', percentage.toFixed(2)); + log.info("Dash Height:", self.height, "Percentage:", percentage.toFixed(2)); } }); } } }; -Dash.prototype._getAddressesFromTransaction = function(transaction) { +Dash.prototype._getAddressesFromTransaction = function (transaction) { var addresses = []; for (var i = 0; i < transaction.inputs.length; i++) { @@ -679,23 +676,23 @@ Dash.prototype._getAddressesFromTransaction = function(transaction) { return _.uniq(addresses); }; -Dash.prototype._notifyAddressTxidSubscribers = function(txid, transaction) { +Dash.prototype._notifyAddressTxidSubscribers = function (txid, transaction) { var addresses = this._getAddressesFromTransaction(transaction); for (var i = 0; i < addresses.length; i++) { var address = addresses[i]; - if(this.subscriptions.address[address]) { + if (this.subscriptions.address[address]) { var emitters = this.subscriptions.address[address]; - for(var j = 0; j < emitters.length; j++) { - emitters[j].emit('dashd/addresstxid', { + for (var j = 0; j < emitters.length; j++) { + emitters[j].emit("dashd/addresstxid", { address: address, - txid: txid + txid: txid, }); } } } }; -Dash.prototype._zmqTransactionHandler = function(node, message) { +Dash.prototype._zmqTransactionHandler = function (node, message) { // It happen that ZMQ is throwing 'rawtx' // We discard this as they are improper received message from ZMQ. if (message.equals(rawtxTopicBuffer)) { @@ -703,21 +700,20 @@ Dash.prototype._zmqTransactionHandler = function(node, message) { } var self = this; var hash = dashcore.crypto.Hash.sha256sha256(message); - var id = hash.toString('binary'); + var id = hash.toString("binary"); if (!self.zmqKnownTransactions.get(id)) { self.zmqKnownTransactions.set(id, true); - self.emit('tx', message); + self.emit("tx", message); // Notify transaction subscribers for (var i = 0; i < this.subscriptions.rawtransaction.length; i++) { - this.subscriptions.rawtransaction[i].emit('dashd/rawtransaction', message.toString('hex')); + this.subscriptions.rawtransaction[i].emit("dashd/rawtransaction", message.toString("hex")); } var tx = dashcore.Transaction(); tx.fromString(message); - var txid = dashcore.util.buffer.reverse(hash).toString('hex'); + var txid = dashcore.util.buffer.reverse(hash).toString("hex"); self._notifyAddressTxidSubscribers(txid, tx); - } }; @@ -730,35 +726,34 @@ Dash.prototype._zmqTransactionLockHandler = function (node, message) { var self = this; var hash = dashcore.crypto.Hash.sha256sha256(message); - var id = hash.toString('binary'); + var id = hash.toString("binary"); if (!self.zmqKnownTransactionLocks.get(id)) { self.zmqKnownTransactionLocks.set(id, true); - self.emit('txlock', message); + self.emit("txlock", message); // Notify transaction lock subscribers for (var i = 0; i < this.subscriptions.transactionlock.length; i++) { - this.subscriptions.transactionlock[i].emit('dashd/transactionlock', message.toString('hex')); + this.subscriptions.transactionlock[i].emit("dashd/transactionlock", message.toString("hex")); } - } }; -Dash.prototype._checkSyncedAndSubscribeZmqEvents = function(node) { +Dash.prototype._checkSyncedAndSubscribeZmqEvents = function (node) { var self = this; var interval; function checkAndSubscribe(callback) { // update tip - node.client.getBestBlockHash(function(err, response) { + node.client.getBestBlockHash(function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } - var blockhash = new Buffer(response.result, 'hex'); - self.emit('block', blockhash); + var blockhash = new Buffer(response.result, "hex"); + self.emit("block", blockhash); self._updateTip(node, blockhash); // check if synced - node.client.getBlockchainInfo(function(err, response) { + node.client.getBlockchainInfo(function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -775,16 +770,16 @@ Dash.prototype._checkSyncedAndSubscribeZmqEvents = function(node) { }); } - checkAndSubscribe(function(err, synced) { + checkAndSubscribe(function (err, synced) { if (err) { log.error(err); } if (!synced) { - interval = setInterval(function() { + interval = setInterval(function () { if (self.node.stopping) { return clearInterval(interval); } - checkAndSubscribe(function(err) { + checkAndSubscribe(function (err) { if (err) { log.error(err); } @@ -792,45 +787,44 @@ Dash.prototype._checkSyncedAndSubscribeZmqEvents = function(node) { }, node._tipUpdateInterval || Dash.DEFAULT_TIP_UPDATE_INTERVAL); } }); - }; -Dash.prototype._subscribeZmqEvents = function(node) { +Dash.prototype._subscribeZmqEvents = function (node) { var self = this; - node.zmqSubSocket.subscribe('hashblock'); - node.zmqSubSocket.subscribe('rawtx'); - node.zmqSubSocket.subscribe('rawtxlock'); - node.zmqSubSocket.on('message', function(topic, message) { - var topicString = topic.toString('utf8'); - if (topicString === 'rawtxlock') { + node.zmqSubSocket.subscribe("hashblock"); + node.zmqSubSocket.subscribe("rawtx"); + node.zmqSubSocket.subscribe("rawtxlock"); + node.zmqSubSocket.on("message", function (topic, message) { + var topicString = topic.toString("utf8"); + if (topicString === "rawtxlock") { self._zmqTransactionLockHandler(node, message); - } else if (topicString === 'rawtx') { + } else if (topicString === "rawtx") { self._zmqTransactionHandler(node, message); - } else if (topicString === 'hashblock') { + } else if (topicString === "hashblock") { self._zmqBlockHandler(node, message); } }); }; -Dash.prototype._initZmqSubSocket = function(node, zmqUrl) { +Dash.prototype._initZmqSubSocket = function (node, zmqUrl) { var self = this; - node.zmqSubSocket = zmq.socket('sub'); + node.zmqSubSocket = zmq.socket("sub"); - node.zmqSubSocket.on('connect', function(fd, endPoint) { - log.info('ZMQ connected to:', endPoint); + node.zmqSubSocket.on("connect", function (fd, endPoint) { + log.info("ZMQ connected to:", endPoint); }); - node.zmqSubSocket.on('connect_delay', function(fd, endPoint) { - log.warn('ZMQ connection delay:', endPoint); + node.zmqSubSocket.on("connect_delay", function (fd, endPoint) { + log.warn("ZMQ connection delay:", endPoint); }); - node.zmqSubSocket.on('disconnect', function(fd, endPoint) { - log.warn('ZMQ disconnect:', endPoint); + node.zmqSubSocket.on("disconnect", function (fd, endPoint) { + log.warn("ZMQ disconnect:", endPoint); }); - node.zmqSubSocket.on('monitor_error', function(err) { - log.error('Error in monitoring: %s, will restart monitoring in 5 seconds', err); - setTimeout(function() { + node.zmqSubSocket.on("monitor_error", function (err) { + log.error("Error in monitoring: %s, will restart monitoring in 5 seconds", err); + setTimeout(function () { self.zmqSubSocket.monitor(500, 0); }, 5000); }); @@ -839,7 +833,7 @@ Dash.prototype._initZmqSubSocket = function(node, zmqUrl) { node.zmqSubSocket.connect(zmqUrl); }; -Dash.prototype._checkReindex = function(node, callback) { +Dash.prototype._checkReindex = function (node, callback) { var self = this; var interval; function finish(err) { @@ -850,13 +844,13 @@ Dash.prototype._checkReindex = function(node, callback) { return callback(); } - interval = setInterval(function() { - node.client.getBlockchainInfo(function(err, response) { + interval = setInterval(function () { + node.client.getBlockchainInfo(function (err, response) { if (err) { return finish(self._wrapRPCError(err)); } var percentSynced = response.result.verificationprogress * 100; - log.info('Dash Core Daemon Reindex Percentage: ' + percentSynced.toFixed(2)); + log.info("Dash Core Daemon Reindex Percentage: " + percentSynced.toFixed(2)); if (Math.round(percentSynced) >= 100) { node._reindex = false; @@ -864,36 +858,35 @@ Dash.prototype._checkReindex = function(node, callback) { } }); }, node._reindexWait || Dash.DEFAULT_REINDEX_INTERVAL); - }; -Dash.prototype._loadTipFromNode = function(node, callback) { +Dash.prototype._loadTipFromNode = function (node, callback) { var self = this; - node.client.getBestBlockHash(function(err, response) { + node.client.getBestBlockHash(function (err, response) { if (err) { callback(self._wrapRPCError(err)); return; } - node.client.getBlock(response.result, function(err, response) { + node.client.getBlock(response.result, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } self.height = response.result.height; $.checkState(self.height >= 0); - self.emit('tip', self.height); + self.emit("tip", self.height); callback(); }); }); }; -Dash.prototype._stopSpawnedDash = function(callback) { +Dash.prototype._stopSpawnedDash = function (callback) { var self = this; var spawnOptions = this.options.spawn; - var pidPath = spawnOptions.datadir + '/dashd.pid'; + var pidPath = spawnOptions.datadir + "/dashd.pid"; function stopProcess() { - fs.readFile(pidPath, 'utf8', function(err, pid) { - if (err && err.code === 'ENOENT') { + fs.readFile(pidPath, "utf8", function (err, pid) { + if (err && err.code === "ENOENT") { // pid file doesn't exist we can continue return callback(null); } else if (err) { @@ -905,17 +898,17 @@ Dash.prototype._stopSpawnedDash = function(callback) { return callback(null); } try { - log.warn('Stopping existing spawned dash process with pid: ' + pid); - self._process.kill(pid, 'SIGINT'); - } catch(err) { - if (err && err.code === 'ESRCH') { - log.warn('Unclean dash process shutdown, process not found with pid: ' + pid); + log.warn("Stopping existing spawned dash process with pid: " + pid); + self._process.kill(pid, "SIGINT"); + } catch (err) { + if (err && err.code === "ESRCH") { + log.warn("Unclean dash process shutdown, process not found with pid: " + pid); return callback(null); - } else if(err) { + } else if (err) { return callback(err); } } - setTimeout(function() { + setTimeout(function () { stopProcess(); }, self.spawnStopTime); }); @@ -924,7 +917,7 @@ Dash.prototype._stopSpawnedDash = function(callback) { stopProcess(); }; -Dash.prototype._spawnChildProcess = function(callback) { +Dash.prototype._spawnChildProcess = function (callback) { var self = this; var node = {}; @@ -933,41 +926,38 @@ Dash.prototype._spawnChildProcess = function(callback) { try { self._loadSpawnConfiguration(node); - } catch(e) { + } catch (e) { return callback(e); } - var options = [ - '--conf=' + this.spawn.configPath, - '--datadir=' + this.spawn.datadir, - ]; + var options = ["--conf=" + this.spawn.configPath, "--datadir=" + this.spawn.datadir]; if (self._getNetworkOption()) { options.push(self._getNetworkOption()); } - self._stopSpawnedDash(function(err) { + self._stopSpawnedDash(function (err) { if (err) { return callback(err); } - log.info('Starting dash process'); - self.spawn.process = spawn(self.spawn.exec, options, {stdio: 'inherit'}); + log.info("Starting dash process"); + self.spawn.process = spawn(self.spawn.exec, options, { stdio: "inherit" }); - self.spawn.process.on('error', function(err) { - self.emit('error', err); + self.spawn.process.on("error", function (err) { + self.emit("error", err); }); - self.spawn.process.once('exit', function(code) { + self.spawn.process.once("exit", function (code) { if (!self.node.stopping) { - log.warn('Dash process unexpectedly exited with code:', code); - log.warn('Restarting dash child process in ' + self.spawnRestartTime + 'ms'); - setTimeout(function() { - self._spawnChildProcess(function(err) { + log.warn("Dash process unexpectedly exited with code:", code); + log.warn("Restarting dash child process in " + self.spawnRestartTime + "ms"); + setTimeout(function () { + self._spawnChildProcess(function (err) { if (err) { - return self.emit('error', err); + return self.emit("error", err); } - log.warn('Dash process restarted'); + log.warn("Dash process restarted"); }); }, self.spawnRestartTime); } @@ -980,47 +970,47 @@ Dash.prototype._spawnChildProcess = function(callback) { interval: self.startRetryInterval, errorFilter: isNonFatalError, }; - async.retry(retryOpts, function (done) { - if (self.node.stopping) { - exitShutdown = true; - return done(); - } - - node.client = new DashdRPC({ - protocol: 'http', - host: '127.0.0.1', - port: self.spawn.config.rpcport, - user: self.spawn.config.rpcuser, - pass: self.spawn.config.rpcpassword - }); - - self._loadTipFromNode(node, done); - - }, function(err) { - if (err) { - return callback(err); - } - if (exitShutdown) { - return callback(new Error('Stopping while trying to spawn dashd.')); - } + async.retry( + retryOpts, + function (done) { + if (self.node.stopping) { + exitShutdown = true; + return done(); + } - self._initZmqSubSocket(node, self.spawn.config.zmqpubrawtx); + node.client = new DashdRPC({ + protocol: "http", + host: "127.0.0.1", + port: self.spawn.config.rpcport, + user: self.spawn.config.rpcuser, + pass: self.spawn.config.rpcpassword, + }); - self._checkReindex(node, function(err) { + self._loadTipFromNode(node, done); + }, + function (err) { if (err) { return callback(err); } - self._checkSyncedAndSubscribeZmqEvents(node); - callback(null, node); - }); + if (exitShutdown) { + return callback(new Error("Stopping while trying to spawn dashd.")); + } - }); + self._initZmqSubSocket(node, self.spawn.config.zmqpubrawtx); + self._checkReindex(node, function (err) { + if (err) { + return callback(err); + } + self._checkSyncedAndSubscribeZmqEvents(node); + callback(null, node); + }); + } + ); }); - }; -Dash.prototype._connectProcess = function(config, callback) { +Dash.prototype._connectProcess = function (config, callback) { var self = this; var node = {}; var exitShutdown = false; @@ -1030,92 +1020,97 @@ Dash.prototype._connectProcess = function(config, callback) { interval: self.startRetryInterval, errorFilter: isNonFatalError, }; - async.retry(retryOpts, function(done) { - if (self.node.stopping) { - exitShutdown = true; - return done(); - } - - node.client = new DashdRPC({ - protocol: config.rpcprotocol || 'http', - host: config.rpchost || '127.0.0.1', - port: config.rpcport, - user: config.rpcuser, - pass: config.rpcpassword, - rejectUnauthorized: _.isUndefined(config.rpcstrict) ? true : config.rpcstrict - }); + async.retry( + retryOpts, + function (done) { + if (self.node.stopping) { + exitShutdown = true; + return done(); + } - self._loadTipFromNode(node, done); + node.client = new DashdRPC({ + protocol: config.rpcprotocol || "http", + host: config.rpchost || "127.0.0.1", + port: config.rpcport, + user: config.rpcuser, + pass: config.rpcpassword, + rejectUnauthorized: _.isUndefined(config.rpcstrict) ? true : config.rpcstrict, + }); - }, function(err) { - if (err) { - return callback(err); - } - if (exitShutdown) { - return callback(new Error('Stopping while trying to connect to dashd.')); - } + self._loadTipFromNode(node, done); + }, + function (err) { + if (err) { + return callback(err); + } + if (exitShutdown) { + return callback(new Error("Stopping while trying to connect to dashd.")); + } - self._initZmqSubSocket(node, config.zmqpubrawtx); - self._subscribeZmqEvents(node); + self._initZmqSubSocket(node, config.zmqpubrawtx); + self._subscribeZmqEvents(node); - callback(null, node); - }); + callback(null, node); + } + ); }; /** * Called by Node to start the service * @param {Function} callback */ -Dash.prototype.start = function(callback) { +Dash.prototype.start = function (callback) { var self = this; - async.series([ - function(next) { - if (self.options.spawn) { - self._spawnChildProcess(function(err, node) { - if (err) { - return next(err); - } - self.nodes.push(node); + async.series( + [ + function (next) { + if (self.options.spawn) { + self._spawnChildProcess(function (err, node) { + if (err) { + return next(err); + } + self.nodes.push(node); + next(); + }); + } else { next(); - }); - } else { - next(); - } - }, - function(next) { - if (self.options.connect) { - async.map(self.options.connect, self._connectProcess.bind(self), function(err, nodes) { - if (err) { - return next(err); - } - for(var i = 0; i < nodes.length; i++) { - self.nodes.push(nodes[i]); - } + } + }, + function (next) { + if (self.options.connect) { + async.map(self.options.connect, self._connectProcess.bind(self), function (err, nodes) { + if (err) { + return next(err); + } + for (var i = 0; i < nodes.length; i++) { + self.nodes.push(nodes[i]); + } + next(); + }); + } else { next(); - }); - } else { - next(); + } + }, + ], + function (err) { + if (err) { + return callback(err); } + if (self.nodes.length === 0) { + return callback(new Error('Dash configuration options "spawn" or "connect" are expected')); + } + self._initChain(callback); } - ], function(err) { - if (err) { - return callback(err); - } - if (self.nodes.length === 0) { - return callback(new Error('Dash configuration options "spawn" or "connect" are expected')); - } - self._initChain(callback); - }); - + ); }; /** * Helper to determine the state of the database. * @param {Function} callback */ -Dash.prototype.isSynced = function(callback) { - this.syncPercentage(function(err, percentage) { +Dash.prototype.isSynced = function (callback) { + this.syncPercentage(function (err, percentage) { if (err) { return callback(err); } @@ -1131,9 +1126,9 @@ Dash.prototype.isSynced = function(callback) { * Helper to determine the progress of the database. * @param {Function} callback */ -Dash.prototype.syncPercentage = function(callback) { +Dash.prototype.syncPercentage = function (callback) { var self = this; - this.client.getBlockchainInfo(function(err, response) { + this.client.getBlockchainInfo(function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1142,7 +1137,7 @@ Dash.prototype.syncPercentage = function(callback) { }); }; -Dash.prototype._normalizeAddressArg = function(addressArg) { +Dash.prototype._normalizeAddressArg = function (addressArg) { var addresses = [addressArg]; if (Array.isArray(addressArg)) { addresses = addressArg; @@ -1156,17 +1151,17 @@ Dash.prototype._normalizeAddressArg = function(addressArg) { * @param {Object} options * @param {Function} callback */ -Dash.prototype.getAddressBalance = function(addressArg, options, callback) { +Dash.prototype.getAddressBalance = function (addressArg, options, callback) { var self = this; var addresses = self._normalizeAddressArg(addressArg); - var cacheKey = addresses.join(''); + var cacheKey = addresses.join(""); var balance = self.balanceCache.get(cacheKey); if (balance) { - return setImmediate(function() { + return setImmediate(function () { callback(null, balance); }); } else { - this.client.getAddressBalance({addresses: addresses}, function(err, response) { + this.client.getAddressBalance({ addresses: addresses }, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1182,11 +1177,11 @@ Dash.prototype.getAddressBalance = function(addressArg, options, callback) { * @param {Object} options * @param {Function} callback */ -Dash.prototype.getAddressUnspentOutputsPaginated = function(addressArg, options, callback) { +Dash.prototype.getAddressUnspentOutputsPaginated = function (addressArg, options, callback) { var self = this; var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool; var addresses = self._normalizeAddressArg(addressArg); - var cacheKey = addresses.join(''); + var cacheKey = addresses.join(""); var utxos = self.utxosCache.get(cacheKey); var fromArg = parseInt(options.from || 0); var toArg = parseInt(options.to || self.maxUTXOHistory); @@ -1201,7 +1196,7 @@ Dash.prototype.getAddressUnspentOutputsPaginated = function(addressArg, options, outputIndex: delta.index, script: script.toHex(), satoshis: delta.satoshis, - timestamp: delta.timestamp + timestamp: delta.timestamp, }; } @@ -1214,7 +1209,7 @@ Dash.prototype.getAddressUnspentOutputsPaginated = function(addressArg, options, utxos = self._paginate(confirmedUtxos, fromArg, toArg, fromHeight, toHeight); return { totalCount: totalCount, - items: utxos + items: utxos, }; } @@ -1237,35 +1232,40 @@ Dash.prototype.getAddressUnspentOutputsPaginated = function(addressArg, options, } utxos = self._paginate( - mempoolUnspentOutputs.reverse().concat(confirmedUtxos), fromArg, toArg, fromHeight, toHeight); + mempoolUnspentOutputs.reverse().concat(confirmedUtxos), + fromArg, + toArg, + fromHeight, + toHeight + ); if (isSpentOutputs) { - var filteredUtxos = utxos.filter(function(utxo) { + var filteredUtxos = utxos.filter(function (utxo) { if (!spentOutputs[utxo.txid]) { return true; } else { - return (spentOutputs[utxo.txid].indexOf(utxo.outputIndex) === -1); + return spentOutputs[utxo.txid].indexOf(utxo.outputIndex) === -1; } }); return { totalCount: totalCount, - items: filteredUtxos + items: filteredUtxos, }; } return { totalCount: totalCount, - items: utxos + items: utxos, }; } function finish(mempoolDeltas) { if (utxos) { - return setImmediate(function() { + return setImmediate(function () { callback(null, updateWithMempool(utxos, mempoolDeltas)); }); } else { - self.client.getAddressUtxos({addresses: addresses}, function(err, response) { + self.client.getAddressUtxos({ addresses: addresses }, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1277,7 +1277,7 @@ Dash.prototype.getAddressUnspentOutputsPaginated = function(addressArg, options, } if (queryMempool) { - self.client.getAddressMempool({addresses: addresses}, function(err, response) { + self.client.getAddressMempool({ addresses: addresses }, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1286,7 +1286,6 @@ Dash.prototype.getAddressUnspentOutputsPaginated = function(addressArg, options, } else { finish(); } - }; /** @@ -1295,11 +1294,11 @@ Dash.prototype.getAddressUnspentOutputsPaginated = function(addressArg, options, * @param {Object} options * @param {Function} callback */ -Dash.prototype.getAddressUnspentOutputs = function(addressArg, options, callback) { +Dash.prototype.getAddressUnspentOutputs = function (addressArg, options, callback) { var self = this; var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool; var addresses = self._normalizeAddressArg(addressArg); - var cacheKey = addresses.join(''); + var cacheKey = addresses.join(""); var utxos = self.utxosCache.get(cacheKey); function transformUnspentOutput(delta) { @@ -1310,7 +1309,7 @@ Dash.prototype.getAddressUnspentOutputs = function(addressArg, options, callback outputIndex: delta.index, script: script.toHex(), satoshis: delta.satoshis, - timestamp: delta.timestamp + timestamp: delta.timestamp, }; } @@ -1340,11 +1339,11 @@ Dash.prototype.getAddressUnspentOutputs = function(addressArg, options, callback var utxos = mempoolUnspentOutputs.reverse().concat(confirmedUtxos); if (isSpentOutputs) { - return utxos.filter(function(utxo) { + return utxos.filter(function (utxo) { if (!spentOutputs[utxo.txid]) { return true; } else { - return (spentOutputs[utxo.txid].indexOf(utxo.outputIndex) === -1); + return spentOutputs[utxo.txid].indexOf(utxo.outputIndex) === -1; } }); } @@ -1354,11 +1353,11 @@ Dash.prototype.getAddressUnspentOutputs = function(addressArg, options, callback function finish(mempoolDeltas) { if (utxos) { - return setImmediate(function() { + return setImmediate(function () { callback(null, updateWithMempool(utxos, mempoolDeltas)); }); } else { - self.client.getAddressUtxos({addresses: addresses}, function(err, response) { + self.client.getAddressUtxos({ addresses: addresses }, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1370,7 +1369,7 @@ Dash.prototype.getAddressUnspentOutputs = function(addressArg, options, callback } if (queryMempool) { - self.client.getAddressMempool({addresses: addresses}, function(err, response) { + self.client.getAddressMempool({ addresses: addresses }, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1379,10 +1378,9 @@ Dash.prototype.getAddressUnspentOutputs = function(addressArg, options, callback } else { finish(); } - }; -Dash.prototype._getBalanceFromMempool = function(deltas) { +Dash.prototype._getBalanceFromMempool = function (deltas) { var satoshis = 0; for (var i = 0; i < deltas.length; i++) { satoshis += deltas[i].satoshis; @@ -1390,7 +1388,7 @@ Dash.prototype._getBalanceFromMempool = function(deltas) { return satoshis; }; -Dash.prototype._getTxidsFromMempool = function(deltas) { +Dash.prototype._getTxidsFromMempool = function (deltas) { var mempoolTxids = []; var mempoolTxidsKnown = {}; for (var i = 0; i < deltas.length; i++) { @@ -1403,7 +1401,7 @@ Dash.prototype._getTxidsFromMempool = function(deltas) { return mempoolTxids; }; -Dash.prototype._getHeightRangeQuery = function(options, clone) { +Dash.prototype._getHeightRangeQuery = function (options, clone) { if (options.start >= 0 && options.end >= 0) { if (options.end > options.start) { throw new TypeError('"end" is expected to be less than or equal to "start"'); @@ -1424,38 +1422,38 @@ Dash.prototype._getHeightRangeQuery = function(options, clone) { * @param {Object} options * @param {Function} callback */ -Dash.prototype.getAddressTxids = function(addressArg, options, callback) { +Dash.prototype.getAddressTxids = function (addressArg, options, callback) { /* jshint maxstatements: 16 */ var self = this; var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool; var rangeQuery = false; try { rangeQuery = self._getHeightRangeQuery(options); - } catch(err) { + } catch (err) { return callback(err); } if (rangeQuery) { queryMempool = false; } var addresses = self._normalizeAddressArg(addressArg); - var cacheKey = addresses.join(''); + var cacheKey = addresses.join(""); var mempoolTxids = []; var txids = self.txidsCache.get(cacheKey); function finish() { if (txids && !rangeQuery) { var allTxids = mempoolTxids.reverse().concat(txids); - return setImmediate(function() { + return setImmediate(function () { callback(null, allTxids); }); } else { var txidOpts = { - addresses: addresses + addresses: addresses, }; if (rangeQuery) { self._getHeightRangeQuery(options, txidOpts); } - self.client.getAddressTxids(txidOpts, function(err, response) { + self.client.getAddressTxids(txidOpts, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1470,7 +1468,7 @@ Dash.prototype.getAddressTxids = function(addressArg, options, callback) { } if (queryMempool) { - self.client.getAddressMempool({addresses: addresses}, function(err, response) { + self.client.getAddressMempool({ addresses: addresses }, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1480,22 +1478,21 @@ Dash.prototype.getAddressTxids = function(addressArg, options, callback) { } else { finish(); } - }; -Dash.prototype._getConfirmationsDetail = function(transaction) { - $.checkState(this.height > 0, 'current height is unknown'); +Dash.prototype._getConfirmationsDetail = function (transaction) { + $.checkState(this.height > 0, "current height is unknown"); var confirmations = 0; if (transaction.height >= 0) { confirmations = this.height - transaction.height + 1; } if (confirmations < 0) { - log.warn('Negative confirmations calculated for transaction:', transaction.hash); + log.warn("Negative confirmations calculated for transaction:", transaction.hash); } return Math.max(0, confirmations); }; -Dash.prototype._getAddressDetailsForInput = function(input, inputIndex, result, addressStrings) { +Dash.prototype._getAddressDetailsForInput = function (input, inputIndex, result, addressStrings) { if (!input.address) { return; } @@ -1504,7 +1501,7 @@ Dash.prototype._getAddressDetailsForInput = function(input, inputIndex, result, if (!result.addresses[address]) { result.addresses[address] = { inputIndexes: [inputIndex], - outputIndexes: [] + outputIndexes: [], }; } else { result.addresses[address].inputIndexes.push(inputIndex); @@ -1513,7 +1510,7 @@ Dash.prototype._getAddressDetailsForInput = function(input, inputIndex, result, } }; -Dash.prototype._getAddressDetailsForOutput = function(output, outputIndex, result, addressStrings) { +Dash.prototype._getAddressDetailsForOutput = function (output, outputIndex, result, addressStrings) { if (!output.address) { return; } @@ -1522,7 +1519,7 @@ Dash.prototype._getAddressDetailsForOutput = function(output, outputIndex, resul if (!result.addresses[address]) { result.addresses[address] = { inputIndexes: [], - outputIndexes: [outputIndex] + outputIndexes: [outputIndex], }; } else { result.addresses[address].outputIndexes.push(outputIndex); @@ -1531,10 +1528,10 @@ Dash.prototype._getAddressDetailsForOutput = function(output, outputIndex, resul } }; -Dash.prototype._getAddressDetailsForTransaction = function(transaction, addressStrings) { +Dash.prototype._getAddressDetailsForTransaction = function (transaction, addressStrings) { var result = { addresses: {}, - satoshis: 0 + satoshis: 0, }; for (var inputIndex = 0; inputIndex < transaction.inputs.length; inputIndex++) { @@ -1557,30 +1554,27 @@ Dash.prototype._getAddressDetailsForTransaction = function(transaction, addressS * @param {Object} txid - A dash transaction id * @param {Function} callback */ -Dash.prototype._getAddressDetailedTransaction = function(txid, options, next) { +Dash.prototype._getAddressDetailedTransaction = function (txid, options, next) { var self = this; - self.getDetailedTransaction( - txid, - function(err, transaction) { - if (err) { - return next(err); - } + self.getDetailedTransaction(txid, function (err, transaction) { + if (err) { + return next(err); + } - var addressDetails = self._getAddressDetailsForTransaction(transaction, options.addressStrings); + var addressDetails = self._getAddressDetailsForTransaction(transaction, options.addressStrings); - var details = { - addresses: addressDetails.addresses, - satoshis: addressDetails.satoshis, - confirmations: self._getConfirmationsDetail(transaction), - tx: transaction - }; - next(null, details); - } - ); + var details = { + addresses: addressDetails.addresses, + satoshis: addressDetails.satoshis, + confirmations: self._getConfirmationsDetail(transaction), + tx: transaction, + }; + next(null, details); + }); }; -Dash.prototype._getAddressStrings = function(addresses) { +Dash.prototype._getAddressStrings = function (addresses) { var addressStrings = []; for (var i = 0; i < addresses.length; i++) { var address = addresses[i]; @@ -1589,42 +1583,43 @@ Dash.prototype._getAddressStrings = function(addresses) { } else if (_.isString(address)) { addressStrings.push(address); } else { - throw new TypeError('Addresses are expected to be strings'); + throw new TypeError("Addresses are expected to be strings"); } } return addressStrings; }; -Dash.prototype._paginate = function(fullArray, fromArg, toArg, fromHeight, toHeight) { +Dash.prototype._paginate = function (fullArray, fromArg, toArg, fromHeight, toHeight) { var slicedArray; var filteredArray; var from = parseInt(fromArg); var to = parseInt(toArg); if (fromHeight !== undefined && toHeight !== undefined) { $.checkState( - fromHeight < toHeight, '"fromHeight" (' + fromHeight + ')' + - ' is expected to be less than "toHeight" (' + toHeight + ')'); - filteredArray = fullArray.filter(function(item) { + fromHeight < toHeight, + '"fromHeight" (' + fromHeight + ")" + ' is expected to be less than "toHeight" (' + toHeight + ")" + ); + filteredArray = fullArray.filter(function (item) { if (item.height >= fromHeight && item.height <= toHeight) { return item; } }); } if (fromHeight !== undefined && toHeight === undefined) { - filteredArray = fullArray.filter(function(item) { + filteredArray = fullArray.filter(function (item) { if (item.height >= fromHeight) { return item; } }); } if (toHeight !== undefined && fromHeight === undefined) { - filteredArray = fullArray.filter(function(item) { + filteredArray = fullArray.filter(function (item) { if (item.height <= toHeight) { return item; } }); } - $.checkState(from < to, '"from" (' + from + ') is expected to be less than "to" (' + to + ')'); + $.checkState(from < to, '"from" (' + from + ') is expected to be less than "to" (' + to + ")"); if (filteredArray) { slicedArray = filteredArray.slice(from, to); } else { @@ -1639,11 +1634,11 @@ Dash.prototype._paginate = function(fullArray, fromArg, toArg, fromHeight, toHei * @param {Object} options * @param {Function} callback */ -Dash.prototype.getAddressHistory = function(addressArg, options, callback) { +Dash.prototype.getAddressHistory = function (addressArg, options, callback) { var self = this; var addresses = self._normalizeAddressArg(addressArg); if (addresses.length > this.maxAddressesQuery) { - return callback(new TypeError('Maximum number of addresses (' + this.maxAddressesQuery + ') exceeded')); + return callback(new TypeError("Maximum number of addresses (" + this.maxAddressesQuery + ") exceeded")); } var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool; @@ -1654,14 +1649,20 @@ Dash.prototype.getAddressHistory = function(addressArg, options, callback) { var fromHeight = parseInt(options.fromHeight) || undefined; var toHeight = parseInt(options.toHeight) || undefined; - if ((toArg - fromArg) > self.maxTransactionHistory) { - return callback(new Error( - '"from" (' + options.from + ') and "to" (' + options.to + ') range should be less than or equal to ' + - self.maxTransactionHistory - )); + if (toArg - fromArg > self.maxTransactionHistory) { + return callback( + new Error( + '"from" (' + + options.from + + ') and "to" (' + + options.to + + ") range should be less than or equal to " + + self.maxTransactionHistory + ) + ); } - self.getAddressTxids(addresses, options, function(err, txids) { + self.getAddressTxids(addresses, options, function (err, txids) { if (err) { return callback(err); } @@ -1669,26 +1670,30 @@ Dash.prototype.getAddressHistory = function(addressArg, options, callback) { var totalCount = txids.length; try { txids = self._paginate(txids, fromArg, toArg, fromHeight, toHeight); - } catch(e) { + } catch (e) { return callback(e); } async.mapLimit( txids, self.transactionConcurrency, - function(txid, next) { - self._getAddressDetailedTransaction(txid, { - queryMempool: queryMempool, - addressStrings: addressStrings - }, next); + function (txid, next) { + self._getAddressDetailedTransaction( + txid, + { + queryMempool: queryMempool, + addressStrings: addressStrings, + }, + next + ); }, - function(err, transactions) { + function (err, transactions) { if (err) { return callback(err); } callback(null, { totalCount: totalCount, - items: transactions + items: transactions, }); } ); @@ -1701,14 +1706,14 @@ Dash.prototype.getAddressHistory = function(addressArg, options, callback) { * @param {Object} options * @param {Function} callback */ -Dash.prototype.getAddressSummary = function(addressArg, options, callback) { +Dash.prototype.getAddressSummary = function (addressArg, options, callback) { var self = this; var summary = {}; var queryMempool = _.isUndefined(options.queryMempool) ? true : options.queryMempool; var summaryTxids = []; var mempoolTxids = []; var addresses = self._normalizeAddressArg(addressArg); - var cacheKey = addresses.join(''); + var cacheKey = addresses.join(""); function finishWithTxids() { if (!options.noTxList) { @@ -1718,16 +1723,17 @@ Dash.prototype.getAddressSummary = function(addressArg, options, callback) { var fromHeight = parseInt(options.fromHeight) || undefined; var toHeight = parseInt(options.toHeight) || undefined; - if ((toArg - fromArg) > self.maxTxids) { - return callback(new Error( - '"from" (' + fromArg + ') and "to" (' + toArg + ') range should be less than or equal to ' + - self.maxTxids - )); + if (toArg - fromArg > self.maxTxids) { + return callback( + new Error( + '"from" (' + fromArg + ') and "to" (' + toArg + ") range should be less than or equal to " + self.maxTxids + ) + ); } var paginatedTxids; try { paginatedTxids = self._paginate(allTxids, fromArg, toArg, fromHeight, toHeight); - } catch(e) { + } catch (e) { return callback(e); } @@ -1740,49 +1746,52 @@ Dash.prototype.getAddressSummary = function(addressArg, options, callback) { } function querySummary() { - async.parallel([ - function getTxList(done) { - self.getAddressTxids(addresses, {queryMempool: false}, function(err, txids) { - if (err) { - return done(err); - } - summaryTxids = txids; - summary.appearances = txids.length; - done(); - }); - }, - function getBalance(done) { - self.getAddressBalance(addresses, options, function(err, data) { - if (err) { - return done(err); + async.parallel( + [ + function getTxList(done) { + self.getAddressTxids(addresses, { queryMempool: false }, function (err, txids) { + if (err) { + return done(err); + } + summaryTxids = txids; + summary.appearances = txids.length; + done(); + }); + }, + function getBalance(done) { + self.getAddressBalance(addresses, options, function (err, data) { + if (err) { + return done(err); + } + summary.totalReceived = data.received; + summary.totalSpent = data.received - data.balance; + summary.balance = data.balance; + done(); + }); + }, + function getMempool(done) { + if (!queryMempool) { + return done(); } - summary.totalReceived = data.received; - summary.totalSpent = data.received - data.balance; - summary.balance = data.balance; - done(); - }); - }, - function getMempool(done) { - if (!queryMempool) { - return done(); + self.client.getAddressMempool({ addresses: addresses }, function (err, response) { + if (err) { + return done(self._wrapRPCError(err)); + } + mempoolTxids = self._getTxidsFromMempool(response.result); + summary.unconfirmedAppearances = mempoolTxids.length; + summary.unconfirmedBalance = self._getBalanceFromMempool(response.result); + done(); + }); + }, + ], + function (err) { + if (err) { + return callback(err); } - self.client.getAddressMempool({'addresses': addresses}, function(err, response) { - if (err) { - return done(self._wrapRPCError(err)); - } - mempoolTxids = self._getTxidsFromMempool(response.result); - summary.unconfirmedAppearances = mempoolTxids.length; - summary.unconfirmedBalance = self._getBalanceFromMempool(response.result); - done(); - }); - }, - ], function(err) { - if (err) { - return callback(err); + self.summaryCache.set(cacheKey, summary); + finishWithTxids(); } - self.summaryCache.set(cacheKey, summary); - finishWithTxids(); - }); + ); } if (options.noTxList) { @@ -1795,7 +1804,6 @@ Dash.prototype.getAddressSummary = function(addressArg, options, callback) { } else { querySummary(); } - }; /** @@ -1805,11 +1813,11 @@ Dash.prototype.getAddressSummary = function(addressArg, options, callback) { * @param {Function} callback * @private */ -Dash.prototype._maybeGetBlockHash = function(blockArg, callback) { +Dash.prototype._maybeGetBlockHash = function (blockArg, callback) { var self = this; if (_.isNumber(blockArg) || (blockArg.length < 40 && /^[0-9]+$/.test(blockArg))) { - self._tryAllClients(function(client, done) { - client.getBlockHash(blockArg, function(err, response) { + self._tryAllClients(function (client, done) { + client.getBlockHash(blockArg, function (err, response) { if (err) { return done(self._wrapRPCError(err)); } @@ -1826,7 +1834,7 @@ Dash.prototype._maybeGetBlockHash = function(blockArg, callback) { * @param {String|Number} block - A block hash or block height number * @param {Function} callback */ -Dash.prototype.getRawBlock = function(blockArg, callback) { +Dash.prototype.getRawBlock = function (blockArg, callback) { // TODO apply performance patch to the RPC method for raw data var self = this; @@ -1834,12 +1842,12 @@ Dash.prototype.getRawBlock = function(blockArg, callback) { if (err) { return callback(err); } - self._tryAllClients(function(client, done) { - self.client.getBlock(blockhash, false, function(err, response) { + self._tryAllClients(function (client, done) { + self.client.getBlock(blockhash, false, function (err, response) { if (err) { return done(self._wrapRPCError(err)); } - var buffer = new Buffer(response.result, 'hex'); + var buffer = new Buffer(response.result, "hex"); self.rawBlockCache.set(blockhash, buffer); done(null, buffer); }); @@ -1848,7 +1856,7 @@ Dash.prototype.getRawBlock = function(blockArg, callback) { var cachedBlock = self.rawBlockCache.get(blockArg); if (cachedBlock) { - return setImmediate(function() { + return setImmediate(function () { callback(null, cachedBlock); }); } else { @@ -1861,7 +1869,7 @@ Dash.prototype.getRawBlock = function(blockArg, callback) { * @param {String|Number} block - A block hash or block height number * @param {Function} callback */ -Dash.prototype.getBlockOverview = function(blockArg, callback) { +Dash.prototype.getBlockOverview = function (blockArg, callback) { var self = this; function queryBlock(err, blockhash) { @@ -1870,12 +1878,12 @@ Dash.prototype.getBlockOverview = function(blockArg, callback) { } var cachedBlock = self.blockOverviewCache.get(blockhash); if (cachedBlock) { - return setImmediate(function() { + return setImmediate(function () { callback(null, cachedBlock); }); } else { - self._tryAllClients(function(client, done) { - client.getBlock(blockhash, true, function(err, response) { + self._tryAllClients(function (client, done) { + client.getBlock(blockhash, true, function (err, response) { if (err) { return done(self._wrapRPCError(err)); } @@ -1894,7 +1902,7 @@ Dash.prototype.getBlockOverview = function(blockArg, callback) { nonce: result.nonce, bits: result.bits, difficulty: result.difficulty, - txids: result.tx + txids: result.tx, }; self.blockOverviewCache.set(blockhash, blockOverview); done(null, blockOverview); @@ -1911,7 +1919,7 @@ Dash.prototype.getBlockOverview = function(blockArg, callback) { * @param {String|Number} block - A block hash or block height number * @param {Function} callback */ -Dash.prototype.getBlock = function(blockArg, callback) { +Dash.prototype.getBlock = function (blockArg, callback) { // TODO apply performance patch to the RPC method for raw data var self = this; @@ -1921,12 +1929,12 @@ Dash.prototype.getBlock = function(blockArg, callback) { } var cachedBlock = self.blockCache.get(blockhash); if (cachedBlock) { - return setImmediate(function() { + return setImmediate(function () { callback(null, cachedBlock); }); } else { - self._tryAllClients(function(client, done) { - client.getBlock(blockhash, false, function(err, response) { + self._tryAllClients(function (client, done) { + client.getBlock(blockhash, false, function (err, response) { if (err) { return done(self._wrapRPCError(err)); } @@ -1947,9 +1955,9 @@ Dash.prototype.getBlock = function(blockArg, callback) { * @param {Number} low - The older timestamp in seconds * @param {Function} callback */ -Dash.prototype.getBlockHashesByTimestamp = function(high, low, callback) { +Dash.prototype.getBlockHashesByTimestamp = function (high, low, callback) { var self = this; - self.client.getBlockHashes(high, low, function(err, response) { + self.client.getBlockHashes(high, low, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -1977,15 +1985,15 @@ Dash.prototype.getBlockHashesByTimestamp = function(high, low, callback) { * @param {String|Number} block - A block hash or block height * @param {Function} callback */ -Dash.prototype.getBlockHeader = function(blockArg, callback) { +Dash.prototype.getBlockHeader = function (blockArg, callback) { var self = this; function queryHeader(err, blockhash) { if (err) { return callback(err); } - self._tryAllClients(function(client, done) { - client.getBlockHeader(blockhash, function(err, response) { + self._tryAllClients(function (client, done) { + client.getBlockHeader(blockhash, function (err, response) { if (err) { return done(self._wrapRPCError(err)); } @@ -2003,7 +2011,7 @@ Dash.prototype.getBlockHeader = function(blockArg, callback) { medianTime: result.mediantime, nonce: result.nonce, bits: result.bits, - difficulty: result.difficulty + difficulty: result.difficulty, }; done(null, header); }); @@ -2034,47 +2042,50 @@ Dash.prototype.getBlockHeader = function(blockArg, callback) { * @param {Function} callback * @param {String|Number} nbOfBlockToFetch - A value allowing to choose how many block to fetch */ -Dash.prototype.getBlockHeaders = function(blockArg, callback, nbOfBlockToFetch) { - var self = this; - var _toFetch = 25; - - if (nbOfBlockToFetch) { +Dash.prototype.getBlockHeaders = function (blockArg, callback, nbOfBlockToFetch) { + var self = this; + var _toFetch = 25; - if (nbOfBlockToFetch.constructor.name === 'String' && !isNaN(parseInt(nbOfBlockToFetch))) { + if (nbOfBlockToFetch) { + if (nbOfBlockToFetch.constructor.name === "String" && !isNaN(parseInt(nbOfBlockToFetch))) { _toFetch = parseInt(nbOfBlockToFetch); - } - if (nbOfBlockToFetch.constructor.name === 'Number') { - _toFetch = nbOfBlockToFetch; - } - if (_toFetch > 250) { - _toFetch = 250;//Limit to avoid asking to many blocks. - } - } - - self._maybeGetBlockHash(blockArg, function(err, blockhash) { - if (err) { - return callback(err); + } + if (nbOfBlockToFetch.constructor.name === "Number") { + _toFetch = nbOfBlockToFetch; + } + if (_toFetch > 250) { + _toFetch = 250; //Limit to avoid asking to many blocks. + } + } + + self._maybeGetBlockHash(blockArg, function (err, blockhash) { + if (err) { + return callback(err); } var headers = []; var nextHash = blockhash; var headersLeft = _toFetch; - async.until(function until() { - return headersLeft === 0 || !nextHash; - }, function getHeader(done) { - self.getBlockHeader(nextHash, function (err, blockHeader) { - if (err) { - return done(err); - } - headersLeft--; - if (!blockHeader) { + async.until( + function until() { + return headersLeft === 0 || !nextHash; + }, + function getHeader(done) { + self.getBlockHeader(nextHash, function (err, blockHeader) { + if (err) { + return done(err); + } + headersLeft--; + if (!blockHeader) { + return done(null, headers); + } + headers.push(blockHeader); + nextHash = blockHeader.nextHash; return done(null, headers); - } - headers.push(blockHeader); - nextHash = blockHeader.nextHash; - return done(null, headers); - }); - }, callback); + }); + }, + callback + ); }); }; @@ -2083,9 +2094,9 @@ Dash.prototype.getBlockHeaders = function(blockArg, callback, nbOfBlockToFetch) * @param {Number} blocks - The number of blocks for the transaction to be confirmed. * @param {Function} callback */ -Dash.prototype.estimateFee = function(blocks, callback) { +Dash.prototype.estimateFee = function (blocks, callback) { var self = this; - this.client.estimateFee(blocks, function(err, response) { + this.client.estimateFee(blocks, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2100,40 +2111,39 @@ Dash.prototype.estimateFee = function(blocks, callback) { * @param {Boolean=} options.maxFeeRate - Cap large fees (0 for unlimited) * @param {Function} callback */ -Dash.prototype.sendTransaction = function(tx, options, callback) { +Dash.prototype.sendTransaction = function (tx, options, callback) { var self = this; - var maxFeeRate = 0.00015000; // duff/kB (typically 1000) + var maxFeeRate = 0.00015; // duff/kB (typically 1000) var isInstantSend = false; if (_.isFunction(options) && _.isUndefined(callback)) { callback = options; } else if (_.isObject(options)) { - if(options.hasOwnProperty('maxFeeRate')){ - maxFeeRate = options.maxFeeRate; + if (options.hasOwnProperty("maxFeeRate")) { + maxFeeRate = options.maxFeeRate; } - if(options.hasOwnProperty('allowAbsurdFees')){ + if (options.hasOwnProperty("allowAbsurdFees")) { console.warn(`the boolean 'allowAbsurdFees' has been replaced by the int 'maxFeeRate'`); - if(true === options.allowAbsurdFees) { + if (true === options.allowAbsurdFees) { maxFeeRate = 0; // unlimited } } - if(options.hasOwnProperty('isInstantSend')){ - isInstantSend = options.isInstantSend; + if (options.hasOwnProperty("isInstantSend")) { + isInstantSend = options.isInstantSend; } } - this.client.sendRawTransaction(tx, maxFeeRate, isInstantSend, function(err, response) { + this.client.sendRawTransaction(tx, maxFeeRate, isInstantSend, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } callback(null, response.result); }); - }; -Dash.prototype._getRawTransactionData = function(txid, callback) { +Dash.prototype._getRawTransactionData = function (txid, callback) { var self = this; - self._tryAllClients(function(client, done) { - client.getRawTransaction(txid, function(err, response) { + self._tryAllClients(function (client, done) { + client.getRawTransaction(txid, function (err, response) { if (err) { return done(self._wrapRPCError(err)); } @@ -2147,19 +2157,19 @@ Dash.prototype._getRawTransactionData = function(txid, callback) { * @param {String} txid - The transaction hash * @param {Function} callback */ -Dash.prototype.getRawTransaction = function(txid, callback) { +Dash.prototype.getRawTransaction = function (txid, callback) { var self = this; var tx = self.rawTransactionCache.get(txid); if (tx) { - return setImmediate(function() { + return setImmediate(function () { callback(null, tx); }); } else { - self._getRawTransactionData(txid, function(err, transactionData) { + self._getRawTransactionData(txid, function (err, transactionData) { if (err) { return callback(err); } - var buffer = new Buffer(transactionData, 'hex'); + var buffer = new Buffer(transactionData, "hex"); self.rawTransactionCache.set(txid, buffer); callback(null, buffer); }); @@ -2172,15 +2182,15 @@ Dash.prototype.getRawTransaction = function(txid, callback) { * @param {Boolean} queryMempool - Include the mempool * @param {Function} callback */ -Dash.prototype.getTransaction = function(txid, callback) { +Dash.prototype.getTransaction = function (txid, callback) { var self = this; var tx = self.transactionCache.get(txid); if (tx) { - return setImmediate(function() { + return setImmediate(function () { callback(null, tx); }); } else { - self._getRawTransactionData(txid, function(err, transactionData) { + self._getRawTransactionData(txid, function (err, transactionData) { if (err) { return callback(err); } @@ -2234,14 +2244,14 @@ Dash.prototype.getTransaction = function(txid, callback) { * @param {String} txid - The hex string of the transaction * @param {Function} callback */ -Dash.prototype.getDetailedTransaction = function(txid, callback) { +Dash.prototype.getDetailedTransaction = function (txid, callback) { var self = this; var tx = self.transactionDetailedCache.get(txid); function addInputsToTx(tx, result) { tx.inputs = []; tx.inputSatoshis = 0; - for(var inputIndex = 0; inputIndex < result.vin.length; inputIndex++) { + for (var inputIndex = 0; inputIndex < result.vin.length; inputIndex++) { var input = result.vin[inputIndex]; if (!tx.coinbase) { tx.inputSatoshis += input.valueSat; @@ -2261,7 +2271,7 @@ Dash.prototype.getDetailedTransaction = function(txid, callback) { scriptAsm: scriptAsm || null, sequence: input.sequence, address: input.address || null, - satoshis: _.isUndefined(input.valueSat) ? null : input.valueSat + satoshis: _.isUndefined(input.valueSat) ? null : input.valueSat, }); } } @@ -2269,7 +2279,7 @@ Dash.prototype.getDetailedTransaction = function(txid, callback) { function addOutputsToTx(tx, result) { tx.outputs = []; tx.outputSatoshis = 0; - for(var outputIndex = 0; outputIndex < result.vout.length; outputIndex++) { + for (var outputIndex = 0; outputIndex < result.vout.length; outputIndex++) { var out = result.vout[outputIndex]; tx.outputSatoshis += out.valueSat; var address = null; @@ -2283,7 +2293,7 @@ Dash.prototype.getDetailedTransaction = function(txid, callback) { spentTxId: out.spentTxId, spentIndex: out.spentIndex, spentHeight: out.spentHeight, - address: address + address: address, }); } } @@ -2321,12 +2331,12 @@ Dash.prototype.getDetailedTransaction = function(txid, callback) { } if (tx) { - return setImmediate(function() { + return setImmediate(function () { callback(null, tx); }); } else { - self._tryAllClients(function(client, done) { - client.getRawTransaction(txid, 1, function(err, response) { + self._tryAllClients(function (client, done) { + client.getRawTransaction(txid, 1, function (err, response) { if (err) { return done(self._wrapRPCError(err)); } @@ -2365,15 +2375,14 @@ Dash.prototype.getDetailedTransaction = function(txid, callback) { } }; - /** * Returns a list of governance objects. * @param options - should be either "1" or "2", used to filter the object type * @param callback */ -Dash.prototype.govObjectList = function(options, callback) { +Dash.prototype.govObjectList = function (options, callback) { var self = this; - this.client.gobject('list', function(err, response) { + this.client.gobject("list", function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2381,38 +2390,35 @@ Dash.prototype.govObjectList = function(options, callback) { var result = []; for (var i = 0; i < gobjects.length; i++) { - var proposal = new Proposal(response.result[gobjects[i]].DataHex); - if ((options.type && proposal.type === options.type)) { - result.push({ - Hash: gobjects[i], - DataHex: response.result.DataHex, - DataObject: { - end_epoch: proposal.end_epoch, - name: proposal.name, - payment_address: proposal.payment_address, - payment_amount: proposal.payment_amount, - start_epoch: proposal.start_epoch, - type: proposal.type, - url: proposal.url - }, - AbsoluteYesCount: response.result[gobjects[i]].AbsoluteYesCount, - YesCount: response.result[gobjects[i]].YesCount, - NoCount: response.result[gobjects[i]].NoCount, - AbstainCount: response.result[gobjects[i]].AbstainCount - }); + if (options.type && proposal.type === options.type) { + result.push({ + Hash: gobjects[i], + DataHex: response.result.DataHex, + DataObject: { + end_epoch: proposal.end_epoch, + name: proposal.name, + payment_address: proposal.payment_address, + payment_amount: proposal.payment_amount, + start_epoch: proposal.start_epoch, + type: proposal.type, + url: proposal.url, + }, + AbsoluteYesCount: response.result[gobjects[i]].AbsoluteYesCount, + YesCount: response.result[gobjects[i]].YesCount, + NoCount: response.result[gobjects[i]].NoCount, + AbstainCount: response.result[gobjects[i]].AbstainCount, + }); } - } callback(null, result); - }); }; Dash.prototype.getCurrentVotes = function (govhash, callback) { var self = this; - this.client.gobject('getcurrentvotes', govhash, function(err, response) { + this.client.gobject("getcurrentvotes", govhash, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2422,7 +2428,7 @@ Dash.prototype.getCurrentVotes = function (govhash, callback) { Dash.prototype.getVotes = function (govhash, callback) { var self = this; - this.client.gobject('getvotes', govhash, function(err, response) { + this.client.gobject("getvotes", govhash, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2432,7 +2438,7 @@ Dash.prototype.getVotes = function (govhash, callback) { Dash.prototype.getSuperBlockBudget = function (blockindex, callback) { var self = this; - this.client.getsuperblockbudget(blockindex, function(err, response) { + this.client.getsuperblockbudget(blockindex, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2442,7 +2448,7 @@ Dash.prototype.getSuperBlockBudget = function (blockindex, callback) { /*jshint maxparams: 6 */ Dash.prototype.govObjectSubmit = function (parentHash, revision, time, dataHex, feeTxId, callback) { var self = this; - this.client.gobject('submit', parentHash, revision, time, dataHex, feeTxId, function(err, response) { + this.client.gobject("submit", parentHash, revision, time, dataHex, feeTxId, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2452,7 +2458,7 @@ Dash.prototype.govObjectSubmit = function (parentHash, revision, time, dataHex, Dash.prototype.govObjectDeserialize = function (hexdata, callback) { var self = this; - this.client.gobject('deserialize', hexdata, function(err, response) { + this.client.gobject("deserialize", hexdata, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2460,10 +2466,10 @@ Dash.prototype.govObjectDeserialize = function (hexdata, callback) { }); }; -Dash.prototype.govObjectCheck = function(hexdata, callback){ +Dash.prototype.govObjectCheck = function (hexdata, callback) { var self = this; - this.client.gobject('check', hexdata, function(err, response) { + this.client.gobject("check", hexdata, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2472,61 +2478,59 @@ Dash.prototype.govObjectCheck = function(hexdata, callback){ }; Dash.prototype.govObjectInfo = function (callback) { var self = this; - var result = self.govCache.get('info'); - if(result){ + var result = self.govCache.get("info"); + if (result) { callback(null, result); - }else{ - this.client.getgovernanceinfo(function(err, response) { - + } else { + this.client.getgovernanceinfo(function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } - self.govCache.set('info',response); + self.govCache.set("info", response); callback(null, response); }); } }; Dash.prototype.govCount = function (callback) { var self = this; - var result = self.govCache.get('count'); - if(result){ + var result = self.govCache.get("count"); + if (result) { callback(null, result); - }else{ - this.client.gobject('count',function(err, response) { - + } else { + this.client.gobject("count", function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } - self.govCache.set('count',response); + self.govCache.set("count", response); callback(null, response); }); } }; -Dash.prototype.getSpork = function(callback){ - var self = this; - var SporksList = {}; - self.client.spork('show', function(err, response){ - if(response && response.hasOwnProperty('result')){ - var result = {sporks:response.result}; - var SporksData = self.sporksListCache.get(''); - if (SporksData) { - return setImmediate(function() { - callback(null, SporksData); - }); - }else{ - SporksList=result; - self.sporksListCache.set('', SporksList); - return callback(null, SporksList); - } - }else{ - return callback(new Error('Impossible to get Sporks Data'),null); - } - }); -}; - -Dash.prototype.getMNList = function(callback){ +Dash.prototype.getSpork = function (callback) { + var self = this; + var SporksList = {}; + self.client.spork("show", function (err, response) { + if (response && response.hasOwnProperty("result")) { + var result = { sporks: response.result }; + var SporksData = self.sporksListCache.get(""); + if (SporksData) { + return setImmediate(function () { + callback(null, SporksData); + }); + } else { + SporksList = result; + self.sporksListCache.set("", SporksList); + return callback(null, SporksList); + } + } else { + return callback(new Error("Impossible to get Sporks Data"), null); + } + }); +}; + +Dash.prototype.getMNList = function (callback) { var self = this; - var rawResults= {}; + var rawResults = {}; var MNList = []; var checkSync = function checkSync(next) { @@ -2535,176 +2539,166 @@ Dash.prototype.getMNList = function(callback){ return next(err); } if (!isSynced) { - return next(new Error('Blockchain is not synced yet')); + return next(new Error("Blockchain is not synced yet")); } return next(); }); }; - var getRank = function(next){ - self.client.masternodelist('rank', function(err, response){ - if(response && response.hasOwnProperty('result')){ + var getRank = function (next) { + self.client.masternodelist("rank", function (err, response) { + if (response && response.hasOwnProperty("result")) { var result = response.result; - rawResults.rank=result; + rawResults.rank = result; } - next(); + next(); }); }; - var getProtocol = function(next){ - self.client.masternodelist('protocol', function(err, response){ - if(response && response.hasOwnProperty('result')){ - var result = response.result; - rawResults.protocol=result; - } - next(); - }); + var getProtocol = function (next) { + self.client.masternodelist("protocol", function (err, response) { + if (response && response.hasOwnProperty("result")) { + var result = response.result; + rawResults.protocol = result; + } + next(); + }); }; - var getPayee = function(next){ - self.client.masternodelist('payee', function(err, response){ - if(response && response.hasOwnProperty('result')){ - var result = response.result; - rawResults.payee=result; - } - next(); - }); + var getPayee = function (next) { + self.client.masternodelist("payee", function (err, response) { + if (response && response.hasOwnProperty("result")) { + var result = response.result; + rawResults.payee = result; + } + next(); + }); }; - var getLastSeen = function(next){ - self.client.masternodelist('lastseen', function(err, response){ - if(response && response.hasOwnProperty('result')){ - var result = response.result; - rawResults.lastseen=result; - } - next(); - }); + var getLastSeen = function (next) { + self.client.masternodelist("lastseen", function (err, response) { + if (response && response.hasOwnProperty("result")) { + var result = response.result; + rawResults.lastseen = result; + } + next(); + }); }; - var getActiveSeconds=function(next){ - self.client.masternodelist('activeseconds', function(err, response){ - if(response && response.hasOwnProperty('result')){ - var result = response.result; - rawResults.activeseconds=result; - } - next(); - }); + var getActiveSeconds = function (next) { + self.client.masternodelist("activeseconds", function (err, response) { + if (response && response.hasOwnProperty("result")) { + var result = response.result; + rawResults.activeseconds = result; + } + next(); + }); }; - var getIP = function(next){ - self.client.masternodelist('addr', function(err, response){ - if(response && response.hasOwnProperty('result')){ - var result = response.result; - rawResults.addr=result; - } - next(); - }); + var getIP = function (next) { + self.client.masternodelist("addr", function (err, response) { + if (response && response.hasOwnProperty("result")) { + var result = response.result; + rawResults.addr = result; + } + next(); + }); }; - var getStatus = function(next){ - self.client.masternodelist('status', function(err, response){ - if(response && response.hasOwnProperty('result')){ - var result = response.result; - rawResults.status=result; - } - next(); - }); + var getStatus = function (next) { + self.client.masternodelist("status", function (err, response) { + if (response && response.hasOwnProperty("result")) { + var result = response.result; + rawResults.status = result; + } + next(); + }); }; - var prepareResponse = function(err){ - if(err){ - return callback(self._wrapRPCError(err),null); + var prepareResponse = function (err) { + if (err) { + return callback(self._wrapRPCError(err), null); } var keys = Object.keys(rawResults); - if( - keys.indexOf('rank') > -1 && - keys.indexOf('protocol')> -1 && - keys.indexOf('payee')> -1 && - keys.indexOf('lastseen')> -1 && - keys.indexOf('activeseconds')> -1 && - keys.indexOf('addr')> -1 - ){ - var rankKeys = Object.keys(rawResults.lastseen); - var rankLength = rankKeys.length; - - //We get threw all vins by rank - for(var i = 0; i -1 && + keys.indexOf("protocol") > -1 && + keys.indexOf("payee") > -1 && + keys.indexOf("lastseen") > -1 && + keys.indexOf("activeseconds") > -1 && + keys.indexOf("addr") > -1 + ) { + var rankKeys = Object.keys(rawResults.lastseen); + var rankLength = rankKeys.length; + + //We get threw all vins by rank + for (var i = 0; i < rankLength; i++) { + var vin = rankKeys[i]; + var MN = { + vin: vin, + status: rawResults.status[vin], + rank: i + 1, + ip: rawResults.addr[vin], + protocol: rawResults.protocol[vin], + payee: rawResults.payee[vin], + activeseconds: rawResults.activeseconds[vin], + lastseen: rawResults.lastseen[vin], + }; + MNList.push(MN); + } + } else { + return callback(new Error("Invalid MasternodeList"), null); } - self.masternodeListCache.set('', MNList); - return callback(null, MNList); + self.masternodeListCache.set("", MNList); + return callback(null, MNList); }; - var MNListData = self.masternodeListCache.get(''); + var MNListData = self.masternodeListCache.get(""); if (MNListData) { - return setImmediate(function() { - callback(null, MNListData); - }); + return setImmediate(function () { + callback(null, MNListData); + }); } else { - return async.series([ - checkSync, - getRank, - getProtocol, - getPayee, - getLastSeen, - getActiveSeconds, - getIP, - getStatus - ], - prepareResponse); + return async.series( + [checkSync, getRank, getProtocol, getPayee, getLastSeen, getActiveSeconds, getIP, getStatus], + prepareResponse + ); } }; - /** * Retrieves a Governance Object by Hash * @param hash * @param callback */ -Dash.prototype.govObjectHash = function(hash, callback) { +Dash.prototype.govObjectHash = function (hash, callback) { var self = this; - this.client.gobject('get', hash, function(err, response) { - if (err) { - return callback(self._wrapRPCError(err)); - } + this.client.gobject("get", hash, function (err, response) { + if (err) { + return callback(self._wrapRPCError(err)); + } - var result = []; - - var proposal = new Proposal(response.result.DataHex); - - // TODO: serialize proposal back to Hex to verify it's consistent with RPC - result.push({ - Hash: response.result.Hash, - CollateralHash: response.result.CollateralHash, - DataHex: response.result.DataHex, - DataObject: { - end_epoch: proposal.end_epoch, - name: proposal.name, - payment_address: proposal.payment_address, - payment_amount: proposal.payment_amount, - start_epoch: proposal.start_epoch, - type: proposal.type, - url: proposal.url - }, - CreationTime: response.result.CreationTime, - FundingResult: response.result.FundingResult, - ValidResult: response.result.ValidResult, - DeleteResult: response.result.DeleteResult, - EndorsedResult: response.result.EndorsedResult - }); + var result = []; - callback(null, result); + var proposal = new Proposal(response.result.DataHex); + + // TODO: serialize proposal back to Hex to verify it's consistent with RPC + result.push({ + Hash: response.result.Hash, + CollateralHash: response.result.CollateralHash, + DataHex: response.result.DataHex, + DataObject: { + end_epoch: proposal.end_epoch, + name: proposal.name, + payment_address: proposal.payment_address, + payment_amount: proposal.payment_amount, + start_epoch: proposal.start_epoch, + type: proposal.type, + url: proposal.url, + }, + CreationTime: response.result.CreationTime, + FundingResult: response.result.FundingResult, + ValidResult: response.result.ValidResult, + DeleteResult: response.result.DeleteResult, + EndorsedResult: response.result.EndorsedResult, + }); + callback(null, result); }); - }; /** @@ -2714,7 +2708,7 @@ Dash.prototype.govObjectHash = function(hash, callback) { */ Dash.prototype.govObjectCheck = function govObjectCheck(hexdata, callback) { var self = this; - this.client.gobject('check', hexdata, function (err, response) { + this.client.gobject("check", hexdata, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2726,9 +2720,9 @@ Dash.prototype.govObjectCheck = function govObjectCheck(hexdata, callback) { * Will get the best block hash for the chain. * @param {Function} callback */ -Dash.prototype.getBestBlockHash = function(callback) { +Dash.prototype.getBestBlockHash = function (callback) { var self = this; - this.client.getBestBlockHash(function(err, response) { + this.client.getBestBlockHash(function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2750,14 +2744,13 @@ Dash.prototype.getBestChainLock = function (callback) { }); }; - /** * Will give the txid and inputIndex that spent an output * @param {Function} callback */ -Dash.prototype.getSpentInfo = function(options, callback) { +Dash.prototype.getSpentInfo = function (options, callback) { var self = this; - this.client.getSpentInfo(options, function(err, response) { + this.client.getSpentInfo(options, function (err, response) { if (err && err.code === -5) { return callback(null, {}); } else if (err) { @@ -2783,17 +2776,17 @@ Dash.prototype.getSpentInfo = function(options, callback) { * } * @param {Function} callback */ -Dash.prototype.getInfo = function(callback) { +Dash.prototype.getInfo = function (callback) { var self = this; var client = this.client; - client.getNetworkInfo(function (err, networkResponse){ + client.getNetworkInfo(function (err, networkResponse) { if (err) { return callback(self._wrapRPCError(err)); } const networkInfo = networkResponse.result; - client.getBlockchainInfo(function (err, blockchainResponse){ - if(err){ + client.getBlockchainInfo(function (err, blockchainResponse) { + if (err) { return callback(self._wrapRPCError(err)); } const blockchainInfo = blockchainResponse.result; @@ -2809,16 +2802,16 @@ Dash.prototype.getInfo = function(callback) { timeOffset: networkInfo.timeoffset, connections: networkInfo.connections, relayFee: networkInfo.relayfee, - network: self.node.getNetworkName() + network: self.node.getNetworkName(), }; callback(null, info); }); }); }; -Dash.prototype.generateBlock = function(num, callback) { +Dash.prototype.generateBlock = function (num, callback) { var self = this; - this.client.generate(num, function(err, response) { + this.client.generate(num, function (err, response) { if (err) { return callback(self._wrapRPCError(err)); } @@ -2830,14 +2823,14 @@ Dash.prototype.generateBlock = function(num, callback) { * Called by Node to stop the service. * @param {Function} callback */ -Dash.prototype.stop = function(callback) { +Dash.prototype.stop = function (callback) { if (this.spawn && this.spawn.process) { var exited = false; - this.spawn.process.once('exit', function(code) { + this.spawn.process.once("exit", function (code) { if (!exited) { exited = true; if (code !== 0) { - var error = new Error('dashd spawned process exited with status code: ' + code); + var error = new Error("dashd spawned process exited with status code: " + code); error.code = code; return callback(error); } else { @@ -2845,11 +2838,11 @@ Dash.prototype.stop = function(callback) { } } }); - this.spawn.process.kill('SIGINT'); - setTimeout(function() { + this.spawn.process.kill("SIGINT"); + setTimeout(function () { if (!exited) { exited = true; - return callback(new Error('dashd process did not exit')); + return callback(new Error("dashd process did not exit")); } }, this.shutdownTimeout).unref(); } else { diff --git a/lib/services/web.js b/lib/services/web.js index f42ae5a64..99dc4c3b7 100644 --- a/lib/services/web.js +++ b/lib/services/web.js @@ -1,20 +1,19 @@ -'use strict'; - -var fs = require('fs'); -var http = require('http'); -var https = require('https'); -var express = require('express'); -var bodyParser = require('body-parser'); -var socketio = require('socket.io'); -var inherits = require('util').inherits; - -var BaseService = require('../service'); -var dashcore = require('@dashevo/dashcore-lib'); +"use strict"; + +var fs = require("fs"); +var http = require("http"); +var https = require("https"); +var express = require("express"); +var bodyParser = require("body-parser"); +var socketio = require("socket.io"); +var inherits = require("util").inherits; + +var BaseService = require("../service"); +var dashcore = require("@dashevo/dashcore-lib"); var _ = dashcore.deps._; -var index = require('../'); +var index = require("../"); var log = index.log; - /** * This service represents a hub for combining several services over a single HTTP port. Services * can extend routes by implementing the methods `getRoutePrefix` and `setupRoutes`. Additionally @@ -30,17 +29,18 @@ var log = index.log; * @param {Boolean} options.enableSocketRPC - Option to enable/disable websocket RPC handling * @param {Number} options.port - The port for the service, defaults to node settings. */ -var WebService = function(options) { +var WebService = function (options) { var self = this; this.node = options.node; this.https = options.https || this.node.https; this.httpsOptions = options.httpsOptions || this.node.httpsOptions; this.port = options.port || this.node.port || 3456; - this.enableSocketRPC = _.isUndefined(options.enableSocketRPC) ? - WebService.DEFAULT_SOCKET_RPC : options.enableSocketRPC; + this.enableSocketRPC = _.isUndefined(options.enableSocketRPC) + ? WebService.DEFAULT_SOCKET_RPC + : options.enableSocketRPC; - this.node.on('ready', function() { + this.node.on("ready", function () { self.eventNames = self.getEventNames(); self.setupAllRoutes(); self.server.listen(self.port); @@ -57,12 +57,12 @@ WebService.DEFAULT_SOCKET_RPC = true; * Called by Node to start the service * @param {Function} callback */ -WebService.prototype.start = function(callback) { +WebService.prototype.start = function (callback) { this.app = express(); this.app.use(bodyParser.json()); - this.app.set('trust proxy', ['loopback', 'uniquelocal']); + this.app.set("trust proxy", ["loopback", "uniquelocal"]); - if(this.https) { + if (this.https) { this.transformHttpsOptions(); this.server = https.createServer(this.httpsOptions, this.app); } else { @@ -70,7 +70,7 @@ WebService.prototype.start = function(callback) { } this.io = socketio.listen(this.server); - this.io.on('connection', this.socketHandler.bind(this)); + this.io.on("connection", this.socketHandler.bind(this)); setImmediate(callback); }; @@ -79,11 +79,11 @@ WebService.prototype.start = function(callback) { * Called by Node. stop the service * @param {Function} callback */ -WebService.prototype.stop = function(callback) { +WebService.prototype.stop = function (callback) { var self = this; - setImmediate(function() { - if(self.server) { + setImmediate(function () { + if (self.server) { self.server.close(); } callback(); @@ -94,16 +94,16 @@ WebService.prototype.stop = function(callback) { * This function will iterate over all of the available services gathering * all of the exposed HTTP routes. */ -WebService.prototype.setupAllRoutes = function() { - for(var key in this.node.services) { +WebService.prototype.setupAllRoutes = function () { + for (var key in this.node.services) { var subApp = new express(); var service = this.node.services[key]; - if(service.getRoutePrefix && service.setupRoutes) { - this.app.use('/' + this.node.services[key].getRoutePrefix(), subApp); + if (service.getRoutePrefix && service.setupRoutes) { + this.app.use("/" + this.node.services[key].getRoutePrefix(), subApp); this.node.services[key].setupRoutes(subApp, express); } else { - log.debug('No routes defined for: ' + key); + log.debug("No routes defined for: " + key); } } }; @@ -112,21 +112,21 @@ WebService.prototype.setupAllRoutes = function() { * This function will construct an API methods map of all of the * available methods that can be called from enable services. */ -WebService.prototype.createMethodsMap = function() { +WebService.prototype.createMethodsMap = function () { var self = this; var methods = this.node.getAllAPIMethods(); this.methodsMap = {}; - methods.forEach(function(data) { + methods.forEach(function (data) { var name = data[0]; var instance = data[1]; var method = data[2]; var args = data[3]; self.methodsMap[name] = { - fn: function() { + fn: function () { return method.apply(instance, arguments); }, - args: args + args: args, }; }); }; @@ -135,22 +135,22 @@ WebService.prototype.createMethodsMap = function() { * This function will gather all of the available events exposed from * the enabled services. */ -WebService.prototype.getEventNames = function() { +WebService.prototype.getEventNames = function () { var events = this.node.getAllPublishEvents(); var eventNames = []; function addEventName(name) { - if(eventNames.indexOf(name) > -1) { - throw new Error('Duplicate event ' + name); + if (eventNames.indexOf(name) > -1) { + throw new Error("Duplicate event " + name); } eventNames.push(name); } - events.forEach(function(event) { + events.forEach(function (event) { addEventName(event.name); - if(event.extraEvents) { - event.extraEvents.forEach(function(name) { + if (event.extraEvents) { + event.extraEvents.forEach(function (name) { addEventName(name); }); } @@ -159,8 +159,8 @@ WebService.prototype.getEventNames = function() { return eventNames; }; -WebService.prototype._getRemoteAddress = function(socket) { - return socket.client.request.headers['cf-connecting-ip'] || socket.conn.remoteAddress; +WebService.prototype._getRemoteAddress = function (socket) { + return socket.client.request.headers["cf-connecting-ip"] || socket.conn.remoteAddress; }; /** @@ -168,31 +168,31 @@ WebService.prototype._getRemoteAddress = function(socket) { * instantiating a new Bus, subscribing/unsubscribing and handling RPC commands. * @param {Socket} socket - A socket.io socket instance */ -WebService.prototype.socketHandler = function(socket) { +WebService.prototype.socketHandler = function (socket) { var self = this; var remoteAddress = self._getRemoteAddress(socket); - var bus = this.node.openBus({remoteAddress: remoteAddress}); + var bus = this.node.openBus({ remoteAddress: remoteAddress }); if (this.enableSocketRPC) { - socket.on('message', this.socketMessageHandler.bind(this)); + socket.on("message", this.socketMessageHandler.bind(this)); } - socket.on('subscribe', function(name, params) { - log.info(remoteAddress, 'web socket subscribe:', name); + socket.on("subscribe", function (name, params) { + log.info(remoteAddress, "web socket subscribe:", name); bus.subscribe(name, params); }); - socket.on('unsubscribe', function(name, params) { - log.info(remoteAddress, 'web socket unsubscribe:', name); + socket.on("unsubscribe", function (name, params) { + log.info(remoteAddress, "web socket unsubscribe:", name); bus.unsubscribe(name, params); }); - this.eventNames.forEach(function(eventName) { - bus.on(eventName, function() { - if(socket.connected) { + this.eventNames.forEach(function (eventName) { + bus.on(eventName, function () { + if (socket.connected) { var results = []; - for(var i = 0; i < arguments.length; i++) { + for (var i = 0; i < arguments.length; i++) { results.push(arguments[i]); } @@ -202,8 +202,8 @@ WebService.prototype.socketHandler = function(socket) { }); }); - socket.on('disconnect', function() { - log.info(remoteAddress, 'web socket disconnect'); + socket.on("disconnect", function () { + log.info(remoteAddress, "web socket disconnect"); bus.close(); }); }; @@ -214,31 +214,31 @@ WebService.prototype.socketHandler = function(socket) { * @param {Object} message - The socket.io "message" object * @param {Function} socketCallback */ -WebService.prototype.socketMessageHandler = function(message, socketCallback) { +WebService.prototype.socketMessageHandler = function (message, socketCallback) { if (this.methodsMap[message.method]) { var params = message.params; - if(!params || !params.length) { + if (!params || !params.length) { params = []; } - if(params.length !== this.methodsMap[message.method].args) { + if (params.length !== this.methodsMap[message.method].args) { return socketCallback({ error: { - message: 'Expected ' + this.methodsMap[message.method].args + ' parameter(s)' - } + message: "Expected " + this.methodsMap[message.method].args + " parameter(s)", + }, }); } - var callback = function(err, result) { + var callback = function (err, result) { var response = {}; - if(err) { + if (err) { response.error = { - message: err.toString() + message: err.toString(), }; } - if(result) { + if (result) { response.result = result; } @@ -250,8 +250,8 @@ WebService.prototype.socketMessageHandler = function(message, socketCallback) { } else { socketCallback({ error: { - message: 'Method Not Found' - } + message: "Method Not Found", + }, }); } }; @@ -260,14 +260,14 @@ WebService.prototype.socketMessageHandler = function(message, socketCallback) { * This method will read `key` and `cert` from disk based on `httpsOptions` and * replace the options with the files. */ -WebService.prototype.transformHttpsOptions = function() { - if(!this.httpsOptions || !this.httpsOptions.key || !this.httpsOptions.cert) { - throw new Error('Missing https options'); +WebService.prototype.transformHttpsOptions = function () { + if (!this.httpsOptions || !this.httpsOptions.key || !this.httpsOptions.cert) { + throw new Error("Missing https options"); } this.httpsOptions = { key: fs.readFileSync(this.httpsOptions.key), - cert: fs.readFileSync(this.httpsOptions.cert) + cert: fs.readFileSync(this.httpsOptions.cert), }; }; diff --git a/lib/utils.js b/lib/utils.js index b4b3af7a0..3b45d4979 100644 --- a/lib/utils.js +++ b/lib/utils.js @@ -1,18 +1,20 @@ -'use strict'; +"use strict"; var MAX_SAFE_INTEGER = 0x1fffffffffffff; // 2 ^ 53 - 1 var utils = {}; utils.isHash = function isHash(value) { - return typeof value === 'string' && value.length === 64 && /^[0-9a-fA-F]+$/.test(value); + return typeof value === "string" && value.length === 64 && /^[0-9a-fA-F]+$/.test(value); }; utils.isSafeNatural = function isSafeNatural(value) { - return typeof value === 'number' && + return ( + typeof value === "number" && isFinite(value) && Math.floor(value) === value && value >= 0 && - value <= MAX_SAFE_INTEGER; + value <= MAX_SAFE_INTEGER + ); }; utils.startAtZero = function startAtZero(obj, key) { @@ -21,17 +23,17 @@ utils.startAtZero = function startAtZero(obj, key) { } }; -utils.isAbsolutePath = require('path').isAbsolute; +utils.isAbsolutePath = require("path").isAbsolute; if (!utils.isAbsolutePath) { - utils.isAbsolutePath = require('path-is-absolute'); + utils.isAbsolutePath = require("path-is-absolute"); } utils.parseParamsWithJSON = function parseParamsWithJSON(paramsArg) { - var params = paramsArg.map(function(paramArg) { + var params = paramsArg.map(function (paramArg) { var param; try { param = JSON.parse(paramArg); - } catch(err) { + } catch (err) { param = paramArg; } return param; diff --git a/regtest/cluster.js b/regtest/cluster.js index 5403e80e8..dd0b19ae9 100755 --- a/regtest/cluster.js +++ b/regtest/cluster.js @@ -1,166 +1,171 @@ -'use strict'; +"use strict"; -var path = require('path'); -var async = require('async'); -var spawn = require('child_process').spawn; +var path = require("path"); +var async = require("async"); +var spawn = require("child_process").spawn; -var DashdRPC = require('@dashevo/dashd-rpc'); -var rimraf = require('rimraf'); -var dashcore = require('@dashevo/dashcore-lib'); -var chai = require('chai'); +var DashdRPC = require("@dashevo/dashd-rpc"); +var rimraf = require("rimraf"); +var dashcore = require("@dashevo/dashcore-lib"); +var chai = require("chai"); var should = chai.should(); -var index = require('..'); +var index = require(".."); var log = index.log; -log.debug = function() {}; +log.debug = function () {}; var DashcoreNode = index.Node; var DashService = index.services.Dash; -describe('Dash Cluster', function() { +describe("Dash Cluster", function () { var node; var daemons = []; - var execPath = path.resolve(__dirname, process.env.HOME, './.dashcore/data/dashd') + var execPath = path.resolve(__dirname, process.env.HOME, "./.dashcore/data/dashd"); var nodesConf = [ { - datadir: path.resolve(__dirname, './data/node1'), - conf: path.resolve(__dirname, './data/node1/dash.conf'), - rpcuser: 'dash', - rpcpassword: 'local321', + datadir: path.resolve(__dirname, "./data/node1"), + conf: path.resolve(__dirname, "./data/node1/dash.conf"), + rpcuser: "dash", + rpcpassword: "local321", rpcport: 30521, - zmqpubrawtx: 'tcp://127.0.0.1:30611', - zmqpubhashblock: 'tcp://127.0.0.1:30611' + zmqpubrawtx: "tcp://127.0.0.1:30611", + zmqpubhashblock: "tcp://127.0.0.1:30611", }, { - datadir: path.resolve(__dirname, './data/node2'), - conf: path.resolve(__dirname, './data/node2/dash.conf'), - rpcuser: 'dash', - rpcpassword: 'local321', + datadir: path.resolve(__dirname, "./data/node2"), + conf: path.resolve(__dirname, "./data/node2/dash.conf"), + rpcuser: "dash", + rpcpassword: "local321", rpcport: 30522, - zmqpubrawtx: 'tcp://127.0.0.1:30622', - zmqpubhashblock: 'tcp://127.0.0.1:30622' + zmqpubrawtx: "tcp://127.0.0.1:30622", + zmqpubhashblock: "tcp://127.0.0.1:30622", }, { - datadir: path.resolve(__dirname, './data/node3'), - conf: path.resolve(__dirname, './data/node3/dash.conf'), - rpcuser: 'dash', - rpcpassword: 'local321', + datadir: path.resolve(__dirname, "./data/node3"), + conf: path.resolve(__dirname, "./data/node3/dash.conf"), + rpcuser: "dash", + rpcpassword: "local321", rpcport: 30523, - zmqpubrawtx: 'tcp://127.0.0.1:30633', - zmqpubhashblock: 'tcp://127.0.0.1:30633' - } + zmqpubrawtx: "tcp://127.0.0.1:30633", + zmqpubhashblock: "tcp://127.0.0.1:30633", + }, ]; - before(function(done) { - log.info('Starting 3 dashd daemons'); + before(function (done) { + log.info("Starting 3 dashd daemons"); this.timeout(200000); - async.each(nodesConf, function(nodeConf, next) { - var opts = [ - '--regtest', - '--datadir=' + nodeConf.datadir, - '--conf=' + nodeConf.conf - ]; - - rimraf(path.resolve(nodeConf.datadir, './regtest'), function(err) { - if (err) { - return done(err); - } - - var process = spawn(execPath, opts, {stdio: 'inherit'}); - - var client = new DashdRPC({ - protocol: 'http', - host: '127.0.0.1', - port: nodeConf.rpcport, - user: nodeConf.rpcuser, - pass: nodeConf.rpcpassword - }); - - daemons.push(process); - - async.retry({times: 10, interval: 5000}, function(ready) { - client.getInfo(ready); - }, next); - - }); + async.each( + nodesConf, + function (nodeConf, next) { + var opts = ["--regtest", "--datadir=" + nodeConf.datadir, "--conf=" + nodeConf.conf]; + + rimraf(path.resolve(nodeConf.datadir, "./regtest"), function (err) { + if (err) { + return done(err); + } - }, done); + var process = spawn(execPath, opts, { stdio: "inherit" }); + + var client = new DashdRPC({ + protocol: "http", + host: "127.0.0.1", + port: nodeConf.rpcport, + user: nodeConf.rpcuser, + pass: nodeConf.rpcpassword, + }); + + daemons.push(process); + + async.retry( + { times: 10, interval: 5000 }, + function (ready) { + client.getInfo(ready); + }, + next + ); + }); + }, + done + ); }); - after(function(done) { + after(function (done) { this.timeout(10000); - setTimeout(function() { - async.each(daemons, function(process, next) { - process.once('exit', next); - process.kill('SIGINT'); - }, done); + setTimeout(function () { + async.each( + daemons, + function (process, next) { + process.once("exit", next); + process.kill("SIGINT"); + }, + done + ); }, 1000); }); - it('step 1: will connect to three dashd daemons', function(done) { + it("step 1: will connect to three dashd daemons", function (done) { this.timeout(20000); var configuration = { - network: 'regtest', + network: "regtest", services: [ { - name: 'dashd', + name: "dashd", module: DashService, config: { connect: [ { - rpchost: '127.0.0.1', + rpchost: "127.0.0.1", rpcport: 30521, - rpcuser: 'dash', - rpcpassword: 'local321', - zmqpubrawtx: 'tcp://127.0.0.1:30611' + rpcuser: "dash", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:30611", }, { - rpchost: '127.0.0.1', + rpchost: "127.0.0.1", rpcport: 30522, - rpcuser: 'dash', - rpcpassword: 'local321', - zmqpubrawtx: 'tcp://127.0.0.1:30622' + rpcuser: "dash", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:30622", }, { - rpchost: '127.0.0.1', + rpchost: "127.0.0.1", rpcport: 30523, - rpcuser: 'dash', - rpcpassword: 'local321', - zmqpubrawtx: 'tcp://127.0.0.1:30633' - } - ] - } - } - ] + rpcuser: "dash", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:30633", + }, + ], + }, + }, + ], }; - var regtest = dashcore.Networks.get('regtest'); + var regtest = dashcore.Networks.get("regtest"); should.exist(regtest); node = new DashcoreNode(configuration); - node.on('error', function(err) { + node.on("error", function (err) { log.error(err); }); - node.on('ready', function() { + node.on("ready", function () { done(); }); - node.start(function(err) { + node.start(function (err) { if (err) { return done(err); } }); - }); - it('step 2: receive block events', function(done) { + it("step 2: receive block events", function (done) { this.timeout(10000); - node.services.dashd.once('tip', function(height) { + node.services.dashd.once("tip", function (height) { height.should.equal(1); done(); }); - node.generateBlock(1, function(err, hashes) { + node.generateBlock(1, function (err, hashes) { if (err) { return done(err); } @@ -168,16 +173,19 @@ describe('Dash Cluster', function() { }); }); - it('step 3: get blocks', function(done) { - async.times(3, function(n, next) { - node.getBlock(1, function(err, block) { - if (err) { - return next(err); - } - should.exist(block); - next(); - }); - }, done); + it("step 3: get blocks", function (done) { + async.times( + 3, + function (n, next) { + node.getBlock(1, function (err, block) { + if (err) { + return next(err); + } + should.exist(block); + next(); + }); + }, + done + ); }); - }); diff --git a/regtest/dashd.js b/regtest/dashd.js index 3bcf8e084..3e762c640 100755 --- a/regtest/dashd.js +++ b/regtest/dashd.js @@ -1,23 +1,23 @@ -'use strict'; +"use strict"; // To run the tests: $ mocha -R spec regtest/dashd.js -var path = require('path'); -var index = require('..'); +var path = require("path"); +var index = require(".."); var log = index.log; -var chai = require('chai'); -var dashcore = require('@dashevo/dashcore-lib'); +var chai = require("chai"); +var dashcore = require("@dashevo/dashcore-lib"); var BN = dashcore.crypto.BN; -var async = require('async'); -var rimraf = require('rimraf'); +var async = require("async"); +var rimraf = require("rimraf"); var dashd; /* jshint unused: false */ var should = chai.should(); var assert = chai.assert; -var sinon = require('sinon'); -var DashdRPC = require('@dashevo/dashd-rpc'); +var sinon = require("sinon"); +var DashdRPC = require("@dashevo/dashd-rpc"); var transactionData = []; var blockHashes = []; var utxos; @@ -26,102 +26,107 @@ var coinbasePrivateKey; var privateKey = dashcore.PrivateKey(); var destKey = dashcore.PrivateKey(); -describe('Dashd Functionality', function() { - - before(function(done) { +describe("Dashd Functionality", function () { + before(function (done) { this.timeout(200000); // Add the regtest network dashcore.Networks.enableRegtest(); - var regtestNetwork = dashcore.Networks.get('regtest'); - - var datadir = __dirname + '/data'; + var regtestNetwork = dashcore.Networks.get("regtest"); - rimraf(datadir + '/regtest', function(err) { + var datadir = __dirname + "/data"; + rimraf(datadir + "/regtest", function (err) { if (err) { throw err; } - dashd = require('../').services.Dash({ + dashd = require("../").services.Dash({ spawn: { datadir: datadir, - exec: path.resolve(__dirname, process.env.HOME, './.dashcore/data/dashd') + exec: path.resolve(__dirname, process.env.HOME, "./.dashcore/data/dashd"), }, node: { network: regtestNetwork, - getNetworkName: function() { - return 'regtest'; - } - } + getNetworkName: function () { + return "regtest"; + }, + }, }); - dashd.on('error', function(err) { + dashd.on("error", function (err) { log.error('error="%s"', err.message); }); - log.info('Waiting for Dash Core to initialize...'); + log.info("Waiting for Dash Core to initialize..."); - dashd.start(function() { - log.info('Dashd started'); + dashd.start(function () { + log.info("Dashd started"); client = new DashdRPC({ - protocol: 'http', - host: '127.0.0.1', + protocol: "http", + host: "127.0.0.1", port: 30331, - user: 'dash', - pass: 'local321', - rejectUnauthorized: false + user: "dash", + pass: "local321", + rejectUnauthorized: false, }); - log.info('Generating 100 blocks...'); + log.info("Generating 100 blocks..."); // Generate enough blocks so that the initial coinbase transactions // can be spent. - setImmediate(function() { - client.generate(150, function(err, response) { + setImmediate(function () { + client.generate(150, function (err, response) { if (err) { throw err; } blockHashes = response.result; - log.info('Preparing test data...'); + log.info("Preparing test data..."); // Get all of the unspent outputs - client.listUnspent(0, 150, function(err, response) { + client.listUnspent(0, 150, function (err, response) { utxos = response.result; - async.mapSeries(utxos, function(utxo, next) { - async.series([ - function(finished) { - // Load all of the transactions for later testing - client.getTransaction(utxo.txid, function(err, txresponse) { - if (err) { - throw err; - } - // add to the list of transactions for testing later - transactionData.push(txresponse.result.hex); - finished(); - }); - }, - function(finished) { - // Get the private key for each utxo - client.dumpPrivKey(utxo.address, function(err, privresponse) { - if (err) { - throw err; - } - utxo.privateKeyWIF = privresponse.result; - finished(); - }); + async.mapSeries( + utxos, + function (utxo, next) { + async.series( + [ + function (finished) { + // Load all of the transactions for later testing + client.getTransaction(utxo.txid, function (err, txresponse) { + if (err) { + throw err; + } + // add to the list of transactions for testing later + transactionData.push(txresponse.result.hex); + finished(); + }); + }, + function (finished) { + // Get the private key for each utxo + client.dumpPrivKey(utxo.address, function (err, privresponse) { + if (err) { + throw err; + } + utxo.privateKeyWIF = privresponse.result; + finished(); + }); + }, + ], + next + ); + }, + function (err) { + if (err) { + throw err; } - ], next); - }, function(err) { - if (err) { - throw err; + done(); } - done(); - }); + ); }); }); }); @@ -129,19 +134,18 @@ describe('Dashd Functionality', function() { }); }); - after(function(done) { + after(function (done) { this.timeout(60000); dashd.node.stopping = true; - dashd.stop(function(err, result) { + dashd.stop(function (err, result) { done(); }); }); - describe('get blocks by hash', function() { - - [0,1,2,3,5,6,7,8,9].forEach(function(i) { - it('generated block ' + i, function(done) { - dashd.getBlock(blockHashes[i], function(err, block) { + describe("get blocks by hash", function () { + [0, 1, 2, 3, 5, 6, 7, 8, 9].forEach(function (i) { + it("generated block " + i, function (done) { + dashd.getBlock(blockHashes[i], function (err, block) { if (err) { throw err; } @@ -153,10 +157,10 @@ describe('Dashd Functionality', function() { }); }); - describe('get blocks as buffers', function() { - [0,1,2,3,5,6,7,8,9].forEach(function(i) { - it('generated block ' + i, function(done) { - dashd.getRawBlock(blockHashes[i], function(err, block) { + describe("get blocks as buffers", function () { + [0, 1, 2, 3, 5, 6, 7, 8, 9].forEach(function (i) { + it("generated block " + i, function (done) { + dashd.getRawBlock(blockHashes[i], function (err, block) { if (err) { throw err; } @@ -168,9 +172,9 @@ describe('Dashd Functionality', function() { }); }); - describe('get errors as error instances', function() { - it('will wrap an rpc into a javascript error', function(done) { - dashd.client.getBlock(1000000000, function(err, response) { + describe("get errors as error instances", function () { + it("will wrap an rpc into a javascript error", function (done) { + dashd.client.getBlock(1000000000, function (err, response) { var error = dashd._wrapRPCError(err); (error instanceof Error).should.equal(true); error.message.should.equal(err.message); @@ -181,13 +185,12 @@ describe('Dashd Functionality', function() { }); }); - describe('get blocks by height', function() { - - [0,1,2,3,4,5,6,7,8,9].forEach(function(i) { - it('generated block ' + i, function(done) { + describe("get blocks by height", function () { + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function (i) { + it("generated block " + i, function (done) { // add the genesis block var height = i + 1; - dashd.getBlock(i + 1, function(err, block) { + dashd.getBlock(i + 1, function (err, block) { if (err) { throw err; } @@ -198,78 +201,77 @@ describe('Dashd Functionality', function() { }); }); - it('will get error with number greater than tip', function(done) { - dashd.getBlock(1000000000, function(err, response) { + it("will get error with number greater than tip", function (done) { + dashd.getBlock(1000000000, function (err, response) { should.exist(err); err.code.should.equal(-8); done(); }); }); - }); - describe('get transactions by hash', function() { - [0,1,2,3,4,5,6,7,8,9].forEach(function(i) { - it('for tx ' + i, function(done) { + describe("get transactions by hash", function () { + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function (i) { + it("for tx " + i, function (done) { var txhex = transactionData[i]; var tx = new dashcore.Transaction(); tx.fromString(txhex); - dashd.getTransaction(tx.hash, function(err, response) { + dashd.getTransaction(tx.hash, function (err, response) { if (err) { throw err; } - assert(response.toString('hex') === txhex, 'incorrect tx data result'); + assert(response.toString("hex") === txhex, "incorrect tx data result"); done(); }); }); }); - it('will return error if the transaction does not exist', function(done) { - var txid = '6226c407d0e9705bdd7158e60983e37d0f5d23529086d6672b07d9238d5aa618'; - dashd.getTransaction(txid, function(err, response) { + it("will return error if the transaction does not exist", function (done) { + var txid = "6226c407d0e9705bdd7158e60983e37d0f5d23529086d6672b07d9238d5aa618"; + dashd.getTransaction(txid, function (err, response) { should.exist(err); done(); }); }); }); - describe('get transactions as buffers', function() { - [0,1,2,3,4,5,6,7,8,9].forEach(function(i) { - it('for tx ' + i, function(done) { + describe("get transactions as buffers", function () { + [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function (i) { + it("for tx " + i, function (done) { var txhex = transactionData[i]; var tx = new dashcore.Transaction(); tx.fromString(txhex); - dashd.getRawTransaction(tx.hash, function(err, response) { + dashd.getRawTransaction(tx.hash, function (err, response) { if (err) { throw err; } response.should.be.instanceOf(Buffer); - assert(response.toString('hex') === txhex, 'incorrect tx data result'); + assert(response.toString("hex") === txhex, "incorrect tx data result"); done(); }); }); }); - it('will return error if the transaction does not exist', function(done) { - var txid = '6226c407d0e9705bdd7158e60983e37d0f5d23529086d6672b07d9238d5aa618'; - dashd.getRawTransaction(txid, function(err, response) { + it("will return error if the transaction does not exist", function (done) { + var txid = "6226c407d0e9705bdd7158e60983e37d0f5d23529086d6672b07d9238d5aa618"; + dashd.getRawTransaction(txid, function (err, response) { should.exist(err); done(); }); }); }); - describe('get block header', function() { + describe("get block header", function () { var expectedWork = new BN(6); - [1,2,3,4,5,6,7,8,9].forEach(function(i) { - it('generate block ' + i, function(done) { - dashd.getBlockHeader(blockHashes[i], function(err, blockIndex) { + [1, 2, 3, 4, 5, 6, 7, 8, 9].forEach(function (i) { + it("generate block " + i, function (done) { + dashd.getBlockHeader(blockHashes[i], function (err, blockIndex) { if (err) { return done(err); } should.exist(blockIndex); should.exist(blockIndex.chainWork); - var work = new BN(blockIndex.chainWork, 'hex'); + var work = new BN(blockIndex.chainWork, "hex"); work.toString(16).should.equal(expectedWork.toString(16)); expectedWork = expectedWork.add(new BN(2)); should.exist(blockIndex.prevHash); @@ -280,8 +282,8 @@ describe('Dashd Functionality', function() { }); }); }); - it('will get null prevHash for the genesis block', function(done) { - dashd.getBlockHeader(0, function(err, header) { + it("will get null prevHash for the genesis block", function (done) { + dashd.getBlockHeader(0, function (err, header) { if (err) { return done(err); } @@ -290,22 +292,22 @@ describe('Dashd Functionality', function() { done(); }); }); - it('will get error for block not found', function(done) { - dashd.getBlockHeader('notahash', function(err, header) { + it("will get error for block not found", function (done) { + dashd.getBlockHeader("notahash", function (err, header) { should.exist(err); done(); }); }); }); - describe('get block index by height', function() { + describe("get block index by height", function () { var expectedWork = new BN(6); - [2,3,4,5,6,7,8,9].forEach(function(i) { - it('generate block ' + i, function() { - dashd.getBlockHeader(i, function(err, header) { + [2, 3, 4, 5, 6, 7, 8, 9].forEach(function (i) { + it("generate block " + i, function () { + dashd.getBlockHeader(i, function (err, header) { should.exist(header); should.exist(header.chainWork); - var work = new BN(header.chainWork, 'hex'); + var work = new BN(header.chainWork, "hex"); work.toString(16).should.equal(expectedWork.toString(16)); expectedWork = expectedWork.add(new BN(2)); should.exist(header.prevHash); @@ -315,18 +317,16 @@ describe('Dashd Functionality', function() { }); }); }); - it('will get error with number greater than tip', function(done) { - dashd.getBlockHeader(100000, function(err, header) { + it("will get error with number greater than tip", function (done) { + dashd.getBlockHeader(100000, function (err, header) { should.exist(err); done(); }); }); }); - describe('send transaction functionality', function() { - - it('will not error and return the transaction hash', function(done) { - + describe("send transaction functionality", function () { + it("will not error and return the transaction hash", function (done) { // create and sign the transaction var tx = dashcore.Transaction(); tx.from(utxos[0]); @@ -335,22 +335,21 @@ describe('Dashd Functionality', function() { tx.sign(dashcore.PrivateKey.fromWIF(utxos[0].privateKeyWIF)); // test sending the transaction - dashd.sendTransaction(tx.serialize(), function(err, hash) { + dashd.sendTransaction(tx.serialize(), function (err, hash) { if (err) { return done(err); } hash.should.equal(tx.hash); done(); }); - }); - it('will throw an error if an unsigned transaction is sent', function(done) { + it("will throw an error if an unsigned transaction is sent", function (done) { var tx = dashcore.Transaction(); tx.from(utxos[1]); tx.change(privateKey.toAddress()); tx.to(destKey.toAddress(), utxos[1].amount * 1e8 - 1000); - dashd.sendTransaction(tx.uncheckedSerialize(), function(err, hash) { + dashd.sendTransaction(tx.uncheckedSerialize(), function (err, hash) { should.exist(err); (err instanceof Error).should.equal(true); should.not.exist(hash); @@ -358,13 +357,13 @@ describe('Dashd Functionality', function() { }); }); - it('will throw an error for unexpected types (tx decode failed)', function(done) { - var garbage = new Buffer('abcdef', 'hex'); - dashd.sendTransaction(garbage, function(err, hash) { + it("will throw an error for unexpected types (tx decode failed)", function (done) { + var garbage = new Buffer("abcdef", "hex"); + dashd.sendTransaction(garbage, function (err, hash) { should.exist(err); should.not.exist(hash); var num = 23; - dashd.sendTransaction(num, function(err, hash) { + dashd.sendTransaction(num, function (err, hash) { should.exist(err); (err instanceof Error).should.equal(true); should.not.exist(hash); @@ -373,7 +372,7 @@ describe('Dashd Functionality', function() { }); }); - it('will emit "tx" events', function(done) { + it('will emit "tx" events', function (done) { var tx = dashcore.Transaction(); tx.from(utxos[2]); tx.change(privateKey.toAddress()); @@ -382,23 +381,22 @@ describe('Dashd Functionality', function() { var serialized = tx.serialize(); - dashd.once('tx', function(buffer) { - buffer.toString('hex').should.equal(serialized); + dashd.once("tx", function (buffer) { + buffer.toString("hex").should.equal(serialized); done(); }); - dashd.sendTransaction(serialized, function(err, hash) { + dashd.sendTransaction(serialized, function (err, hash) { if (err) { return done(err); } should.exist(hash); }); }); - }); - describe('fee estimation', function() { - it('will estimate fees', function(done) { - dashd.estimateFee(1, function(err, fees) { + describe("fee estimation", function () { + it("will estimate fees", function (done) { + dashd.estimateFee(1, function (err, fees) { if (err) { return done(err); } @@ -408,15 +406,15 @@ describe('Dashd Functionality', function() { }); }); - describe('tip updates', function() { - it('will get an event when the tip is new', function(done) { + describe("tip updates", function () { + it("will get an event when the tip is new", function (done) { this.timeout(4000); - dashd.on('tip', function(height) { + dashd.on("tip", function (height) { if (height === 151) { done(); } }); - client.generate(1, function(err, response) { + client.generate(1, function (err, response) { if (err) { throw err; } @@ -424,19 +422,19 @@ describe('Dashd Functionality', function() { }); }); - describe('get detailed transaction', function() { - it('should include details for coinbase tx', function(done) { - dashd.getDetailedTransaction(utxos[0].txid, function(err, tx) { + describe("get detailed transaction", function () { + it("should include details for coinbase tx", function (done) { + dashd.getDetailedTransaction(utxos[0].txid, function (err, tx) { if (err) { return done(err); } should.exist(tx.height); - tx.height.should.be.a('number'); + tx.height.should.be.a("number"); should.exist(tx.blockTimestamp); should.exist(tx.blockHash); tx.coinbase.should.equal(true); tx.version.should.equal(1); - tx.hex.should.be.a('string'); + tx.hex.should.be.a("string"); tx.locktime.should.equal(0); tx.feeSatoshis.should.equal(0); tx.outputSatoshis.should.equal(500 * 1e8); @@ -445,30 +443,30 @@ describe('Dashd Functionality', function() { tx.outputs.length.should.equal(1); should.equal(tx.inputs[0].prevTxId, null); should.equal(tx.inputs[0].outputIndex, null); - tx.inputs[0].script.should.be.a('string'); + tx.inputs[0].script.should.be.a("string"); should.equal(tx.inputs[0].scriptAsm, null); should.equal(tx.inputs[0].address, null); should.equal(tx.inputs[0].satoshis, null); tx.outputs[0].satoshis.should.equal(500 * 1e8); - tx.outputs[0].script.should.be.a('string'); - tx.outputs[0].scriptAsm.should.be.a('string'); - tx.outputs[0].spentTxId.should.be.a('string'); + tx.outputs[0].script.should.be.a("string"); + tx.outputs[0].scriptAsm.should.be.a("string"); + tx.outputs[0].spentTxId.should.be.a("string"); tx.outputs[0].spentIndex.should.equal(0); - tx.outputs[0].spentHeight.should.be.a('number'); - tx.outputs[0].address.should.be.a('string'); + tx.outputs[0].spentHeight.should.be.a("number"); + tx.outputs[0].address.should.be.a("string"); tx.txlock.should.equal(false); done(); }); }); }); - describe('#getInfo', function() { - it('will get information', function(done) { - dashd.getInfo(function(err, info) { + describe("#getInfo", function () { + it("will get information", function (done) { + dashd.getInfo(function (err, info) { if (err) { return done(err); } - info.network.should.equal('regtest'); + info.network.should.equal("regtest"); should.exist(info); should.exist(info.version); should.exist(info.blocks); @@ -482,5 +480,4 @@ describe('Dashd Functionality', function() { }); }); }); - }); diff --git a/regtest/node.js b/regtest/node.js index c4c75a313..f8d4bf77e 100644 --- a/regtest/node.js +++ b/regtest/node.js @@ -1,127 +1,122 @@ -'use strict'; +"use strict"; // To run the tests: $ mocha -R spec regtest/node.js -var path = require('path'); -var index = require('..'); -var async = require('async'); +var path = require("path"); +var index = require(".."); +var async = require("async"); var log = index.log; -log.debug = function() {}; +log.debug = function () {}; -var chai = require('chai'); -var dashcore = require('@dashevo/dashcore-lib'); -var rimraf = require('rimraf'); +var chai = require("chai"); +var dashcore = require("@dashevo/dashcore-lib"); +var rimraf = require("rimraf"); var node; var should = chai.should(); -var DashdRPC = require('@dashevo/dashd-rpc'); -var index = require('..'); +var DashdRPC = require("@dashevo/dashd-rpc"); +var index = require(".."); var Transaction = dashcore.Transaction; var DashcoreNode = index.Node; var DashService = index.services.Dash; -var testWIF = 'cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG'; +var testWIF = "cSdkPxkAjA4HDr5VHgsebAPDEh9Gyub4HK8UJr2DFGGqKKy4K5sG"; var testKey; var client; var outputForIsSpentTest1; var unspentOutputSpentTxId; -describe('Node Functionality', function() { - +describe("Node Functionality", function () { var regtest; - before(function(done) { + before(function (done) { this.timeout(200000); - var datadir = __dirname + '/data'; + var datadir = __dirname + "/data"; testKey = dashcore.PrivateKey(testWIF); - rimraf(datadir + '/regtest', function(err) { - + rimraf(datadir + "/regtest", function (err) { if (err) { throw err; } var configuration = { - network: 'regtest', + network: "regtest", services: [ { - name: 'dashd', + name: "dashd", module: DashService, config: { spawn: { datadir: datadir, - exec: path.resolve(__dirname, process.env.HOME, './.dashcore/data/dashd') - } - } - } - ] + exec: path.resolve(__dirname, process.env.HOME, "./.dashcore/data/dashd"), + }, + }, + }, + ], }; node = new DashcoreNode(configuration); - regtest = dashcore.Networks.get('regtest'); + regtest = dashcore.Networks.get("regtest"); should.exist(regtest); - node.on('error', function(err) { + node.on("error", function (err) { log.error(err); }); - node.start(function(err) { + node.start(function (err) { if (err) { return done(err); } client = new DashdRPC({ - protocol: 'http', - host: '127.0.0.1', + protocol: "http", + host: "127.0.0.1", port: 30331, - user: 'dash', - pass: 'local321', - rejectUnauthorized: false + user: "dash", + pass: "local321", + rejectUnauthorized: false, }); - var syncedHandler = function() { + var syncedHandler = function () { if (node.services.dashd.height === 150) { - node.services.dashd.removeListener('synced', syncedHandler); + node.services.dashd.removeListener("synced", syncedHandler); done(); } }; - node.services.dashd.on('synced', syncedHandler); + node.services.dashd.on("synced", syncedHandler); - client.generate(150, function(err) { + client.generate(150, function (err) { if (err) { throw err; } }); - }); - - }); }); - after(function(done) { + after(function (done) { this.timeout(200000); - node.stop(function(err, result) { - if(err) { + node.stop(function (err, result) { + if (err) { throw err; } done(); }); }); - describe('Bus Functionality', function() { - it('subscribes and unsubscribes to an event on the bus', function(done) { + describe("Bus Functionality", function () { + it("subscribes and unsubscribes to an event on the bus", function (done) { var bus = node.openBus(); var blockExpected; var blockReceived; - bus.subscribe('dashd/hashblock'); - bus.on('dashd/hashblock', function(data) { - bus.unsubscribe('dashd/hashblock'); + bus.subscribe("dashd/hashblock"); + bus.on("dashd/hashblock", function (data) { + bus.unsubscribe("dashd/hashblock"); if (blockExpected) { data.should.be.equal(blockExpected); done(); @@ -129,7 +124,7 @@ describe('Node Functionality', function() { blockReceived = data; } }); - client.generate(1, function(err, response) { + client.generate(1, function (err, response) { if (err) { throw err; } @@ -143,31 +138,31 @@ describe('Node Functionality', function() { }); }); - describe('Address Functionality', function() { + describe("Address Functionality", function () { var address; var unspentOutput; - before(function(done) { + before(function (done) { this.timeout(300000); address = testKey.toAddress(regtest).toString(); var startHeight = node.services.dashd.height; - node.services.dashd.on('tip', function(height) { + node.services.dashd.on("tip", function (height) { if (height === startHeight + 3) { done(); } }); - client.sendToAddress(testKey.toAddress(regtest).toString(), 10, function(err) { + client.sendToAddress(testKey.toAddress(regtest).toString(), 10, function (err) { if (err) { throw err; } - client.generate(3, function(err) { + client.generate(3, function (err) { if (err) { throw err; } }); }); }); - it('should be able to get the balance of the test address', function(done) { - node.getAddressBalance(address, false, function(err, data) { + it("should be able to get the balance of the test address", function (done) { + node.getAddressBalance(address, false, function (err, data) { if (err) { throw err; } @@ -175,8 +170,8 @@ describe('Node Functionality', function() { done(); }); }); - it('can get unspent outputs for address', function(done) { - node.getAddressUnspentOutputs(address, false, function(err, results) { + it("can get unspent outputs for address", function (done) { + node.getAddressUnspentOutputs(address, false, function (err, results) { if (err) { throw err; } @@ -185,13 +180,13 @@ describe('Node Functionality', function() { done(); }); }); - it('correctly give the history for the address', function(done) { + it("correctly give the history for the address", function (done) { var options = { from: 0, to: 10, - queryMempool: false + queryMempool: false, }; - node.getAddressHistory(address, options, function(err, results) { + node.getAddressHistory(address, options, function (err, results) { if (err) { throw err; } @@ -204,16 +199,16 @@ describe('Node Functionality', function() { info.addresses[address].inputIndexes.should.deep.equal([]); info.satoshis.should.equal(10 * 1e8); info.confirmations.should.equal(3); - info.tx.blockTimestamp.should.be.a('number'); + info.tx.blockTimestamp.should.be.a("number"); info.tx.feeSatoshis.should.be.within(950, 4000); done(); }); }); - it('correctly give the summary for the address', function(done) { + it("correctly give the summary for the address", function (done) { var options = { - queryMempool: false + queryMempool: false, }; - node.getAddressSummary(address, options, function(err, results) { + node.getAddressSummary(address, options, function (err, results) { if (err) { throw err; } @@ -227,8 +222,7 @@ describe('Node Functionality', function() { done(); }); }); - describe('History', function() { - + describe("History", function () { this.timeout(200000); var testKey2; @@ -244,30 +238,30 @@ describe('Node Functionality', function() { var tx2Amount; var tx2Hash; - before(function(done) { + before(function (done) { /* jshint maxstatements: 50 */ // Finished once all blocks have been mined var startHeight = node.services.dashd.height; - node.services.dashd.on('tip', function(height) { + node.services.dashd.on("tip", function (height) { if (height === startHeight + 5) { done(); } }); - testKey2 = dashcore.PrivateKey.fromWIF('cNfF4jXiLHQnFRsxaJyr2YSGcmtNYvxQYSakNhuDGxpkSzAwn95x'); + testKey2 = dashcore.PrivateKey.fromWIF("cNfF4jXiLHQnFRsxaJyr2YSGcmtNYvxQYSakNhuDGxpkSzAwn95x"); address2 = testKey2.toAddress(regtest).toString(); - testKey3 = dashcore.PrivateKey.fromWIF('cVTYQbaFNetiZcvxzXcVMin89uMLC43pEBMy2etgZHbPPxH5obYt'); + testKey3 = dashcore.PrivateKey.fromWIF("cVTYQbaFNetiZcvxzXcVMin89uMLC43pEBMy2etgZHbPPxH5obYt"); address3 = testKey3.toAddress(regtest).toString(); - testKey4 = dashcore.PrivateKey.fromWIF('cPNQmfE31H2oCUFqaHpfSqjDibkt7XoT2vydLJLDHNTvcddCesGw'); + testKey4 = dashcore.PrivateKey.fromWIF("cPNQmfE31H2oCUFqaHpfSqjDibkt7XoT2vydLJLDHNTvcddCesGw"); address4 = testKey4.toAddress(regtest).toString(); - testKey5 = dashcore.PrivateKey.fromWIF('cVrzm9gCmnzwEVMGeCxY6xLVPdG3XWW97kwkFH3H3v722nb99QBF'); + testKey5 = dashcore.PrivateKey.fromWIF("cVrzm9gCmnzwEVMGeCxY6xLVPdG3XWW97kwkFH3H3v722nb99QBF"); address5 = testKey5.toAddress(regtest).toString(); - testKey6 = dashcore.PrivateKey.fromWIF('cPfMesNR2gsQEK69a6xe7qE44CZEZavgMUak5hQ74XDgsRmmGBYF'); + testKey6 = dashcore.PrivateKey.fromWIF("cPfMesNR2gsQEK69a6xe7qE44CZEZavgMUak5hQ74XDgsRmmGBYF"); address6 = testKey6.toAddress(regtest).toString(); var tx = new Transaction(); @@ -283,7 +277,7 @@ describe('Node Functionality', function() { unspentOutputSpentTxId = tx.id; function mineBlock(next) { - client.generate(1, function(err, response) { + client.generate(1, function (err, response) { if (err) { throw err; } @@ -292,101 +286,98 @@ describe('Node Functionality', function() { }); } - node.sendTransaction(tx.serialize(), function(err, hash) { + node.sendTransaction(tx.serialize(), function (err, hash) { if (err) { return done(err); } - client.generate(1, function(err, response) { + client.generate(1, function (err, response) { if (err) { throw err; } should.exist(response); - node.getAddressUnspentOutputs(address, false, function(err, results) { + node.getAddressUnspentOutputs(address, false, function (err, results) { /* jshint maxstatements: 50 */ if (err) { throw err; } results.length.should.equal(5); - async.series([ - function(next) { - var tx2 = new Transaction(); - tx2Amount = results[0].satoshis - 10000; - tx2.from(results[0]); - tx2.to(address2, tx2Amount); - tx2.change(address); - tx2.sign(testKey); - tx2Hash = tx2.hash; - node.sendTransaction(tx2.serialize(), function(err) { - if (err) { - return next(err); - } - mineBlock(next); - }); - }, function(next) { - var tx3 = new Transaction(); - tx3.from(results[1]); - tx3.to(address3, results[1].satoshis - 10000); - tx3.change(address); - tx3.sign(testKey); - node.sendTransaction(tx3.serialize(), function(err) { - if (err) { - return next(err); - } - mineBlock(next); - }); - }, function(next) { - var tx4 = new Transaction(); - tx4.from(results[2]); - tx4.to(address4, results[2].satoshis - 10000); - tx4.change(address); - tx4.sign(testKey); - node.sendTransaction(tx4.serialize(), function(err) { - if (err) { - return next(err); - } - mineBlock(next); - }); - }, function(next) { - var tx5 = new Transaction(); - tx5.from(results[3]); - tx5.from(results[4]); - tx5.to(address5, results[3].satoshis - 10000); - tx5.to(address6, results[4].satoshis - 10000); - tx5.change(address); - tx5.sign(testKey); - node.sendTransaction(tx5.serialize(), function(err) { - if (err) { - return next(err); - } - mineBlock(next); - }); - } - ], function(err) { - if (err) { - throw err; + async.series( + [ + function (next) { + var tx2 = new Transaction(); + tx2Amount = results[0].satoshis - 10000; + tx2.from(results[0]); + tx2.to(address2, tx2Amount); + tx2.change(address); + tx2.sign(testKey); + tx2Hash = tx2.hash; + node.sendTransaction(tx2.serialize(), function (err) { + if (err) { + return next(err); + } + mineBlock(next); + }); + }, + function (next) { + var tx3 = new Transaction(); + tx3.from(results[1]); + tx3.to(address3, results[1].satoshis - 10000); + tx3.change(address); + tx3.sign(testKey); + node.sendTransaction(tx3.serialize(), function (err) { + if (err) { + return next(err); + } + mineBlock(next); + }); + }, + function (next) { + var tx4 = new Transaction(); + tx4.from(results[2]); + tx4.to(address4, results[2].satoshis - 10000); + tx4.change(address); + tx4.sign(testKey); + node.sendTransaction(tx4.serialize(), function (err) { + if (err) { + return next(err); + } + mineBlock(next); + }); + }, + function (next) { + var tx5 = new Transaction(); + tx5.from(results[3]); + tx5.from(results[4]); + tx5.to(address5, results[3].satoshis - 10000); + tx5.to(address6, results[4].satoshis - 10000); + tx5.change(address); + tx5.sign(testKey); + node.sendTransaction(tx5.serialize(), function (err) { + if (err) { + return next(err); + } + mineBlock(next); + }); + }, + ], + function (err) { + if (err) { + throw err; + } } - }); + ); }); - }); - }); - }); - it('five addresses', function(done) { - var addresses = [ - address2, - address3, - address4, - address5, - address6 - ]; + it("five addresses", function (done) { + var addresses = [address2, address3, address4, address5, address6]; var options = {}; - node.getAddressHistory(addresses, options, function(err, results) { + node.getAddressHistory(addresses, options, function (err, results) { if (err) { throw err; } @@ -408,19 +399,13 @@ describe('Node Functionality', function() { }); }); - it('five addresses (limited by height)', function(done) { - var addresses = [ - address2, - address3, - address4, - address5, - address6 - ]; + it("five addresses (limited by height)", function (done) { + var addresses = [address2, address3, address4, address5, address6]; var options = { start: 158, - end: 157 + end: 157, }; - node.getAddressHistory(addresses, options, function(err, results) { + node.getAddressHistory(addresses, options, function (err, results) { if (err) { throw err; } @@ -435,19 +420,13 @@ describe('Node Functionality', function() { }); }); - it('five addresses (limited by height 155 to 154)', function(done) { - var addresses = [ - address2, - address3, - address4, - address5, - address6 - ]; + it("five addresses (limited by height 155 to 154)", function (done) { + var addresses = [address2, address3, address4, address5, address6]; var options = { start: 157, - end: 156 + end: 156, }; - node.getAddressHistory(addresses, options, function(err, results) { + node.getAddressHistory(addresses, options, function (err, results) { if (err) { throw err; } @@ -460,19 +439,13 @@ describe('Node Functionality', function() { }); }); - it('five addresses (paginated by index)', function(done) { - var addresses = [ - address2, - address3, - address4, - address5, - address6 - ]; + it("five addresses (paginated by index)", function (done) { + var addresses = [address2, address3, address4, address5, address6]; var options = { from: 0, - to: 3 + to: 3, }; - node.getAddressHistory(addresses, options, function(err, results) { + node.getAddressHistory(addresses, options, function (err, results) { if (err) { throw err; } @@ -487,12 +460,10 @@ describe('Node Functionality', function() { }); }); - it('one address with sending and receiving', function(done) { - var addresses = [ - address - ]; + it("one address with sending and receiving", function (done) { + var addresses = [address]; var options = {}; - node.getAddressHistory(addresses, options, function(err, results) { + node.getAddressHistory(addresses, options, function (err, results) { if (err) { throw err; } @@ -516,8 +487,8 @@ describe('Node Functionality', function() { }); }); - it('summary for an address (sending and receiving)', function(done) { - node.getAddressSummary(address, {}, function(err, results) { + it("summary for an address (sending and receiving)", function (done) { + node.getAddressSummary(address, {}, function (err, results) { if (err) { throw err; } @@ -532,13 +503,10 @@ describe('Node Functionality', function() { }); }); - - it('total transaction count (sending and receiving)', function(done) { - var addresses = [ - address - ]; + it("total transaction count (sending and receiving)", function (done) { + var addresses = [address]; var options = {}; - node.getAddressHistory(addresses, options, function(err, results) { + node.getAddressHistory(addresses, options, function (err, results) { if (err) { throw err; } @@ -547,13 +515,13 @@ describe('Node Functionality', function() { }); }); - describe('Pagination', function() { - it('from 0 to 1', function(done) { + describe("Pagination", function () { + it("from 0 to 1", function (done) { var options = { from: 0, - to: 1 + to: 1, }; - node.getAddressHistory(address, options, function(err, results) { + node.getAddressHistory(address, options, function (err, results) { if (err) { throw err; } @@ -563,12 +531,12 @@ describe('Node Functionality', function() { done(); }); }); - it('from 1 to 2', function(done) { + it("from 1 to 2", function (done) { var options = { from: 1, - to: 2 + to: 2, }; - node.getAddressHistory(address, options, function(err, results) { + node.getAddressHistory(address, options, function (err, results) { if (err) { throw err; } @@ -578,12 +546,12 @@ describe('Node Functionality', function() { done(); }); }); - it('from 2 to 3', function(done) { + it("from 2 to 3", function (done) { var options = { from: 2, - to: 3 + to: 3, }; - node.getAddressHistory(address, options, function(err, results) { + node.getAddressHistory(address, options, function (err, results) { if (err) { throw err; } @@ -593,12 +561,12 @@ describe('Node Functionality', function() { done(); }); }); - it('from 3 to 4', function(done) { + it("from 3 to 4", function (done) { var options = { from: 3, - to: 4 + to: 4, }; - node.getAddressHistory(address, options, function(err, results) { + node.getAddressHistory(address, options, function (err, results) { if (err) { throw err; } @@ -608,12 +576,12 @@ describe('Node Functionality', function() { done(); }); }); - it('from 4 to 5', function(done) { + it("from 4 to 5", function (done) { var options = { from: 4, - to: 5 + to: 5, }; - node.getAddressHistory(address, options, function(err, results) { + node.getAddressHistory(address, options, function (err, results) { if (err) { throw err; } @@ -626,12 +594,12 @@ describe('Node Functionality', function() { done(); }); }); - it('from 5 to 6', function(done) { + it("from 5 to 6", function (done) { var options = { from: 5, - to: 6 + to: 6, }; - node.getAddressHistory(address, options, function(err, results) { + node.getAddressHistory(address, options, function (err, results) { if (err) { throw err; } @@ -642,14 +610,13 @@ describe('Node Functionality', function() { done(); }); }); - }); }); - describe('Mempool Index', function() { + describe("Mempool Index", function () { var unspentOutput; - before(function(done) { - node.getAddressUnspentOutputs(address, false, function(err, results) { + before(function (done) { + node.getAddressUnspentOutputs(address, false, function (err, results) { if (err) { throw err; } @@ -659,7 +626,7 @@ describe('Node Functionality', function() { }); }); - it('will update the mempool index after new tx', function(done) { + it("will update the mempool index after new tx", function (done) { var memAddress = dashcore.PrivateKey().toAddress(node.network).toString(); var tx = new Transaction(); tx.from(unspentOutput); @@ -667,8 +634,8 @@ describe('Node Functionality', function() { tx.fee(2000); tx.sign(testKey); - node.services.dashd.sendTransaction(tx.serialize(), function(err, hash) { - node.getAddressTxids(memAddress, {}, function(err, txids) { + node.services.dashd.sendTransaction(tx.serialize(), function (err, hash) { + node.getAddressTxids(memAddress, {}, function (err, txids) { if (err) { return done(err); } @@ -678,71 +645,72 @@ describe('Node Functionality', function() { }); }); }); - }); - }); - describe('Orphaned Transactions', function() { + describe("Orphaned Transactions", function () { this.timeout(80000); var orphanedTransaction; - before(function(done) { + before(function (done) { var count; var invalidatedBlockHash; - async.series([ - function(next) { - client.sendToAddress(testKey.toAddress(regtest).toString(), 10, function(err) { - if (err) { - return next(err); - } - client.generate(1, next); - }); - }, - function(next) { - client.getBlockCount(function(err, response) { - if (err) { - return next(err); - } - count = response.result; - next(); - }); - }, - function(next) { - client.getBlockHash(count, function(err, response) { - if (err) { - return next(err); - } - invalidatedBlockHash = response.result; - next(); - }); - }, - function(next) { - client.getBlock(invalidatedBlockHash, function(err, response) { - if (err) { - return next(err); - } - orphanedTransaction = response.result.tx[1]; - should.exist(orphanedTransaction); - next(); - }); - }, - function(next) { - client.invalidateBlock(invalidatedBlockHash, next); - } - ], function(err) { - if (err) { - throw err; + async.series( + [ + function (next) { + client.sendToAddress(testKey.toAddress(regtest).toString(), 10, function (err) { + if (err) { + return next(err); + } + client.generate(1, next); + }); + }, + function (next) { + client.getBlockCount(function (err, response) { + if (err) { + return next(err); + } + count = response.result; + next(); + }); + }, + function (next) { + client.getBlockHash(count, function (err, response) { + if (err) { + return next(err); + } + invalidatedBlockHash = response.result; + next(); + }); + }, + function (next) { + client.getBlock(invalidatedBlockHash, function (err, response) { + if (err) { + return next(err); + } + orphanedTransaction = response.result.tx[1]; + should.exist(orphanedTransaction); + next(); + }); + }, + function (next) { + client.invalidateBlock(invalidatedBlockHash, next); + }, + ], + function (err) { + if (err) { + throw err; + } + done(); } - done(); - }); + ); }); - it('will not show confirmation count for orphaned transaction', function(done) { + it("will not show confirmation count for orphaned transaction", function (done) { // This test verifies that in the situation that the transaction is not in the mempool and // is included in an orphaned block transaction index that the confirmation count will be unconfirmed. - node.getDetailedTransaction(orphanedTransaction, function(err, data) { + node.getDetailedTransaction(orphanedTransaction, function (err, data) { if (err) { return done(err); } @@ -752,7 +720,5 @@ describe('Node Functionality', function() { done(); }); }); - }); - }); diff --git a/regtest/p2p.js b/regtest/p2p.js index 574555a40..4679a35f5 100755 --- a/regtest/p2p.js +++ b/regtest/p2p.js @@ -1,27 +1,27 @@ -'use strict'; +"use strict"; // To run the tests: $ mocha -R spec regtest/p2p.js -var path = require('path'); -var index = require('..'); +var path = require("path"); +var index = require(".."); var log = index.log; -var p2p = require('@dashevo/dashcore-p2p'); +var p2p = require("@dashevo/dashcore-p2p"); var Peer = p2p.Peer; var Messages = p2p.Messages; -var chai = require('chai'); -var dashcore = require('@dashevo/dashcore-lib'); +var chai = require("chai"); +var dashcore = require("@dashevo/dashcore-lib"); var Transaction = dashcore.Transaction; var BN = dashcore.crypto.BN; -var async = require('async'); -var rimraf = require('rimraf'); +var async = require("async"); +var rimraf = require("rimraf"); var dashd; /* jshint unused: false */ var should = chai.should(); var assert = chai.assert; -var sinon = require('sinon'); -var DashdRPC = require('@dashevo/dashd-rpc'); +var sinon = require("sinon"); +var DashdRPC = require("@dashevo/dashd-rpc"); var transactionData = []; var blockHashes = []; var txs = []; @@ -34,162 +34,167 @@ var destKey = dashcore.PrivateKey(); var BufferUtil = dashcore.util.buffer; var blocks; -describe('P2P Functionality', function() { - - before(function(done) { +describe("P2P Functionality", function () { + before(function (done) { this.timeout(200000); // enable regtest dashcore.Networks.enableRegtest(); - var regtestNetwork = dashcore.Networks.get('regtest'); - var datadir = __dirname + '/data'; + var regtestNetwork = dashcore.Networks.get("regtest"); + var datadir = __dirname + "/data"; - rimraf(datadir + '/regtest', function(err) { + rimraf(datadir + "/regtest", function (err) { if (err) { throw err; } - dashd = require('../').services.Dash({ + dashd = require("../").services.Dash({ spawn: { datadir: datadir, - exec: path.resolve(__dirname, process.env.HOME, './.dashcore/data/dashd') + exec: path.resolve(__dirname, process.env.HOME, "./.dashcore/data/dashd"), }, node: { - network: dashcore.Networks.testnet - } + network: dashcore.Networks.testnet, + }, }); - dashd.on('error', function(err) { + dashd.on("error", function (err) { log.error('error="%s"', err.message); }); - log.info('Waiting for Dash Core to initialize...'); + log.info("Waiting for Dash Core to initialize..."); - dashd.start(function(err) { + dashd.start(function (err) { if (err) { throw err; } - log.info('Dashd started'); + log.info("Dashd started"); client = new DashdRPC({ - protocol: 'http', - host: '127.0.0.1', + protocol: "http", + host: "127.0.0.1", port: 30331, - user: 'dash', - pass: 'local321', - rejectUnauthorized: false + user: "dash", + pass: "local321", + rejectUnauthorized: false, }); peer = new Peer({ - host: '127.0.0.1', - port: '19994', - network: regtestNetwork + host: "127.0.0.1", + port: "19994", + network: regtestNetwork, }); messages = new Messages({ - network: regtestNetwork + network: regtestNetwork, }); blocks = 500; - log.info('Generating ' + blocks + ' blocks...'); + log.info("Generating " + blocks + " blocks..."); // Generate enough blocks so that the initial coinbase transactions // can be spent. - setImmediate(function() { - client.generate(blocks, function(err, response) { + setImmediate(function () { + client.generate(blocks, function (err, response) { if (err) { throw err; } blockHashes = response.result; - log.info('Preparing test data...'); + log.info("Preparing test data..."); // Get all of the unspent outputs - client.listUnspent(0, blocks, function(err, response) { + client.listUnspent(0, blocks, function (err, response) { var utxos = response.result; - async.mapSeries(utxos, function(utxo, next) { - async.series([ - function(finished) { - // Load all of the transactions for later testing - client.getTransaction(utxo.txid, function(err, txresponse) { - if (err) { - throw err; - } - // add to the list of transactions for testing later - transactionData.push(txresponse.result.hex); - finished(); - }); - }, - function(finished) { - // Get the private key for each utxo - client.dumpPrivKey(utxo.address, function(err, privresponse) { - if (err) { - throw err; - } - utxo.privateKeyWIF = privresponse.result; - var tx = dashcore.Transaction(); - tx.from(utxo); - tx.change(privateKey.toAddress()); - tx.to(destKey.toAddress(), utxo.amount * 1e8 - 1000); - tx.sign(dashcore.PrivateKey.fromWIF(utxo.privateKeyWIF)); - txs.push(tx); - finished(); - }); + async.mapSeries( + utxos, + function (utxo, next) { + async.series( + [ + function (finished) { + // Load all of the transactions for later testing + client.getTransaction(utxo.txid, function (err, txresponse) { + if (err) { + throw err; + } + // add to the list of transactions for testing later + transactionData.push(txresponse.result.hex); + finished(); + }); + }, + function (finished) { + // Get the private key for each utxo + client.dumpPrivKey(utxo.address, function (err, privresponse) { + if (err) { + throw err; + } + utxo.privateKeyWIF = privresponse.result; + var tx = dashcore.Transaction(); + tx.from(utxo); + tx.change(privateKey.toAddress()); + tx.to(destKey.toAddress(), utxo.amount * 1e8 - 1000); + tx.sign(dashcore.PrivateKey.fromWIF(utxo.privateKeyWIF)); + txs.push(tx); + finished(); + }); + }, + ], + next + ); + }, + function (err) { + if (err) { + throw err; } - ], next); - }, function(err) { - if (err) { - throw err; + peer.on("ready", function () { + log.info("Peer ready"); + done(); + }); + log.info("Connecting to peer"); + peer.connect(); } - peer.on('ready', function() { - log.info('Peer ready'); - done(); - }); - log.info('Connecting to peer'); - peer.connect(); - }); + ); }); }); }); }); }); - }); - after(function(done) { + after(function (done) { this.timeout(20000); - peer.on('disconnect', function() { - log.info('Peer disconnected'); + peer.on("disconnect", function () { + log.info("Peer disconnected"); dashd.node.stopping = true; - dashd.stop(function(err, result) { + dashd.stop(function (err, result) { done(); }); }); peer.disconnect(); }); - it('will be able to handle many inventory messages and be able to send getdata messages and received the txs', function(done) { + it("will be able to handle many inventory messages and be able to send getdata messages and received the txs", function (done) { this.timeout(100000); var usedTxs = {}; - dashd.on('tx', function(buffer) { + dashd.on("tx", function (buffer) { var txFromResult = new Transaction().fromBuffer(buffer); var tx = usedTxs[txFromResult.id]; should.exist(tx); - buffer.toString('hex').should.equal(tx.serialize()); + buffer.toString("hex").should.equal(tx.serialize()); delete usedTxs[tx.id]; if (Object.keys(usedTxs).length === 0) { done(); } }); - peer.on('getdata', function(message) { + peer.on("getdata", function (message) { var hash = message.inventory[0].hash; - var reversedHash = BufferUtil.reverse(hash).toString('hex'); + var reversedHash = BufferUtil.reverse(hash).toString("hex"); var tx = usedTxs[reversedHash]; if (reversedHash === tx.id) { var txMessage = messages.Transaction(tx); @@ -197,21 +202,21 @@ describe('P2P Functionality', function() { } }); async.whilst( - function() { + function () { return txs.length > 0; }, - function(callback) { + function (callback) { var tx = txs.pop(); usedTxs[tx.id] = tx; var message = messages.Inventory.forTransaction(tx.hash); peer.sendMessage(message); callback(); }, - function(err) { + function (err) { if (err) { throw err; } - }); + } + ); }); - }); diff --git a/test/bus.integration.js b/test/bus.integration.js index ae34874d5..158e2b4e2 100644 --- a/test/bus.integration.js +++ b/test/bus.integration.js @@ -1,104 +1,101 @@ -'use strict'; +"use strict"; -var sinon = require('sinon'); -var Service = require('../lib/service'); -var DashcoreNode = require('../lib/node'); -var util = require('util'); -var should = require('chai').should(); -var index = require('../lib'); +var sinon = require("sinon"); +var Service = require("../lib/service"); +var DashcoreNode = require("../lib/node"); +var util = require("util"); +var should = require("chai").should(); +var index = require("../lib"); var log = index.log; -var TestService = function(options) { +var TestService = function (options) { this.node = options.node; }; util.inherits(TestService, Service); TestService.dependencies = []; -TestService.prototype.start = function(callback) { +TestService.prototype.start = function (callback) { callback(); }; -TestService.prototype.stop = function(callback) { +TestService.prototype.stop = function (callback) { callback(); }; -TestService.prototype.close = function(callback) { +TestService.prototype.close = function (callback) { callback(); }; -TestService.prototype.getPublishEvents = function() { +TestService.prototype.getPublishEvents = function () { return [ { - name: 'test/testEvent', + name: "test/testEvent", scope: this, - subscribe: this.subscribe.bind(this, 'test/testEvent'), - unsubscribe: this.unsubscribe.bind(this, 'test/testEvent') - } + subscribe: this.subscribe.bind(this, "test/testEvent"), + unsubscribe: this.unsubscribe.bind(this, "test/testEvent"), + }, ]; }; -TestService.prototype.subscribe = function(name, emitter, params) { +TestService.prototype.subscribe = function (name, emitter, params) { emitter.emit(name, params); }; -TestService.prototype.unsubscribe = function(name, emitter) { - emitter.emit('unsubscribe'); +TestService.prototype.unsubscribe = function (name, emitter) { + emitter.emit("unsubscribe"); }; - -describe('Bus Functionality', function() { +describe("Bus Functionality", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('should subscribe to testEvent', function(done) { + it("should subscribe to testEvent", function (done) { var node = new DashcoreNode({ - datadir: './', - network: 'testnet', + datadir: "./", + network: "testnet", port: 8888, services: [ { - name: 'testService', + name: "testService", config: {}, - module: TestService - } - ] + module: TestService, + }, + ], }); - node.start(function() { + node.start(function () { var bus = node.openBus(); - var params = 'somedata'; - bus.on('test/testEvent', function(data) { + var params = "somedata"; + bus.on("test/testEvent", function (data) { data.should.be.equal(params); done(); }); - bus.subscribe('test/testEvent', params); + bus.subscribe("test/testEvent", params); }); }); - it('should unsubscribe from a testEvent', function(done) { + it("should unsubscribe from a testEvent", function (done) { var node = new DashcoreNode({ - datadir: './', - network: 'testnet', + datadir: "./", + network: "testnet", port: 8888, services: [ { - name: 'testService', + name: "testService", config: {}, - module: TestService - } - ] + module: TestService, + }, + ], }); - node.start(function() { + node.start(function () { var bus = node.openBus(); - var params = 'somedata'; - bus.on('unsubscribe', function() { + var params = "somedata"; + bus.on("unsubscribe", function () { done(); }); - bus.subscribe('test/testEvent'); - bus.unsubscribe('test/testEvent'); - + bus.subscribe("test/testEvent"); + bus.unsubscribe("test/testEvent"); }); - }); }); diff --git a/test/bus.unit.js b/test/bus.unit.js index 0b2bf298d..be7505ed1 100644 --- a/test/bus.unit.js +++ b/test/bus.unit.js @@ -1,13 +1,12 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var sinon = require('sinon'); -var Bus = require('../lib/bus'); +var should = require("chai").should(); +var sinon = require("sinon"); +var Bus = require("../lib/bus"); -describe('Bus', function() { - - describe('#subscribe', function() { - it('will call db and services subscribe function with the correct arguments', function() { +describe("Bus", function () { + describe("#subscribe", function () { + it("will call db and services subscribe function with the correct arguments", function () { var subscribeDb = sinon.spy(); var subscribeService = sinon.spy(); var node = { @@ -15,41 +14,41 @@ describe('Bus', function() { db: { getPublishEvents: sinon.stub().returns([ { - name: 'dbtest', + name: "dbtest", scope: this, - subscribe: subscribeDb - } - ]) + subscribe: subscribeDb, + }, + ]), }, service1: { getPublishEvents: sinon.stub().returns([ { - name: 'test', + name: "test", scope: this, subscribe: subscribeService, - } - ]) - } - } + }, + ]), + }, + }, }; - var bus = new Bus({node: node}); - bus.subscribe('dbtest', 'a', 'b', 'c'); - bus.subscribe('test', 'a', 'b', 'c'); + var bus = new Bus({ node: node }); + bus.subscribe("dbtest", "a", "b", "c"); + bus.subscribe("test", "a", "b", "c"); subscribeService.callCount.should.equal(1); subscribeDb.callCount.should.equal(1); subscribeDb.args[0][0].should.equal(bus); - subscribeDb.args[0][1].should.equal('a'); - subscribeDb.args[0][2].should.equal('b'); - subscribeDb.args[0][3].should.equal('c'); + subscribeDb.args[0][1].should.equal("a"); + subscribeDb.args[0][2].should.equal("b"); + subscribeDb.args[0][3].should.equal("c"); subscribeService.args[0][0].should.equal(bus); - subscribeService.args[0][1].should.equal('a'); - subscribeService.args[0][2].should.equal('b'); - subscribeService.args[0][3].should.equal('c'); + subscribeService.args[0][1].should.equal("a"); + subscribeService.args[0][2].should.equal("b"); + subscribeService.args[0][3].should.equal("c"); }); }); - describe('#unsubscribe', function() { - it('will call db and services unsubscribe function with the correct arguments', function() { + describe("#unsubscribe", function () { + it("will call db and services unsubscribe function with the correct arguments", function () { var unsubscribeDb = sinon.spy(); var unsubscribeService = sinon.spy(); var node = { @@ -57,41 +56,41 @@ describe('Bus', function() { db: { getPublishEvents: sinon.stub().returns([ { - name: 'dbtest', + name: "dbtest", scope: this, - unsubscribe: unsubscribeDb - } - ]) + unsubscribe: unsubscribeDb, + }, + ]), }, service1: { getPublishEvents: sinon.stub().returns([ { - name: 'test', + name: "test", scope: this, unsubscribe: unsubscribeService, - } - ]) - } - } + }, + ]), + }, + }, }; - var bus = new Bus({node: node}); - bus.unsubscribe('dbtest', 'a', 'b', 'c'); - bus.unsubscribe('test', 'a', 'b', 'c'); + var bus = new Bus({ node: node }); + bus.unsubscribe("dbtest", "a", "b", "c"); + bus.unsubscribe("test", "a", "b", "c"); unsubscribeService.callCount.should.equal(1); unsubscribeDb.callCount.should.equal(1); unsubscribeDb.args[0][0].should.equal(bus); - unsubscribeDb.args[0][1].should.equal('a'); - unsubscribeDb.args[0][2].should.equal('b'); - unsubscribeDb.args[0][3].should.equal('c'); + unsubscribeDb.args[0][1].should.equal("a"); + unsubscribeDb.args[0][2].should.equal("b"); + unsubscribeDb.args[0][3].should.equal("c"); unsubscribeService.args[0][0].should.equal(bus); - unsubscribeService.args[0][1].should.equal('a'); - unsubscribeService.args[0][2].should.equal('b'); - unsubscribeService.args[0][3].should.equal('c'); + unsubscribeService.args[0][1].should.equal("a"); + unsubscribeService.args[0][2].should.equal("b"); + unsubscribeService.args[0][3].should.equal("c"); }); }); - describe('#close', function() { - it('will unsubscribe from all events', function() { + describe("#close", function () { + it("will unsubscribe from all events", function () { var unsubscribeDb = sinon.spy(); var unsubscribeService = sinon.spy(); var node = { @@ -99,24 +98,24 @@ describe('Bus', function() { db: { getPublishEvents: sinon.stub().returns([ { - name: 'dbtest', + name: "dbtest", scope: this, - unsubscribe: unsubscribeDb - } - ]) + unsubscribe: unsubscribeDb, + }, + ]), }, service1: { getPublishEvents: sinon.stub().returns([ { - name: 'test', + name: "test", scope: this, - unsubscribe: unsubscribeService - } - ]) - } - } + unsubscribe: unsubscribeService, + }, + ]), + }, + }, }; - var bus = new Bus({node: node}); + var bus = new Bus({ node: node }); bus.close(); unsubscribeDb.callCount.should.equal(1); @@ -127,5 +126,4 @@ describe('Bus', function() { unsubscribeService.args[0][0].should.equal(bus); }); }); - }); diff --git a/test/index.unit.js b/test/index.unit.js index 4245c9484..095026eb8 100644 --- a/test/index.unit.js +++ b/test/index.unit.js @@ -1,10 +1,10 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); +var should = require("chai").should(); -describe('Index Exports', function() { - it('will export dashcore-lib', function() { - var dashcore = require('../'); +describe("Index Exports", function () { + it("will export dashcore-lib", function () { + var dashcore = require("../"); should.exist(dashcore.lib); should.exist(dashcore.lib.Transaction); should.exist(dashcore.lib.Block); diff --git a/test/logger.unit.js b/test/logger.unit.js index 1e983c93e..3e1b556cb 100644 --- a/test/logger.unit.js +++ b/test/logger.unit.js @@ -1,101 +1,98 @@ -'use strict'; +"use strict"; -var sinon = require('sinon'); -var chai = require('chai'); +var sinon = require("sinon"); +var chai = require("chai"); var should = chai.should(); -var Logger = require('../lib/logger'); +var Logger = require("../lib/logger"); -describe('Logger', function() { +describe("Logger", function () { var sandbox = sinon.sandbox.create(); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will instatiate without options', function() { + it("will instatiate without options", function () { var logger = new Logger(); should.exist(logger); logger.formatting.should.equal(true); }); - it('will instatiate with formatting option', function() { + it("will instatiate with formatting option", function () { var logger = new Logger({ - formatting: false + formatting: false, }); logger.formatting.should.equal(false); var logger2 = new Logger({ - formatting: true + formatting: true, }); logger2.formatting.should.equal(true); }); - it('will log with formatting', function() { - var logger = new Logger({formatting: true}); + it("will log with formatting", function () { + var logger = new Logger({ formatting: true }); - sandbox.stub(console, 'info'); - logger.info('Test info log'); + sandbox.stub(console, "info"); + logger.info("Test info log"); console.info.callCount.should.equal(1); console.info.restore(); - sandbox.stub(console, 'error'); - logger.error(new Error('Test error log')); + sandbox.stub(console, "error"); + logger.error(new Error("Test error log")); console.error.callCount.should.equal(1); console.error.restore(); //Node 6+ - if(console.hasOwnProperty('debug')){ - sandbox.stub(console, 'debug'); - logger.debug('Test debug log'); + if (console.hasOwnProperty("debug")) { + sandbox.stub(console, "debug"); + logger.debug("Test debug log"); console.debug.callCount.should.equal(1); console.debug.restore(); - }else{ - sandbox.stub(console, 'log'); - logger.debug('Test debug log'); + } else { + sandbox.stub(console, "log"); + logger.debug("Test debug log"); console.log.callCount.should.equal(1); console.log.restore(); } - - sandbox.stub(console, 'warn'); - logger.warn('Test warn log'); + sandbox.stub(console, "warn"); + logger.warn("Test warn log"); console.warn.callCount.should.equal(1); console.warn.restore(); }); - it('will log without formatting', function() { - var logger = new Logger({formatting: false}); + it("will log without formatting", function () { + var logger = new Logger({ formatting: false }); - sandbox.stub(console, 'info'); - logger.info('Test info log'); + sandbox.stub(console, "info"); + logger.info("Test info log"); console.info.callCount.should.equal(1); should.not.exist(console.info.args[0][0].match(/^\[/)); console.info.restore(); - sandbox.stub(console, 'error'); - logger.error(new Error('Test error log')); + sandbox.stub(console, "error"); + logger.error(new Error("Test error log")); console.error.callCount.should.equal(1); console.error.args[0][0].should.be.instanceof(Error); console.error.restore(); //Node 6+ - if(console.hasOwnProperty('debug')){ - sandbox.stub(console, 'debug'); - logger.debug('Test debug log'); + if (console.hasOwnProperty("debug")) { + sandbox.stub(console, "debug"); + logger.debug("Test debug log"); console.debug.callCount.should.equal(1); should.equal(console.debug.args[0][0].match(/^\[/), null); console.debug.restore(); - }else{ - sandbox.stub(console, 'log'); - logger.debug('Test debug log'); + } else { + sandbox.stub(console, "log"); + logger.debug("Test debug log"); console.log.callCount.should.equal(1); should.equal(console.log.args[0][0].match(/^\[/), null); console.log.restore(); } - - sandbox.stub(console, 'warn'); - logger.warn('Test warn log'); + sandbox.stub(console, "warn"); + logger.warn("Test warn log"); console.warn.callCount.should.equal(1); should.equal(console.warn.args[0][0].match(/^\[/), null); console.warn.restore(); }); - }); diff --git a/test/node.unit.js b/test/node.unit.js index fee696dc5..b68a0b77a 100644 --- a/test/node.unit.js +++ b/test/node.unit.js @@ -1,257 +1,254 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var sinon = require('sinon'); -var dashcore = require('@dashevo/dashcore-lib'); +var should = require("chai").should(); +var sinon = require("sinon"); +var dashcore = require("@dashevo/dashcore-lib"); var Networks = dashcore.Networks; -var proxyquire = require('proxyquire'); -var util = require('util'); -var BaseService = require('../lib/service'); -var index = require('../lib'); +var proxyquire = require("proxyquire"); +var util = require("util"); +var BaseService = require("../lib/service"); +var index = require("../lib"); var log = index.log; -describe('Dashcore Node', function() { - +describe("Dashcore Node", function () { var baseConfig = {}; var Node; - before(function() { - Node = proxyquire('../lib/node', {}); + before(function () { + Node = proxyquire("../lib/node", {}); Node.prototype._loadConfiguration = sinon.spy(); Node.prototype._initialize = sinon.spy(); }); - after(function() { + after(function () { Networks.disableRegtest(); }); - describe('@constructor', function() { + describe("@constructor", function () { var TestService; - before(function() { + before(function () { TestService = function TestService() {}; util.inherits(TestService, BaseService); }); - it('will set properties', function() { + it("will set properties", function () { var config = { services: [ { - name: 'test1', - module: TestService - } + name: "test1", + module: TestService, + }, ], }; - var TestNode = proxyquire('../lib/node', {}); + var TestNode = proxyquire("../lib/node", {}); TestNode.prototype.start = sinon.spy(); var node = new TestNode(config); node._unloadedServices.length.should.equal(1); - node._unloadedServices[0].name.should.equal('test1'); + node._unloadedServices[0].name.should.equal("test1"); node._unloadedServices[0].module.should.equal(TestService); node.network.should.equal(Networks.defaultNetwork); var node2 = TestNode(config); node2._unloadedServices.length.should.equal(1); - node2._unloadedServices[0].name.should.equal('test1'); + node2._unloadedServices[0].name.should.equal("test1"); node2._unloadedServices[0].module.should.equal(TestService); node2.network.should.equal(Networks.defaultNetwork); }); - it('will set network to testnet', function() { + it("will set network to testnet", function () { var config = { - network: 'testnet', + network: "testnet", services: [ { - name: 'test1', - module: TestService - } + name: "test1", + module: TestService, + }, ], }; - var TestNode = proxyquire('../lib/node', {}); + var TestNode = proxyquire("../lib/node", {}); TestNode.prototype.start = sinon.spy(); var node = new TestNode(config); node.network.should.equal(Networks.testnet); }); - it('will set network to regtest', function() { + it("will set network to regtest", function () { var config = { - network: 'regtest', + network: "regtest", services: [ { - name: 'test1', - module: TestService - } + name: "test1", + module: TestService, + }, ], }; - var TestNode = proxyquire('../lib/node', {}); + var TestNode = proxyquire("../lib/node", {}); TestNode.prototype.start = sinon.spy(); var node = new TestNode(config); - var regtest = Networks.get('regtest'); + var regtest = Networks.get("regtest"); should.exist(regtest); node.network.should.equal(regtest); }); - it('will be able to disable log formatting', function() { + it("will be able to disable log formatting", function () { var config = { - network: 'regtest', + network: "regtest", services: [ { - name: 'test1', - module: TestService - } + name: "test1", + module: TestService, + }, ], - formatLogs: false + formatLogs: false, }; - var TestNode = proxyquire('../lib/node', {}); + var TestNode = proxyquire("../lib/node", {}); var node = new TestNode(config); node.log.formatting.should.equal(false); - var TestNode = proxyquire('../lib/node', {}); + var TestNode = proxyquire("../lib/node", {}); config.formatLogs = true; var node2 = new TestNode(config); node2.log.formatting.should.equal(true); }); }); - describe('#openBus', function() { - it('will create a new bus', function() { + describe("#openBus", function () { + it("will create a new bus", function () { var node = new Node(baseConfig); var bus = node.openBus(); bus.node.should.equal(node); }); - it('will use remoteAddress config option', function() { + it("will use remoteAddress config option", function () { var node = new Node(baseConfig); - var bus = node.openBus({remoteAddress: '127.0.0.1'}); - bus.remoteAddress.should.equal('127.0.0.1'); + var bus = node.openBus({ remoteAddress: "127.0.0.1" }); + bus.remoteAddress.should.equal("127.0.0.1"); }); }); - describe('#getAllAPIMethods', function() { - it('should return db methods and service methods', function() { + describe("#getAllAPIMethods", function () { + it("should return db methods and service methods", function () { var node = new Node(baseConfig); node.services = { db: { - getAPIMethods: sinon.stub().returns(['db1', 'db2']), + getAPIMethods: sinon.stub().returns(["db1", "db2"]), }, service1: { - getAPIMethods: sinon.stub().returns(['mda1', 'mda2']) + getAPIMethods: sinon.stub().returns(["mda1", "mda2"]), }, service2: { - getAPIMethods: sinon.stub().returns(['mdb1', 'mdb2']) - } + getAPIMethods: sinon.stub().returns(["mdb1", "mdb2"]), + }, }; var methods = node.getAllAPIMethods(); - methods.should.deep.equal(['db1', 'db2', 'mda1', 'mda2', 'mdb1', 'mdb2']); + methods.should.deep.equal(["db1", "db2", "mda1", "mda2", "mdb1", "mdb2"]); }); - it('will handle service without getAPIMethods defined', function() { + it("will handle service without getAPIMethods defined", function () { var node = new Node(baseConfig); node.services = { db: { - getAPIMethods: sinon.stub().returns(['db1', 'db2']), + getAPIMethods: sinon.stub().returns(["db1", "db2"]), }, service1: {}, service2: { - getAPIMethods: sinon.stub().returns(['mdb1', 'mdb2']) - } + getAPIMethods: sinon.stub().returns(["mdb1", "mdb2"]), + }, }; var methods = node.getAllAPIMethods(); - methods.should.deep.equal(['db1', 'db2', 'mdb1', 'mdb2']); + methods.should.deep.equal(["db1", "db2", "mdb1", "mdb2"]); }); }); - describe('#getAllPublishEvents', function() { - it('should return services publish events', function() { + describe("#getAllPublishEvents", function () { + it("should return services publish events", function () { var node = new Node(baseConfig); node.services = { db: { - getPublishEvents: sinon.stub().returns(['db1', 'db2']), + getPublishEvents: sinon.stub().returns(["db1", "db2"]), }, service1: { - getPublishEvents: sinon.stub().returns(['mda1', 'mda2']) + getPublishEvents: sinon.stub().returns(["mda1", "mda2"]), }, service2: { - getPublishEvents: sinon.stub().returns(['mdb1', 'mdb2']) - } + getPublishEvents: sinon.stub().returns(["mdb1", "mdb2"]), + }, }; var events = node.getAllPublishEvents(); - events.should.deep.equal(['db1', 'db2', 'mda1', 'mda2', 'mdb1', 'mdb2']); + events.should.deep.equal(["db1", "db2", "mda1", "mda2", "mdb1", "mdb2"]); }); - it('will handle service without getPublishEvents defined', function() { + it("will handle service without getPublishEvents defined", function () { var node = new Node(baseConfig); node.services = { db: { - getPublishEvents: sinon.stub().returns(['db1', 'db2']), + getPublishEvents: sinon.stub().returns(["db1", "db2"]), }, service1: {}, service2: { - getPublishEvents: sinon.stub().returns(['mdb1', 'mdb2']) - } + getPublishEvents: sinon.stub().returns(["mdb1", "mdb2"]), + }, }; var events = node.getAllPublishEvents(); - events.should.deep.equal(['db1', 'db2', 'mdb1', 'mdb2']); + events.should.deep.equal(["db1", "db2", "mdb1", "mdb2"]); }); }); - describe('#getServiceOrder', function() { - it('should return the services in the correct order', function() { + describe("#getServiceOrder", function () { + it("should return the services in the correct order", function () { var node = new Node(baseConfig); node._unloadedServices = [ { - name: 'chain', + name: "chain", module: { - dependencies: ['db'] - } + dependencies: ["db"], + }, }, { - name: 'db', + name: "db", module: { - dependencies: ['daemon', 'p2p'] - } + dependencies: ["daemon", "p2p"], + }, }, { - name:'daemon', + name: "daemon", module: { - dependencies: [] - } + dependencies: [], + }, }, { - name: 'p2p', + name: "p2p", module: { - dependencies: [] - } - } + dependencies: [], + }, + }, ]; var order = node.getServiceOrder(); - order[0].name.should.equal('daemon'); - order[1].name.should.equal('p2p'); - order[2].name.should.equal('db'); - order[3].name.should.equal('chain'); + order[0].name.should.equal("daemon"); + order[1].name.should.equal("p2p"); + order[2].name.should.equal("db"); + order[3].name.should.equal("chain"); }); }); - describe('#_startService', function() { + describe("#_startService", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will instantiate an instance and load api methods', function() { + it("will instantiate an instance and load api methods", function () { var node = new Node(baseConfig); function TestService() {} util.inherits(TestService, BaseService); TestService.prototype.start = sinon.stub().callsArg(0); var getData = sinon.stub(); TestService.prototype.getData = getData; - TestService.prototype.getAPIMethods = function() { - return [ - ['getData', this, this.getData, 1] - ]; + TestService.prototype.getAPIMethods = function () { + return [["getData", this, this.getData, 1]]; }; var service = { - name: 'testservice', + name: "testservice", module: TestService, - config: {} + config: {}, }; - node._startService(service, function(err) { + node._startService(service, function (err) { if (err) { throw err; } @@ -262,23 +259,21 @@ describe('Dashcore Node', function() { getData.callCount.should.equal(1); }); }); - it('will handle config not being set', function() { + it("will handle config not being set", function () { var node = new Node(baseConfig); function TestService() {} util.inherits(TestService, BaseService); TestService.prototype.start = sinon.stub().callsArg(0); var getData = sinon.stub(); TestService.prototype.getData = getData; - TestService.prototype.getAPIMethods = function() { - return [ - ['getData', this, this.getData, 1] - ]; + TestService.prototype.getAPIMethods = function () { + return [["getData", this, this.getData, 1]]; }; var service = { - name: 'testservice', + name: "testservice", module: TestService, }; - node._startService(service, function(err) { + node._startService(service, function (err) { if (err) { throw err; } @@ -289,66 +284,62 @@ describe('Dashcore Node', function() { getData.callCount.should.equal(1); }); }); - it('will give an error from start', function() { + it("will give an error from start", function () { var node = new Node(baseConfig); function TestService() {} util.inherits(TestService, BaseService); - TestService.prototype.start = sinon.stub().callsArgWith(0, new Error('test')); + TestService.prototype.start = sinon.stub().callsArgWith(0, new Error("test")); var service = { - name: 'testservice', + name: "testservice", module: TestService, - config: {} + config: {}, }; - node._startService(service, function(err) { - err.message.should.equal('test'); + node._startService(service, function (err) { + err.message.should.equal("test"); }); }); }); - describe('#start', function() { + describe("#start", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will call start for each service', function(done) { + it("will call start for each service", function (done) { var node = new Node(baseConfig); function TestService() {} util.inherits(TestService, BaseService); TestService.prototype.start = sinon.stub().callsArg(0); - TestService.prototype.getData = function() {}; - TestService.prototype.getAPIMethods = function() { - return [ - ['getData', this, this.getData, 1] - ]; + TestService.prototype.getData = function () {}; + TestService.prototype.getAPIMethods = function () { + return [["getData", this, this.getData, 1]]; }; function TestService2() {} util.inherits(TestService2, BaseService); TestService2.prototype.start = sinon.stub().callsArg(0); - TestService2.prototype.getData2 = function() {}; - TestService2.prototype.getAPIMethods = function() { - return [ - ['getData2', this, this.getData2, 1] - ]; + TestService2.prototype.getData2 = function () {}; + TestService2.prototype.getAPIMethods = function () { + return [["getData2", this, this.getData2, 1]]; }; node.getServiceOrder = sinon.stub().returns([ { - name: 'test1', + name: "test1", module: TestService, - config: {} + config: {}, }, { - name: 'test2', + name: "test2", module: TestService2, - config: {} - } + config: {}, + }, ]); - node.start(function() { + node.start(function () { TestService2.prototype.start.callCount.should.equal(1); TestService.prototype.start.callCount.should.equal(1); should.exist(node.getData2); @@ -356,128 +347,120 @@ describe('Dashcore Node', function() { done(); }); }); - it('will error if there are conflicting API methods', function(done) { + it("will error if there are conflicting API methods", function (done) { var node = new Node(baseConfig); function TestService() {} util.inherits(TestService, BaseService); TestService.prototype.start = sinon.stub().callsArg(0); - TestService.prototype.getData = function() {}; - TestService.prototype.getAPIMethods = function() { - return [ - ['getData', this, this.getData, 1] - ]; + TestService.prototype.getData = function () {}; + TestService.prototype.getAPIMethods = function () { + return [["getData", this, this.getData, 1]]; }; function ConflictService() {} util.inherits(ConflictService, BaseService); ConflictService.prototype.start = sinon.stub().callsArg(0); - ConflictService.prototype.getData = function() {}; - ConflictService.prototype.getAPIMethods = function() { - return [ - ['getData', this, this.getData, 1] - ]; + ConflictService.prototype.getData = function () {}; + ConflictService.prototype.getAPIMethods = function () { + return [["getData", this, this.getData, 1]]; }; node.getServiceOrder = sinon.stub().returns([ { - name: 'test', + name: "test", module: TestService, - config: {} + config: {}, }, { - name: 'conflict', + name: "conflict", module: ConflictService, - config: {} - } + config: {}, + }, ]); - node.start(function(err) { + node.start(function (err) { should.exist(err); err.message.should.match(/^Existing API method\(s\) exists\:/); done(); }); - }); - it('will handle service with getAPIMethods undefined', function(done) { + it("will handle service with getAPIMethods undefined", function (done) { var node = new Node(baseConfig); function TestService() {} util.inherits(TestService, BaseService); TestService.prototype.start = sinon.stub().callsArg(0); - TestService.prototype.getData = function() {}; + TestService.prototype.getData = function () {}; node.getServiceOrder = sinon.stub().returns([ { - name: 'test', + name: "test", module: TestService, - config: {} + config: {}, }, ]); - node.start(function() { + node.start(function () { TestService.prototype.start.callCount.should.equal(1); done(); }); - }); }); - describe('#getNetworkName', function() { - afterEach(function() { + describe("#getNetworkName", function () { + afterEach(function () { dashcore.Networks.disableRegtest(); }); - it('it will return the network name for livenet', function() { + it("it will return the network name for livenet", function () { var node = new Node(baseConfig); - node.getNetworkName().should.equal('livenet'); + node.getNetworkName().should.equal("livenet"); }); - it('it will return the network name for testnet', function() { + it("it will return the network name for testnet", function () { var baseConfig = { - network: 'testnet' + network: "testnet", }; var node = new Node(baseConfig); - node.getNetworkName().should.equal('testnet'); + node.getNetworkName().should.equal("testnet"); }); - it('it will return the network for regtest', function() { + it("it will return the network for regtest", function () { var baseConfig = { - network: 'regtest' + network: "regtest", }; var node = new Node(baseConfig); - node.getNetworkName().should.equal('regtest'); + node.getNetworkName().should.equal("regtest"); }); }); - describe('#stop', function() { + describe("#stop", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will call stop for each service', function(done) { + it("will call stop for each service", function (done) { var node = new Node(baseConfig); function TestService() {} util.inherits(TestService, BaseService); TestService.prototype.stop = sinon.stub().callsArg(0); - TestService.prototype.getData = function() {}; - TestService.prototype.getAPIMethods = function() { - return [ - ['getData', this, this.getData, 1] - ]; + TestService.prototype.getData = function () {}; + TestService.prototype.getAPIMethods = function () { + return [["getData", this, this.getData, 1]]; }; node.services = { - 'test1': new TestService({node: node}) + test1: new TestService({ node: node }), }; node.test2 = {}; node.test2.stop = sinon.stub().callsArg(0); node.getServiceOrder = sinon.stub().returns([ { - name: 'test1', - module: TestService - } + name: "test1", + module: TestService, + }, ]); - node.stop(function() { + node.stop(function () { TestService.prototype.stop.callCount.should.equal(1); done(); }); diff --git a/test/scaffold/add.integration.js b/test/scaffold/add.integration.js index afed7a245..f9fadfdc6 100644 --- a/test/scaffold/add.integration.js +++ b/test/scaffold/add.integration.js @@ -1,48 +1,39 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var sinon = require('sinon'); -var path = require('path'); -var fs = require('fs'); -var proxyquire = require('proxyquire'); -var rimraf = require('rimraf'); -var add = require('../../lib/scaffold/add'); +var should = require("chai").should(); +var sinon = require("sinon"); +var path = require("path"); +var fs = require("fs"); +var proxyquire = require("proxyquire"); +var rimraf = require("rimraf"); +var add = require("../../lib/scaffold/add"); -describe('#add', function() { - - var basePath = path.resolve(__dirname, '..'); - var testDir = path.resolve(basePath, 'temporary-test-data'); +describe("#add", function () { + var basePath = path.resolve(__dirname, ".."); + var testDir = path.resolve(basePath, "temporary-test-data"); var startConfig = { - name: 'My Node', - services: [] + name: "My Node", + services: [], }; var startPackage = {}; - before(function(done) { - fs.mkdir(testDir + '/s0/s1', { recursive: true }, function(err) { + before(function (done) { + fs.mkdir(testDir + "/s0/s1", { recursive: true }, function (err) { if (err) { throw err; } - fs.writeFile( - testDir + '/s0/s1/dashcore-node.json', - JSON.stringify(startConfig), - function(err) { - if (err) { - throw err; - } - fs.writeFile( - testDir + '/s0/s1/package.json', - JSON.stringify(startPackage), - done - ); + fs.writeFile(testDir + "/s0/s1/dashcore-node.json", JSON.stringify(startConfig), function (err) { + if (err) { + throw err; } - ); + fs.writeFile(testDir + "/s0/s1/package.json", JSON.stringify(startPackage), done); + }); }); }); - after(function(done) { + after(function (done) { // cleanup testing directories - rimraf(testDir, function(err) { + rimraf(testDir, function (err) { if (err) { throw err; } @@ -50,92 +41,98 @@ describe('#add', function() { }); }); - describe('will modify scaffold files', function() { - - it('will give an error if expected files do not exist', function(done) { - add({ - path: path.resolve(testDir, 's0'), - services: ['a', 'b', 'c'] - }, function(err) { - should.exist(err); - err.message.match(/^Invalid state/); - done(); - }); + describe("will modify scaffold files", function () { + it("will give an error if expected files do not exist", function (done) { + add( + { + path: path.resolve(testDir, "s0"), + services: ["a", "b", "c"], + }, + function (err) { + should.exist(err); + err.message.match(/^Invalid state/); + done(); + } + ); }); - it('will receive error from `npm install`', function(done) { + it("will receive error from `npm install`", function (done) { var spawn = sinon.stub().returns({ stdout: { - on: sinon.stub() + on: sinon.stub(), }, stderr: { - on: sinon.stub() + on: sinon.stub(), }, - on: sinon.stub().callsArgWith(1, 1) + on: sinon.stub().callsArgWith(1, 1), }); - var addtest = proxyquire('../../lib/scaffold/add', { - 'child_process': { - spawn: spawn - } + var addtest = proxyquire("../../lib/scaffold/add", { + child_process: { + spawn: spawn, + }, }); - addtest({ - path: path.resolve(testDir, 's0/s1/'), - services: ['a', 'b', 'c'] - }, function(err) { - should.exist(err); - err.message.should.equal('There was an error installing service: a'); - done(); - }); + addtest( + { + path: path.resolve(testDir, "s0/s1/"), + services: ["a", "b", "c"], + }, + function (err) { + should.exist(err); + err.message.should.equal("There was an error installing service: a"); + done(); + } + ); }); - it('will update dashcore-node.json services', function(done) { + it("will update dashcore-node.json services", function (done) { var callCount = 0; var oldPackage = { dependencies: { - '@dashevo/dashcore-lib': '^v0.15.4', - '@dashevo/dashcore-node': '^v3.0.7' - } + "@dashevo/dashcore-lib": "^v0.15.4", + "@dashevo/dashcore-node": "^v3.0.7", + }, }; var spawn = sinon.stub().returns({ stdout: { - on: sinon.stub() + on: sinon.stub(), }, stderr: { - on: sinon.stub() + on: sinon.stub(), }, - on: sinon.stub().callsArgWith(1, 0) + on: sinon.stub().callsArgWith(1, 0), }); - var addtest = proxyquire('../../lib/scaffold/add', { - 'child_process': { - spawn: spawn + var addtest = proxyquire("../../lib/scaffold/add", { + child_process: { + spawn: spawn, }, - 'fs': { - readFileSync: function() { - if (callCount === 1){ - oldPackage.dependencies.a = '^v0.1'; - } else if (callCount === 2){ - oldPackage.dependencies.b = '^v0.1'; - } else if (callCount === 3){ - oldPackage.dependencies.c = '^v0.1'; + fs: { + readFileSync: function () { + if (callCount === 1) { + oldPackage.dependencies.a = "^v0.1"; + } else if (callCount === 2) { + oldPackage.dependencies.b = "^v0.1"; + } else if (callCount === 3) { + oldPackage.dependencies.c = "^v0.1"; } callCount++; return JSON.stringify(oldPackage); - } - } - }); - addtest({ - path: path.resolve(testDir, 's0/s1/'), - services: ['a', 'b', 'c'] - }, function(err) { - should.not.exist(err); - var configPath = path.resolve(testDir, 's0/s1/dashcore-node.json'); - var config = JSON.parse(fs.readFileSync(configPath)); - config.services.should.deep.equal(['a','b','c']); - done(); + }, + }, }); + addtest( + { + path: path.resolve(testDir, "s0/s1/"), + services: ["a", "b", "c"], + }, + function (err) { + should.not.exist(err); + var configPath = path.resolve(testDir, "s0/s1/dashcore-node.json"); + var config = JSON.parse(fs.readFileSync(configPath)); + config.services.should.deep.equal(["a", "b", "c"]); + done(); + } + ); }); - }); - }); diff --git a/test/scaffold/call-method.unit.js b/test/scaffold/call-method.unit.js index cf2291bea..815cc75d8 100644 --- a/test/scaffold/call-method.unit.js +++ b/test/scaffold/call-method.unit.js @@ -1,65 +1,64 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var sinon = require('sinon'); -var proxyquire = require('proxyquire'); -var EventEmitter = require('events').EventEmitter; +var should = require("chai").should(); +var sinon = require("sinon"); +var proxyquire = require("proxyquire"); +var EventEmitter = require("events").EventEmitter; -describe('#callMethod', function() { - - var expectedUrl = 'http://localhost:3001'; +describe("#callMethod", function () { + var expectedUrl = "http://localhost:3001"; var expectedOptions = { reconnection: false, - connect_timeout: 5000 + connect_timeout: 5000, }; var callOptions = { - host: 'localhost', + host: "localhost", port: 3001, - protocol: 'http' + protocol: "http", }; var callMethod; - before(function() { - callMethod = proxyquire('../../lib/scaffold/call-method', { - 'socket.io-client': function(url, options) { + before(function () { + callMethod = proxyquire("../../lib/scaffold/call-method", { + "socket.io-client": function (url, options) { url.should.equal(expectedUrl); options.should.deep.equal(expectedOptions); return new EventEmitter(); - } + }, }); }); - it('handle a connection error', function(done) { - var socket = callMethod(callOptions, 'getInfo', null, function(err) { + it("handle a connection error", function (done) { + var socket = callMethod(callOptions, "getInfo", null, function (err) { should.exist(err); - err.message.should.equal('connect'); + err.message.should.equal("connect"); done(); }); - socket.emit('connect_error', new Error('connect')); + socket.emit("connect_error", new Error("connect")); }); - it('give an error response', function(done) { - var socket = callMethod(callOptions, 'getInfo', null, function(err) { + it("give an error response", function (done) { + var socket = callMethod(callOptions, "getInfo", null, function (err) { should.exist(err); - err.message.should.equal('response'); + err.message.should.equal("response"); done(); }); - socket.send = function(opts, callback) { - opts.method.should.equal('getInfo'); + socket.send = function (opts, callback) { + opts.method.should.equal("getInfo"); should.equal(opts.params, null); var response = { error: { - message: 'response' - } + message: "response", + }, }; callback(response); }; - socket.emit('connect'); + socket.emit("connect"); }); - it('give result and close socket', function(done) { + it("give result and close socket", function (done) { var expectedData = { version: 110000, protocolversion: 70002, @@ -69,25 +68,24 @@ describe('#callMethod', function() { difficulty: 112628548.66634709, testnet: false, relayfee: 1000, - errors: '' + errors: "", }; - var socket = callMethod(callOptions, 'getInfo', null, function(err, data) { + var socket = callMethod(callOptions, "getInfo", null, function (err, data) { should.not.exist(err); data.should.deep.equal(expectedData); socket.close.callCount.should.equal(1); done(); }); socket.close = sinon.stub(); - socket.send = function(opts, callback) { - opts.method.should.equal('getInfo'); + socket.send = function (opts, callback) { + opts.method.should.equal("getInfo"); should.equal(opts.params, null); var response = { error: null, - result: expectedData + result: expectedData, }; callback(response); }; - socket.emit('connect'); + socket.emit("connect"); }); - }); diff --git a/test/scaffold/create.integration.js b/test/scaffold/create.integration.js index aa55b86be..de4ddc7e7 100644 --- a/test/scaffold/create.integration.js +++ b/test/scaffold/create.integration.js @@ -1,38 +1,37 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var proxyquire = require('proxyquire'); -var sinon = require('sinon'); -var create = proxyquire('../../lib/scaffold/create', { - 'child_process': { +var should = require("chai").should(); +var proxyquire = require("proxyquire"); +var sinon = require("sinon"); +var create = proxyquire("../../lib/scaffold/create", { + child_process: { spawn: sinon.stub().returns({ stdout: { - on: sinon.stub() + on: sinon.stub(), }, stderr: { - on: sinon.stub() + on: sinon.stub(), }, - on: function(event, cb) { + on: function (event, cb) { cb(0); - } - }) - } + }, + }), + }, }); -var fs = require('fs'); -var rimraf = require('rimraf'); - -describe('#create', function() { +var fs = require("fs"); +var rimraf = require("rimraf"); - var basePath = __dirname + '/../'; - var testDir = basePath + 'temporary-test-data'; +describe("#create", function () { + var basePath = __dirname + "/../"; + var testDir = basePath + "temporary-test-data"; - before(function(done) { + before(function (done) { // setup testing directories - fs.mkdir(testDir, { recursive: true }, function(err) { + fs.mkdir(testDir, { recursive: true }, function (err) { if (err) { throw err; } - fs.mkdir(testDir + '/.dash', { recursive: true }, function(err) { + fs.mkdir(testDir + "/.dash", { recursive: true }, function (err) { if (err) { throw err; } @@ -41,9 +40,9 @@ describe('#create', function() { }); }); - after(function(done) { + after(function (done) { // cleanup testing directories - rimraf(testDir, function(err) { + rimraf(testDir, function (err) { if (err) { throw err; } @@ -51,100 +50,103 @@ describe('#create', function() { }); }); - it('will create scaffold files', function() { - create({ - cwd: testDir, - dirname: 'mynode', - name: 'My Node 1', - isGlobal: false, - datadir: './data' - }, function(err) { - if (err) { - throw err; - } - - var configPath = testDir + '/mynode/dashcore-node.json'; - var packagePath = testDir + '/mynode/package.json'; - var dataPath = testDir + '/mynode/data'; - - should.equal(fs.existsSync(configPath), true); - should.equal(fs.existsSync(packagePath), true); - should.equal(fs.existsSync(dataPath), true); + it("will create scaffold files", function () { + create( + { + cwd: testDir, + dirname: "mynode", + name: "My Node 1", + isGlobal: false, + datadir: "./data", + }, + function (err) { + if (err) { + throw err; + } - var config = JSON.parse(fs.readFileSync(configPath)); - config.services.should.deep.equal(['dashd', 'web']); - config.network.should.equal('livenet'); + var configPath = testDir + "/mynode/dashcore-node.json"; + var packagePath = testDir + "/mynode/package.json"; + var dataPath = testDir + "/mynode/data"; - var pack = JSON.parse(fs.readFileSync(packagePath)); - should.exist(pack.dependencies); + should.equal(fs.existsSync(configPath), true); + should.equal(fs.existsSync(packagePath), true); + should.equal(fs.existsSync(dataPath), true); - }); + var config = JSON.parse(fs.readFileSync(configPath)); + config.services.should.deep.equal(["dashd", "web"]); + config.network.should.equal("livenet"); + var pack = JSON.parse(fs.readFileSync(packagePath)); + should.exist(pack.dependencies); + } + ); }); - it('will error if directory already exists', function() { - - create({ - cwd: testDir, - dirname: 'mynode', - name: 'My Node 2', - isGlobal: false, - datadir: './data' - }, function(err) { - should.exist(err); - err.message.should.match(/^Directory/); - }); - + it("will error if directory already exists", function () { + create( + { + cwd: testDir, + dirname: "mynode", + name: "My Node 2", + isGlobal: false, + datadir: "./data", + }, + function (err) { + should.exist(err); + err.message.should.match(/^Directory/); + } + ); }); - it('will not create a package.json if globally installed', function() { + it("will not create a package.json if globally installed", function () { + create( + { + cwd: testDir, + dirname: "mynode3", + name: "My Node 3", + isGlobal: true, + datadir: "../.dash", + }, + function (err) { + if (err) { + throw err; + } - create({ - cwd: testDir, - dirname: 'mynode3', - name: 'My Node 3', - isGlobal: true, - datadir: '../.dash' - }, function(err) { - if (err) { - throw err; + var packagePath = testDir + "/mynode3/package.json"; + should.equal(fs.existsSync(packagePath), false); } - - var packagePath = testDir + '/mynode3/package.json'; - should.equal(fs.existsSync(packagePath), false); - - }); - + ); }); - it('will receieve an error from npm', function() { - var createtest = proxyquire('../../lib/scaffold/create', { - 'child_process': { + it("will receieve an error from npm", function () { + var createtest = proxyquire("../../lib/scaffold/create", { + child_process: { spawn: sinon.stub().returns({ stdout: { - on: sinon.stub() + on: sinon.stub(), }, stderr: { - on: sinon.stub() + on: sinon.stub(), }, - on: function(event, cb) { + on: function (event, cb) { cb(1); - } - }) - } - }); - - createtest({ - cwd: testDir, - dirname: 'mynode4', - name: 'My Node 4', - isGlobal: false, - datadir: '../.dash' - }, function(err) { - should.exist(err); - err.message.should.equal('There was an error installing dependencies.'); + }, + }), + }, }); + createtest( + { + cwd: testDir, + dirname: "mynode4", + name: "My Node 4", + isGlobal: false, + datadir: "../.dash", + }, + function (err) { + should.exist(err); + err.message.should.equal("There was an error installing dependencies."); + } + ); }); - }); diff --git a/test/scaffold/default-base-config.integration.js b/test/scaffold/default-base-config.integration.js index 7fcf21294..f19ef69c9 100644 --- a/test/scaffold/default-base-config.integration.js +++ b/test/scaffold/default-base-config.integration.js @@ -1,28 +1,28 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var path = require('path'); -var defaultBaseConfig = require('../../lib/scaffold/default-base-config'); +var should = require("chai").should(); +var path = require("path"); +var defaultBaseConfig = require("../../lib/scaffold/default-base-config"); -describe('#defaultBaseConfig', function() { - it('will return expected configuration', function() { +describe("#defaultBaseConfig", function () { + it("will return expected configuration", function () { var cwd = process.cwd(); var home = process.env.HOME; var info = defaultBaseConfig(); info.path.should.equal(cwd); - info.config.network.should.equal('livenet'); + info.config.network.should.equal("livenet"); info.config.port.should.equal(3001); - info.config.services.should.deep.equal(['dashd', 'web']); + info.config.services.should.deep.equal(["dashd", "web"]); var dashd = info.config.servicesConfig.dashd; - dashd.spawn.datadir.should.equal(home + '/.dash'); - dashd.spawn.exec.should.equal(path.resolve(__dirname, process.env.HOME, './.dash/dashd')); + dashd.spawn.datadir.should.equal(home + "/.dash"); + dashd.spawn.exec.should.equal(path.resolve(__dirname, process.env.HOME, "./.dash/dashd")); }); - it('be able to specify a network', function() { - var info = defaultBaseConfig({network: 'testnet'}); - info.config.network.should.equal('testnet'); + it("be able to specify a network", function () { + var info = defaultBaseConfig({ network: "testnet" }); + info.config.network.should.equal("testnet"); }); - it('be able to specify a datadir', function() { - var info = defaultBaseConfig({datadir: './data2', network: 'testnet'}); - info.config.servicesConfig.dashd.spawn.datadir.should.equal('./data2'); + it("be able to specify a datadir", function () { + var info = defaultBaseConfig({ datadir: "./data2", network: "testnet" }); + info.config.servicesConfig.dashd.spawn.datadir.should.equal("./data2"); }); }); diff --git a/test/scaffold/default-config.integration.js b/test/scaffold/default-config.integration.js index 55eb60c33..44f64b31d 100644 --- a/test/scaffold/default-config.integration.js +++ b/test/scaffold/default-config.integration.js @@ -1,41 +1,44 @@ -'use strict'; +"use strict"; -var path = require('path'); -var should = require('chai').should(); -var sinon = require('sinon'); -var proxyquire = require('proxyquire'); +var path = require("path"); +var should = require("chai").should(); +var sinon = require("sinon"); +var proxyquire = require("proxyquire"); -describe('#defaultConfig', function() { - var expectedExecPath = path.resolve(__dirname, process.env.HOME, './.dashcore/data/dashd'); +describe("#defaultConfig", function () { + var expectedExecPath = path.resolve(__dirname, process.env.HOME, "./.dashcore/data/dashd"); - it('will return expected configuration', function() { - var config = JSON.stringify({ - network: 'livenet', - port: 3001, - services: [ - 'dashd', - 'web' - ], - servicesConfig: { - dashd: { - connect: [{ - rpchost: '127.0.0.1', - rpcport: 9998, - rpcuser: 'dash', - rpcpassword: 'local321', - zmqpubrawtx: 'tcp://127.0.0.1:28332' - }] - } - } - }, null, 2); - var defaultConfig = proxyquire('../../lib/scaffold/default-config', { + it("will return expected configuration", function () { + var config = JSON.stringify( + { + network: "livenet", + port: 3001, + services: ["dashd", "web"], + servicesConfig: { + dashd: { + connect: [ + { + rpchost: "127.0.0.1", + rpcport: 9998, + rpcuser: "dash", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:28332", + }, + ], + }, + }, + }, + null, + 2 + ); + var defaultConfig = proxyquire("../../lib/scaffold/default-config", { fs: { existsSync: sinon.stub().returns(false), - writeFileSync: function(path, data) { - path.should.equal(process.env.HOME + '/.dashcore/dashcore-node.json'); + writeFileSync: function (path, data) { + path.should.equal(process.env.HOME + "/.dashcore/dashcore-node.json"); data.should.equal(config); }, - readFileSync: function() { + readFileSync: function () { return config; }, mkdirSync: sinon.stub(), @@ -43,43 +46,44 @@ describe('#defaultConfig', function() { }); var home = process.env.HOME; var info = defaultConfig(); - info.path.should.equal(home + '/.dashcore'); - info.config.network.should.equal('livenet'); + info.path.should.equal(home + "/.dashcore"); + info.config.network.should.equal("livenet"); info.config.port.should.equal(3001); - info.config.services.should.deep.equal(['dashd', 'web']); + info.config.services.should.deep.equal(["dashd", "web"]); var dashd = info.config.servicesConfig.dashd; should.exist(dashd); }); - it('will include additional services', function() { - var config = JSON.stringify({ - network: 'livenet', - port: 3001, - services: [ - 'dashd', - 'web', - 'insight-api', - 'insight-ui' - ], - servicesConfig: { - dashd: { - connect: [{ - rpchost: '127.0.0.1', - rpcport: 9998, - rpcuser: 'dash', - rpcpassword: 'local321', - zmqpubrawtx: 'tcp://127.0.0.1:28332' - }] - } - } - }, null, 2); - var defaultConfig = proxyquire('../../lib/scaffold/default-config', { + it("will include additional services", function () { + var config = JSON.stringify( + { + network: "livenet", + port: 3001, + services: ["dashd", "web", "insight-api", "insight-ui"], + servicesConfig: { + dashd: { + connect: [ + { + rpchost: "127.0.0.1", + rpcport: 9998, + rpcuser: "dash", + rpcpassword: "local321", + zmqpubrawtx: "tcp://127.0.0.1:28332", + }, + ], + }, + }, + }, + null, + 2 + ); + var defaultConfig = proxyquire("../../lib/scaffold/default-config", { fs: { existsSync: sinon.stub().returns(false), - writeFileSync: function(path, data) { - path.should.equal(process.env.HOME + '/.dashcore/dashcore-node.json'); + writeFileSync: function (path, data) { + path.should.equal(process.env.HOME + "/.dashcore/dashcore-node.json"); data.should.equal(config); }, - readFileSync: function() { + readFileSync: function () { return config; }, mkdirSync: sinon.stub(), @@ -87,17 +91,12 @@ describe('#defaultConfig', function() { }); var home = process.env.HOME; var info = defaultConfig({ - additionalServices: ['insight-api', 'insight-ui'] + additionalServices: ["insight-api", "insight-ui"], }); - info.path.should.equal(home + '/.dashcore'); - info.config.network.should.equal('livenet'); + info.path.should.equal(home + "/.dashcore"); + info.config.network.should.equal("livenet"); info.config.port.should.equal(3001); - info.config.services.should.deep.equal([ - 'dashd', - 'web', - 'insight-api', - 'insight-ui' - ]); + info.config.services.should.deep.equal(["dashd", "web", "insight-api", "insight-ui"]); var dashd = info.config.servicesConfig.dashd; should.exist(dashd); }); diff --git a/test/scaffold/find-config.integration.js b/test/scaffold/find-config.integration.js index 893a325c3..1951d64ad 100644 --- a/test/scaffold/find-config.integration.js +++ b/test/scaffold/find-config.integration.js @@ -1,45 +1,39 @@ -'use strict'; +"use strict"; -var fs = require('fs'); -var path = require('path'); -var should = require('chai').should(); -var sinon = require('sinon'); -var rimraf = require('rimraf'); +var fs = require("fs"); +var path = require("path"); +var should = require("chai").should(); +var sinon = require("sinon"); +var rimraf = require("rimraf"); -var findConfig = require('../../lib/scaffold/find-config'); +var findConfig = require("../../lib/scaffold/find-config"); -describe('#findConfig', function() { - - var testDir = path.resolve(__dirname, '../temporary-test-data'); +describe("#findConfig", function () { + var testDir = path.resolve(__dirname, "../temporary-test-data"); var expectedConfig = { - name: 'My Node' + name: "My Node", }; - before(function(done) { + before(function (done) { // setup testing directories - fs.mkdir(testDir + '/p2/p1/p0', { recursive: true }, function(err) { + fs.mkdir(testDir + "/p2/p1/p0", { recursive: true }, function (err) { if (err) { throw err; } - fs.writeFile( - testDir + '/p2/dashcore-node.json', - JSON.stringify(expectedConfig), - function() { - fs.mkdir(testDir + '/e0', { recursive: true }, function(err) { - if (err) { - throw err; - } - done(); - }); - } - ); + fs.writeFile(testDir + "/p2/dashcore-node.json", JSON.stringify(expectedConfig), function () { + fs.mkdir(testDir + "/e0", { recursive: true }, function (err) { + if (err) { + throw err; + } + done(); + }); + }); }); - }); - after(function(done) { + after(function (done) { // cleanup testing directories - rimraf(testDir, function(err) { + rimraf(testDir, function (err) { if (err) { throw err; } @@ -47,32 +41,28 @@ describe('#findConfig', function() { }); }); - - describe('will find a configuration file', function() { - - it('in the current directory', function() { - var config = findConfig(path.resolve(testDir, 'p2')); - config.path.should.equal(path.resolve(testDir, 'p2')); + describe("will find a configuration file", function () { + it("in the current directory", function () { + var config = findConfig(path.resolve(testDir, "p2")); + config.path.should.equal(path.resolve(testDir, "p2")); config.config.should.deep.equal(expectedConfig); }); - it('in a parent directory', function() { - var config = findConfig(path.resolve(testDir, 'p2/p1')); - config.path.should.equal(path.resolve(testDir, 'p2')); + it("in a parent directory", function () { + var config = findConfig(path.resolve(testDir, "p2/p1")); + config.path.should.equal(path.resolve(testDir, "p2")); config.config.should.deep.equal(expectedConfig); }); - it('recursively find in parent directories', function() { - var config = findConfig(path.resolve(testDir, 'p2/p1/p0')); - config.path.should.equal(path.resolve(testDir, 'p2')); + it("recursively find in parent directories", function () { + var config = findConfig(path.resolve(testDir, "p2/p1/p0")); + config.path.should.equal(path.resolve(testDir, "p2")); config.config.should.deep.equal(expectedConfig); }); - }); - it('will return false if missing a configuration', function() { - var config = findConfig(path.resolve(testDir, 'e0')); + it("will return false if missing a configuration", function () { + var config = findConfig(path.resolve(testDir, "e0")); config.should.equal(false); }); - }); diff --git a/test/scaffold/remove.integration.js b/test/scaffold/remove.integration.js index 461513bbd..4a2959739 100644 --- a/test/scaffold/remove.integration.js +++ b/test/scaffold/remove.integration.js @@ -1,48 +1,39 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var sinon = require('sinon'); -var path = require('path'); -var fs = require('fs'); -var proxyquire = require('proxyquire'); -var rimraf = require('rimraf'); -var remove = require('../../lib/scaffold/remove'); +var should = require("chai").should(); +var sinon = require("sinon"); +var path = require("path"); +var fs = require("fs"); +var proxyquire = require("proxyquire"); +var rimraf = require("rimraf"); +var remove = require("../../lib/scaffold/remove"); -describe('#remove', function() { - - var basePath = path.resolve(__dirname, '..'); - var testDir = path.resolve(basePath, 'temporary-test-data'); +describe("#remove", function () { + var basePath = path.resolve(__dirname, ".."); + var testDir = path.resolve(basePath, "temporary-test-data"); var startConfig = { - name: 'My Node', - services: ['a', 'b', 'c'] + name: "My Node", + services: ["a", "b", "c"], }; var startPackage = {}; - before(function(done) { - fs.mkdir(testDir + '/s0/s1', { recursive: true }, function(err) { + before(function (done) { + fs.mkdir(testDir + "/s0/s1", { recursive: true }, function (err) { if (err) { throw err; } - fs.writeFile( - testDir + '/s0/s1/dashcore-node.json', - JSON.stringify(startConfig), - function(err) { - if (err) { - throw err; - } - fs.writeFile( - testDir + '/s0/s1/package.json', - JSON.stringify(startPackage), - done - ); + fs.writeFile(testDir + "/s0/s1/dashcore-node.json", JSON.stringify(startConfig), function (err) { + if (err) { + throw err; } - ); + fs.writeFile(testDir + "/s0/s1/package.json", JSON.stringify(startPackage), done); + }); }); }); - after(function(done) { + after(function (done) { // cleanup testing directories - rimraf(testDir, function(err) { + rimraf(testDir, function (err) { if (err) { throw err; } @@ -50,88 +41,104 @@ describe('#remove', function() { }); }); - describe('will modify scaffold files', function() { - - it('will give an error if expected files do not exist', function(done) { - remove({ - path: path.resolve(testDir, 's0'), - services: ['b'] - }, function(err) { - should.exist(err); - err.message.match(/^Invalid state/); - done(); - }); + describe("will modify scaffold files", function () { + it("will give an error if expected files do not exist", function (done) { + remove( + { + path: path.resolve(testDir, "s0"), + services: ["b"], + }, + function (err) { + should.exist(err); + err.message.match(/^Invalid state/); + done(); + } + ); }); - it('will update dashcore-node.json services', function(done) { + it("will update dashcore-node.json services", function (done) { var spawn = sinon.stub().returns({ stdout: { - on: sinon.stub() + on: sinon.stub(), }, stderr: { - on: sinon.stub() + on: sinon.stub(), }, - on: sinon.stub().callsArgWith(1, 0) + on: sinon.stub().callsArgWith(1, 0), }); - var removetest = proxyquire('../../lib/scaffold/remove', { - 'child_process': { - spawn: spawn + var removetest = proxyquire("../../lib/scaffold/remove", { + child_process: { + spawn: spawn, }, - 'npm': { + npm: { load: sinon.stub().callsArg(0), commands: { - ls: sinon.stub().callsArgWith(2, null, {}, { - dependencies: {} - }) - } - } - }); - removetest({ - path: path.resolve(testDir, 's0/s1/'), - services: ['b'] - }, function(err) { - should.not.exist(err); - var configPath = path.resolve(testDir, 's0/s1/dashcore-node.json'); - var config = JSON.parse(fs.readFileSync(configPath)); - config.services.should.deep.equal(['a', 'c']); - done(); + ls: sinon.stub().callsArgWith( + 2, + null, + {}, + { + dependencies: {}, + } + ), + }, + }, }); + removetest( + { + path: path.resolve(testDir, "s0/s1/"), + services: ["b"], + }, + function (err) { + should.not.exist(err); + var configPath = path.resolve(testDir, "s0/s1/dashcore-node.json"); + var config = JSON.parse(fs.readFileSync(configPath)); + config.services.should.deep.equal(["a", "c"]); + done(); + } + ); }); - it('will receive error from `npm uninstall`', function(done) { + it("will receive error from `npm uninstall`", function (done) { var spawn = sinon.stub().returns({ stdout: { - on: sinon.stub() + on: sinon.stub(), }, stderr: { - on: sinon.stub() + on: sinon.stub(), }, - on: sinon.stub().callsArgWith(1, 1) + on: sinon.stub().callsArgWith(1, 1), }); - var removetest = proxyquire('../../lib/scaffold/remove', { - 'child_process': { - spawn: spawn + var removetest = proxyquire("../../lib/scaffold/remove", { + child_process: { + spawn: spawn, }, - 'npm': { + npm: { load: sinon.stub().callsArg(0), commands: { - ls: sinon.stub().callsArgWith(2, null, {}, { - dependencies: {} - }) - } - } + ls: sinon.stub().callsArgWith( + 2, + null, + {}, + { + dependencies: {}, + } + ), + }, + }, }); - removetest({ - path: path.resolve(testDir, 's0/s1/'), - services: ['b'] - }, function(err) { - should.exist(err); - err.message.should.equal('There was an error uninstalling service(s): b'); - done(); - }); + removetest( + { + path: path.resolve(testDir, "s0/s1/"), + services: ["b"], + }, + function (err) { + should.exist(err); + err.message.should.equal("There was an error uninstalling service(s): b"); + done(); + } + ); }); - }); - }); diff --git a/test/scaffold/start.integration.js b/test/scaffold/start.integration.js index 2e5ecccdd..ac4486f52 100644 --- a/test/scaffold/start.integration.js +++ b/test/scaffold/start.integration.js @@ -1,45 +1,43 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var sinon = require('sinon'); -var proxyquire = require('proxyquire'); -var DashService = require('../../lib/services/dashd'); -var index = require('../../lib'); +var should = require("chai").should(); +var sinon = require("sinon"); +var proxyquire = require("proxyquire"); +var DashService = require("../../lib/services/dashd"); +var index = require("../../lib"); var log = index.log; -describe('#start', function() { - +describe("#start", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'error'); + beforeEach(function () { + sandbox.stub(log, "error"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - describe('will dynamically create a node from a configuration', function() { - - it('require each dashcore-node service with default config', function(done) { + describe("will dynamically create a node from a configuration", function () { + it("require each dashcore-node service with default config", function (done) { var node; - var TestNode = function(options) { + var TestNode = function (options) { options.services[0].should.deep.equal({ - name: 'dashd', + name: "dashd", module: DashService, config: { spawn: { - datadir: './data' - } - } + datadir: "./data", + }, + }, }); }; TestNode.prototype.start = sinon.stub().callsArg(0); TestNode.prototype.on = sinon.stub(); TestNode.prototype.chain = { - on: sinon.stub() + on: sinon.stub(), }; - var starttest = proxyquire('../../lib/scaffold/start', { - '../node': TestNode + var starttest = proxyquire("../../lib/scaffold/start", { + "../node": TestNode, }); starttest.registerExitHandlers = sinon.stub(); @@ -47,30 +45,28 @@ describe('#start', function() { node = starttest({ path: __dirname, config: { - services: [ - 'dashd' - ], + services: ["dashd"], servicesConfig: { dashd: { spawn: { - datadir: './data' - } - } - } - } + datadir: "./data", + }, + }, + }, + }, }); node.should.be.instanceof(TestNode); done(); }); - it('shutdown with an error from start', function(done) { - var TestNode = proxyquire('../../lib/node', {}); - TestNode.prototype.start = function(callback) { - setImmediate(function() { - callback(new Error('error')); + it("shutdown with an error from start", function (done) { + var TestNode = proxyquire("../../lib/node", {}); + TestNode.prototype.start = function (callback) { + setImmediate(function () { + callback(new Error("error")); }); }; - var starttest = proxyquire('../../lib/scaffold/start', { - '../node': TestNode + var starttest = proxyquire("../../lib/scaffold/start", { + "../node": TestNode, }); starttest.cleanShutdown = sinon.stub(); starttest.registerExitHandlers = sinon.stub(); @@ -79,55 +75,52 @@ describe('#start', function() { path: __dirname, config: { services: [], - servicesConfig: {} - } + servicesConfig: {}, + }, }); - setImmediate(function() { + setImmediate(function () { starttest.cleanShutdown.callCount.should.equal(1); done(); }); }); - it('require each dashcore-node service with explicit config', function(done) { + it("require each dashcore-node service with explicit config", function (done) { var node; - var TestNode = function(options) { + var TestNode = function (options) { options.services[0].should.deep.equal({ - name: 'dashd', + name: "dashd", module: DashService, config: { - param: 'test', + param: "test", spawn: { - datadir: './data' - } - } + datadir: "./data", + }, + }, }); }; TestNode.prototype.start = sinon.stub().callsArg(0); TestNode.prototype.on = sinon.stub(); TestNode.prototype.chain = { - on: sinon.stub() + on: sinon.stub(), }; - var starttest = proxyquire('../../lib/scaffold/start', { - '../node': TestNode + var starttest = proxyquire("../../lib/scaffold/start", { + "../node": TestNode, }); starttest.registerExitHandlers = sinon.stub(); node = starttest({ path: __dirname, config: { - services: [ - 'dashd' - ], + services: ["dashd"], servicesConfig: { - 'dashd': { - param: 'test', + dashd: { + param: "test", spawn: { - datadir: './data' - } - } + datadir: "./data", + }, + }, }, - - } + }, }); node.should.be.instanceof(TestNode); done(); diff --git a/test/scaffold/start.unit.js b/test/scaffold/start.unit.js index 49a670f42..cb7832366 100644 --- a/test/scaffold/start.unit.js +++ b/test/scaffold/start.unit.js @@ -1,172 +1,172 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var EventEmitter = require('events').EventEmitter; -var path = require('path'); -var sinon = require('sinon'); -var proxyquire = require('proxyquire'); -var start = require('../../lib/scaffold/start'); +var should = require("chai").should(); +var EventEmitter = require("events").EventEmitter; +var path = require("path"); +var sinon = require("sinon"); +var proxyquire = require("proxyquire"); +var start = require("../../lib/scaffold/start"); -describe('#start', function() { - describe('#checkConfigVersion2', function() { +describe("#start", function () { + describe("#checkConfigVersion2", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(console, 'warn'); + beforeEach(function () { + sandbox.stub(console, "warn"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will give true with "datadir" at root', function() { - var checkConfigVersion2 = proxyquire('../../lib/scaffold/start', {}).checkConfigVersion2; - var v2 = checkConfigVersion2({datadir: '/home/user/.dashcore/data', services: []}); + it('will give true with "datadir" at root', function () { + var checkConfigVersion2 = proxyquire("../../lib/scaffold/start", {}).checkConfigVersion2; + var v2 = checkConfigVersion2({ datadir: "/home/user/.dashcore/data", services: [] }); v2.should.equal(true); }); - it('will give true with "address" service enabled', function() { - var checkConfigVersion2 = proxyquire('../../lib/scaffold/start', {}).checkConfigVersion2; - var v2 = checkConfigVersion2({services: ['address']}); + it('will give true with "address" service enabled', function () { + var checkConfigVersion2 = proxyquire("../../lib/scaffold/start", {}).checkConfigVersion2; + var v2 = checkConfigVersion2({ services: ["address"] }); v2.should.equal(true); }); - it('will give true with "db" service enabled', function() { - var checkConfigVersion2 = proxyquire('../../lib/scaffold/start', {}).checkConfigVersion2; - var v2 = checkConfigVersion2({services: ['db']}); + it('will give true with "db" service enabled', function () { + var checkConfigVersion2 = proxyquire("../../lib/scaffold/start", {}).checkConfigVersion2; + var v2 = checkConfigVersion2({ services: ["db"] }); v2.should.equal(true); }); - it('will give false without "datadir" at root and "address", "db" services disabled', function() { - var checkConfigVersion2 = proxyquire('../../lib/scaffold/start', {}).checkConfigVersion2; - var v2 = checkConfigVersion2({services: []}); + it('will give false without "datadir" at root and "address", "db" services disabled', function () { + var checkConfigVersion2 = proxyquire("../../lib/scaffold/start", {}).checkConfigVersion2; + var v2 = checkConfigVersion2({ services: [] }); v2.should.equal(false); }); }); - describe('#setupServices', function() { + describe("#setupServices", function () { var cwd = process.cwd(); - var setupServices = proxyquire('../../lib/scaffold/start', {}).setupServices; - it('will require an internal module', function() { + var setupServices = proxyquire("../../lib/scaffold/start", {}).setupServices; + it("will require an internal module", function () { function InternalService() {} InternalService.dependencies = []; InternalService.prototype.start = sinon.stub(); InternalService.prototype.stop = sinon.stub(); - var expectedPath = path.resolve(__dirname, '../../lib/services/internal'); - var testRequire = function(p) { + var expectedPath = path.resolve(__dirname, "../../lib/services/internal"); + var testRequire = function (p) { p.should.equal(expectedPath); return InternalService; }; var config = { - services: ['internal'], + services: ["internal"], servicesConfig: { internal: { - param: 'value' - } - } + param: "value", + }, + }, }; var services = setupServices(testRequire, cwd, config); - services[0].name.should.equal('internal'); - services[0].config.should.deep.equal({param: 'value'}); + services[0].name.should.equal("internal"); + services[0].config.should.deep.equal({ param: "value" }); services[0].module.should.equal(InternalService); }); - it('will require a local module', function() { + it("will require a local module", function () { function LocalService() {} LocalService.dependencies = []; LocalService.prototype.start = sinon.stub(); LocalService.prototype.stop = sinon.stub(); - var notfoundPath = path.resolve(__dirname, '../../lib/services/local'); - var testRequire = function(p) { + var notfoundPath = path.resolve(__dirname, "../../lib/services/local"); + var testRequire = function (p) { if (p === notfoundPath) { throw new Error(); - } else if (p === 'local') { + } else if (p === "local") { return LocalService; - } else if (p === 'local/package.json') { + } else if (p === "local/package.json") { return { - name: 'local' + name: "local", }; } }; var config = { - services: ['local'] + services: ["local"], }; var services = setupServices(testRequire, cwd, config); - services[0].name.should.equal('local'); + services[0].name.should.equal("local"); services[0].module.should.equal(LocalService); }); - it('will require a local module with "dashcoreNode" in package.json', function() { + it('will require a local module with "dashcoreNode" in package.json', function () { function LocalService() {} LocalService.dependencies = []; LocalService.prototype.start = sinon.stub(); LocalService.prototype.stop = sinon.stub(); - var notfoundPath = path.resolve(__dirname, '../../lib/services/local'); - var testRequire = function(p) { + var notfoundPath = path.resolve(__dirname, "../../lib/services/local"); + var testRequire = function (p) { if (p === notfoundPath) { throw new Error(); - } else if (p === 'local/package.json') { + } else if (p === "local/package.json") { return { - name: 'local', - dashcoreNode: 'lib/dashcoreNode.js' + name: "local", + dashcoreNode: "lib/dashcoreNode.js", }; - } else if (p === 'local/lib/dashcoreNode.js') { + } else if (p === "local/lib/dashcoreNode.js") { return LocalService; } }; var config = { - services: ['local'] + services: ["local"], }; var services = setupServices(testRequire, cwd, config); - services[0].name.should.equal('local'); + services[0].name.should.equal("local"); services[0].module.should.equal(LocalService); }); - it('will throw error if module is incompatible', function() { + it("will throw error if module is incompatible", function () { var internal = {}; - var testRequire = function() { + var testRequire = function () { return internal; }; var config = { - services: ['dashd'] + services: ["dashd"], }; - (function() { + (function () { setupServices(testRequire, cwd, config); - }).should.throw('Could not load service'); + }).should.throw("Could not load service"); }); }); - describe('#cleanShutdown', function() { - it('will call node stop and process exit', function() { + describe("#cleanShutdown", function () { + it("will call node stop and process exit", function () { var log = { info: sinon.stub(), - error: sinon.stub() + error: sinon.stub(), }; - var cleanShutdown = proxyquire('../../lib/scaffold/start', { - '../': { - log: log - } + var cleanShutdown = proxyquire("../../lib/scaffold/start", { + "../": { + log: log, + }, }).cleanShutdown; var node = { - stop: sinon.stub().callsArg(0) + stop: sinon.stub().callsArg(0), }; var _process = { - exit: sinon.stub() + exit: sinon.stub(), }; cleanShutdown(_process, node); - setImmediate(function() { + setImmediate(function () { node.stop.callCount.should.equal(1); _process.exit.callCount.should.equal(1); _process.exit.args[0][0].should.equal(0); }); }); - it('will log error during shutdown and exit with status 1', function() { + it("will log error during shutdown and exit with status 1", function () { var log = { info: sinon.stub(), - error: sinon.stub() + error: sinon.stub(), }; - var cleanShutdown = proxyquire('../../lib/scaffold/start', { - '../': { - log: log - } + var cleanShutdown = proxyquire("../../lib/scaffold/start", { + "../": { + log: log, + }, }).cleanShutdown; var node = { - stop: sinon.stub().callsArgWith(0, new Error('test')) + stop: sinon.stub().callsArgWith(0, new Error("test")), }; var _process = { - exit: sinon.stub() + exit: sinon.stub(), }; cleanShutdown(_process, node); - setImmediate(function() { + setImmediate(function () { node.stop.callCount.should.equal(1); log.error.callCount.should.equal(1); _process.exit.callCount.should.equal(1); @@ -174,83 +174,83 @@ describe('#start', function() { }); }); }); - describe('#registerExitHandlers', function() { + describe("#registerExitHandlers", function () { var log = { info: sinon.stub(), - error: sinon.stub() + error: sinon.stub(), }; - var registerExitHandlers = proxyquire('../../lib/scaffold/start', { - '../': { - log: log - } + var registerExitHandlers = proxyquire("../../lib/scaffold/start", { + "../": { + log: log, + }, }).registerExitHandlers; - it('log, stop and exit with an `uncaughtException`', function(done) { + it("log, stop and exit with an `uncaughtException`", function (done) { var proc = new EventEmitter(); proc.exit = sinon.stub(); var node = { - stop: sinon.stub().callsArg(0) + stop: sinon.stub().callsArg(0), }; registerExitHandlers(proc, node); - proc.emit('uncaughtException', new Error('test')); - setImmediate(function() { + proc.emit("uncaughtException", new Error("test")); + setImmediate(function () { node.stop.callCount.should.equal(1); proc.exit.callCount.should.equal(1); done(); }); }); - it('stop and exit on `SIGINT`', function(done) { + it("stop and exit on `SIGINT`", function (done) { var proc = new EventEmitter(); proc.exit = sinon.stub(); var node = { - stop: sinon.stub().callsArg(0) + stop: sinon.stub().callsArg(0), }; registerExitHandlers(proc, node); - proc.emit('SIGINT'); - setImmediate(function() { + proc.emit("SIGINT"); + setImmediate(function () { node.stop.callCount.should.equal(1); proc.exit.callCount.should.equal(1); done(); }); }); }); - describe('#registerExitHandlers', function() { + describe("#registerExitHandlers", function () { var stub; - var registerExitHandlers = require('../../lib/scaffold/start').registerExitHandlers; + var registerExitHandlers = require("../../lib/scaffold/start").registerExitHandlers; - before(function() { - stub = sinon.stub(process, 'on'); + before(function () { + stub = sinon.stub(process, "on"); }); - after(function() { + after(function () { stub.restore(); }); - it('should setup two listeners on process when registering exit handlers', function() { + it("should setup two listeners on process when registering exit handlers", function () { registerExitHandlers(process, {}); stub.callCount.should.equal(2); }); - describe('#exitHandler', function() { + describe("#exitHandler", function () { var sandbox; var cleanShutdown; var exitHandler; var logStub; - before(function() { + before(function () { sandbox = sinon.sandbox.create(); - var start = require('../../lib/scaffold/start'); - var log = require('../../lib').log; - logStub = sandbox.stub(log, 'error'); - cleanShutdown = sandbox.stub(start, 'cleanShutdown', function() {}); - exitHandler = require('../../lib/scaffold/start').exitHandler; + var start = require("../../lib/scaffold/start"); + var log = require("../../lib").log; + logStub = sandbox.stub(log, "error"); + cleanShutdown = sandbox.stub(start, "cleanShutdown", function () {}); + exitHandler = require("../../lib/scaffold/start").exitHandler; }); - after(function() { + after(function () { sandbox.restore(); }); - it('should replace the listener for SIGINT after the first SIGINT is handled', function() { - var options = { sigint: true }; + it("should replace the listener for SIGINT after the first SIGINT is handled", function () { + var options = { sigint: true }; var node = {}; exitHandler(options, process, node); cleanShutdown.callCount.should.equal(1); @@ -258,17 +258,16 @@ describe('#start', function() { cleanShutdown.callCount.should.equal(1); }); - it('should log all errors and stops the services nonetheless', function() { - var options = { sigint: true }; + it("should log all errors and stops the services nonetheless", function () { + var options = { sigint: true }; var stop = sinon.stub(); var node = { - stop: stop + stop: stop, }; - exitHandler(options, process, node, new Error('some error')); + exitHandler(options, process, node, new Error("some error")); logStub.callCount.should.equal(2); stop.callCount.should.equal(1); }); - }); }); }); diff --git a/test/services/dashd.unit.js b/test/services/dashd.unit.js index 22eb397dd..3723c1678 100644 --- a/test/services/dashd.unit.js +++ b/test/services/dashd.unit.js @@ -1,58 +1,59 @@ // jshint ignore: start -'use strict'; +"use strict"; -var path = require('path'); -var EventEmitter = require('events').EventEmitter; -var should = require('chai').should(); -var crypto = require('crypto'); -var dashcore = require('@dashevo/dashcore-lib'); +var path = require("path"); +var EventEmitter = require("events").EventEmitter; +var should = require("chai").should(); +var crypto = require("crypto"); +var dashcore = require("@dashevo/dashcore-lib"); var _ = dashcore.deps._; -var sinon = require('sinon'); -var proxyquire = require('proxyquire'); -var fs = require('fs'); -var sinon = require('sinon'); +var sinon = require("sinon"); +var proxyquire = require("proxyquire"); +var fs = require("fs"); +var sinon = require("sinon"); -var index = require('../../lib'); +var index = require("../../lib"); var log = index.log; var errors = index.errors; var Transaction = dashcore.Transaction; -var readFileSync = sinon.stub().returns(fs.readFileSync(path.resolve(__dirname, '../data/dash.conf'))); -var DashService = proxyquire('../../lib/services/dashd', { +var readFileSync = sinon.stub().returns(fs.readFileSync(path.resolve(__dirname, "../data/dash.conf"))); +var DashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync - } + readFileSync: readFileSync, + }, }); -var defaultDashConf = fs.readFileSync(path.resolve(__dirname, '../data/default.dash.conf'), 'utf8'); +var defaultDashConf = fs.readFileSync(path.resolve(__dirname, "../data/default.dash.conf"), "utf8"); -describe('Dash Service', function() { - var txhex = '01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000'; +describe("Dash Service", function () { + var txhex = + "01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000"; var baseConfig = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath', - } + datadir: "testdir", + exec: "testpath", + }, }; - var RPC_IN_WARMUP_ERROR = new Error('Verifying blocks...'); + var RPC_IN_WARMUP_ERROR = new Error("Verifying blocks..."); Object.assign(RPC_IN_WARMUP_ERROR, { - code: DashService.E_RPC_IN_WARMUP - }) + code: DashService.E_RPC_IN_WARMUP, + }); - describe('@constructor', function() { - it('will create an instance', function() { + describe("@constructor", function () { + it("will create an instance", function () { var dashd = new DashService(baseConfig); should.exist(dashd); }); - it('will create an instance without `new`', function() { + it("will create an instance without `new`", function () { var dashd = DashService(baseConfig); should.exist(dashd); }); - it('will init caches', function() { + it("will init caches", function () { var dashd = new DashService(baseConfig); should.exist(dashd.utxosCache); should.exist(dashd.txidsCache); @@ -71,42 +72,42 @@ describe('Dash Service', function() { should.exist(dashd.lastTip); should.exist(dashd.lastTipTimeout); }); - it('will init clients', function() { + it("will init clients", function () { var dashd = new DashService(baseConfig); dashd.nodes.should.deep.equal([]); dashd.nodesIndex.should.equal(0); - dashd.nodes.push({client: sinon.stub()}); + dashd.nodes.push({ client: sinon.stub() }); should.exist(dashd.client); }); - it('will set subscriptions', function() { + it("will set subscriptions", function () { var dashd = new DashService(baseConfig); dashd.subscriptions.should.deep.equal({ address: {}, rawtransaction: [], hashblock: [], - transactionlock: [] + transactionlock: [], }); }); }); - describe('#_initDefaults', function() { - it('will set transaction concurrency', function() { + describe("#_initDefaults", function () { + it("will set transaction concurrency", function () { var dashd = new DashService(baseConfig); - dashd._initDefaults({transactionConcurrency: 10}); + dashd._initDefaults({ transactionConcurrency: 10 }); dashd.transactionConcurrency.should.equal(10); dashd._initDefaults({}); dashd.transactionConcurrency.should.equal(5); }); }); - describe('@dependencies', function() { - it('will have no dependencies', function() { + describe("@dependencies", function () { + it("will have no dependencies", function () { DashService.dependencies.should.deep.equal([]); }); }); - describe('#getAPIMethods', function() { - it('will return spec', function() { + describe("#getAPIMethods", function () { + it("will return spec", function () { var dashd = new DashService(baseConfig); var methods = dashd.getAPIMethods(); should.exist(methods); @@ -114,269 +115,269 @@ describe('Dash Service', function() { }); }); - describe('#getPublishEvents', function() { - it('will return spec', function() { + describe("#getPublishEvents", function () { + it("will return spec", function () { var dashd = new DashService(baseConfig); var events = dashd.getPublishEvents(); should.exist(events); events.length.should.equal(4); - events[0].name.should.equal('dashd/rawtransaction'); + events[0].name.should.equal("dashd/rawtransaction"); events[0].scope.should.equal(dashd); - events[0].subscribe.should.be.a('function'); - events[0].unsubscribe.should.be.a('function'); - events[1].name.should.equal('dashd/transactionlock'); + events[0].subscribe.should.be.a("function"); + events[0].unsubscribe.should.be.a("function"); + events[1].name.should.equal("dashd/transactionlock"); events[1].scope.should.equal(dashd); - events[1].subscribe.should.be.a('function'); - events[1].unsubscribe.should.be.a('function'); - events[2].name.should.equal('dashd/hashblock'); + events[1].subscribe.should.be.a("function"); + events[1].unsubscribe.should.be.a("function"); + events[2].name.should.equal("dashd/hashblock"); events[2].scope.should.equal(dashd); - events[2].subscribe.should.be.a('function'); - events[2].unsubscribe.should.be.a('function'); - events[3].name.should.equal('dashd/addresstxid'); + events[2].subscribe.should.be.a("function"); + events[2].unsubscribe.should.be.a("function"); + events[3].name.should.equal("dashd/addresstxid"); events[3].scope.should.equal(dashd); - events[3].subscribe.should.be.a('function'); - events[3].unsubscribe.should.be.a('function'); + events[3].subscribe.should.be.a("function"); + events[3].unsubscribe.should.be.a("function"); }); - it('will call subscribe/unsubscribe with correct args', function() { + it("will call subscribe/unsubscribe with correct args", function () { var dashd = new DashService(baseConfig); dashd.subscribe = sinon.stub(); dashd.unsubscribe = sinon.stub(); var events = dashd.getPublishEvents(); - events[0].subscribe('test'); - dashd.subscribe.args[0][0].should.equal('rawtransaction'); - dashd.subscribe.args[0][1].should.equal('test'); + events[0].subscribe("test"); + dashd.subscribe.args[0][0].should.equal("rawtransaction"); + dashd.subscribe.args[0][1].should.equal("test"); - events[0].unsubscribe('test'); - dashd.unsubscribe.args[0][0].should.equal('rawtransaction'); - dashd.unsubscribe.args[0][1].should.equal('test'); + events[0].unsubscribe("test"); + dashd.unsubscribe.args[0][0].should.equal("rawtransaction"); + dashd.unsubscribe.args[0][1].should.equal("test"); - events[1].subscribe('test'); - dashd.subscribe.args[1][0].should.equal('transactionlock'); - dashd.subscribe.args[1][1].should.equal('test'); + events[1].subscribe("test"); + dashd.subscribe.args[1][0].should.equal("transactionlock"); + dashd.subscribe.args[1][1].should.equal("test"); - events[1].unsubscribe('test'); - dashd.unsubscribe.args[1][0].should.equal('transactionlock'); - dashd.unsubscribe.args[1][1].should.equal('test'); + events[1].unsubscribe("test"); + dashd.unsubscribe.args[1][0].should.equal("transactionlock"); + dashd.unsubscribe.args[1][1].should.equal("test"); - events[2].subscribe('test'); - dashd.subscribe.args[2][0].should.equal('hashblock'); - dashd.subscribe.args[2][1].should.equal('test'); + events[2].subscribe("test"); + dashd.subscribe.args[2][0].should.equal("hashblock"); + dashd.subscribe.args[2][1].should.equal("test"); - events[2].unsubscribe('test'); - dashd.unsubscribe.args[2][0].should.equal('hashblock'); - dashd.unsubscribe.args[2][1].should.equal('test'); + events[2].unsubscribe("test"); + dashd.unsubscribe.args[2][0].should.equal("hashblock"); + dashd.unsubscribe.args[2][1].should.equal("test"); }); }); - describe('#subscribe', function() { + describe("#subscribe", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will push to subscriptions', function() { + it("will push to subscriptions", function () { var dashd = new DashService(baseConfig); var emitter = {}; - dashd.subscribe('hashblock', emitter); + dashd.subscribe("hashblock", emitter); dashd.subscriptions.hashblock[0].should.equal(emitter); var emitter2 = {}; - dashd.subscribe('rawtransaction', emitter2); + dashd.subscribe("rawtransaction", emitter2); dashd.subscriptions.rawtransaction[0].should.equal(emitter2); }); }); - describe('#unsubscribe', function() { + describe("#unsubscribe", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will remove item from subscriptions', function() { + it("will remove item from subscriptions", function () { var dashd = new DashService(baseConfig); var emitter1 = {}; var emitter2 = {}; var emitter3 = {}; var emitter4 = {}; var emitter5 = {}; - dashd.subscribe('hashblock', emitter1); - dashd.subscribe('hashblock', emitter2); - dashd.subscribe('hashblock', emitter3); - dashd.subscribe('hashblock', emitter4); - dashd.subscribe('hashblock', emitter5); + dashd.subscribe("hashblock", emitter1); + dashd.subscribe("hashblock", emitter2); + dashd.subscribe("hashblock", emitter3); + dashd.subscribe("hashblock", emitter4); + dashd.subscribe("hashblock", emitter5); dashd.subscriptions.hashblock.length.should.equal(5); - dashd.unsubscribe('hashblock', emitter3); + dashd.unsubscribe("hashblock", emitter3); dashd.subscriptions.hashblock.length.should.equal(4); dashd.subscriptions.hashblock[0].should.equal(emitter1); dashd.subscriptions.hashblock[1].should.equal(emitter2); dashd.subscriptions.hashblock[2].should.equal(emitter4); dashd.subscriptions.hashblock[3].should.equal(emitter5); }); - it('will not remove item an already unsubscribed item', function() { + it("will not remove item an already unsubscribed item", function () { var dashd = new DashService(baseConfig); var emitter1 = {}; var emitter3 = {}; - dashd.subscriptions.hashblock= [emitter1]; - dashd.unsubscribe('hashblock', emitter3); + dashd.subscriptions.hashblock = [emitter1]; + dashd.unsubscribe("hashblock", emitter3); dashd.subscriptions.hashblock.length.should.equal(1); dashd.subscriptions.hashblock[0].should.equal(emitter1); }); }); - describe('#subscribeAddress', function() { + describe("#subscribeAddress", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will not an invalid address', function() { + it("will not an invalid address", function () { var dashd = new DashService(baseConfig); var emitter = new EventEmitter(); - dashd.subscribeAddress(emitter, ['invalidaddress']); - should.not.exist(dashd.subscriptions.address['invalidaddress']); + dashd.subscribeAddress(emitter, ["invalidaddress"]); + should.not.exist(dashd.subscriptions.address["invalidaddress"]); }); - it('will add a valid address', function() { + it("will add a valid address", function () { var dashd = new DashService(baseConfig); var emitter = new EventEmitter(); - dashd.subscribeAddress(emitter, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - should.exist(dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); + dashd.subscribeAddress(emitter, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + should.exist(dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); }); - it('will handle multiple address subscribers', function() { + it("will handle multiple address subscribers", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); var emitter2 = new EventEmitter(); - dashd.subscribeAddress(emitter1, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.subscribeAddress(emitter2, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - should.exist(dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(2); + dashd.subscribeAddress(emitter1, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.subscribeAddress(emitter2, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + should.exist(dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(2); }); - it('will not add the same emitter twice', function() { + it("will not add the same emitter twice", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); - dashd.subscribeAddress(emitter1, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.subscribeAddress(emitter1, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - should.exist(dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(1); + dashd.subscribeAddress(emitter1, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.subscribeAddress(emitter1, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + should.exist(dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(1); }); }); - describe('#unsubscribeAddress', function() { + describe("#unsubscribeAddress", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('it will remove a subscription', function() { + it("it will remove a subscription", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); var emitter2 = new EventEmitter(); - dashd.subscribeAddress(emitter1, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.subscribeAddress(emitter2, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - should.exist(dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(2); - dashd.unsubscribeAddress(emitter1, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(1); + dashd.subscribeAddress(emitter1, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.subscribeAddress(emitter2, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + should.exist(dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(2); + dashd.unsubscribeAddress(emitter1, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(1); }); - it('will unsubscribe subscriptions for an emitter', function() { + it("will unsubscribe subscriptions for an emitter", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); var emitter2 = new EventEmitter(); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'] = [emitter1, emitter2]; + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"] = [emitter1, emitter2]; dashd.unsubscribeAddress(emitter1); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(1); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(1); }); - it('will NOT unsubscribe subscription with missing address', function() { + it("will NOT unsubscribe subscription with missing address", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); var emitter2 = new EventEmitter(); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'] = [emitter1, emitter2]; - dashd.unsubscribeAddress(emitter1, ['XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs']); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(2); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"] = [emitter1, emitter2]; + dashd.unsubscribeAddress(emitter1, ["XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"]); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(2); }); - it('will NOT unsubscribe subscription with missing emitter', function() { + it("will NOT unsubscribe subscription with missing emitter", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); var emitter2 = new EventEmitter(); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'] = [emitter2]; - dashd.unsubscribeAddress(emitter1, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(1); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'][0].should.equal(emitter2); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"] = [emitter2]; + dashd.unsubscribeAddress(emitter1, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(1); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"][0].should.equal(emitter2); }); - it('will remove empty addresses', function() { + it("will remove empty addresses", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); var emitter2 = new EventEmitter(); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'] = [emitter1, emitter2]; - dashd.unsubscribeAddress(emitter1, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - dashd.unsubscribeAddress(emitter2, ['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); - should.not.exist(dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi']); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"] = [emitter1, emitter2]; + dashd.unsubscribeAddress(emitter1, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + dashd.unsubscribeAddress(emitter2, ["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); + should.not.exist(dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"]); }); - it('will unsubscribe emitter for all addresses', function() { + it("will unsubscribe emitter for all addresses", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); var emitter2 = new EventEmitter(); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'] = [emitter1, emitter2]; - dashd.subscriptions.address['XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'] = [emitter1, emitter2]; - sinon.spy(dashd, 'unsubscribeAddressAll'); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"] = [emitter1, emitter2]; + dashd.subscriptions.address["XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"] = [emitter1, emitter2]; + sinon.spy(dashd, "unsubscribeAddressAll"); dashd.unsubscribeAddress(emitter1); dashd.unsubscribeAddressAll.callCount.should.equal(1); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(1); - dashd.subscriptions.address['XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'].length.should.equal(1); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(1); + dashd.subscriptions.address["XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"].length.should.equal(1); }); }); - describe('#unsubscribeAddressAll', function() { + describe("#unsubscribeAddressAll", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will unsubscribe emitter for all addresses', function() { + it("will unsubscribe emitter for all addresses", function () { var dashd = new DashService(baseConfig); var emitter1 = new EventEmitter(); var emitter2 = new EventEmitter(); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'] = [emitter1, emitter2]; - dashd.subscriptions.address['XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'] = [emitter1, emitter2]; - dashd.subscriptions.address['mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW'] = [emitter2]; - dashd.subscriptions.address['7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz'] = [emitter1]; + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"] = [emitter1, emitter2]; + dashd.subscriptions.address["XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"] = [emitter1, emitter2]; + dashd.subscriptions.address["mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"] = [emitter2]; + dashd.subscriptions.address["7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz"] = [emitter1]; dashd.unsubscribeAddress(emitter1); - dashd.subscriptions.address['8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'].length.should.equal(1); - dashd.subscriptions.address['XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'].length.should.equal(1); - dashd.subscriptions.address['mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW'].length.should.equal(1); - should.not.exist(dashd.subscriptions.address['7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz']); + dashd.subscriptions.address["8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"].length.should.equal(1); + dashd.subscriptions.address["XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"].length.should.equal(1); + dashd.subscriptions.address["mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"].length.should.equal(1); + should.not.exist(dashd.subscriptions.address["7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz"]); }); }); - describe('#_getDefaultConfig', function() { - it('will generate config file from defaults', function() { + describe("#_getDefaultConfig", function () { + it("will generate config file from defaults", function () { var dashd = new DashService(baseConfig); var config = dashd._getDefaultConfig(); config.should.equal(defaultDashConf); }); }); - describe('#_loadSpawnConfiguration', function() { + describe("#_loadSpawnConfiguration", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will parse a dash.conf file', function() { - var TestDash = proxyquire('../../lib/services/dashd', { + it("will parse a dash.conf file", function () { + var TestDash = proxyquire("../../lib/services/dashd", { fs: { readFileSync: readFileSync, existsSync: sinon.stub().returns(true), @@ -385,7 +386,7 @@ describe('Dash Service', function() { }, }); var dashd = new TestDash(baseConfig); - dashd.options.spawn.datadir = '/tmp/.dash'; + dashd.options.spawn.datadir = "/tmp/.dash"; var node = {}; dashd._loadSpawnConfiguration(node); should.exist(dashd.spawn.config); @@ -396,22 +397,22 @@ describe('Dash Service', function() { maxuploadtarget: 1024, port: 20000, rpcport: 50001, - rpcallowip: '127.0.0.1', - rpcuser: 'dash', - rpcpassword: 'local321', + rpcallowip: "127.0.0.1", + rpcuser: "dash", + rpcpassword: "local321", server: 1, spentindex: 1, timestampindex: 1, txindex: 1, upnp: 0, - whitelist: '127.0.0.1', - zmqpubhashblock: 'tcp://127.0.0.1:28332', - zmqpubrawtx: 'tcp://127.0.0.1:28332', - zmqpubrawtxlock: 'tcp://127.0.0.1:28332' + whitelist: "127.0.0.1", + zmqpubhashblock: "tcp://127.0.0.1:28332", + zmqpubrawtx: "tcp://127.0.0.1:28332", + zmqpubrawtxlock: "tcp://127.0.0.1:28332", }); }); - it('will expand relative datadir to absolute path', function() { - var TestDash = proxyquire('../../lib/services/dashd', { + it("will expand relative datadir to absolute path", function () { + var TestDash = proxyquire("../../lib/services/dashd", { fs: { readFileSync: readFileSync, existsSync: sinon.stub().returns(true), @@ -422,37 +423,37 @@ describe('Dash Service', function() { var config = { node: { network: dashcore.Networks.testnet, - configPath: '/tmp/.dashcore/dashcore-node.json' + configPath: "/tmp/.dashcore/dashcore-node.json", }, spawn: { - datadir: './data', - exec: 'testpath' - } + datadir: "./data", + exec: "testpath", + }, }; var dashd = new TestDash(config); - dashd.options.spawn.datadir = './data'; + dashd.options.spawn.datadir = "./data"; var node = {}; dashd._loadSpawnConfiguration(node); - dashd.options.spawn.datadir.should.equal('/tmp/.dashcore/data'); + dashd.options.spawn.datadir.should.equal("/tmp/.dashcore/data"); }); - it('should throw an exception if txindex isn\'t enabled in the configuration', function() { - var TestDash = proxyquire('../../lib/services/dashd', { + it("should throw an exception if txindex isn't enabled in the configuration", function () { + var TestDash = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: sinon.stub().returns(fs.readFileSync(__dirname + '/../data/baddash.conf')), + readFileSync: sinon.stub().returns(fs.readFileSync(__dirname + "/../data/baddash.conf")), existsSync: sinon.stub().returns(true), mkdirSync: sinon.stub(), }, }); var dashd = new TestDash(baseConfig); - (function() { - dashd._loadSpawnConfiguration({datadir: './test'}); + (function () { + dashd._loadSpawnConfiguration({ datadir: "./test" }); }).should.throw(dashcore.errors.InvalidState); }); - it('should NOT set https options if node https options are set', function() { - var writeFileSync = function(path, config) { + it("should NOT set https options if node https options are set", function () { + var writeFileSync = function (path, config) { config.should.equal(defaultDashConf); }; - var TestDash = proxyquire('../../lib/services/dashd', { + var TestDash = proxyquire("../../lib/services/dashd", { fs: { writeFileSync: writeFileSync, readFileSync: readFileSync, @@ -463,35 +464,35 @@ describe('Dash Service', function() { var config = { node: { network: { - name: 'regtest' + name: "regtest", }, https: true, httpsOptions: { - key: 'key.pem', - cert: 'cert.pem' - } + key: "key.pem", + cert: "cert.pem", + }, }, spawn: { - datadir: 'testdir', - exec: 'testexec' - } + datadir: "testdir", + exec: "testexec", + }, }; var dashd = new TestDash(config); - dashd.options.spawn.datadir = '/tmp/.dash'; + dashd.options.spawn.datadir = "/tmp/.dash"; var node = {}; dashd._loadSpawnConfiguration(node); }); }); - describe('#_checkConfigIndexes', function() { + describe("#_checkConfigIndexes", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'warn'); + beforeEach(function () { + sandbox.stub(log, "warn"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('should warn the user if reindex is set to 1 in the dash.conf file', function() { + it("should warn the user if reindex is set to 1 in the dash.conf file", function () { var dashd = new DashService(baseConfig); var config = { txindex: 1, @@ -501,34 +502,34 @@ describe('Dash Service', function() { zmqpubrawtx: 1, zmqpubhashblock: 1, zmqpubrawtxlock: 1, - reindex: 1 + reindex: 1, }; var node = {}; dashd._checkConfigIndexes(config, node); log.warn.callCount.should.equal(1); node._reindex.should.equal(true); }); - it('should warn if zmq port and hosts do not match', function() { + it("should warn if zmq port and hosts do not match", function () { var dashd = new DashService(baseConfig); var config = { txindex: 1, addressindex: 1, spentindex: 1, server: 1, - zmqpubrawtx: 'tcp://127.0.0.1:28332', - zmqpubhashblock: 'tcp://127.0.0.1:28331', - zmqpubrawtxlock: 'tcp://127.0.0.1:28332', - reindex: 1 + zmqpubrawtx: "tcp://127.0.0.1:28332", + zmqpubhashblock: "tcp://127.0.0.1:28331", + zmqpubrawtxlock: "tcp://127.0.0.1:28332", + reindex: 1, }; var node = {}; - (function() { + (function () { dashd._checkConfigIndexes(config, node); }).should.throw('"zmqpubrawtx" and "zmqpubhashblock"'); }); }); - describe('#_resetCaches', function() { - it('will reset LRU caches', function() { + describe("#_resetCaches", function () { + it("will reset LRU caches", function () { var dashd = new DashService(baseConfig); var keys = []; for (var i = 0; i < 10; i++) { @@ -548,335 +549,344 @@ describe('Dash Service', function() { }); }); - describe('#_tryAllClients', function() { - it('will retry for each node client', function(done) { + describe("#_tryAllClients", function () { + it("will retry for each node client", function (done) { var dashd = new DashService(baseConfig); dashd.tryAllInterval = 1; dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArgWith(0, new Error('test')) - } + getInfo: sinon.stub().callsArgWith(0, new Error("test")), + }, }); dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArgWith(0, new Error('test')) - } + getInfo: sinon.stub().callsArgWith(0, new Error("test")), + }, }); dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArg(0) - } + getInfo: sinon.stub().callsArg(0), + }, }); - dashd._tryAllClients(function(client, next) { - client.getInfo(next); - }, function(err) { - if (err) { - return done(err); + dashd._tryAllClients( + function (client, next) { + client.getInfo(next); + }, + function (err) { + if (err) { + return done(err); + } + dashd.nodes[0].client.getInfo.callCount.should.equal(1); + dashd.nodes[1].client.getInfo.callCount.should.equal(1); + dashd.nodes[2].client.getInfo.callCount.should.equal(1); + done(); } - dashd.nodes[0].client.getInfo.callCount.should.equal(1); - dashd.nodes[1].client.getInfo.callCount.should.equal(1); - dashd.nodes[2].client.getInfo.callCount.should.equal(1); - done(); - }); + ); }); - it('will start using the current node index (round-robin)', function(done) { + it("will start using the current node index (round-robin)", function (done) { var dashd = new DashService(baseConfig); dashd.tryAllInterval = 1; dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArgWith(0, new Error('2')) - } + getInfo: sinon.stub().callsArgWith(0, new Error("2")), + }, }); dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArgWith(0, new Error('3')) - } + getInfo: sinon.stub().callsArgWith(0, new Error("3")), + }, }); dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArgWith(0, new Error('1')) - } + getInfo: sinon.stub().callsArgWith(0, new Error("1")), + }, }); dashd.nodesIndex = 2; - dashd._tryAllClients(function(client, next) { - client.getInfo(next); - }, function(err) { - err.should.be.instanceOf(Error); - err.message.should.equal('3'); - dashd.nodes[0].client.getInfo.callCount.should.equal(1); - dashd.nodes[1].client.getInfo.callCount.should.equal(1); - dashd.nodes[2].client.getInfo.callCount.should.equal(1); - dashd.nodesIndex.should.equal(0); - done(); - }); + dashd._tryAllClients( + function (client, next) { + client.getInfo(next); + }, + function (err) { + err.should.be.instanceOf(Error); + err.message.should.equal("3"); + dashd.nodes[0].client.getInfo.callCount.should.equal(1); + dashd.nodes[1].client.getInfo.callCount.should.equal(1); + dashd.nodes[2].client.getInfo.callCount.should.equal(1); + dashd.nodesIndex.should.equal(0); + done(); + } + ); }); - it('will get error if all clients fail', function(done) { + it("will get error if all clients fail", function (done) { var dashd = new DashService(baseConfig); dashd.tryAllInterval = 1; dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArgWith(0, new Error('test')) - } + getInfo: sinon.stub().callsArgWith(0, new Error("test")), + }, }); dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArgWith(0, new Error('test')) - } + getInfo: sinon.stub().callsArgWith(0, new Error("test")), + }, }); dashd.nodes.push({ client: { - getInfo: sinon.stub().callsArgWith(0, new Error('test')) - } - }); - dashd._tryAllClients(function(client, next) { - client.getInfo(next); - }, function(err) { - should.exist(err); - err.should.be.instanceOf(Error); - err.message.should.equal('test'); - done(); + getInfo: sinon.stub().callsArgWith(0, new Error("test")), + }, }); + dashd._tryAllClients( + function (client, next) { + client.getInfo(next); + }, + function (err) { + should.exist(err); + err.should.be.instanceOf(Error); + err.message.should.equal("test"); + done(); + } + ); }); }); - describe('#_wrapRPCError', function() { - it('will convert dashd-rpc object into JavaScript error', function() { + describe("#_wrapRPCError", function () { + it("will convert dashd-rpc object into JavaScript error", function () { var dashd = new DashService(baseConfig); - var error = dashd._wrapRPCError({message: 'Test error', code: -1}); + var error = dashd._wrapRPCError({ message: "Test error", code: -1 }); error.should.be.an.instanceof(errors.RPCError); error.code.should.equal(-1); - error.message.should.equal('Test error'); + error.message.should.equal("Test error"); }); }); - describe('#_initChain', function() { + describe("#_initChain", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will set height and genesis buffer', function(done) { + it("will set height and genesis buffer", function (done) { var dashd = new DashService(baseConfig); var genesisBuffer = new Buffer([]); dashd.getRawBlock = sinon.stub().callsArgWith(1, null, genesisBuffer); dashd.nodes.push({ client: { - getBestBlockHash: function(callback) { + getBestBlockHash: function (callback) { callback(null, { - result: 'bestblockhash' + result: "bestblockhash", }); }, - getBlock: function(hash, callback) { - if (hash === 'bestblockhash') { + getBlock: function (hash, callback) { + if (hash === "bestblockhash") { callback(null, { result: { - height: 5000 - } + height: 5000, + }, }); } }, - getBlockHash: function(num, callback) { + getBlockHash: function (num, callback) { callback(null, { - result: 'genesishash' + result: "genesishash", }); - } - } + }, + }, }); - dashd._initChain(function() { + dashd._initChain(function () { log.info.callCount.should.equal(1); dashd.getRawBlock.callCount.should.equal(1); - dashd.getRawBlock.args[0][0].should.equal('genesishash'); + dashd.getRawBlock.args[0][0].should.equal("genesishash"); dashd.height.should.equal(5000); dashd.genesisBuffer.should.equal(genesisBuffer); done(); }); }); - it('it will handle error from getBestBlockHash', function(done) { + it("it will handle error from getBestBlockHash", function (done) { var dashd = new DashService(baseConfig); - var getBestBlockHash = sinon.stub().callsArgWith(0, {code: -1, message: 'error'}); + var getBestBlockHash = sinon.stub().callsArgWith(0, { code: -1, message: "error" }); dashd.nodes.push({ client: { - getBestBlockHash: getBestBlockHash - } + getBestBlockHash: getBestBlockHash, + }, }); - dashd._initChain(function(err) { + dashd._initChain(function (err) { err.should.be.instanceOf(Error); done(); }); }); - it('it will handle error from getBlock', function(done) { + it("it will handle error from getBlock", function (done) { var dashd = new DashService(baseConfig); var getBestBlockHash = sinon.stub().callsArgWith(0, null, {}); - var getBlock = sinon.stub().callsArgWith(1, {code: -1, message: 'error'}); + var getBlock = sinon.stub().callsArgWith(1, { code: -1, message: "error" }); dashd.nodes.push({ client: { getBestBlockHash: getBestBlockHash, - getBlock: getBlock - } + getBlock: getBlock, + }, }); - dashd._initChain(function(err) { + dashd._initChain(function (err) { err.should.be.instanceOf(Error); done(); }); }); - it('it will handle error from getBlockHash', function(done) { + it("it will handle error from getBlockHash", function (done) { var dashd = new DashService(baseConfig); var getBestBlockHash = sinon.stub().callsArgWith(0, null, {}); var getBlock = sinon.stub().callsArgWith(1, null, { result: { - height: 10 - } + height: 10, + }, }); - var getBlockHash = sinon.stub().callsArgWith(1, {code: -1, message: 'error'}); + var getBlockHash = sinon.stub().callsArgWith(1, { code: -1, message: "error" }); dashd.nodes.push({ client: { getBestBlockHash: getBestBlockHash, getBlock: getBlock, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd._initChain(function(err) { + dashd._initChain(function (err) { err.should.be.instanceOf(Error); done(); }); }); - it('it will handle error from getRawBlock', function(done) { + it("it will handle error from getRawBlock", function (done) { var dashd = new DashService(baseConfig); var getBestBlockHash = sinon.stub().callsArgWith(0, null, {}); var getBlock = sinon.stub().callsArgWith(1, null, { result: { - height: 10 - } + height: 10, + }, }); var getBlockHash = sinon.stub().callsArgWith(1, null, {}); dashd.nodes.push({ client: { getBestBlockHash: getBestBlockHash, getBlock: getBlock, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getRawBlock = sinon.stub().callsArgWith(1, new Error('test')); - dashd._initChain(function(err) { + dashd.getRawBlock = sinon.stub().callsArgWith(1, new Error("test")); + dashd._initChain(function (err) { err.should.be.instanceOf(Error); done(); }); }); }); - describe('#_getDefaultConf', function() { - afterEach(function() { + describe("#_getDefaultConf", function () { + afterEach(function () { dashcore.Networks.disableRegtest(); baseConfig.node.network = dashcore.Networks.testnet; }); - it('will get default rpc port for livenet', function() { + it("will get default rpc port for livenet", function () { var config = { node: { - network: dashcore.Networks.livenet + network: dashcore.Networks.livenet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); dashd._getDefaultConf().rpcport.should.equal(9998); }); - it('will get default rpc port for testnet', function() { + it("will get default rpc port for testnet", function () { var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); dashd._getDefaultConf().rpcport.should.equal(19998); }); - it('will get default rpc port for regtest', function() { + it("will get default rpc port for regtest", function () { dashcore.Networks.enableRegtest(); var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); dashd._getDefaultConf().rpcport.should.equal(19998); }); }); - describe('#_getNetworkConfigPath', function() { - afterEach(function() { + describe("#_getNetworkConfigPath", function () { + afterEach(function () { dashcore.Networks.disableRegtest(); baseConfig.node.network = dashcore.Networks.testnet; }); - it('will get default config path for livenet', function() { + it("will get default config path for livenet", function () { var config = { node: { - network: dashcore.Networks.livenet + network: dashcore.Networks.livenet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); should.equal(dashd._getNetworkConfigPath(), undefined); }); - it('will get default rpc port for testnet', function() { + it("will get default rpc port for testnet", function () { var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); - dashd._getNetworkConfigPath().should.equal('testnet3/dash.conf'); + dashd._getNetworkConfigPath().should.equal("testnet3/dash.conf"); }); - it('will get default rpc port for regtest', function() { + it("will get default rpc port for regtest", function () { dashcore.Networks.enableRegtest(); var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); - dashd._getNetworkConfigPath().should.equal('regtest/dash.conf'); + dashd._getNetworkConfigPath().should.equal("regtest/dash.conf"); }); }); - describe('#_getNetworkOption', function() { - afterEach(function() { + describe("#_getNetworkOption", function () { + afterEach(function () { dashcore.Networks.disableRegtest(); baseConfig.node.network = dashcore.Networks.testnet; }); - it('return --testnet for testnet', function() { + it("return --testnet for testnet", function () { var dashd = new DashService(baseConfig); dashd.node.network = dashcore.Networks.testnet; - dashd._getNetworkOption().should.equal('--testnet'); + dashd._getNetworkOption().should.equal("--testnet"); }); - it('return --regtest for testnet', function() { + it("return --regtest for testnet", function () { var dashd = new DashService(baseConfig); dashd.node.network = dashcore.Networks.testnet; dashcore.Networks.enableRegtest(); - dashd._getNetworkOption().should.equal('--regtest'); + dashd._getNetworkOption().should.equal("--regtest"); }); - it('return undefined for livenet', function() { + it("return undefined for livenet", function () { var dashd = new DashService(baseConfig); dashd.node.network = dashcore.Networks.livenet; dashcore.Networks.enableRegtest(); @@ -884,60 +894,60 @@ describe('Dash Service', function() { }); }); - describe('#_zmqBlockHandler', function() { - it('will emit block', function(done) { + describe("#_zmqBlockHandler", function () { + it("will emit block", function (done) { var dashd = new DashService(baseConfig); var node = {}; - var message = new Buffer('00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa', 'hex'); + var message = new Buffer("00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa", "hex"); dashd._rapidProtectedUpdateTip = sinon.stub(); - dashd.on('block', function(block) { + dashd.on("block", function (block) { block.should.equal(message); done(); }); dashd._zmqBlockHandler(node, message); }); - it('will not emit same block twice', function(done) { + it("will not emit same block twice", function (done) { var dashd = new DashService(baseConfig); var node = {}; - var message = new Buffer('00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa', 'hex'); + var message = new Buffer("00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa", "hex"); dashd._rapidProtectedUpdateTip = sinon.stub(); - dashd.on('block', function(block) { + dashd.on("block", function (block) { block.should.equal(message); done(); }); dashd._zmqBlockHandler(node, message); dashd._zmqBlockHandler(node, message); }); - it('will call function to update tip', function() { + it("will call function to update tip", function () { var dashd = new DashService(baseConfig); var node = {}; - var message = new Buffer('00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa', 'hex'); + var message = new Buffer("00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa", "hex"); dashd._rapidProtectedUpdateTip = sinon.stub(); dashd._zmqBlockHandler(node, message); dashd._rapidProtectedUpdateTip.callCount.should.equal(1); dashd._rapidProtectedUpdateTip.args[0][0].should.equal(node); dashd._rapidProtectedUpdateTip.args[0][1].should.equal(message); }); - it('will emit to subscribers', function(done) { + it("will emit to subscribers", function (done) { var dashd = new DashService(baseConfig); var node = {}; - var message = new Buffer('00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa', 'hex'); + var message = new Buffer("00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa", "hex"); dashd._rapidProtectedUpdateTip = sinon.stub(); var emitter = new EventEmitter(); dashd.subscriptions.hashblock.push(emitter); - emitter.on('dashd/hashblock', function(blockHash) { - blockHash.should.equal(message.toString('hex')); + emitter.on("dashd/hashblock", function (blockHash) { + blockHash.should.equal(message.toString("hex")); done(); }); dashd._zmqBlockHandler(node, message); }); }); - describe('#_rapidProtectedUpdateTip', function() { - it('will limit tip updates with rapid calls', function(done) { + describe("#_rapidProtectedUpdateTip", function () { + it("will limit tip updates with rapid calls", function (done) { var dashd = new DashService(baseConfig); var callCount = 0; - dashd._updateTip = function() { + dashd._updateTip = function () { callCount++; callCount.should.be.within(1, 2); if (callCount > 1) { @@ -945,7 +955,7 @@ describe('Dash Service', function() { } }; var node = {}; - var message = new Buffer('00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa', 'hex'); + var message = new Buffer("00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa", "hex"); var count = 0; function repeat() { dashd._rapidProtectedUpdateTip(node, message); @@ -958,80 +968,80 @@ describe('Dash Service', function() { }); }); - describe('#_updateTip', function() { + describe("#_updateTip", function () { var sandbox = sinon.sandbox.create(); - var message = new Buffer('00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa', 'hex'); - beforeEach(function() { - sandbox.stub(log, 'error'); - sandbox.stub(log, 'info'); + var message = new Buffer("00000000002e08fc7ae9a9aa5380e95e2adcdc5752a4a66a7d3a22466bd4e6aa", "hex"); + beforeEach(function () { + sandbox.stub(log, "error"); + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('log and emit rpc error from get block', function(done) { + it("log and emit rpc error from get block", function (done) { var dashd = new DashService(baseConfig); dashd.syncPercentage = sinon.stub(); - dashd.on('error', function(err) { + dashd.on("error", function (err) { err.code.should.equal(-1); - err.message.should.equal('Test error'); + err.message.should.equal("Test error"); log.error.callCount.should.equal(1); done(); }); var node = { client: { - getBlock: sinon.stub().callsArgWith(1, {message: 'Test error', code: -1}) - } + getBlock: sinon.stub().callsArgWith(1, { message: "Test error", code: -1 }), + }, }; dashd._updateTip(node, message); }); - it('emit synced if percentage is 100', function(done) { + it("emit synced if percentage is 100", function (done) { var dashd = new DashService(baseConfig); dashd.syncPercentage = sinon.stub().callsArgWith(0, null, 100); - dashd.on('synced', function() { + dashd.on("synced", function () { done(); }); var node = { client: { - getBlock: sinon.stub() - } + getBlock: sinon.stub(), + }, }; dashd._updateTip(node, message); }); - it('NOT emit synced if percentage is less than 100', function(done) { + it("NOT emit synced if percentage is less than 100", function (done) { var dashd = new DashService(baseConfig); dashd.syncPercentage = sinon.stub().callsArgWith(0, null, 99); - dashd.on('synced', function() { - throw new Error('Synced called'); + dashd.on("synced", function () { + throw new Error("Synced called"); }); var node = { client: { - getBlock: sinon.stub() - } + getBlock: sinon.stub(), + }, }; dashd._updateTip(node, message); log.info.callCount.should.equal(1); done(); }); - it('log and emit error from syncPercentage', function(done) { + it("log and emit error from syncPercentage", function (done) { var dashd = new DashService(baseConfig); - dashd.syncPercentage = sinon.stub().callsArgWith(0, new Error('test')); - dashd.on('error', function(err) { + dashd.syncPercentage = sinon.stub().callsArgWith(0, new Error("test")); + dashd.on("error", function (err) { log.error.callCount.should.equal(1); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); var node = { client: { - getBlock: sinon.stub() - } + getBlock: sinon.stub(), + }, }; dashd._updateTip(node, message); }); - it('reset caches and set height', function(done) { + it("reset caches and set height", function (done) { var dashd = new DashService(baseConfig); dashd.syncPercentage = sinon.stub(); dashd._resetCaches = sinon.stub(); - dashd.on('tip', function(height) { + dashd.on("tip", function (height) { dashd._resetCaches.callCount.should.equal(1); height.should.equal(10); dashd.height.should.equal(10); @@ -1041,41 +1051,41 @@ describe('Dash Service', function() { client: { getBlock: sinon.stub().callsArgWith(1, null, { result: { - height: 10 - } - }) - } + height: 10, + }, + }), + }, }; dashd._updateTip(node, message); }); - it('will NOT update twice for the same hash', function(done) { + it("will NOT update twice for the same hash", function (done) { var dashd = new DashService(baseConfig); dashd.syncPercentage = sinon.stub(); dashd._resetCaches = sinon.stub(); - dashd.on('tip', function() { + dashd.on("tip", function () { done(); }); var node = { client: { getBlock: sinon.stub().callsArgWith(1, null, { result: { - height: 10 - } - }) - } + height: 10, + }, + }), + }, }; dashd._updateTip(node, message); dashd._updateTip(node, message); }); - it('will not call syncPercentage if node is stopping', function(done) { + it("will not call syncPercentage if node is stopping", function (done) { var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); dashd.syncPercentage = sinon.stub(); @@ -1085,12 +1095,12 @@ describe('Dash Service', function() { client: { getBlock: sinon.stub().callsArgWith(1, null, { result: { - height: 10 - } - }) - } + height: 10, + }, + }), + }, }; - dashd.on('tip', function() { + dashd.on("tip", function () { dashd.syncPercentage.callCount.should.equal(0); done(); }); @@ -1098,20 +1108,20 @@ describe('Dash Service', function() { }); }); - describe('#_getAddressesFromTransaction', function() { - it('will get results using dashcore.Transaction', function() { + describe("#_getAddressesFromTransaction", function () { + it("will get results using dashcore.Transaction", function () { var dashd = new DashService(baseConfig); - var wif = 'XGLgPK8gbmzU7jcbw34Pj55AXV7SmG6carKuiwtu4WtvTjyTbpwX'; + var wif = "XGLgPK8gbmzU7jcbw34Pj55AXV7SmG6carKuiwtu4WtvTjyTbpwX"; var privkey = dashcore.PrivateKey.fromWIF(wif); var inputAddress = privkey.toAddress(dashcore.Networks.testnet); - var outputAddress = dashcore.Address('8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'); + var outputAddress = dashcore.Address("8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"); var tx = dashcore.Transaction(); tx.from({ - txid: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b', + txid: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", outputIndex: 0, script: dashcore.Script(inputAddress), address: inputAddress.toString(), - satoshis: 5000000000 + satoshis: 5000000000, }); tx.to(outputAddress, 5000000000); tx.sign(privkey); @@ -1120,76 +1130,86 @@ describe('Dash Service', function() { addresses[0].should.equal(inputAddress.toString()); addresses[1].should.equal(outputAddress.toString()); }); - it('will handle non-standard script types', function() { + it("will handle non-standard script types", function () { var dashd = new DashService(baseConfig); var tx = dashcore.Transaction(); - tx.addInput(dashcore.Transaction.Input({ - prevTxId: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b', - script: dashcore.Script('OP_TRUE'), - outputIndex: 1, - output: { - script: dashcore.Script('OP_TRUE'), - satoshis: 5000000000 - } - })); - tx.addOutput(dashcore.Transaction.Output({ - script: dashcore.Script('OP_TRUE'), - satoshis: 5000000000 - })); + tx.addInput( + dashcore.Transaction.Input({ + prevTxId: "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", + script: dashcore.Script("OP_TRUE"), + outputIndex: 1, + output: { + script: dashcore.Script("OP_TRUE"), + satoshis: 5000000000, + }, + }) + ); + tx.addOutput( + dashcore.Transaction.Output({ + script: dashcore.Script("OP_TRUE"), + satoshis: 5000000000, + }) + ); var addresses = dashd._getAddressesFromTransaction(tx); addresses.length.should.equal(0); }); - it('will handle unparsable script types or missing input script', function() { + it("will handle unparsable script types or missing input script", function () { var dashd = new DashService(baseConfig); var tx = dashcore.Transaction(); - tx.addOutput(dashcore.Transaction.Output({ - script: new Buffer('4c', 'hex'), - satoshis: 5000000000 - })); + tx.addOutput( + dashcore.Transaction.Output({ + script: new Buffer("4c", "hex"), + satoshis: 5000000000, + }) + ); var addresses = dashd._getAddressesFromTransaction(tx); addresses.length.should.equal(0); }); - it('will return unique values', function() { + it("will return unique values", function () { var dashd = new DashService(baseConfig); var tx = dashcore.Transaction(); - var address = dashcore.Address('8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'); - tx.addOutput(dashcore.Transaction.Output({ - script: dashcore.Script(address), - satoshis: 5000000000 - })); - tx.addOutput(dashcore.Transaction.Output({ - script: dashcore.Script(address), - satoshis: 5000000000 - })); + var address = dashcore.Address("8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"); + tx.addOutput( + dashcore.Transaction.Output({ + script: dashcore.Script(address), + satoshis: 5000000000, + }) + ); + tx.addOutput( + dashcore.Transaction.Output({ + script: dashcore.Script(address), + satoshis: 5000000000, + }) + ); var addresses = dashd._getAddressesFromTransaction(tx); addresses.length.should.equal(1); }); }); - describe('#_notifyAddressTxidSubscribers', function() { - it('will emit event if matching addresses', function(done) { + describe("#_notifyAddressTxidSubscribers", function () { + it("will emit event if matching addresses", function (done) { var dashd = new DashService(baseConfig); - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; dashd._getAddressesFromTransaction = sinon.stub().returns([address]); var emitter = new EventEmitter(); dashd.subscriptions.address[address] = [emitter]; - var txid = '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0'; + var txid = "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0"; var transaction = {}; - emitter.on('dashd/addresstxid', function(data) { + emitter.on("dashd/addresstxid", function (data) { data.address.should.equal(address); data.txid.should.equal(txid); done(); }); - sinon.spy(emitter, 'emit'); + sinon.spy(emitter, "emit"); dashd._notifyAddressTxidSubscribers(txid, transaction); emitter.emit.callCount.should.equal(1); }); - it('will NOT emit event without matching addresses', function() { + it("will NOT emit event without matching addresses", function () { var dashd = new DashService(baseConfig); - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; dashd._getAddressesFromTransaction = sinon.stub().returns([address]); var emitter = new EventEmitter(); - var txid = '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0'; + var txid = "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0"; var transaction = {}; emitter.emit = sinon.stub(); dashd._notifyAddressTxidSubscribers(txid, transaction); @@ -1197,47 +1217,47 @@ describe('Dash Service', function() { }); }); - describe('#_zmqTransactionHandler', function() { - it('will emit to subscribers', function(done) { + describe("#_zmqTransactionHandler", function () { + it("will emit to subscribers", function (done) { var dashd = new DashService(baseConfig); - var expectedBuffer = new Buffer(txhex, 'hex'); + var expectedBuffer = new Buffer(txhex, "hex"); var emitter = new EventEmitter(); dashd.subscriptions.rawtransaction.push(emitter); - emitter.on('dashd/rawtransaction', function(hex) { - hex.should.be.a('string'); - hex.should.equal(expectedBuffer.toString('hex')); + emitter.on("dashd/rawtransaction", function (hex) { + hex.should.be.a("string"); + hex.should.equal(expectedBuffer.toString("hex")); done(); }); var node = {}; dashd._zmqTransactionHandler(node, expectedBuffer); }); - it('will NOT emit to subscribers more than once for the same tx', function(done) { + it("will NOT emit to subscribers more than once for the same tx", function (done) { var dashd = new DashService(baseConfig); - var expectedBuffer = new Buffer(txhex, 'hex'); + var expectedBuffer = new Buffer(txhex, "hex"); var emitter = new EventEmitter(); dashd.subscriptions.rawtransaction.push(emitter); - emitter.on('dashd/rawtransaction', function() { + emitter.on("dashd/rawtransaction", function () { done(); }); var node = {}; dashd._zmqTransactionHandler(node, expectedBuffer); dashd._zmqTransactionHandler(node, expectedBuffer); }); - it('will emit "tx" event', function(done) { + it('will emit "tx" event', function (done) { var dashd = new DashService(baseConfig); - var expectedBuffer = new Buffer(txhex, 'hex'); - dashd.on('tx', function(buffer) { + var expectedBuffer = new Buffer(txhex, "hex"); + dashd.on("tx", function (buffer) { buffer.should.be.instanceof(Buffer); - buffer.toString('hex').should.equal(expectedBuffer.toString('hex')); + buffer.toString("hex").should.equal(expectedBuffer.toString("hex")); done(); }); var node = {}; dashd._zmqTransactionHandler(node, expectedBuffer); }); - it('will NOT emit "tx" event more than once for the same tx', function(done) { + it('will NOT emit "tx" event more than once for the same tx', function (done) { var dashd = new DashService(baseConfig); - var expectedBuffer = new Buffer(txhex, 'hex'); - dashd.on('tx', function() { + var expectedBuffer = new Buffer(txhex, "hex"); + dashd.on("tx", function () { done(); }); var node = {}; @@ -1247,47 +1267,47 @@ describe('Dash Service', function() { }); // TODO: transaction lock test coverage - describe('#_zmqTransactionLockHandler', function() { - it('will emit to subscribers', function(done) { + describe("#_zmqTransactionLockHandler", function () { + it("will emit to subscribers", function (done) { var dashd = new DashService(baseConfig); - var expectedBuffer = new Buffer(txhex, 'hex'); + var expectedBuffer = new Buffer(txhex, "hex"); var emitter = new EventEmitter(); dashd.subscriptions.transactionlock.push(emitter); - emitter.on('dashd/transactionlock', function(hex) { - hex.should.be.a('string'); - hex.should.equal(expectedBuffer.toString('hex')); + emitter.on("dashd/transactionlock", function (hex) { + hex.should.be.a("string"); + hex.should.equal(expectedBuffer.toString("hex")); done(); }); var node = {}; dashd._zmqTransactionLockHandler(node, expectedBuffer); }); - it('will NOT emit to subscribers more than once for the same tx', function(done) { + it("will NOT emit to subscribers more than once for the same tx", function (done) { var dashd = new DashService(baseConfig); - var expectedBuffer = new Buffer(txhex, 'hex'); + var expectedBuffer = new Buffer(txhex, "hex"); var emitter = new EventEmitter(); dashd.subscriptions.transactionlock.push(emitter); - emitter.on('dashd/transactionlock', function() { + emitter.on("dashd/transactionlock", function () { done(); }); var node = {}; dashd._zmqTransactionLockHandler(node, expectedBuffer); dashd._zmqTransactionLockHandler(node, expectedBuffer); }); - it('will emit "tx" event', function(done) { + it('will emit "tx" event', function (done) { var dashd = new DashService(baseConfig); - var expectedBuffer = new Buffer(txhex, 'hex'); - dashd.on('txlock', function(buffer) { + var expectedBuffer = new Buffer(txhex, "hex"); + dashd.on("txlock", function (buffer) { buffer.should.be.instanceof(Buffer); - buffer.toString('hex').should.equal(expectedBuffer.toString('hex')); + buffer.toString("hex").should.equal(expectedBuffer.toString("hex")); done(); }); var node = {}; dashd._zmqTransactionLockHandler(node, expectedBuffer); }); - it('will NOT emit "tx" event more than once for the same tx', function(done) { + it('will NOT emit "tx" event more than once for the same tx', function (done) { var dashd = new DashService(baseConfig); - var expectedBuffer = new Buffer(txhex, 'hex'); - dashd.on('txlock', function() { + var expectedBuffer = new Buffer(txhex, "hex"); + dashd.on("txlock", function () { done(); }); var node = {}; @@ -1296,52 +1316,52 @@ describe('Dash Service', function() { }); }); - describe('#_checkSyncedAndSubscribeZmqEvents', function() { + describe("#_checkSyncedAndSubscribeZmqEvents", function () { var sandbox = sinon.sandbox.create(); - before(function() { - sandbox.stub(log, 'error'); + before(function () { + sandbox.stub(log, "error"); }); - after(function() { + after(function () { sandbox.restore(); }); - it('log errors, update tip and subscribe to zmq events', function(done) { + it("log errors, update tip and subscribe to zmq events", function (done) { var dashd = new DashService(baseConfig); dashd._updateTip = sinon.stub(); dashd._subscribeZmqEvents = sinon.stub(); var blockEvents = 0; - dashd.on('block', function() { + dashd.on("block", function () { blockEvents++; }); var getBestBlockHash = sinon.stub().callsArgWith(0, null, { - result: '00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45' + result: "00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45", }); - getBestBlockHash.onCall(0).callsArgWith(0, {code: -1 , message: 'Test error'}); - var progress = 0.90; + getBestBlockHash.onCall(0).callsArgWith(0, { code: -1, message: "Test error" }); + var progress = 0.9; function getProgress() { progress = progress + 0.01; return progress; } var info = {}; - Object.defineProperty(info, 'result', { - get: function() { + Object.defineProperty(info, "result", { + get: function () { return { - verificationprogress: getProgress() + verificationprogress: getProgress(), }; - } + }, }); var getBlockchainInfo = sinon.stub().callsArgWith(0, null, info); - getBlockchainInfo.onCall(0).callsArgWith(0, {code: -1, message: 'Test error'}); + getBlockchainInfo.onCall(0).callsArgWith(0, { code: -1, message: "Test error" }); var node = { _reindex: true, _reindexWait: 1, _tipUpdateInterval: 1, client: { getBestBlockHash: getBestBlockHash, - getBlockchainInfo: getBlockchainInfo - } + getBlockchainInfo: getBlockchainInfo, + }, }; dashd._checkSyncedAndSubscribeZmqEvents(node); - setTimeout(function() { + setTimeout(function () { log.error.callCount.should.equal(2); blockEvents.should.equal(11); dashd._updateTip.callCount.should.equal(11); @@ -1349,56 +1369,56 @@ describe('Dash Service', function() { done(); }, 200); }); - it('it will clear interval if node is stopping', function(done) { + it("it will clear interval if node is stopping", function (done) { var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); - var getBestBlockHash = sinon.stub().callsArgWith(0, {code: -1, message: 'error'}); + var getBestBlockHash = sinon.stub().callsArgWith(0, { code: -1, message: "error" }); var node = { _tipUpdateInterval: 1, client: { - getBestBlockHash: getBestBlockHash - } + getBestBlockHash: getBestBlockHash, + }, }; dashd._checkSyncedAndSubscribeZmqEvents(node); - setTimeout(function() { + setTimeout(function () { dashd.node.stopping = true; var count = getBestBlockHash.callCount; - setTimeout(function() { + setTimeout(function () { getBestBlockHash.callCount.should.equal(count); done(); }, 100); }, 100); }); - it('will not set interval if synced is true', function(done) { + it("will not set interval if synced is true", function (done) { var dashd = new DashService(baseConfig); dashd._updateTip = sinon.stub(); dashd._subscribeZmqEvents = sinon.stub(); var getBestBlockHash = sinon.stub().callsArgWith(0, null, { - result: '00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45' + result: "00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45", }); var info = { result: { - verificationprogress: 1.00 - } + verificationprogress: 1.0, + }, }; var getBlockchainInfo = sinon.stub().callsArgWith(0, null, info); var node = { _tipUpdateInterval: 1, client: { getBestBlockHash: getBestBlockHash, - getBlockchainInfo: getBlockchainInfo - } + getBlockchainInfo: getBlockchainInfo, + }, }; dashd._checkSyncedAndSubscribeZmqEvents(node); - setTimeout(function() { + setTimeout(function () { getBestBlockHash.callCount.should.equal(1); getBlockchainInfo.callCount.should.equal(1); done(); @@ -1406,233 +1426,233 @@ describe('Dash Service', function() { }); }); - describe('#_subscribeZmqEvents', function() { - it('will call subscribe on zmq socket', function() { + describe("#_subscribeZmqEvents", function () { + it("will call subscribe on zmq socket", function () { var dashd = new DashService(baseConfig); var node = { zmqSubSocket: { subscribe: sinon.stub(), - on: sinon.stub() - } + on: sinon.stub(), + }, }; dashd._subscribeZmqEvents(node); node.zmqSubSocket.subscribe.callCount.should.equal(3); - node.zmqSubSocket.subscribe.args[0][0].should.equal('hashblock'); - node.zmqSubSocket.subscribe.args[1][0].should.equal('rawtx'); - node.zmqSubSocket.subscribe.args[2][0].should.equal('rawtxlock'); + node.zmqSubSocket.subscribe.args[0][0].should.equal("hashblock"); + node.zmqSubSocket.subscribe.args[1][0].should.equal("rawtx"); + node.zmqSubSocket.subscribe.args[2][0].should.equal("rawtxlock"); }); - it('will call relevant handler for rawtx topics', function(done) { + it("will call relevant handler for rawtx topics", function (done) { var dashd = new DashService(baseConfig); dashd._zmqTransactionHandler = sinon.stub(); var node = { - zmqSubSocket: new EventEmitter() + zmqSubSocket: new EventEmitter(), }; node.zmqSubSocket.subscribe = sinon.stub(); dashd._subscribeZmqEvents(node); - node.zmqSubSocket.on('message', function() { + node.zmqSubSocket.on("message", function () { dashd._zmqTransactionHandler.callCount.should.equal(1); done(); }); - var topic = new Buffer('rawtx', 'utf8'); - var message = new Buffer('abcdef', 'hex'); - node.zmqSubSocket.emit('message', topic, message); + var topic = new Buffer("rawtx", "utf8"); + var message = new Buffer("abcdef", "hex"); + node.zmqSubSocket.emit("message", topic, message); }); - it('will call relevant handler for hashblock topics', function(done) { + it("will call relevant handler for hashblock topics", function (done) { var dashd = new DashService(baseConfig); dashd._zmqBlockHandler = sinon.stub(); var node = { - zmqSubSocket: new EventEmitter() + zmqSubSocket: new EventEmitter(), }; node.zmqSubSocket.subscribe = sinon.stub(); dashd._subscribeZmqEvents(node); - node.zmqSubSocket.on('message', function() { + node.zmqSubSocket.on("message", function () { dashd._zmqBlockHandler.callCount.should.equal(1); done(); }); - var topic = new Buffer('hashblock', 'utf8'); - var message = new Buffer('abcdef', 'hex'); - node.zmqSubSocket.emit('message', topic, message); + var topic = new Buffer("hashblock", "utf8"); + var message = new Buffer("abcdef", "hex"); + node.zmqSubSocket.emit("message", topic, message); }); - it('will ignore unknown topic types', function(done) { + it("will ignore unknown topic types", function (done) { var dashd = new DashService(baseConfig); dashd._zmqBlockHandler = sinon.stub(); dashd._zmqTransactionHandler = sinon.stub(); var node = { - zmqSubSocket: new EventEmitter() + zmqSubSocket: new EventEmitter(), }; node.zmqSubSocket.subscribe = sinon.stub(); dashd._subscribeZmqEvents(node); - node.zmqSubSocket.on('message', function() { + node.zmqSubSocket.on("message", function () { dashd._zmqBlockHandler.callCount.should.equal(0); dashd._zmqTransactionHandler.callCount.should.equal(0); done(); }); - var topic = new Buffer('unknown', 'utf8'); - var message = new Buffer('abcdef', 'hex'); - node.zmqSubSocket.emit('message', topic, message); + var topic = new Buffer("unknown", "utf8"); + var message = new Buffer("abcdef", "hex"); + node.zmqSubSocket.emit("message", topic, message); }); }); - describe('#_initZmqSubSocket', function() { - it('will setup zmq socket', function() { + describe("#_initZmqSubSocket", function () { + it("will setup zmq socket", function () { var socket = new EventEmitter(); socket.monitor = sinon.stub(); socket.connect = sinon.stub(); - var socketFunc = function() { + var socketFunc = function () { return socket; }; - var DashService = proxyquire('../../lib/services/dashd', { + var DashService = proxyquire("../../lib/services/dashd", { zeromq: { - socket: socketFunc - } + socket: socketFunc, + }, }); var dashd = new DashService(baseConfig); var node = {}; - dashd._initZmqSubSocket(node, 'url'); + dashd._initZmqSubSocket(node, "url"); node.zmqSubSocket.should.equal(socket); socket.connect.callCount.should.equal(1); - socket.connect.args[0][0].should.equal('url'); + socket.connect.args[0][0].should.equal("url"); socket.monitor.callCount.should.equal(1); socket.monitor.args[0][0].should.equal(500); socket.monitor.args[0][1].should.equal(0); }); }); - describe('#_checkReindex', function() { + describe("#_checkReindex", function () { var sandbox = sinon.sandbox.create(); - before(function() { - sandbox.stub(log, 'info'); + before(function () { + sandbox.stub(log, "info"); }); - after(function() { + after(function () { sandbox.restore(); }); - it('give error from client getblockchaininfo', function(done) { + it("give error from client getblockchaininfo", function (done) { var dashd = new DashService(baseConfig); var node = { _reindex: true, _reindexWait: 1, client: { - getBlockchainInfo: sinon.stub().callsArgWith(0, {code: -1 , message: 'Test error'}) - } + getBlockchainInfo: sinon.stub().callsArgWith(0, { code: -1, message: "Test error" }), + }, }; - dashd._checkReindex(node, function(err) { + dashd._checkReindex(node, function (err) { should.exist(err); err.should.be.instanceof(errors.RPCError); done(); }); }); - it('will wait until sync is 100 percent', function(done) { + it("will wait until sync is 100 percent", function (done) { var dashd = new DashService(baseConfig); var percent = 0.89; var node = { _reindex: true, _reindexWait: 1, client: { - getBlockchainInfo: function(callback) { + getBlockchainInfo: function (callback) { percent += 0.01; callback(null, { result: { - verificationprogress: percent - } + verificationprogress: percent, + }, }); - } - } + }, + }, }; - dashd._checkReindex(node, function() { + dashd._checkReindex(node, function () { node._reindex.should.equal(false); log.info.callCount.should.equal(11); done(); }); }); - it('will call callback if reindex is not enabled', function(done) { + it("will call callback if reindex is not enabled", function (done) { var dashd = new DashService(baseConfig); var node = { - _reindex: false + _reindex: false, }; - dashd._checkReindex(node, function() { + dashd._checkReindex(node, function () { node._reindex.should.equal(false); done(); }); }); }); - describe('#_loadTipFromNode', function() { + describe("#_loadTipFromNode", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'warn'); + beforeEach(function () { + sandbox.stub(log, "warn"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will give rpc from client getbestblockhash', function(done) { + it("will give rpc from client getbestblockhash", function (done) { var dashd = new DashService(baseConfig); - var getBestBlockHash = sinon.stub().callsArgWith(0, {code: -1, message: 'Test error'}); + var getBestBlockHash = sinon.stub().callsArgWith(0, { code: -1, message: "Test error" }); var node = { client: { - getBestBlockHash: getBestBlockHash - } + getBestBlockHash: getBestBlockHash, + }, }; - dashd._loadTipFromNode(node, function(err) { + dashd._loadTipFromNode(node, function (err) { err.should.be.instanceof(Error); log.warn.callCount.should.equal(0); done(); }); }); - it('will give rpc from client getblock', function(done) { + it("will give rpc from client getblock", function (done) { var dashd = new DashService(baseConfig); var getBestBlockHash = sinon.stub().callsArgWith(0, null, { - result: '00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45' + result: "00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45", }); - var getBlock = sinon.stub().callsArgWith(1, new Error('Test error')); + var getBlock = sinon.stub().callsArgWith(1, new Error("Test error")); var node = { client: { getBestBlockHash: getBestBlockHash, - getBlock: getBlock - } + getBlock: getBlock, + }, }; - dashd._loadTipFromNode(node, function(err) { - getBlock.args[0][0].should.equal('00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45'); + dashd._loadTipFromNode(node, function (err) { + getBlock.args[0][0].should.equal("00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45"); err.should.be.instanceof(Error); log.warn.callCount.should.equal(0); done(); }); }); - it('will throw when error is RPC_IN_WARMUP outside of retry', function(done) { + it("will throw when error is RPC_IN_WARMUP outside of retry", function (done) { var dashd = new DashService(baseConfig); var getBestBlockHash = sinon.stub().callsArgWith(0, RPC_IN_WARMUP_ERROR); var node = { client: { - getBestBlockHash: getBestBlockHash - } + getBestBlockHash: getBestBlockHash, + }, }; - dashd._loadTipFromNode(node, function(err) { + dashd._loadTipFromNode(node, function (err) { err.should.be.instanceof(Error); log.warn.callCount.should.equal(0); done(); }); }); - it('will set height and emit tip', function(done) { + it("will set height and emit tip", function (done) { var dashd = new DashService(baseConfig); var getBestBlockHash = sinon.stub().callsArgWith(0, null, { - result: '00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45' + result: "00000000000000001bb82a7f5973618cfd3185ba1ded04dd852a653f92a27c45", }); var getBlock = sinon.stub().callsArgWith(1, null, { result: { - height: 100 - } + height: 100, + }, }); var node = { client: { getBestBlockHash: getBestBlockHash, - getBlock: getBlock - } + getBlock: getBlock, + }, }; - dashd.on('tip', function(height) { + dashd.on("tip", function (height) { height.should.equal(100); dashd.height.should.equal(100); done(); }); - dashd._loadTipFromNode(node, function(err) { + dashd._loadTipFromNode(node, function (err) { if (err) { return done(err); } @@ -1640,30 +1660,30 @@ describe('Dash Service', function() { }); }); - describe('#_stopSpawnedProcess', function() { + describe("#_stopSpawnedProcess", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'warn'); + beforeEach(function () { + sandbox.stub(log, "warn"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('it will kill process and resume', function(done) { + it("it will kill process and resume", function (done) { var readFile = sandbox.stub(); - readFile.onCall(0).callsArgWith(2, null, '4321'); - var error = new Error('Test error'); - error.code = 'ENOENT'; + readFile.onCall(0).callsArgWith(2, null, "4321"); + var error = new Error("Test error"); + error.code = "ENOENT"; readFile.onCall(1).callsArgWith(2, error); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFile: readFile - } + readFile: readFile, + }, }); var dashd = new TestDashService(baseConfig); dashd.spawnStopTime = 1; dashd._process = {}; dashd._process.kill = sinon.stub(); - dashd._stopSpawnedDash(function(err) { + dashd._stopSpawnedDash(function (err) { if (err) { return done(err); } @@ -1672,24 +1692,24 @@ describe('Dash Service', function() { done(); }); }); - it('it will attempt to kill process and resume', function(done) { + it("it will attempt to kill process and resume", function (done) { var readFile = sandbox.stub(); - readFile.onCall(0).callsArgWith(2, null, '4321'); - var error = new Error('Test error'); - error.code = 'ENOENT'; + readFile.onCall(0).callsArgWith(2, null, "4321"); + var error = new Error("Test error"); + error.code = "ENOENT"; readFile.onCall(1).callsArgWith(2, error); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFile: readFile - } + readFile: readFile, + }, }); var dashd = new TestDashService(baseConfig); dashd.spawnStopTime = 1; dashd._process = {}; - var error2 = new Error('Test error'); - error2.code = 'ESRCH'; + var error2 = new Error("Test error"); + error2.code = "ESRCH"; dashd._process.kill = sinon.stub().throws(error2); - dashd._stopSpawnedDash(function(err) { + dashd._stopSpawnedDash(function (err) { if (err) { return done(err); } @@ -1698,38 +1718,38 @@ describe('Dash Service', function() { done(); }); }); - it('it will attempt to kill process with NaN', function(done) { + it("it will attempt to kill process with NaN", function (done) { var readFile = sandbox.stub(); - readFile.onCall(0).callsArgWith(2, null, ' '); - var TestDashService = proxyquire('../../lib/services/dashd', { + readFile.onCall(0).callsArgWith(2, null, " "); + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFile: readFile - } + readFile: readFile, + }, }); var dashd = new TestDashService(baseConfig); dashd.spawnStopTime = 1; dashd._process = {}; dashd._process.kill = sinon.stub(); - dashd._stopSpawnedDash(function(err) { + dashd._stopSpawnedDash(function (err) { if (err) { return done(err); } done(); }); }); - it('it will attempt to kill process without pid', function(done) { + it("it will attempt to kill process without pid", function (done) { var readFile = sandbox.stub(); - readFile.onCall(0).callsArgWith(2, null, ''); - var TestDashService = proxyquire('../../lib/services/dashd', { + readFile.onCall(0).callsArgWith(2, null, ""); + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFile: readFile - } + readFile: readFile, + }, }); var dashd = new TestDashService(baseConfig); dashd.spawnStopTime = 1; dashd._process = {}; dashd._process.kill = sinon.stub(); - dashd._stopSpawnedDash(function(err) { + dashd._stopSpawnedDash(function (err) { if (err) { return done(err); } @@ -1738,110 +1758,106 @@ describe('Dash Service', function() { }); }); - describe('#_spawnChildProcess', function() { + describe("#_spawnChildProcess", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); - sandbox.stub(log, 'warn'); - sandbox.stub(log, 'error'); + beforeEach(function () { + sandbox.stub(log, "info"); + sandbox.stub(log, "warn"); + sandbox.stub(log, "error"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will give error from spawn config', function(done) { + it("will give error from spawn config", function (done) { var dashd = new DashService(baseConfig); dashd._loadSpawnConfiguration = sinon.stub(); - dashd._loadSpawnConfiguration = sinon.stub().throws(new Error('test')); - dashd._spawnChildProcess(function(err) { + dashd._loadSpawnConfiguration = sinon.stub().throws(new Error("test")); + dashd._spawnChildProcess(function (err) { err.should.be.instanceof(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will give error from stopSpawnedDash', function() { + it("will give error from stopSpawnedDash", function () { var dashd = new DashService(baseConfig); dashd._loadSpawnConfiguration = sinon.stub(); - dashd._stopSpawnedDash = sinon.stub().callsArgWith(0, new Error('test')); - dashd._spawnChildProcess(function(err) { + dashd._stopSpawnedDash = sinon.stub().callsArgWith(0, new Error("test")); + dashd._spawnChildProcess(function (err) { err.should.be.instanceOf(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); }); }); - it('will exit spawn if shutdown', function() { + it("will exit spawn if shutdown", function () { var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var process = new EventEmitter(); var spawn = sinon.stub().returns(process); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync + readFileSync: readFileSync, }, child_process: { - spawn: spawn - } + spawn: spawn, + }, }); var dashd = new TestDashService(config); dashd.spawn = {}; dashd._loadSpawnConfiguration = sinon.stub(); dashd._stopSpawnedDash = sinon.stub().callsArgWith(0, null); dashd.node.stopping = true; - dashd._spawnChildProcess(function(err) { + dashd._spawnChildProcess(function (err) { err.should.be.instanceOf(Error); err.message.should.match(/Stopping while trying to spawn/); }); }); - it('will include network with spawn command and init zmq/rpc on node', function(done) { + it("will include network with spawn command and init zmq/rpc on node", function (done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync + readFileSync: readFileSync, }, child_process: { - spawn: spawn - } + spawn: spawn, + }, }); var dashd = new TestDashService(baseConfig); dashd._loadSpawnConfiguration = sinon.stub(); dashd.spawn = {}; - dashd.spawn.exec = 'testexec'; - dashd.spawn.configPath = 'testdir/dash.conf'; - dashd.spawn.datadir = 'testdir'; + dashd.spawn.exec = "testexec"; + dashd.spawn.configPath = "testdir/dash.conf"; + dashd.spawn.datadir = "testdir"; dashd.spawn.config = {}; dashd.spawn.config.rpcport = 20001; - dashd.spawn.config.rpcuser = 'dash'; - dashd.spawn.config.rpcpassword = 'password'; - dashd.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001'; - dashd.spawn.config.zmqpubrawtxlock = 'tcp://127.0.0.1:30001'; + dashd.spawn.config.rpcuser = "dash"; + dashd.spawn.config.rpcpassword = "password"; + dashd.spawn.config.zmqpubrawtx = "tcp://127.0.0.1:30001"; + dashd.spawn.config.zmqpubrawtxlock = "tcp://127.0.0.1:30001"; dashd._loadTipFromNode = sinon.stub().callsArgWith(1, null); dashd._initZmqSubSocket = sinon.stub(); dashd._checkSyncedAndSubscribeZmqEvents = sinon.stub(); dashd._checkReindex = sinon.stub().callsArgWith(1, null); - dashd._spawnChildProcess(function(err, node) { + dashd._spawnChildProcess(function (err, node) { should.not.exist(err); spawn.callCount.should.equal(1); - spawn.args[0][0].should.equal('testexec'); - spawn.args[0][1].should.deep.equal([ - '--conf=testdir/dash.conf', - '--datadir=testdir', - '--testnet' - ]); + spawn.args[0][0].should.equal("testexec"); + spawn.args[0][1].should.deep.equal(["--conf=testdir/dash.conf", "--datadir=testdir", "--testnet"]); spawn.args[0][2].should.deep.equal({ - stdio: 'inherit' + stdio: "inherit", }); dashd._loadTipFromNode.callCount.should.equal(1); dashd._initZmqSubSocket.callCount.should.equal(1); should.exist(dashd._initZmqSubSocket.args[0][0].client); - dashd._initZmqSubSocket.args[0][1].should.equal('tcp://127.0.0.1:30001'); + dashd._initZmqSubSocket.args[0][1].should.equal("tcp://127.0.0.1:30001"); dashd._checkSyncedAndSubscribeZmqEvents.callCount.should.equal(1); should.exist(dashd._checkSyncedAndSubscribeZmqEvents.args[0][0].client); should.exist(node); @@ -1849,23 +1865,23 @@ describe('Dash Service', function() { done(); }); }); - it('will respawn dashd spawned process', function(done) { + it("will respawn dashd spawned process", function (done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync + readFileSync: readFileSync, }, child_process: { - spawn: spawn - } + spawn: spawn, + }, }); var dashd = new TestDashService(baseConfig); dashd._loadSpawnConfiguration = sinon.stub(); dashd.spawn = {}; - dashd.spawn.exec = 'dashd'; - dashd.spawn.datadir = '/tmp/dash'; - dashd.spawn.configPath = '/tmp/dash/dash.conf'; + dashd.spawn.exec = "dashd"; + dashd.spawn.datadir = "/tmp/dash"; + dashd.spawn.configPath = "/tmp/dash/dash.conf"; dashd.spawn.config = {}; dashd.spawnRestartTime = 1; dashd._loadTipFromNode = sinon.stub().callsArg(1); @@ -1873,37 +1889,37 @@ describe('Dash Service', function() { dashd._checkReindex = sinon.stub().callsArg(1); dashd._checkSyncedAndSubscribeZmqEvents = sinon.stub(); dashd._stopSpawnedDash = sinon.stub().callsArg(0); - sinon.spy(dashd, '_spawnChildProcess'); - dashd._spawnChildProcess(function(err) { + sinon.spy(dashd, "_spawnChildProcess"); + dashd._spawnChildProcess(function (err) { if (err) { return done(err); } - process.once('exit', function() { - setTimeout(function() { + process.once("exit", function () { + setTimeout(function () { dashd._spawnChildProcess.callCount.should.equal(2); done(); }, 5); }); - process.emit('exit', 1); + process.emit("exit", 1); }); }); - it('will emit error during respawn', function(done) { + it("will emit error during respawn", function (done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync + readFileSync: readFileSync, }, child_process: { - spawn: spawn - } + spawn: spawn, + }, }); var dashd = new TestDashService(baseConfig); dashd._loadSpawnConfiguration = sinon.stub(); dashd.spawn = {}; - dashd.spawn.exec = 'dashd'; - dashd.spawn.datadir = '/tmp/dash'; - dashd.spawn.configPath = '/tmp/dash/dash.conf'; + dashd.spawn.exec = "dashd"; + dashd.spawn.datadir = "/tmp/dash"; + dashd.spawn.configPath = "/tmp/dash/dash.conf"; dashd.spawn.config = {}; dashd.spawnRestartTime = 1; dashd._loadTipFromNode = sinon.stub().callsArg(1); @@ -1911,46 +1927,46 @@ describe('Dash Service', function() { dashd._checkReindex = sinon.stub().callsArg(1); dashd._checkSyncedAndSubscribeZmqEvents = sinon.stub(); dashd._stopSpawnedDash = sinon.stub().callsArg(0); - sinon.spy(dashd, '_spawnChildProcess'); - dashd._spawnChildProcess(function(err) { + sinon.spy(dashd, "_spawnChildProcess"); + dashd._spawnChildProcess(function (err) { if (err) { return done(err); } - dashd._spawnChildProcess = sinon.stub().callsArgWith(0, new Error('test')); - dashd.on('error', function(err) { + dashd._spawnChildProcess = sinon.stub().callsArgWith(0, new Error("test")); + dashd.on("error", function (err) { err.should.be.instanceOf(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); - process.emit('exit', 1); + process.emit("exit", 1); }); }); - it('will NOT respawn dashd spawned process if shutting down', function(done) { + it("will NOT respawn dashd spawned process if shutting down", function (done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync + readFileSync: readFileSync, }, child_process: { - spawn: spawn - } + spawn: spawn, + }, }); var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new TestDashService(config); dashd._loadSpawnConfiguration = sinon.stub(); dashd.spawn = {}; - dashd.spawn.exec = 'dashd'; - dashd.spawn.datadir = '/tmp/dash'; - dashd.spawn.configPath = '/tmp/dash/dash.conf'; + dashd.spawn.exec = "dashd"; + dashd.spawn.datadir = "/tmp/dash"; + dashd.spawn.configPath = "/tmp/dash/dash.conf"; dashd.spawn.config = {}; dashd.spawnRestartTime = 1; dashd._loadTipFromNode = sinon.stub().callsArg(1); @@ -1958,171 +1974,171 @@ describe('Dash Service', function() { dashd._checkReindex = sinon.stub().callsArg(1); dashd._checkSyncedAndSubscribeZmqEvents = sinon.stub(); dashd._stopSpawnedDash = sinon.stub().callsArg(0); - sinon.spy(dashd, '_spawnChildProcess'); - dashd._spawnChildProcess(function(err) { + sinon.spy(dashd, "_spawnChildProcess"); + dashd._spawnChildProcess(function (err) { if (err) { return done(err); } dashd.node.stopping = true; - process.once('exit', function() { - setTimeout(function() { + process.once("exit", function () { + setTimeout(function () { dashd._spawnChildProcess.callCount.should.equal(1); done(); }, 5); }); - process.emit('exit', 1); + process.emit("exit", 1); }); }); - it('will give error after 60 retries of RPC_IN_WARMUP warning', function(done) { + it("will give error after 60 retries of RPC_IN_WARMUP warning", function (done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync + readFileSync: readFileSync, }, child_process: { - spawn: spawn - } + spawn: spawn, + }, }); var dashd = new TestDashService(baseConfig); dashd.startRetryInterval = 1; dashd._loadSpawnConfiguration = sinon.stub(); dashd.spawn = {}; - dashd.spawn.exec = 'testexec'; - dashd.spawn.configPath = 'testdir/dash.conf'; - dashd.spawn.datadir = 'testdir'; + dashd.spawn.exec = "testexec"; + dashd.spawn.configPath = "testdir/dash.conf"; + dashd.spawn.datadir = "testdir"; dashd.spawn.config = {}; dashd.spawn.config.rpcport = 20001; - dashd.spawn.config.rpcuser = 'dash'; - dashd.spawn.config.rpcpassword = 'password'; - dashd.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001'; - dashd.spawn.config.zmqpubrawtxlock = 'tcp://127.0.0.1:30001'; + dashd.spawn.config.rpcuser = "dash"; + dashd.spawn.config.rpcpassword = "password"; + dashd.spawn.config.zmqpubrawtx = "tcp://127.0.0.1:30001"; + dashd.spawn.config.zmqpubrawtxlock = "tcp://127.0.0.1:30001"; dashd._loadTipFromNode = sinon.stub().callsArgWith(1, RPC_IN_WARMUP_ERROR); - dashd._spawnChildProcess(function(err) { + dashd._spawnChildProcess(function (err) { dashd._loadTipFromNode.callCount.should.equal(60); err.should.be.instanceof(Error); done(); }); }); - it('will give error WITHOUT retrying for fatal and unknown errors', function(done) { + it("will give error WITHOUT retrying for fatal and unknown errors", function (done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync + readFileSync: readFileSync, }, child_process: { - spawn: spawn - } + spawn: spawn, + }, }); var dashd = new TestDashService(baseConfig); dashd.startRetryInterval = 1; dashd._loadSpawnConfiguration = sinon.stub(); dashd.spawn = {}; - dashd.spawn.exec = 'testexec'; - dashd.spawn.configPath = 'testdir/dash.conf'; - dashd.spawn.datadir = 'testdir'; + dashd.spawn.exec = "testexec"; + dashd.spawn.configPath = "testdir/dash.conf"; + dashd.spawn.datadir = "testdir"; dashd.spawn.config = {}; dashd.spawn.config.rpcport = 20001; - dashd.spawn.config.rpcuser = 'dash'; - dashd.spawn.config.rpcpassword = 'password'; - dashd.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001'; - dashd.spawn.config.zmqpubrawtxlock = 'tcp://127.0.0.1:30001'; - dashd._loadTipFromNode = sinon.stub().callsArgWith(1, new Error('test')); - dashd._spawnChildProcess(function(err) { + dashd.spawn.config.rpcuser = "dash"; + dashd.spawn.config.rpcpassword = "password"; + dashd.spawn.config.zmqpubrawtx = "tcp://127.0.0.1:30001"; + dashd.spawn.config.zmqpubrawtxlock = "tcp://127.0.0.1:30001"; + dashd._loadTipFromNode = sinon.stub().callsArgWith(1, new Error("test")); + dashd._spawnChildProcess(function (err) { dashd._loadTipFromNode.callCount.should.equal(1); err.should.be.instanceof(Error); done(); }); }); - it('will give error from check reindex', function(done) { + it("will give error from check reindex", function (done) { var process = new EventEmitter(); var spawn = sinon.stub().returns(process); - var TestDashService = proxyquire('../../lib/services/dashd', { + var TestDashService = proxyquire("../../lib/services/dashd", { fs: { - readFileSync: readFileSync + readFileSync: readFileSync, }, child_process: { - spawn: spawn - } + spawn: spawn, + }, }); var dashd = new TestDashService(baseConfig); dashd._loadSpawnConfiguration = sinon.stub(); dashd.spawn = {}; - dashd.spawn.exec = 'testexec'; - dashd.spawn.configPath = 'testdir/dash.conf'; - dashd.spawn.datadir = 'testdir'; + dashd.spawn.exec = "testexec"; + dashd.spawn.configPath = "testdir/dash.conf"; + dashd.spawn.datadir = "testdir"; dashd.spawn.config = {}; dashd.spawn.config.rpcport = 20001; - dashd.spawn.config.rpcuser = 'dash'; - dashd.spawn.config.rpcpassword = 'password'; - dashd.spawn.config.zmqpubrawtx = 'tcp://127.0.0.1:30001'; - dashd.spawn.config.zmqpubrawtxlock = 'tcp://127.0.0.1:30001'; + dashd.spawn.config.rpcuser = "dash"; + dashd.spawn.config.rpcpassword = "password"; + dashd.spawn.config.zmqpubrawtx = "tcp://127.0.0.1:30001"; + dashd.spawn.config.zmqpubrawtxlock = "tcp://127.0.0.1:30001"; dashd._loadTipFromNode = sinon.stub().callsArgWith(1, null); dashd._initZmqSubSocket = sinon.stub(); dashd._checkSyncedAndSubscribeZmqEvents = sinon.stub(); - dashd._checkReindex = sinon.stub().callsArgWith(1, new Error('test')); + dashd._checkReindex = sinon.stub().callsArgWith(1, new Error("test")); - dashd._spawnChildProcess(function(err) { + dashd._spawnChildProcess(function (err) { err.should.be.instanceof(Error); done(); }); }); }); - describe('#_connectProcess', function() { - it('will give error if connecting while shutting down', function(done) { + describe("#_connectProcess", function () { + it("will give error if connecting while shutting down", function (done) { var config = { node: { - network: dashcore.Networks.testnet + network: dashcore.Networks.testnet, }, spawn: { - datadir: 'testdir', - exec: 'testpath' - } + datadir: "testdir", + exec: "testpath", + }, }; var dashd = new DashService(config); dashd.node.stopping = true; dashd.startRetryInterval = 100; dashd._loadTipFromNode = sinon.stub(); - dashd._connectProcess({}, function(err) { + dashd._connectProcess({}, function (err) { err.should.be.instanceof(Error); err.message.should.match(/Stopping while trying to connect/); dashd._loadTipFromNode.callCount.should.equal(0); done(); }); }); - it('will give error for warnings from loadTipFromNode after 60 retries', function(done) { + it("will give error for warnings from loadTipFromNode after 60 retries", function (done) { var dashd = new DashService(baseConfig); dashd._loadTipFromNode = sinon.stub().callsArgWith(1, RPC_IN_WARMUP_ERROR); dashd.startRetryInterval = 1; var config = {}; - dashd._connectProcess(config, function(err) { + dashd._connectProcess(config, function (err) { err.should.be.instanceof(Error); dashd._loadTipFromNode.callCount.should.equal(60); done(); }); }); - it('will immediately fail from loadTipFromNode for fatal and unknown errors', function(done) { + it("will immediately fail from loadTipFromNode for fatal and unknown errors", function (done) { var dashd = new DashService(baseConfig); - dashd._loadTipFromNode = sinon.stub().callsArgWith(1, new Error('test')); + dashd._loadTipFromNode = sinon.stub().callsArgWith(1, new Error("test")); dashd.startRetryInterval = 1; var config = {}; - dashd._connectProcess(config, function(err) { + dashd._connectProcess(config, function (err) { err.should.be.instanceof(Error); dashd._loadTipFromNode.callCount.should.equal(1); done(); }); }); - it('will init zmq/rpc on node', function(done) { + it("will init zmq/rpc on node", function (done) { var dashd = new DashService(baseConfig); dashd._initZmqSubSocket = sinon.stub(); dashd._subscribeZmqEvents = sinon.stub(); dashd._loadTipFromNode = sinon.stub().callsArgWith(1, null); var config = {}; - dashd._connectProcess(config, function(err, node) { + dashd._connectProcess(config, function (err, node) { should.not.exist(err); dashd._loadTipFromNode.callCount.should.equal(1); dashd._initZmqSubSocket.callCount.should.equal(1); @@ -2134,75 +2150,71 @@ describe('Dash Service', function() { }); }); - describe('#start', function() { + describe("#start", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('will give error if "spawn" and "connect" are both not configured', function(done) { + it('will give error if "spawn" and "connect" are both not configured', function (done) { var dashd = new DashService(baseConfig); dashd.options = {}; - dashd.start(function(err) { + dashd.start(function (err) { err.should.be.instanceof(Error); err.message.should.match(/Dash configuration options/); }); done(); }); - it('will give error from spawnChildProcess', function(done) { + it("will give error from spawnChildProcess", function (done) { var dashd = new DashService(baseConfig); - dashd._spawnChildProcess = sinon.stub().callsArgWith(0, new Error('test')); + dashd._spawnChildProcess = sinon.stub().callsArgWith(0, new Error("test")); dashd.options = { - spawn: {} + spawn: {}, }; - dashd.start(function(err) { + dashd.start(function (err) { err.should.be.instanceof(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will give error from connectProcess', function(done) { + it("will give error from connectProcess", function (done) { var dashd = new DashService(baseConfig); - dashd._connectProcess = sinon.stub().callsArgWith(1, new Error('test')); + dashd._connectProcess = sinon.stub().callsArgWith(1, new Error("test")); dashd.options = { - connect: [ - {} - ] + connect: [{}], }; - dashd.start(function(err) { + dashd.start(function (err) { dashd._connectProcess.callCount.should.equal(1); err.should.be.instanceof(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will push node from spawnChildProcess', function(done) { + it("will push node from spawnChildProcess", function (done) { var dashd = new DashService(baseConfig); var node = {}; dashd._initChain = sinon.stub().callsArg(0); dashd._spawnChildProcess = sinon.stub().callsArgWith(0, null, node); dashd.options = { - spawn: {} + spawn: {}, }; - dashd.start(function(err) { + dashd.start(function (err) { should.not.exist(err); dashd.nodes.length.should.equal(1); done(); }); }); - it('will push node from connectProcess', function(done) { + it("will push node from connectProcess", function (done) { var dashd = new DashService(baseConfig); dashd._initChain = sinon.stub().callsArg(0); var nodes = [{}]; dashd._connectProcess = sinon.stub().callsArgWith(1, null, nodes); dashd.options = { - connect: [ - {} - ] + connect: [{}], }; - dashd.start(function(err) { + dashd.start(function (err) { should.not.exist(err); dashd._connectProcess.callCount.should.equal(1); dashd.nodes.length.should.equal(1); @@ -2211,20 +2223,20 @@ describe('Dash Service', function() { }); }); - describe('#isSynced', function() { - it('will give error from syncPercentage', function(done) { + describe("#isSynced", function () { + it("will give error from syncPercentage", function (done) { var dashd = new DashService(baseConfig); - dashd.syncPercentage = sinon.stub().callsArgWith(0, new Error('test')); - dashd.isSynced(function(err) { + dashd.syncPercentage = sinon.stub().callsArgWith(0, new Error("test")); + dashd.isSynced(function (err) { should.exist(err); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will give "true" if percentage is 100.00', function(done) { + it('will give "true" if percentage is 100.00', function (done) { var dashd = new DashService(baseConfig); - dashd.syncPercentage = sinon.stub().callsArgWith(0, null, 100.00); - dashd.isSynced(function(err, synced) { + dashd.syncPercentage = sinon.stub().callsArgWith(0, null, 100.0); + dashd.isSynced(function (err, synced) { if (err) { return done(err); } @@ -2232,10 +2244,10 @@ describe('Dash Service', function() { done(); }); }); - it('will give "true" if percentage is 99.98', function(done) { + it('will give "true" if percentage is 99.98', function (done) { var dashd = new DashService(baseConfig); dashd.syncPercentage = sinon.stub().callsArgWith(0, null, 99.98); - dashd.isSynced(function(err, synced) { + dashd.isSynced(function (err, synced) { if (err) { return done(err); } @@ -2243,10 +2255,10 @@ describe('Dash Service', function() { done(); }); }); - it('will give "false" if percentage is 99.49', function(done) { + it('will give "false" if percentage is 99.49', function (done) { var dashd = new DashService(baseConfig); dashd.syncPercentage = sinon.stub().callsArgWith(0, null, 99.49); - dashd.isSynced(function(err, synced) { + dashd.isSynced(function (err, synced) { if (err) { return done(err); } @@ -2254,10 +2266,10 @@ describe('Dash Service', function() { done(); }); }); - it('will give "false" if percentage is 1', function(done) { + it('will give "false" if percentage is 1', function (done) { var dashd = new DashService(baseConfig); dashd.syncPercentage = sinon.stub().callsArgWith(0, null, 1); - dashd.isSynced(function(err, synced) { + dashd.isSynced(function (err, synced) { if (err) { return done(err); } @@ -2267,34 +2279,34 @@ describe('Dash Service', function() { }); }); - describe('#syncPercentage', function() { - it('will give rpc error', function(done) { + describe("#syncPercentage", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var getBlockchainInfo = sinon.stub().callsArgWith(0, {message: 'error', code: -1}); + var getBlockchainInfo = sinon.stub().callsArgWith(0, { message: "error", code: -1 }); dashd.nodes.push({ client: { - getBlockchainInfo: getBlockchainInfo - } + getBlockchainInfo: getBlockchainInfo, + }, }); - dashd.syncPercentage(function(err) { + dashd.syncPercentage(function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will call client getInfo and give result', function(done) { + it("will call client getInfo and give result", function (done) { var dashd = new DashService(baseConfig); var getBlockchainInfo = sinon.stub().callsArgWith(0, null, { result: { - verificationprogress: '0.983821387' - } + verificationprogress: "0.983821387", + }, }); dashd.nodes.push({ client: { - getBlockchainInfo: getBlockchainInfo - } + getBlockchainInfo: getBlockchainInfo, + }, }); - dashd.syncPercentage(function(err, percentage) { + dashd.syncPercentage(function (err, percentage) { if (err) { return done(err); } @@ -2304,56 +2316,56 @@ describe('Dash Service', function() { }); }); - describe('#_normalizeAddressArg', function() { - it('will turn single address into array', function() { + describe("#_normalizeAddressArg", function () { + it("will turn single address into array", function () { var dashd = new DashService(baseConfig); - var args = dashd._normalizeAddressArg('address'); - args.should.deep.equal(['address']); + var args = dashd._normalizeAddressArg("address"); + args.should.deep.equal(["address"]); }); - it('will keep an array as an array', function() { + it("will keep an array as an array", function () { var dashd = new DashService(baseConfig); - var args = dashd._normalizeAddressArg(['address', 'address']); - args.should.deep.equal(['address', 'address']); + var args = dashd._normalizeAddressArg(["address", "address"]); + args.should.deep.equal(["address", "address"]); }); }); - describe('#getAddressBalance', function() { - it('will give rpc error', function(done) { + describe("#getAddressBalance", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getAddressBalance: sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}) - } + getAddressBalance: sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }), + }, }); - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; var options = {}; - dashd.getAddressBalance(address, options, function(err) { + dashd.getAddressBalance(address, options, function (err) { err.should.be.instanceof(Error); done(); }); }); - it('will give balance', function(done) { + it("will give balance", function (done) { var dashd = new DashService(baseConfig); var getAddressBalance = sinon.stub().callsArgWith(1, null, { result: { received: 100000, - balance: 10000 - } + balance: 10000, + }, }); dashd.nodes.push({ client: { - getAddressBalance: getAddressBalance - } + getAddressBalance: getAddressBalance, + }, }); - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; var options = {}; - dashd.getAddressBalance(address, options, function(err, data) { + dashd.getAddressBalance(address, options, function (err, data) { if (err) { return done(err); } data.balance.should.equal(10000); data.received.should.equal(100000); - dashd.getAddressBalance(address, options, function(err, data2) { + dashd.getAddressBalance(address, options, function (err, data2) { if (err) { return done(err); } @@ -2366,48 +2378,48 @@ describe('Dash Service', function() { }); }); - describe('#getAddressUnspentOutputs', function() { - it('will give rpc error', function(done) { + describe("#getAddressUnspentOutputs", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getAddressUtxos: sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}) - } + getAddressUtxos: sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }), + }, }); var options = { - queryMempool: false + queryMempool: false, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err) { should.exist(err); err.should.be.instanceof(errors.RPCError); done(); }); }); - it('will give results from client getaddressutxos', function(done) { + it("will give results from client getaddressutxos", function (done) { var dashd = new DashService(baseConfig); var expectedUtxos = [ { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 1, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 7679241, - height: 207111 - } + height: 207111, + }, ]; dashd.nodes.push({ client: { getAddressUtxos: sinon.stub().callsArgWith(1, null, { - result: expectedUtxos - }) - } + result: expectedUtxos, + }), + }, }); var options = { - queryMempool: false + queryMempool: false, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } @@ -2416,38 +2428,38 @@ describe('Dash Service', function() { done(); }); }); - it('will use cache', function(done) { + it("will use cache", function (done) { var dashd = new DashService(baseConfig); var expectedUtxos = [ { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 1, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 7679241, - height: 207111 - } + height: 207111, + }, ]; var getAddressUtxos = sinon.stub().callsArgWith(1, null, { - result: expectedUtxos + result: expectedUtxos, }); dashd.nodes.push({ client: { - getAddressUtxos: getAddressUtxos - } + getAddressUtxos: getAddressUtxos, + }, }); var options = { - queryMempool: false + queryMempool: false, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } utxos.length.should.equal(1); utxos.should.deep.equal(expectedUtxos); getAddressUtxos.callCount.should.equal(1); - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } @@ -2458,76 +2470,76 @@ describe('Dash Service', function() { }); }); }); - it('will update with mempool results', function(done) { + it("will update with mempool results", function (done) { var deltas = [ { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 1 + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 1, }, { - txid: 'f637384e9f81f18767ea50e00bce58fc9848b6588a1130529eebba22a410155f', + txid: "f637384e9f81f18767ea50e00bce58fc9848b6588a1130529eebba22a410155f", satoshis: 100000, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, - timestamp: 1461342833133 + timestamp: 1461342833133, }, { - txid: 'f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345', + txid: "f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345", satoshis: 400000, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 1, - timestamp: 1461342954813 - } + timestamp: 1461342954813, + }, ]; var dashd = new DashService(baseConfig); var confirmedUtxos = [ { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 1, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 7679241, - height: 207111 - } + height: 207111, + }, ]; var expectedUtxos = [ { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", outputIndex: 1, satoshis: 400000, - script: '76a914809dc14496f99b6deb722cf46d89d22f4beb8efd88ac', + script: "76a914809dc14496f99b6deb722cf46d89d22f4beb8efd88ac", timestamp: 1461342954813, - txid: 'f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345' + txid: "f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345", }, { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", outputIndex: 0, satoshis: 100000, - script: '76a914809dc14496f99b6deb722cf46d89d22f4beb8efd88ac', + script: "76a914809dc14496f99b6deb722cf46d89d22f4beb8efd88ac", timestamp: 1461342833133, - txid: 'f637384e9f81f18767ea50e00bce58fc9848b6588a1130529eebba22a410155f' - } + txid: "f637384e9f81f18767ea50e00bce58fc9848b6588a1130529eebba22a410155f", + }, ]; dashd.nodes.push({ client: { getAddressUtxos: sinon.stub().callsArgWith(1, null, { - result: confirmedUtxos + result: confirmedUtxos, }), getAddressMempool: sinon.stub().callsArgWith(1, null, { - result: deltas - }) - } + result: deltas, + }), + }, }); var options = { - queryMempool: true + queryMempool: true, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } @@ -2536,61 +2548,61 @@ describe('Dash Service', function() { done(); }); }); - it('will update with mempool results with multiple outputs', function(done) { + it("will update with mempool results with multiple outputs", function (done) { var deltas = [ { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 1 + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 1, }, { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 1, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 2 - } + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 2, + }, ]; var dashd = new DashService(baseConfig); var confirmedUtxos = [ { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 1, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 7679241, - height: 207111 + height: 207111, }, { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 2, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 7679241, - height: 207111 - } + height: 207111, + }, ]; dashd.nodes.push({ client: { getAddressUtxos: sinon.stub().callsArgWith(1, null, { - result: confirmedUtxos + result: confirmedUtxos, }), getAddressMempool: sinon.stub().callsArgWith(1, null, { - result: deltas - }) - } + result: deltas, + }), + }, }); var options = { - queryMempool: true + queryMempool: true, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } @@ -2598,86 +2610,86 @@ describe('Dash Service', function() { done(); }); }); - it('three confirmed utxos -> one utxo after mempool', function(done) { + it("three confirmed utxos -> one utxo after mempool", function (done) { var deltas = [ { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 0 + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 0, }, { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 1 + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 1, }, { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 1, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 2 + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 2, }, { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: 100000, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 1, - script: '76a914809dc14496f99b6deb722cf46d89d22f4beb8efd88ac', - timestamp: 1461342833133 - } + script: "76a914809dc14496f99b6deb722cf46d89d22f4beb8efd88ac", + timestamp: 1461342833133, + }, ]; var dashd = new DashService(baseConfig); var confirmedUtxos = [ { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 0, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 7679241, - height: 207111 + height: 207111, }, { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 1, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 7679241, - height: 207111 + height: 207111, }, { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 2, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 7679241, - height: 207111 - } + height: 207111, + }, ]; dashd.nodes.push({ client: { getAddressUtxos: sinon.stub().callsArgWith(1, null, { - result: confirmedUtxos + result: confirmedUtxos, }), getAddressMempool: sinon.stub().callsArgWith(1, null, { - result: deltas - }) - } + result: deltas, + }), + }, }); var options = { - queryMempool: true + queryMempool: true, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } @@ -2685,131 +2697,131 @@ describe('Dash Service', function() { done(); }); }); - it('spending utxos in the mempool', function(done) { + it("spending utxos in the mempool", function (done) { var deltas = [ { - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", satoshis: 7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, - timestamp: 1461342707724 + timestamp: 1461342707724, }, { - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", satoshis: 7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 1, - timestamp: 1461342707724 + timestamp: 1461342707724, }, { - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", satoshis: 7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", timestamp: 1461342707724, index: 2, }, { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 0 + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 0, }, { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 1 + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 1, }, { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: -7679241, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 1, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 2 + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 2, }, { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: 100000, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 1, - timestamp: 1461342833133 - } + timestamp: 1461342833133, + }, ]; var dashd = new DashService(baseConfig); var confirmedUtxos = []; dashd.nodes.push({ client: { getAddressUtxos: sinon.stub().callsArgWith(1, null, { - result: confirmedUtxos + result: confirmedUtxos, }), getAddressMempool: sinon.stub().callsArgWith(1, null, { - result: deltas - }) - } + result: deltas, + }), + }, }); var options = { - queryMempool: true + queryMempool: true, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } utxos.length.should.equal(1); utxos[0].address.should.equal(address); - utxos[0].txid.should.equal('e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce'); + utxos[0].txid.should.equal("e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce"); utxos[0].outputIndex.should.equal(1); - utxos[0].script.should.equal('76a914809dc14496f99b6deb722cf46d89d22f4beb8efd88ac'); + utxos[0].script.should.equal("76a914809dc14496f99b6deb722cf46d89d22f4beb8efd88ac"); utxos[0].timestamp.should.equal(1461342833133); done(); }); }); - it('will update with mempool results spending zero value output (likely never to happen)', function(done) { + it("will update with mempool results spending zero value output (likely never to happen)", function (done) { var deltas = [ { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: 0, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, timestamp: 1461342707725, - prevtxid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', - prevout: 1 - } + prevtxid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", + prevout: 1, + }, ]; var dashd = new DashService(baseConfig); var confirmedUtxos = [ { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 1, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 0, - height: 207111 - } + height: 207111, + }, ]; dashd.nodes.push({ client: { getAddressUtxos: sinon.stub().callsArgWith(1, null, { - result: confirmedUtxos + result: confirmedUtxos, }), getAddressMempool: sinon.stub().callsArgWith(1, null, { - result: deltas - }) - } + result: deltas, + }), + }, }); var options = { - queryMempool: true + queryMempool: true, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } @@ -2817,42 +2829,42 @@ describe('Dash Service', function() { done(); }); }); - it('will not filter results if mempool is not spending', function(done) { + it("will not filter results if mempool is not spending", function (done) { var deltas = [ { - txid: 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', + txid: "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", satoshis: 10000, - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", index: 0, - timestamp: 1461342707725 - } + timestamp: 1461342707725, + }, ]; var dashd = new DashService(baseConfig); var confirmedUtxos = [ { - address: 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs', - txid: '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0', + address: "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs", + txid: "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0", outputIndex: 1, - script: '76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac', + script: "76a914f399b4b8894f1153b96fce29f05e6e116eb4c21788ac", satoshis: 0, - height: 207111 - } + height: 207111, + }, ]; dashd.nodes.push({ client: { getAddressUtxos: sinon.stub().callsArgWith(1, null, { - result: confirmedUtxos + result: confirmedUtxos, }), getAddressMempool: sinon.stub().callsArgWith(1, null, { - result: deltas - }) - } + result: deltas, + }), + }, }); var options = { - queryMempool: true + queryMempool: true, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err, utxos) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err, utxos) { if (err) { return done(err); } @@ -2860,41 +2872,41 @@ describe('Dash Service', function() { done(); }); }); - it('it will handle error from getAddressMempool', function(done) { + it("it will handle error from getAddressMempool", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getAddressMempool: sinon.stub().callsArgWith(1, {code: -1, message: 'test'}) - } + getAddressMempool: sinon.stub().callsArgWith(1, { code: -1, message: "test" }), + }, }); var options = { - queryMempool: true + queryMempool: true, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err) { err.should.be.instanceOf(Error); done(); }); }); - it('should set query mempool if undefined', function(done) { + it("should set query mempool if undefined", function (done) { var dashd = new DashService(baseConfig); - var getAddressMempool = sinon.stub().callsArgWith(1, {code: -1, message: 'test'}); + var getAddressMempool = sinon.stub().callsArgWith(1, { code: -1, message: "test" }); dashd.nodes.push({ client: { - getAddressMempool: getAddressMempool - } + getAddressMempool: getAddressMempool, + }, }); var options = {}; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressUnspentOutputs(address, options, function(err) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressUnspentOutputs(address, options, function (err) { getAddressMempool.callCount.should.equal(1); done(); }); }); }); - describe('#_getBalanceFromMempool', function() { - it('will sum satoshis', function() { + describe("#_getBalanceFromMempool", function () { + it("will sum satoshis", function () { var dashd = new DashService(baseConfig); var deltas = [ { @@ -2905,152 +2917,152 @@ describe('Dash Service', function() { }, { satoshis: -10, - } + }, ]; var sum = dashd._getBalanceFromMempool(deltas); sum.should.equal(990); }); }); - describe('#_getTxidsFromMempool', function() { - it('will filter to txids', function() { + describe("#_getTxidsFromMempool", function () { + it("will filter to txids", function () { var dashd = new DashService(baseConfig); var deltas = [ { - txid: 'txid0', + txid: "txid0", }, { - txid: 'txid1', + txid: "txid1", }, { - txid: 'txid2', - } + txid: "txid2", + }, ]; var txids = dashd._getTxidsFromMempool(deltas); txids.length.should.equal(3); - txids[0].should.equal('txid0'); - txids[1].should.equal('txid1'); - txids[2].should.equal('txid2'); + txids[0].should.equal("txid0"); + txids[1].should.equal("txid1"); + txids[2].should.equal("txid2"); }); - it('will not include duplicates', function() { + it("will not include duplicates", function () { var dashd = new DashService(baseConfig); var deltas = [ { - txid: 'txid0', + txid: "txid0", }, { - txid: 'txid0', + txid: "txid0", }, { - txid: 'txid1', - } + txid: "txid1", + }, ]; var txids = dashd._getTxidsFromMempool(deltas); txids.length.should.equal(2); - txids[0].should.equal('txid0'); - txids[1].should.equal('txid1'); + txids[0].should.equal("txid0"); + txids[1].should.equal("txid1"); }); }); - describe('#_getHeightRangeQuery', function() { - it('will detect range query', function() { + describe("#_getHeightRangeQuery", function () { + it("will detect range query", function () { var dashd = new DashService(baseConfig); var options = { start: 20, - end: 0 + end: 0, }; var rangeQuery = dashd._getHeightRangeQuery(options); rangeQuery.should.equal(true); }); - it('will get range properties', function() { + it("will get range properties", function () { var dashd = new DashService(baseConfig); var options = { start: 20, - end: 0 + end: 0, }; var clone = {}; dashd._getHeightRangeQuery(options, clone); clone.end.should.equal(20); clone.start.should.equal(0); }); - it('will throw error with invalid range', function() { + it("will throw error with invalid range", function () { var dashd = new DashService(baseConfig); var options = { start: 0, - end: 20 + end: 20, }; - (function() { + (function () { dashd._getHeightRangeQuery(options); }).should.throw('"end" is expected'); }); }); - describe('#getAddressTxids', function() { - it('will give error from _getHeightRangeQuery', function(done) { + describe("#getAddressTxids", function () { + it("will give error from _getHeightRangeQuery", function (done) { var dashd = new DashService(baseConfig); - dashd._getHeightRangeQuery = sinon.stub().throws(new Error('test')); - dashd.getAddressTxids('address', {}, function(err) { + dashd._getHeightRangeQuery = sinon.stub().throws(new Error("test")); + dashd.getAddressTxids("address", {}, function (err) { err.should.be.instanceOf(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will give rpc error from mempool query', function() { + it("will give rpc error from mempool query", function () { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getAddressMempool: sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}) - } + getAddressMempool: sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }), + }, }); var options = {}; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressTxids(address, options, function(err) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressTxids(address, options, function (err) { should.exist(err); err.should.be.instanceof(errors.RPCError); }); }); - it('will give rpc error from txids query', function() { + it("will give rpc error from txids query", function () { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getAddressTxids: sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}) - } + getAddressTxids: sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }), + }, }); var options = { - queryMempool: false + queryMempool: false, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressTxids(address, options, function(err) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressTxids(address, options, function (err) { should.exist(err); err.should.be.instanceof(errors.RPCError); }); }); - it('will get txid results', function(done) { + it("will get txid results", function (done) { var expectedTxids = [ - 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', - 'f637384e9f81f18767ea50e00bce58fc9848b6588a1130529eebba22a410155f', - 'f3c1ba3ef86a0420d6102e40e2cfc8682632ab95d09d86a27f5d466b9fa9da47', - '56fafeb01961831b926558d040c246b97709fd700adcaa916541270583e8e579', - 'bc992ad772eb02864db07ef248d31fb3c6826d25f1153ebf8c79df9b7f70fcf2', - 'f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345', - 'f35e7e2a2334e845946f3eaca76890d9a68f4393ccc9fe37a0c2fb035f66d2e9', - 'edc080f2084eed362aa488ccc873a24c378dc0979aa29b05767517b70569414a', - 'ed11a08e3102f9610bda44c80c46781d97936a4290691d87244b1b345b39a693', - 'ec94d845c603f292a93b7c829811ac624b76e52b351617ca5a758e9d61a11681' + "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", + "f637384e9f81f18767ea50e00bce58fc9848b6588a1130529eebba22a410155f", + "f3c1ba3ef86a0420d6102e40e2cfc8682632ab95d09d86a27f5d466b9fa9da47", + "56fafeb01961831b926558d040c246b97709fd700adcaa916541270583e8e579", + "bc992ad772eb02864db07ef248d31fb3c6826d25f1153ebf8c79df9b7f70fcf2", + "f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345", + "f35e7e2a2334e845946f3eaca76890d9a68f4393ccc9fe37a0c2fb035f66d2e9", + "edc080f2084eed362aa488ccc873a24c378dc0979aa29b05767517b70569414a", + "ed11a08e3102f9610bda44c80c46781d97936a4290691d87244b1b345b39a693", + "ec94d845c603f292a93b7c829811ac624b76e52b351617ca5a758e9d61a11681", ]; var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { getAddressTxids: sinon.stub().callsArgWith(1, null, { - result: expectedTxids.reverse() - }) - } + result: expectedTxids.reverse(), + }), + }, }); var options = { - queryMempool: false + queryMempool: false, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressTxids(address, options, function(err, txids) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressTxids(address, options, function (err, txids) { if (err) { return done(err); } @@ -3059,31 +3071,29 @@ describe('Dash Service', function() { done(); }); }); - it('will get txid results from cache', function(done) { - var expectedTxids = [ - 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce' - ]; + it("will get txid results from cache", function (done) { + var expectedTxids = ["e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce"]; var dashd = new DashService(baseConfig); var getAddressTxids = sinon.stub().callsArgWith(1, null, { - result: expectedTxids.reverse() + result: expectedTxids.reverse(), }); dashd.nodes.push({ client: { - getAddressTxids: getAddressTxids - } + getAddressTxids: getAddressTxids, + }, }); var options = { - queryMempool: false + queryMempool: false, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressTxids(address, options, function(err, txids) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressTxids(address, options, function (err, txids) { if (err) { return done(err); } getAddressTxids.callCount.should.equal(1); txids.should.deep.equal(expectedTxids); - dashd.getAddressTxids(address, options, function(err, txids) { + dashd.getAddressTxids(address, options, function (err, txids) { if (err) { return done(err); } @@ -3093,28 +3103,26 @@ describe('Dash Service', function() { }); }); }); - it('will get txid results WITHOUT cache if rangeQuery and exclude mempool', function(done) { - var expectedTxids = [ - 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce' - ]; + it("will get txid results WITHOUT cache if rangeQuery and exclude mempool", function (done) { + var expectedTxids = ["e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce"]; var dashd = new DashService(baseConfig); var getAddressMempool = sinon.stub(); var getAddressTxids = sinon.stub().callsArgWith(1, null, { - result: expectedTxids.reverse() + result: expectedTxids.reverse(), }); dashd.nodes.push({ client: { getAddressTxids: getAddressTxids, - getAddressMempool: getAddressMempool - } + getAddressMempool: getAddressMempool, + }, }); var options = { queryMempool: true, // start and end will exclude mempool start: 4, - end: 2 + end: 2, }; - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressTxids(address, options, function(err, txids) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressTxids(address, options, function (err, txids) { if (err) { return done(err); } @@ -3122,7 +3130,7 @@ describe('Dash Service', function() { getAddressMempool.callCount.should.equal(0); txids.should.deep.equal(expectedTxids); - dashd.getAddressTxids(address, options, function(err, txids) { + dashd.getAddressTxids(address, options, function (err, txids) { if (err) { return done(err); } @@ -3133,51 +3141,49 @@ describe('Dash Service', function() { }); }); }); - it('will get txid results from cache and live mempool', function(done) { - var expectedTxids = [ - 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce' - ]; + it("will get txid results from cache and live mempool", function (done) { + var expectedTxids = ["e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce"]; var dashd = new DashService(baseConfig); var getAddressTxids = sinon.stub().callsArgWith(1, null, { - result: expectedTxids.reverse() + result: expectedTxids.reverse(), }); var getAddressMempool = sinon.stub().callsArgWith(1, null, { result: [ { - txid: 'bc992ad772eb02864db07ef248d31fb3c6826d25f1153ebf8c79df9b7f70fcf2' + txid: "bc992ad772eb02864db07ef248d31fb3c6826d25f1153ebf8c79df9b7f70fcf2", }, { - txid: 'f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345' + txid: "f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345", }, { - txid: 'f35e7e2a2334e845946f3eaca76890d9a68f4393ccc9fe37a0c2fb035f66d2e9' - } - ] + txid: "f35e7e2a2334e845946f3eaca76890d9a68f4393ccc9fe37a0c2fb035f66d2e9", + }, + ], }); dashd.nodes.push({ client: { getAddressTxids: getAddressTxids, - getAddressMempool: getAddressMempool - } + getAddressMempool: getAddressMempool, + }, }); - var address = 'XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs'; - dashd.getAddressTxids(address, {queryMempool: false}, function(err, txids) { + var address = "XnQuJpAgEDNtRwoXWLfuEs69cMgCYS8rgs"; + dashd.getAddressTxids(address, { queryMempool: false }, function (err, txids) { if (err) { return done(err); } getAddressTxids.callCount.should.equal(1); txids.should.deep.equal(expectedTxids); - dashd.getAddressTxids(address, {queryMempool: true}, function(err, txids) { + dashd.getAddressTxids(address, { queryMempool: true }, function (err, txids) { if (err) { return done(err); } getAddressTxids.callCount.should.equal(1); txids.should.deep.equal([ - 'f35e7e2a2334e845946f3eaca76890d9a68f4393ccc9fe37a0c2fb035f66d2e9', // mempool - 'f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345', // mempool - 'bc992ad772eb02864db07ef248d31fb3c6826d25f1153ebf8c79df9b7f70fcf2', // mempool - 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce' // confirmed + "f35e7e2a2334e845946f3eaca76890d9a68f4393ccc9fe37a0c2fb035f66d2e9", // mempool + "f71bccef3a8f5609c7f016154922adbfe0194a96fb17a798c24077c18d0a9345", // mempool + "bc992ad772eb02864db07ef248d31fb3c6826d25f1153ebf8c79df9b7f70fcf2", // mempool + "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", // confirmed ]); done(); }); @@ -3185,15 +3191,15 @@ describe('Dash Service', function() { }); }); - describe('#_getConfirmationDetail', function() { + describe("#_getConfirmationDetail", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'warn'); + beforeEach(function () { + sandbox.stub(log, "warn"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); - it('should get 0 confirmation', function() { + it("should get 0 confirmation", function () { var tx = new Transaction(txhex); tx.height = -1; var dashd = new DashService(baseConfig); @@ -3201,7 +3207,7 @@ describe('Dash Service', function() { var confirmations = dashd._getConfirmationsDetail(tx); confirmations.should.equal(0); }); - it('should get 1 confirmation', function() { + it("should get 1 confirmation", function () { var tx = new Transaction(txhex); tx.height = 10; var dashd = new DashService(baseConfig); @@ -3209,7 +3215,7 @@ describe('Dash Service', function() { var confirmations = dashd._getConfirmationsDetail(tx); confirmations.should.equal(1); }); - it('should get 2 confirmation', function() { + it("should get 2 confirmation", function () { var dashd = new DashService(baseConfig); var tx = new Transaction(txhex); dashd.height = 11; @@ -3217,7 +3223,7 @@ describe('Dash Service', function() { var confirmations = dashd._getConfirmationsDetail(tx); confirmations.should.equal(2); }); - it('should get 0 confirmation with overflow', function() { + it("should get 0 confirmation with overflow", function () { var dashd = new DashService(baseConfig); var tx = new Transaction(txhex); dashd.height = 3; @@ -3226,7 +3232,7 @@ describe('Dash Service', function() { log.warn.callCount.should.equal(1); confirmations.should.equal(0); }); - it('should get 1000 confirmation', function() { + it("should get 1000 confirmation", function () { var dashd = new DashService(baseConfig); var tx = new Transaction(txhex); dashd.height = 1000; @@ -3236,148 +3242,176 @@ describe('Dash Service', function() { }); }); - describe('#_getAddressDetailsForInput', function() { - it('will return if missing an address', function() { + describe("#_getAddressDetailsForInput", function () { + it("will return if missing an address", function () { var dashd = new DashService(baseConfig); var result = {}; dashd._getAddressDetailsForInput({}, 0, result, []); should.not.exist(result.addresses); should.not.exist(result.satoshis); }); - it('will only add address if it matches', function() { + it("will only add address if it matches", function () { var dashd = new DashService(baseConfig); var result = {}; - dashd._getAddressDetailsForInput({ - address: 'address1' - }, 0, result, ['address2']); + dashd._getAddressDetailsForInput( + { + address: "address1", + }, + 0, + result, + ["address2"] + ); should.not.exist(result.addresses); should.not.exist(result.satoshis); }); - it('will instantiate if outputIndexes not defined', function() { + it("will instantiate if outputIndexes not defined", function () { var dashd = new DashService(baseConfig); var result = { - addresses: {} + addresses: {}, }; - dashd._getAddressDetailsForInput({ - address: 'address1' - }, 0, result, ['address1']); + dashd._getAddressDetailsForInput( + { + address: "address1", + }, + 0, + result, + ["address1"] + ); should.exist(result.addresses); - result.addresses['address1'].inputIndexes.should.deep.equal([0]); - result.addresses['address1'].outputIndexes.should.deep.equal([]); + result.addresses["address1"].inputIndexes.should.deep.equal([0]); + result.addresses["address1"].outputIndexes.should.deep.equal([]); }); - it('will push to inputIndexes', function() { + it("will push to inputIndexes", function () { var dashd = new DashService(baseConfig); var result = { addresses: { - 'address1': { - inputIndexes: [1] - } - } + address1: { + inputIndexes: [1], + }, + }, }; - dashd._getAddressDetailsForInput({ - address: 'address1' - }, 2, result, ['address1']); + dashd._getAddressDetailsForInput( + { + address: "address1", + }, + 2, + result, + ["address1"] + ); should.exist(result.addresses); - result.addresses['address1'].inputIndexes.should.deep.equal([1, 2]); + result.addresses["address1"].inputIndexes.should.deep.equal([1, 2]); }); }); - describe('#_getAddressDetailsForOutput', function() { - it('will return if missing an address', function() { + describe("#_getAddressDetailsForOutput", function () { + it("will return if missing an address", function () { var dashd = new DashService(baseConfig); var result = {}; dashd._getAddressDetailsForOutput({}, 0, result, []); should.not.exist(result.addresses); should.not.exist(result.satoshis); }); - it('will only add address if it matches', function() { + it("will only add address if it matches", function () { var dashd = new DashService(baseConfig); var result = {}; - dashd._getAddressDetailsForOutput({ - address: 'address1' - }, 0, result, ['address2']); + dashd._getAddressDetailsForOutput( + { + address: "address1", + }, + 0, + result, + ["address2"] + ); should.not.exist(result.addresses); should.not.exist(result.satoshis); }); - it('will instantiate if outputIndexes not defined', function() { + it("will instantiate if outputIndexes not defined", function () { var dashd = new DashService(baseConfig); var result = { - addresses: {} + addresses: {}, }; - dashd._getAddressDetailsForOutput({ - address: 'address1' - }, 0, result, ['address1']); + dashd._getAddressDetailsForOutput( + { + address: "address1", + }, + 0, + result, + ["address1"] + ); should.exist(result.addresses); - result.addresses['address1'].inputIndexes.should.deep.equal([]); - result.addresses['address1'].outputIndexes.should.deep.equal([0]); + result.addresses["address1"].inputIndexes.should.deep.equal([]); + result.addresses["address1"].outputIndexes.should.deep.equal([0]); }); - it('will push if outputIndexes defined', function() { + it("will push if outputIndexes defined", function () { var dashd = new DashService(baseConfig); var result = { addresses: { - 'address1': { - outputIndexes: [0] - } - } + address1: { + outputIndexes: [0], + }, + }, }; - dashd._getAddressDetailsForOutput({ - address: 'address1' - }, 1, result, ['address1']); + dashd._getAddressDetailsForOutput( + { + address: "address1", + }, + 1, + result, + ["address1"] + ); should.exist(result.addresses); - result.addresses['address1'].outputIndexes.should.deep.equal([0, 1]); + result.addresses["address1"].outputIndexes.should.deep.equal([0, 1]); }); }); - describe('#_getAddressDetailsForTransaction', function() { - it('will calculate details for the transaction', function(done) { + describe("#_getAddressDetailsForTransaction", function () { + it("will calculate details for the transaction", function (done) { /* jshint sub:true */ var tx = { inputs: [ { satoshis: 1000000000, - address: 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW' - } + address: "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW", + }, ], outputs: [ { satoshis: 100000000, - address: 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW' + address: "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW", }, { satoshis: 200000000, - address: 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW' + address: "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW", }, { satoshis: 50000000, - address: 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW' + address: "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW", }, { satoshis: 300000000, - address: 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW' + address: "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW", }, { satoshis: 349990000, - address: 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW' - } + address: "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW", + }, ], - locktime: 0 + locktime: 0, }; var dashd = new DashService(baseConfig); - var addresses = ['mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW']; + var addresses = ["mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"]; var details = dashd._getAddressDetailsForTransaction(tx, addresses); - should.exist(details.addresses['mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW']); - details.addresses['mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW'].inputIndexes.should.deep.equal([0]); - details.addresses['mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW'].outputIndexes.should.deep.equal([ - 0, 1, 2, 3, 4 - ]); + should.exist(details.addresses["mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"]); + details.addresses["mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"].inputIndexes.should.deep.equal([0]); + details.addresses["mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"].outputIndexes.should.deep.equal([0, 1, 2, 3, 4]); details.satoshis.should.equal(-10000); done(); }); }); - describe('#_getAddressDetailedTransaction', function() { - it('will get detailed transaction info', function(done) { - var txid = '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0'; + describe("#_getAddressDetailedTransaction", function () { + it("will get detailed transaction info", function (done) { + var txid = "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0"; var tx = { height: 20, }; @@ -3389,7 +3423,7 @@ describe('Dash Service', function() { addresses: addresses, satoshis: 1000, }); - dashd._getAddressDetailedTransaction(txid, {}, function(err, details) { + dashd._getAddressDetailedTransaction(txid, {}, function (err, details) { if (err) { return done(err); } @@ -3400,237 +3434,228 @@ describe('Dash Service', function() { done(); }); }); - it('give error from getDetailedTransaction', function(done) { - var txid = '46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0'; + it("give error from getDetailedTransaction", function (done) { + var txid = "46f24e0c274fc07708b781963576c4c5d5625d926dbb0a17fa865dcd9fe58ea0"; var dashd = new DashService(baseConfig); - dashd.getDetailedTransaction = sinon.stub().callsArgWith(1, new Error('test')); - dashd._getAddressDetailedTransaction(txid, {}, function(err) { + dashd.getDetailedTransaction = sinon.stub().callsArgWith(1, new Error("test")); + dashd._getAddressDetailedTransaction(txid, {}, function (err) { err.should.be.instanceof(Error); done(); }); }); }); - describe('#_getAddressStrings', function() { - it('will get address strings from dashcore addresses', function() { + describe("#_getAddressStrings", function () { + it("will get address strings from dashcore addresses", function () { var addresses = [ - dashcore.Address('XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN'), - dashcore.Address('7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz'), + dashcore.Address("XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN"), + dashcore.Address("7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz"), ]; var dashd = new DashService(baseConfig); var strings = dashd._getAddressStrings(addresses); - strings[0].should.equal('XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN'); - strings[1].should.equal('7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz'); + strings[0].should.equal("XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN"); + strings[1].should.equal("7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz"); }); - it('will get address strings from strings', function() { - var addresses = [ - 'XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN', - '7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz', - ]; + it("will get address strings from strings", function () { + var addresses = ["XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN", "7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz"]; var dashd = new DashService(baseConfig); var strings = dashd._getAddressStrings(addresses); - strings[0].should.equal('XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN'); - strings[1].should.equal('7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz'); + strings[0].should.equal("XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN"); + strings[1].should.equal("7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz"); }); - it('will get address strings from mixture of types', function() { - var addresses = [ - dashcore.Address('XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN'), - '7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz', - ]; + it("will get address strings from mixture of types", function () { + var addresses = [dashcore.Address("XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN"), "7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz"]; var dashd = new DashService(baseConfig); var strings = dashd._getAddressStrings(addresses); - strings[0].should.equal('XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN'); - strings[1].should.equal('7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz'); + strings[0].should.equal("XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN"); + strings[1].should.equal("7d5169eBcGHF4BYC6DTffTyeCpWbrZnNgz"); }); - it('will give error with unknown', function() { - var addresses = [ - dashcore.Address('XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN'), - 0, - ]; + it("will give error with unknown", function () { + var addresses = [dashcore.Address("XjxDQFjTNEP9dcrJhBLvy5i1Dobz4x1LJN"), 0]; var dashd = new DashService(baseConfig); - (function() { + (function () { dashd._getAddressStrings(addresses); }).should.throw(TypeError); }); }); - describe('#_paginate', function() { - it('slice txids based on "from" and "to" (3 to 13)', function() { + describe("#_paginate", function () { + it('slice txids based on "from" and "to" (3 to 13)', function () { var dashd = new DashService(baseConfig); var txids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var paginated = dashd._paginate(txids, 3, 13); paginated.should.deep.equal([3, 4, 5, 6, 7, 8, 9, 10]); }); - it('slice txids based on "from" and "to" (0 to 3)', function() { + it('slice txids based on "from" and "to" (0 to 3)', function () { var dashd = new DashService(baseConfig); var txids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var paginated = dashd._paginate(txids, 0, 3); paginated.should.deep.equal([0, 1, 2]); }); - it('slice txids based on "from" and "to" (0 to 1)', function() { + it('slice txids based on "from" and "to" (0 to 1)', function () { var dashd = new DashService(baseConfig); var txids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; var paginated = dashd._paginate(txids, 0, 1); paginated.should.deep.equal([0]); }); - it('will throw error if "from" is greater than "to"', function() { + it('will throw error if "from" is greater than "to"', function () { var dashd = new DashService(baseConfig); var txids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - (function() { + (function () { dashd._paginate(txids, 1, 0); }).should.throw('"from" (1) is expected to be less than "to"'); }); - it('will handle string numbers', function() { + it("will handle string numbers", function () { var dashd = new DashService(baseConfig); var txids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; - var paginated = dashd._paginate(txids, '1', '3'); + var paginated = dashd._paginate(txids, "1", "3"); paginated.should.deep.equal([1, 2]); }); }); - describe('#getAddressHistory', function() { - var address = 'XcHw3hNN293dY1AYrbeBrP1sB6vsugTQTz'; - it('will give error with "from" and "to" range that exceeds max size', function(done) { + describe("#getAddressHistory", function () { + var address = "XcHw3hNN293dY1AYrbeBrP1sB6vsugTQTz"; + it('will give error with "from" and "to" range that exceeds max size', function (done) { var dashd = new DashService(baseConfig); - dashd.getAddressHistory(address, {from: 0, to: 51}, function(err) { + dashd.getAddressHistory(address, { from: 0, to: 51 }, function (err) { should.exist(err); err.message.match(/^\"from/); done(); }); }); - it('will give error with "from" and "to" order is reversed', function(done) { + it('will give error with "from" and "to" order is reversed', function (done) { var dashd = new DashService(baseConfig); dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, []); - dashd.getAddressHistory(address, {from: 51, to: 0}, function(err) { + dashd.getAddressHistory(address, { from: 51, to: 0 }, function (err) { should.exist(err); err.message.match(/^\"from/); done(); }); }); - it('will give error from _getAddressDetailedTransaction', function(done) { + it("will give error from _getAddressDetailedTransaction", function (done) { var dashd = new DashService(baseConfig); - dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, ['txid']); - dashd._getAddressDetailedTransaction = sinon.stub().callsArgWith(2, new Error('test')); - dashd.getAddressHistory(address, {}, function(err) { + dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, ["txid"]); + dashd._getAddressDetailedTransaction = sinon.stub().callsArgWith(2, new Error("test")); + dashd.getAddressHistory(address, {}, function (err) { should.exist(err); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will give an error if length of addresses is too long', function(done) { + it("will give an error if length of addresses is too long", function (done) { var addresses = []; for (var i = 0; i < 101; i++) { addresses.push(address); } var dashd = new DashService(baseConfig); dashd.maxAddressesQuery = 100; - dashd.getAddressHistory(addresses, {}, function(err) { + dashd.getAddressHistory(addresses, {}, function (err) { should.exist(err); err.message.match(/Maximum/); done(); }); }); - it('give error from getAddressTxids', function(done) { + it("give error from getAddressTxids", function (done) { var dashd = new DashService(baseConfig); - dashd.getAddressTxids = sinon.stub().callsArgWith(2, new Error('test')); - dashd.getAddressHistory('address', {}, function(err) { + dashd.getAddressTxids = sinon.stub().callsArgWith(2, new Error("test")); + dashd.getAddressHistory("address", {}, function (err) { should.exist(err); err.should.be.instanceof(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will paginate', function(done) { + it("will paginate", function (done) { var dashd = new DashService(baseConfig); - dashd._getAddressDetailedTransaction = function(txid, options, callback) { + dashd._getAddressDetailedTransaction = function (txid, options, callback) { callback(null, txid); }; - var txids = ['one', 'two', 'three', 'four']; + var txids = ["one", "two", "three", "four"]; dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, txids); - dashd.getAddressHistory('address', {from: 1, to: 3}, function(err, data) { + dashd.getAddressHistory("address", { from: 1, to: 3 }, function (err, data) { if (err) { return done(err); } data.items.length.should.equal(2); - data.items.should.deep.equal(['two', 'three']); + data.items.should.deep.equal(["two", "three"]); done(); }); }); }); - describe('#getAddressSummary', function() { - var txid1 = '70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8'; - var txid2 = '35fafaf572341798b2ce2858755afa7c8800bb6b1e885d3e030b81255b5e172d'; - var txid3 = '57b7842afc97a2b46575b490839df46e9273524c6ea59ba62e1e86477cf25247'; - var memtxid1 = 'b1bfa8dbbde790cb46b9763ef3407c1a21c8264b67bfe224f462ec0e1f569e92'; - var memtxid2 = 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce'; - it('will handle error from getAddressTxids', function(done) { + describe("#getAddressSummary", function () { + var txid1 = "70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8"; + var txid2 = "35fafaf572341798b2ce2858755afa7c8800bb6b1e885d3e030b81255b5e172d"; + var txid3 = "57b7842afc97a2b46575b490839df46e9273524c6ea59ba62e1e86477cf25247"; + var memtxid1 = "b1bfa8dbbde790cb46b9763ef3407c1a21c8264b67bfe224f462ec0e1f569e92"; + var memtxid2 = "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce"; + it("will handle error from getAddressTxids", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { getAddressMempool: sinon.stub().callsArgWith(1, null, { result: [ { - txid: '70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8', - } - ] - }) - } + txid: "70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8", + }, + ], + }), + }, }); - dashd.getAddressTxids = sinon.stub().callsArgWith(2, new Error('test')); + dashd.getAddressTxids = sinon.stub().callsArgWith(2, new Error("test")); dashd.getAddressBalance = sinon.stub().callsArgWith(2, null, {}); - var address = ''; + var address = ""; var options = {}; - dashd.getAddressSummary(address, options, function(err) { + dashd.getAddressSummary(address, options, function (err) { should.exist(err); err.should.be.instanceof(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will handle error from getAddressBalance', function(done) { + it("will handle error from getAddressBalance", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { getAddressMempool: sinon.stub().callsArgWith(1, null, { result: [ { - txid: '70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8', - } - ] - }) - } + txid: "70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8", + }, + ], + }), + }, }); dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, {}); - dashd.getAddressBalance = sinon.stub().callsArgWith(2, new Error('test'), {}); - var address = ''; + dashd.getAddressBalance = sinon.stub().callsArgWith(2, new Error("test"), {}); + var address = ""; var options = {}; - dashd.getAddressSummary(address, options, function(err) { + dashd.getAddressSummary(address, options, function (err) { should.exist(err); err.should.be.instanceof(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will handle error from client getAddressMempool', function(done) { + it("will handle error from client getAddressMempool", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getAddressMempool: sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}) - } + getAddressMempool: sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }), + }, }); dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, {}); dashd.getAddressBalance = sinon.stub().callsArgWith(2, null, {}); - var address = ''; + var address = ""; var options = {}; - dashd.getAddressSummary(address, options, function(err) { + dashd.getAddressSummary(address, options, function (err) { should.exist(err); err.should.be.instanceof(Error); - err.message.should.equal('Test error'); + err.message.should.equal("Test error"); done(); }); }); - it('should set all properties', function(done) { + it("should set all properties", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { @@ -3638,25 +3663,25 @@ describe('Dash Service', function() { result: [ { txid: memtxid1, - satoshis: -1000000 + satoshis: -1000000, }, { txid: memtxid2, - satoshis: 99999 - } - ] - }) - } + satoshis: 99999, + }, + ], + }), + }, }); - sinon.spy(dashd, '_paginate'); + sinon.spy(dashd, "_paginate"); dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, [txid1, txid2, txid3]); dashd.getAddressBalance = sinon.stub().callsArgWith(2, null, { received: 30 * 1e8, - balance: 20 * 1e8 + balance: 20 * 1e8, }); - var address = '7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT'; + var address = "7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT"; var options = {}; - dashd.getAddressSummary(address, options, function(err, summary) { + dashd.getAddressSummary(address, options, function (err, summary) { dashd._paginate.callCount.should.equal(1); dashd._paginate.args[0][1].should.equal(0); dashd._paginate.args[0][2].should.equal(1000); @@ -3667,16 +3692,16 @@ describe('Dash Service', function() { summary.unconfirmedAppearances.should.equal(2); summary.unconfirmedBalance.should.equal(-900001); summary.txids.should.deep.equal([ - 'e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce', - 'b1bfa8dbbde790cb46b9763ef3407c1a21c8264b67bfe224f462ec0e1f569e92', - '70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8', - '35fafaf572341798b2ce2858755afa7c8800bb6b1e885d3e030b81255b5e172d', - '57b7842afc97a2b46575b490839df46e9273524c6ea59ba62e1e86477cf25247' + "e9dcf22807db77ac0276b03cc2d3a8b03c4837db8ac6650501ef45af1c807cce", + "b1bfa8dbbde790cb46b9763ef3407c1a21c8264b67bfe224f462ec0e1f569e92", + "70d9d441d7409aace8e0ffe24ff0190407b2fcb405799a266e0327017288d1f8", + "35fafaf572341798b2ce2858755afa7c8800bb6b1e885d3e030b81255b5e172d", + "57b7842afc97a2b46575b490839df46e9273524c6ea59ba62e1e86477cf25247", ]); done(); }); }); - it('will give error with "from" and "to" range that exceeds max size', function(done) { + it('will give error with "from" and "to" range that exceeds max size', function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { @@ -3684,33 +3709,33 @@ describe('Dash Service', function() { result: [ { txid: memtxid1, - satoshis: -1000000 + satoshis: -1000000, }, { txid: memtxid2, - satoshis: 99999 - } - ] - }) - } + satoshis: 99999, + }, + ], + }), + }, }); dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, [txid1, txid2, txid3]); dashd.getAddressBalance = sinon.stub().callsArgWith(2, null, { received: 30 * 1e8, - balance: 20 * 1e8 + balance: 20 * 1e8, }); - var address = '7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT'; + var address = "7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT"; var options = { from: 0, - to: 1001 + to: 1001, }; - dashd.getAddressSummary(address, options, function(err) { + dashd.getAddressSummary(address, options, function (err) { should.exist(err); err.message.match(/^\"from/); done(); }); }); - it('will get from cache with noTxList', function(done) { + it("will get from cache with noTxList", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { @@ -3718,24 +3743,24 @@ describe('Dash Service', function() { result: [ { txid: memtxid1, - satoshis: -1000000 + satoshis: -1000000, }, { txid: memtxid2, - satoshis: 99999 - } - ] - }) - } + satoshis: 99999, + }, + ], + }), + }, }); dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, [txid1, txid2, txid3]); dashd.getAddressBalance = sinon.stub().callsArgWith(2, null, { received: 30 * 1e8, - balance: 20 * 1e8 + balance: 20 * 1e8, }); - var address = '7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT'; + var address = "7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT"; var options = { - noTxList: true + noTxList: true, }; function checkSummary(summary) { summary.appearances.should.equal(3); @@ -3746,11 +3771,11 @@ describe('Dash Service', function() { summary.unconfirmedBalance.should.equal(-900001); should.not.exist(summary.txids); } - dashd.getAddressSummary(address, options, function(err, summary) { + dashd.getAddressSummary(address, options, function (err, summary) { checkSummary(summary); dashd.getAddressTxids.callCount.should.equal(1); dashd.getAddressBalance.callCount.should.equal(1); - dashd.getAddressSummary(address, options, function(err, summary) { + dashd.getAddressSummary(address, options, function (err, summary) { checkSummary(summary); dashd.getAddressTxids.callCount.should.equal(1); dashd.getAddressBalance.callCount.should.equal(1); @@ -3758,109 +3783,110 @@ describe('Dash Service', function() { }); }); }); - it('will skip querying the mempool with queryMempool set to false', function(done) { + it("will skip querying the mempool with queryMempool set to false", function (done) { var dashd = new DashService(baseConfig); var getAddressMempool = sinon.stub(); dashd.nodes.push({ client: { - getAddressMempool: getAddressMempool - } + getAddressMempool: getAddressMempool, + }, }); - sinon.spy(dashd, '_paginate'); + sinon.spy(dashd, "_paginate"); dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, [txid1, txid2, txid3]); dashd.getAddressBalance = sinon.stub().callsArgWith(2, null, { received: 30 * 1e8, - balance: 20 * 1e8 + balance: 20 * 1e8, }); - var address = '7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT'; + var address = "7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT"; var options = { - queryMempool: false + queryMempool: false, }; - dashd.getAddressSummary(address, options, function() { + dashd.getAddressSummary(address, options, function () { getAddressMempool.callCount.should.equal(0); done(); }); }); - it('will give error from _paginate', function(done) { + it("will give error from _paginate", function (done) { var dashd = new DashService(baseConfig); var getAddressMempool = sinon.stub(); dashd.nodes.push({ client: { - getAddressMempool: getAddressMempool - } + getAddressMempool: getAddressMempool, + }, }); - sinon.spy(dashd, '_paginate'); + sinon.spy(dashd, "_paginate"); dashd.getAddressTxids = sinon.stub().callsArgWith(2, null, [txid1, txid2, txid3]); dashd.getAddressBalance = sinon.stub().callsArgWith(2, null, { received: 30 * 1e8, - balance: 20 * 1e8 + balance: 20 * 1e8, }); - dashd._paginate = sinon.stub().throws(new Error('test')); - var address = '7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT'; + dashd._paginate = sinon.stub().throws(new Error("test")); + var address = "7oK6xjGeVK5YCT5dpqzNXGUag1bQadPAyT"; var options = { - queryMempool: false + queryMempool: false, }; - dashd.getAddressSummary(address, options, function(err) { + dashd.getAddressSummary(address, options, function (err) { err.should.be.instanceOf(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); }); - describe('#getRawBlock', function() { - var blockhash = '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'; - var blockhex = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; - it('will give rcp error from client getblockhash', function(done) { + describe("#getRawBlock", function () { + var blockhash = "00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"; + var blockhex = + "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"; + it("will give rcp error from client getblockhash", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getBlockHash: sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}) - } + getBlockHash: sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }), + }, }); - dashd.getRawBlock(10, function(err) { + dashd.getRawBlock(10, function (err) { should.exist(err); err.should.be.instanceof(errors.RPCError); done(); }); }); - it('will give rcp error from client getblock', function(done) { + it("will give rcp error from client getblock", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getBlock: sinon.stub().callsArgWith(2, {code: -1, message: 'Test error'}) - } + getBlock: sinon.stub().callsArgWith(2, { code: -1, message: "Test error" }), + }, }); - dashd.getRawBlock(blockhash, function(err) { + dashd.getRawBlock(blockhash, function (err) { should.exist(err); err.should.be.instanceof(errors.RPCError); done(); }); }); - it('will try all nodes for getblock', function(done) { + it("will try all nodes for getblock", function (done) { var dashd = new DashService(baseConfig); - var getBlockWithError = sinon.stub().callsArgWith(2, {code: -1, message: 'Test error'}); + var getBlockWithError = sinon.stub().callsArgWith(2, { code: -1, message: "Test error" }); dashd.tryAllInterval = 1; dashd.nodes.push({ client: { - getBlock: getBlockWithError - } + getBlock: getBlockWithError, + }, }); dashd.nodes.push({ client: { - getBlock: getBlockWithError - } + getBlock: getBlockWithError, + }, }); dashd.nodes.push({ client: { getBlock: sinon.stub().callsArgWith(2, null, { - result: blockhex - }) - } + result: blockhex, + }), + }, }); //cause first call will be not getBlock, but _maybeGetBlockHash, which will set up nodesIndex to 0 dashd.nodesIndex = 2; - dashd.getRawBlock(blockhash, function(err, buffer) { + dashd.getRawBlock(blockhash, function (err, buffer) { if (err) { return done(err); } @@ -3869,23 +3895,23 @@ describe('Dash Service', function() { done(); }); }); - it('will get block from cache', function(done) { + it("will get block from cache", function (done) { var dashd = new DashService(baseConfig); var getBlock = sinon.stub().callsArgWith(2, null, { - result: blockhex + result: blockhex, }); dashd.nodes.push({ client: { - getBlock: getBlock - } + getBlock: getBlock, + }, }); - dashd.getRawBlock(blockhash, function(err, buffer) { + dashd.getRawBlock(blockhash, function (err, buffer) { if (err) { return done(err); } buffer.should.be.instanceof(Buffer); getBlock.callCount.should.equal(1); - dashd.getRawBlock(blockhash, function(err, buffer) { + dashd.getRawBlock(blockhash, function (err, buffer) { if (err) { return done(err); } @@ -3895,21 +3921,21 @@ describe('Dash Service', function() { }); }); }); - it('will get block by height', function(done) { + it("will get block by height", function (done) { var dashd = new DashService(baseConfig); var getBlock = sinon.stub().callsArgWith(2, null, { - result: blockhex + result: blockhex, }); var getBlockHash = sinon.stub().callsArgWith(1, null, { - result: '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f' + result: "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", }); dashd.nodes.push({ client: { getBlock: getBlock, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getRawBlock(0, function(err, buffer) { + dashd.getRawBlock(0, function (err, buffer) { if (err) { return done(err); } @@ -3921,99 +3947,100 @@ describe('Dash Service', function() { }); }); - describe('#getBlock', function() { - var blockhex = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000'; - it('will give an rpc error from client getblock', function(done) { + describe("#getBlock", function () { + var blockhex = + "0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c0101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000"; + it("will give an rpc error from client getblock", function (done) { var dashd = new DashService(baseConfig); - var getBlock = sinon.stub().callsArgWith(2, {code: -1, message: 'Test error'}); + var getBlock = sinon.stub().callsArgWith(2, { code: -1, message: "Test error" }); var getBlockHash = sinon.stub().callsArgWith(1, null, {}); dashd.nodes.push({ client: { getBlock: getBlock, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlock(0, function(err) { + dashd.getBlock(0, function (err) { err.should.be.instanceof(Error); done(); }); }); - it('will give an rpc error from client getblockhash', function(done) { + it("will give an rpc error from client getblockhash", function (done) { var dashd = new DashService(baseConfig); - var getBlockHash = sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}); + var getBlockHash = sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }); dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlock(0, function(err) { + dashd.getBlock(0, function (err) { err.should.be.instanceof(Error); done(); }); }); - it('will getblock as dashcore object from height', function(done) { + it("will getblock as dashcore object from height", function (done) { var dashd = new DashService(baseConfig); var getBlock = sinon.stub().callsArgWith(2, null, { - result: blockhex + result: blockhex, }); var getBlockHash = sinon.stub().callsArgWith(1, null, { - result: '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b' + result: "00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b", }); dashd.nodes.push({ client: { getBlock: getBlock, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlock(0, function(err, block) { + dashd.getBlock(0, function (err, block) { should.not.exist(err); - getBlock.args[0][0].should.equal('00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'); + getBlock.args[0][0].should.equal("00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"); getBlock.args[0][1].should.equal(false); block.should.be.instanceof(dashcore.Block); done(); }); }); - it('will getblock as dashcore object', function(done) { + it("will getblock as dashcore object", function (done) { var dashd = new DashService(baseConfig); var getBlock = sinon.stub().callsArgWith(2, null, { - result: blockhex + result: blockhex, }); var getBlockHash = sinon.stub(); dashd.nodes.push({ client: { getBlock: getBlock, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlock('00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b', function(err, block) { + dashd.getBlock("00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b", function (err, block) { should.not.exist(err); getBlockHash.callCount.should.equal(0); getBlock.callCount.should.equal(1); - getBlock.args[0][0].should.equal('00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'); + getBlock.args[0][0].should.equal("00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"); getBlock.args[0][1].should.equal(false); block.should.be.instanceof(dashcore.Block); done(); }); }); - it('will get block from cache', function(done) { + it("will get block from cache", function (done) { var dashd = new DashService(baseConfig); var getBlock = sinon.stub().callsArgWith(2, null, { - result: blockhex + result: blockhex, }); var getBlockHash = sinon.stub(); dashd.nodes.push({ client: { getBlock: getBlock, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - var hash = '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'; - dashd.getBlock(hash, function(err, block) { + var hash = "00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"; + dashd.getBlock(hash, function (err, block) { should.not.exist(err); getBlockHash.callCount.should.equal(0); getBlock.callCount.should.equal(1); block.should.be.instanceof(dashcore.Block); - dashd.getBlock(hash, function(err, block) { + dashd.getBlock(hash, function (err, block) { should.not.exist(err); getBlockHash.callCount.should.equal(0); getBlock.callCount.should.equal(1); @@ -4022,26 +4049,26 @@ describe('Dash Service', function() { }); }); }); - it('will get block from cache with height (but not height)', function(done) { + it("will get block from cache with height (but not height)", function (done) { var dashd = new DashService(baseConfig); var getBlock = sinon.stub().callsArgWith(2, null, { - result: blockhex + result: blockhex, }); var getBlockHash = sinon.stub().callsArgWith(1, null, { - result: '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b' + result: "00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b", }); dashd.nodes.push({ client: { getBlock: getBlock, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlock(0, function(err, block) { + dashd.getBlock(0, function (err, block) { should.not.exist(err); getBlockHash.callCount.should.equal(1); getBlock.callCount.should.equal(1); block.should.be.instanceof(dashcore.Block); - dashd.getBlock(0, function(err, block) { + dashd.getBlock(0, function (err, block) { should.not.exist(err); getBlockHash.callCount.should.equal(2); getBlock.callCount.should.equal(1); @@ -4052,34 +4079,34 @@ describe('Dash Service', function() { }); }); - describe('#getBlockHashesByTimestamp', function() { - it('should give an rpc error', function(done) { + describe("#getBlockHashesByTimestamp", function () { + it("should give an rpc error", function (done) { var dashd = new DashService(baseConfig); - var getBlockHashes = sinon.stub().callsArgWith(2, {message: 'error', code: -1}); + var getBlockHashes = sinon.stub().callsArgWith(2, { message: "error", code: -1 }); dashd.nodes.push({ client: { - getBlockHashes: getBlockHashes - } + getBlockHashes: getBlockHashes, + }, }); - dashd.getBlockHashesByTimestamp(1441911000, 1441914000, function(err, hashes) { + dashd.getBlockHashesByTimestamp(1441911000, 1441914000, function (err, hashes) { should.exist(err); - err.message.should.equal('error'); + err.message.should.equal("error"); done(); }); }); - it('should get the correct block hashes', function(done) { + it("should get the correct block hashes", function (done) { var dashd = new DashService(baseConfig); - var block1 = '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'; - var block2 = '000000000383752a55a0b2891ce018fd0fdc0b6352502772b034ec282b4a1bf6'; + var block1 = "00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"; + var block2 = "000000000383752a55a0b2891ce018fd0fdc0b6352502772b034ec282b4a1bf6"; var getBlockHashes = sinon.stub().callsArgWith(2, null, { - result: [block2, block1] + result: [block2, block1], }); dashd.nodes.push({ client: { - getBlockHashes: getBlockHashes - } + getBlockHashes: getBlockHashes, + }, }); - dashd.getBlockHashesByTimestamp(1441914000, 1441911000, function(err, hashes) { + dashd.getBlockHashesByTimestamp(1441914000, 1441911000, function (err, hashes) { should.not.exist(err); hashes.should.deep.equal([block2, block1]); done(); @@ -4087,137 +4114,137 @@ describe('Dash Service', function() { }); }); - describe('#getBlockHeader', function() { - var blockhash = '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'; - it('will give error from getBlockHash', function() { + describe("#getBlockHeader", function () { + var blockhash = "00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"; + it("will give error from getBlockHash", function () { var dashd = new DashService(baseConfig); - var getBlockHash = sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}); + var getBlockHash = sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }); dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlockHeader(10, function(err) { + dashd.getBlockHeader(10, function (err) { err.should.be.instanceof(Error); }); }); - it('it will give rpc error from client getblockheader', function() { + it("it will give rpc error from client getblockheader", function () { var dashd = new DashService(baseConfig); - var getBlockHeader = sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}); + var getBlockHeader = sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }); dashd.nodes.push({ client: { - getBlockHeader: getBlockHeader - } + getBlockHeader: getBlockHeader, + }, }); - dashd.getBlockHeader(blockhash, function(err) { + dashd.getBlockHeader(blockhash, function (err) { err.should.be.instanceof(Error); }); }); - it('it will give rpc error from client getblockhash', function() { + it("it will give rpc error from client getblockhash", function () { var dashd = new DashService(baseConfig); var getBlockHeader = sinon.stub(); - var getBlockHash = sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}); + var getBlockHash = sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }); dashd.nodes.push({ client: { getBlockHeader: getBlockHeader, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlockHeader(0, function(err) { + dashd.getBlockHeader(0, function (err) { err.should.be.instanceof(Error); }); }); - it('will give result from client getblockheader (from height)', function() { + it("will give result from client getblockheader (from height)", function () { var dashd = new DashService(baseConfig); var result = { - hash: '0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6', + hash: "0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6", version: 536870912, confirmations: 5, height: 828781, - chainWork: '00000000000000000000000000000000000000000000000ad467352c93bc6a3b', - prevHash: '0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9', - nextHash: '00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8', - merkleRoot: '124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9', + chainWork: "00000000000000000000000000000000000000000000000ad467352c93bc6a3b", + prevHash: "0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9", + nextHash: "00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8", + merkleRoot: "124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9", time: 1462979126, medianTime: 1462976771, nonce: 2981820714, - bits: '1a13ca10', - difficulty: 847779.0710240941 + bits: "1a13ca10", + difficulty: 847779.0710240941, }; var getBlockHeader = sinon.stub().callsArgWith(1, null, { result: { - hash: '0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6', + hash: "0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6", version: 536870912, confirmations: 5, height: 828781, - chainwork: '00000000000000000000000000000000000000000000000ad467352c93bc6a3b', - previousblockhash: '0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9', - nextblockhash: '00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8', - merkleroot: '124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9', + chainwork: "00000000000000000000000000000000000000000000000ad467352c93bc6a3b", + previousblockhash: "0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9", + nextblockhash: "00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8", + merkleroot: "124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9", time: 1462979126, mediantime: 1462976771, nonce: 2981820714, - bits: '1a13ca10', - difficulty: 847779.0710240941 - } + bits: "1a13ca10", + difficulty: 847779.0710240941, + }, }); var getBlockHash = sinon.stub().callsArgWith(1, null, { - result: blockhash + result: blockhash, }); dashd.nodes.push({ client: { getBlockHeader: getBlockHeader, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlockHeader(0, function(err, blockHeader) { + dashd.getBlockHeader(0, function (err, blockHeader) { should.not.exist(err); getBlockHeader.args[0][0].should.equal(blockhash); blockHeader.should.deep.equal(result); }); }); - it('will give result from client getblockheader (from hash)', function() { + it("will give result from client getblockheader (from hash)", function () { var dashd = new DashService(baseConfig); var result = { - hash: '0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6', + hash: "0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6", version: 536870912, confirmations: 5, height: 828781, - chainWork: '00000000000000000000000000000000000000000000000ad467352c93bc6a3b', - prevHash: '0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9', - nextHash: '00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8', - merkleRoot: '124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9', + chainWork: "00000000000000000000000000000000000000000000000ad467352c93bc6a3b", + prevHash: "0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9", + nextHash: "00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8", + merkleRoot: "124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9", time: 1462979126, medianTime: 1462976771, nonce: 2981820714, - bits: '1a13ca10', - difficulty: 847779.0710240941 + bits: "1a13ca10", + difficulty: 847779.0710240941, }; var getBlockHeader = sinon.stub().callsArgWith(1, null, { result: { - hash: '0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6', + hash: "0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6", version: 536870912, confirmations: 5, height: 828781, - chainwork: '00000000000000000000000000000000000000000000000ad467352c93bc6a3b', - previousblockhash: '0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9', - nextblockhash: '00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8', - merkleroot: '124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9', + chainwork: "00000000000000000000000000000000000000000000000ad467352c93bc6a3b", + previousblockhash: "0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9", + nextblockhash: "00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8", + merkleroot: "124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9", time: 1462979126, mediantime: 1462976771, nonce: 2981820714, - bits: '1a13ca10', - difficulty: 847779.0710240941 - } + bits: "1a13ca10", + difficulty: 847779.0710240941, + }, }); var getBlockHash = sinon.stub(); dashd.nodes.push({ client: { getBlockHeader: getBlockHeader, - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd.getBlockHeader(blockhash, function(err, blockHeader) { + dashd.getBlockHeader(blockhash, function (err, blockHeader) { should.not.exist(err); getBlockHash.callCount.should.equal(0); blockHeader.should.deep.equal(result); @@ -4225,323 +4252,327 @@ describe('Dash Service', function() { }); }); - describe('#getBlockHeaders', function(){ - var blockhash = '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'; - it('will gave error from getBlockHash', function(){ - var dashd = new DashService(baseConfig); - var getBlockHash = sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}); - dashd.nodes.push({ - client: { - getBlockHash: getBlockHash - } - }); - dashd.getBlockHeaders(10, function(err) { - err.should.be.instanceof(Error); - }); - }); - it('it will give rpc error from client getblockheaders', function() { - var dashd = new DashService(baseConfig); - var getBlockHeader = sinon.stub().callsArgWith(1, {code: -1, message: 'Test error'}); - dashd.nodes.push({ - client: { - getBlockHeader: getBlockHeader - } - }); - dashd.getBlockHeaders(blockhash, function(err){ - err.should.be.instanceof(Error); - }); - }); - it("will get an array of block headers", function(){ - var dashd = new DashService(baseConfig); - - var result = { - hash: '0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6', - version: 536870912, - confirmations: 5, - height: 828781, - chainWork: '00000000000000000000000000000000000000000000000ad467352c93bc6a3b', - prevHash: '0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9', - nextHash: '00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8', - merkleRoot: '124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9', - time: 1462979126, - medianTime: 1462976771, - nonce: 2981820714, - bits: '1a13ca10', - difficulty: 847779.0710240941 - }; - var _blockHash = "0000000000004244572caa69779a8e0a6d09fa426856b55cffc1dbc9060cab0d"; - var getBlockHeader = sinon.stub().callsArgWith(1, null, { - result: { - hash: '0000000000004244572caa69779a8e0a6d09fa426856b55cffc1dbc9060cab0d', - version: 3, - confirmations: 3, - height: 596802, - size:1011, - chainwork: '0000000000000000000000000000000000000000000000013b107cbccb2955f0', - previousblockhash: '0000000000002c6816b083abb8cd8d1e2b13181d39e62b456807a4ccecaccf0d', - nextblockhash: '00000000000012093f65b9fdba40c4131270a90158864ea422f0ab6acc12ec08', - merkleroot: '5aed5d0acabaaea2463f50333f4bebd9b661af1b6cbf620750dead86c53c8a32', - tx: [ - "ad86010c4acfb66d1dd5ce00eeba936396a8a002cc324e7126316e9d48b34a2d", - "35ca72c44ae96cab5fe80c22bf72b48324e31242eba7030dec407f0948e6662f", - "bfb5c2b60ca73376339185e93b9eac1027655b62da04bacdb502607606598c8d" - ], - time: 1483290225, - nonce: 268203724, - bits: '1b00d5dd', - difficulty: 78447.12707081 - } - }); - var getBlockHash = sinon.stub().callsArgWith(1, null, { - result: "0000000000004244572caa69779a8e0a6d09fa426856b55cffc1dbc9060cab0d" - }); + describe("#getBlockHeaders", function () { + var blockhash = "00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"; + it("will gave error from getBlockHash", function () { + var dashd = new DashService(baseConfig); + var getBlockHash = sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }); + dashd.nodes.push({ + client: { + getBlockHash: getBlockHash, + }, + }); + dashd.getBlockHeaders(10, function (err) { + err.should.be.instanceof(Error); + }); + }); + it("it will give rpc error from client getblockheaders", function () { + var dashd = new DashService(baseConfig); + var getBlockHeader = sinon.stub().callsArgWith(1, { code: -1, message: "Test error" }); + dashd.nodes.push({ + client: { + getBlockHeader: getBlockHeader, + }, + }); + dashd.getBlockHeaders(blockhash, function (err) { + err.should.be.instanceof(Error); + }); + }); + it("will get an array of block headers", function () { + var dashd = new DashService(baseConfig); - var _blockHash2 = "00000000000012093f65b9fdba40c4131270a90158864ea422f0ab6acc12ec08"; + var result = { + hash: "0000000000000a817cd3a74aec2f2246b59eb2cbb1ad730213e6c4a1d68ec2f6", + version: 536870912, + confirmations: 5, + height: 828781, + chainWork: "00000000000000000000000000000000000000000000000ad467352c93bc6a3b", + prevHash: "0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9", + nextHash: "00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8", + merkleRoot: "124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9", + time: 1462979126, + medianTime: 1462976771, + nonce: 2981820714, + bits: "1a13ca10", + difficulty: 847779.0710240941, + }; + var _blockHash = "0000000000004244572caa69779a8e0a6d09fa426856b55cffc1dbc9060cab0d"; + var getBlockHeader = sinon.stub().callsArgWith(1, null, { + result: { + hash: "0000000000004244572caa69779a8e0a6d09fa426856b55cffc1dbc9060cab0d", + version: 3, + confirmations: 3, + height: 596802, + size: 1011, + chainwork: "0000000000000000000000000000000000000000000000013b107cbccb2955f0", + previousblockhash: "0000000000002c6816b083abb8cd8d1e2b13181d39e62b456807a4ccecaccf0d", + nextblockhash: "00000000000012093f65b9fdba40c4131270a90158864ea422f0ab6acc12ec08", + merkleroot: "5aed5d0acabaaea2463f50333f4bebd9b661af1b6cbf620750dead86c53c8a32", + tx: [ + "ad86010c4acfb66d1dd5ce00eeba936396a8a002cc324e7126316e9d48b34a2d", + "35ca72c44ae96cab5fe80c22bf72b48324e31242eba7030dec407f0948e6662f", + "bfb5c2b60ca73376339185e93b9eac1027655b62da04bacdb502607606598c8d", + ], + time: 1483290225, + nonce: 268203724, + bits: "1b00d5dd", + difficulty: 78447.12707081, + }, + }); + var getBlockHash = sinon.stub().callsArgWith(1, null, { + result: "0000000000004244572caa69779a8e0a6d09fa426856b55cffc1dbc9060cab0d", + }); - var getBlockHeader2 = sinon.stub().callsArgWith(1, null, { - result: { - hash: '00000000000012093f65b9fdba40c4131270a90158864ea422f0ab6acc12ec08', - version: 3, - confirmations: 2, - height: 596803, - size:9004, - chainwork: '0000000000000000000000000000000000000000000000013b11b1f8dc564404', - previousblockhash: '0000000000004244572caa69779a8e0a6d09fa426856b55cffc1dbc9060cab0d', - nextblockhash: '0000000000007dbd3e7b09b457c57436e8f15e76d33768bce1e879678c8699b9', - merkleroot: '7e1301c4edd06a61c9081738ef6c704e5b5622680c8a5d6bb9d68f177c645915', - tx: [ - "b0614db089313a5c572cd1b4abd0e7924c6ed8e14092d55f3b1b539935dc1579", - "aba6bf61c5eea6a7b215e95f3a881ef259d9b720476c3f3ac453155bbf041d6e", - "080acf0b48929bced37bd5bb28217fc0eb98876fc5afbeba9598c641e670dca7", - "0ec875ccd7e69cd3c2d44b67b617e4120fdc3447754e6610e75dd2227c9e9b32", - "bd0db2ea00c12b31ab21c565f55b0d6534074aced6208d6076219ff35e7fab79", - "006a1c7ff5ffc369ee542ba959aad69a993a7923feb60b68e15984dd71c6baa0", - "aa41c6780e5f1b54192f97ef11ef5adaf27e15da94f924ffe8317a3e72f00a42" - ], - time: 1483290547, - nonce: 3123079945, - bits: '1b00d3ee', - difficulty: 79162.85914403 - } - }); - var getBlockHash2 = sinon.stub().callsArgWith(1, null, { - result: "00000000000012093f65b9fdba40c4131270a90158864ea422f0ab6acc12ec08" - }); - dashd.nodes.push({ - client: { - getBlockHeader: getBlockHeader, - getBlockHash: getBlockHash - } - }); - dashd.nodes.push({ - client: { - getBlockHeader: getBlockHeader2, - getBlockHash: getBlockHash2 - } - }); + var _blockHash2 = "00000000000012093f65b9fdba40c4131270a90158864ea422f0ab6acc12ec08"; - dashd.getBlockHeaders(_blockHash, function(err, blockHeader){ - should.not.exist(err); - blockHeader[0].hash.should.equal(_blockHash); - // getBlockHeader.args[0][0].should.equal(blockhash); - // blockHeader.should.deep.equal(result); - },5); + var getBlockHeader2 = sinon.stub().callsArgWith(1, null, { + result: { + hash: "00000000000012093f65b9fdba40c4131270a90158864ea422f0ab6acc12ec08", + version: 3, + confirmations: 2, + height: 596803, + size: 9004, + chainwork: "0000000000000000000000000000000000000000000000013b11b1f8dc564404", + previousblockhash: "0000000000004244572caa69779a8e0a6d09fa426856b55cffc1dbc9060cab0d", + nextblockhash: "0000000000007dbd3e7b09b457c57436e8f15e76d33768bce1e879678c8699b9", + merkleroot: "7e1301c4edd06a61c9081738ef6c704e5b5622680c8a5d6bb9d68f177c645915", + tx: [ + "b0614db089313a5c572cd1b4abd0e7924c6ed8e14092d55f3b1b539935dc1579", + "aba6bf61c5eea6a7b215e95f3a881ef259d9b720476c3f3ac453155bbf041d6e", + "080acf0b48929bced37bd5bb28217fc0eb98876fc5afbeba9598c641e670dca7", + "0ec875ccd7e69cd3c2d44b67b617e4120fdc3447754e6610e75dd2227c9e9b32", + "bd0db2ea00c12b31ab21c565f55b0d6534074aced6208d6076219ff35e7fab79", + "006a1c7ff5ffc369ee542ba959aad69a993a7923feb60b68e15984dd71c6baa0", + "aa41c6780e5f1b54192f97ef11ef5adaf27e15da94f924ffe8317a3e72f00a42", + ], + time: 1483290547, + nonce: 3123079945, + bits: "1b00d3ee", + difficulty: 79162.85914403, + }, + }); + var getBlockHash2 = sinon.stub().callsArgWith(1, null, { + result: "00000000000012093f65b9fdba40c4131270a90158864ea422f0ab6acc12ec08", + }); + dashd.nodes.push({ + client: { + getBlockHeader: getBlockHeader, + getBlockHash: getBlockHash, + }, + }); + dashd.nodes.push({ + client: { + getBlockHeader: getBlockHeader2, + getBlockHash: getBlockHash2, + }, }); + + dashd.getBlockHeaders( + _blockHash, + function (err, blockHeader) { + should.not.exist(err); + blockHeader[0].hash.should.equal(_blockHash); + // getBlockHeader.args[0][0].should.equal(blockhash); + // blockHeader.should.deep.equal(result); + }, + 5 + ); + }); }); - describe('#_maybeGetBlockHash', function() { - it('will not get block hash with an address', function(done) { + describe("#_maybeGetBlockHash", function () { + it("will not get block hash with an address", function (done) { var dashd = new DashService(baseConfig); var getBlockHash = sinon.stub(); dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd._maybeGetBlockHash('8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi', function(err, hash) { + dashd._maybeGetBlockHash("8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi", function (err, hash) { if (err) { return done(err); } getBlockHash.callCount.should.equal(0); - hash.should.equal('8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi'); + hash.should.equal("8oUSpiq5REeEKAzS1qSXoJbZ9TRfH1L6mi"); done(); }); }); - it('will not get block hash with non zero-nine numeric string', function(done) { + it("will not get block hash with non zero-nine numeric string", function (done) { var dashd = new DashService(baseConfig); var getBlockHash = sinon.stub(); dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd._maybeGetBlockHash('109a', function(err, hash) { + dashd._maybeGetBlockHash("109a", function (err, hash) { if (err) { return done(err); } getBlockHash.callCount.should.equal(0); - hash.should.equal('109a'); + hash.should.equal("109a"); done(); }); }); - it('will get the block hash if argument is a number', function(done) { + it("will get the block hash if argument is a number", function (done) { var dashd = new DashService(baseConfig); var getBlockHash = sinon.stub().callsArgWith(1, null, { - result: 'blockhash' + result: "blockhash", }); dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd._maybeGetBlockHash(10, function(err, hash) { + dashd._maybeGetBlockHash(10, function (err, hash) { if (err) { return done(err); } - hash.should.equal('blockhash'); + hash.should.equal("blockhash"); getBlockHash.callCount.should.equal(1); done(); }); }); - it('will get the block hash if argument is a number (as string)', function(done) { + it("will get the block hash if argument is a number (as string)", function (done) { var dashd = new DashService(baseConfig); var getBlockHash = sinon.stub().callsArgWith(1, null, { - result: 'blockhash' + result: "blockhash", }); dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd._maybeGetBlockHash('10', function(err, hash) { + dashd._maybeGetBlockHash("10", function (err, hash) { if (err) { return done(err); } - hash.should.equal('blockhash'); + hash.should.equal("blockhash"); getBlockHash.callCount.should.equal(1); done(); }); }); - it('will try multiple nodes if one fails', function(done) { + it("will try multiple nodes if one fails", function (done) { var dashd = new DashService(baseConfig); var getBlockHash = sinon.stub().callsArgWith(1, null, { - result: 'blockhash' + result: "blockhash", }); - getBlockHash.onCall(0).callsArgWith(1, {code: -1, message: 'test'}); + getBlockHash.onCall(0).callsArgWith(1, { code: -1, message: "test" }); dashd.tryAllInterval = 1; dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd._maybeGetBlockHash(10, function(err, hash) { + dashd._maybeGetBlockHash(10, function (err, hash) { if (err) { return done(err); } - hash.should.equal('blockhash'); + hash.should.equal("blockhash"); getBlockHash.callCount.should.equal(2); done(); }); }); - it('will give error from getBlockHash', function(done) { + it("will give error from getBlockHash", function (done) { var dashd = new DashService(baseConfig); - var getBlockHash = sinon.stub().callsArgWith(1, {code: -1, message: 'test'}); + var getBlockHash = sinon.stub().callsArgWith(1, { code: -1, message: "test" }); dashd.tryAllInterval = 1; dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); dashd.nodes.push({ client: { - getBlockHash: getBlockHash - } + getBlockHash: getBlockHash, + }, }); - dashd._maybeGetBlockHash(10, function(err, hash) { + dashd._maybeGetBlockHash(10, function (err, hash) { getBlockHash.callCount.should.equal(2); err.should.be.instanceOf(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); err.code.should.equal(-1); done(); }); }); }); - describe('#getBlockOverview', function() { - var blockhash = '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'; - it('will handle error from maybeGetBlockHash', function(done) { + describe("#getBlockOverview", function () { + var blockhash = "00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"; + it("will handle error from maybeGetBlockHash", function (done) { var dashd = new DashService(baseConfig); - dashd._maybeGetBlockHash = sinon.stub().callsArgWith(1, new Error('test')); - dashd.getBlockOverview(blockhash, function(err) { + dashd._maybeGetBlockHash = sinon.stub().callsArgWith(1, new Error("test")); + dashd.getBlockOverview(blockhash, function (err) { err.should.be.instanceOf(Error); done(); }); }); - it('will give error from client.getBlock', function(done) { + it("will give error from client.getBlock", function (done) { var dashd = new DashService(baseConfig); - var getBlock = sinon.stub().callsArgWith(2, {code: -1, message: 'test'}); + var getBlock = sinon.stub().callsArgWith(2, { code: -1, message: "test" }); dashd.nodes.push({ client: { - getBlock: getBlock - } + getBlock: getBlock, + }, }); - dashd.getBlockOverview(blockhash, function(err) { + dashd.getBlockOverview(blockhash, function (err) { err.should.be.instanceOf(Error); - err.message.should.equal('test'); + err.message.should.equal("test"); done(); }); }); - it('will give expected result', function(done) { + it("will give expected result", function (done) { var dashd = new DashService(baseConfig); var blockResult = { hash: blockhash, version: 536870912, confirmations: 5, height: 828781, - chainwork: '00000000000000000000000000000000000000000000000ad467352c93bc6a3b', - previousblockhash: '0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9', - nextblockhash: '00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8', - merkleroot: '124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9', + chainwork: "00000000000000000000000000000000000000000000000ad467352c93bc6a3b", + previousblockhash: "0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9", + nextblockhash: "00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8", + merkleroot: "124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9", time: 1462979126, mediantime: 1462976771, nonce: 2981820714, - bits: '1a13ca10', - difficulty: 847779.0710240941 + bits: "1a13ca10", + difficulty: 847779.0710240941, }; var getBlock = sinon.stub().callsArgWith(2, null, { - result: blockResult + result: blockResult, }); dashd.nodes.push({ client: { - getBlock: getBlock - } + getBlock: getBlock, + }, }); function checkBlock(blockOverview) { - blockOverview.hash.should.equal('00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b'); + blockOverview.hash.should.equal("00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b"); blockOverview.version.should.equal(536870912); blockOverview.confirmations.should.equal(5); blockOverview.height.should.equal(828781); - blockOverview.chainWork.should.equal('00000000000000000000000000000000000000000000000ad467352c93bc6a3b'); - blockOverview.prevHash.should.equal('0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9'); - blockOverview.nextHash.should.equal('00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8'); - blockOverview.merkleRoot.should.equal('124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9'); + blockOverview.chainWork.should.equal("00000000000000000000000000000000000000000000000ad467352c93bc6a3b"); + blockOverview.prevHash.should.equal("0000000000000504235b2aff578a48470dbf6b94dafa9b3703bbf0ed554c9dd9"); + blockOverview.nextHash.should.equal("00000000000000eedd967ec155f237f033686f0924d574b946caf1b0e89551b8"); + blockOverview.merkleRoot.should.equal("124e0f3fb5aa268f102b0447002dd9700988fc570efcb3e0b5b396ac7db437a9"); blockOverview.time.should.equal(1462979126); blockOverview.medianTime.should.equal(1462976771); blockOverview.nonce.should.equal(2981820714); - blockOverview.bits.should.equal('1a13ca10'); + blockOverview.bits.should.equal("1a13ca10"); blockOverview.difficulty.should.equal(847779.0710240941); } - dashd.getBlockOverview(blockhash, function(err, blockOverview) { + dashd.getBlockOverview(blockhash, function (err, blockOverview) { if (err) { return done(err); } checkBlock(blockOverview); - dashd.getBlockOverview(blockhash, function(err, blockOverview) { + dashd.getBlockOverview(blockhash, function (err, blockOverview) { checkBlock(blockOverview); getBlock.callCount.should.equal(1); done(); @@ -4550,32 +4581,32 @@ describe('Dash Service', function() { }); }); - describe('#estimateFee', function() { - it('will give rpc error', function(done) { + describe("#estimateFee", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var estimateFee = sinon.stub().callsArgWith(1, {message: 'error', code: -1}); + var estimateFee = sinon.stub().callsArgWith(1, { message: "error", code: -1 }); dashd.nodes.push({ client: { - estimateFee: estimateFee - } + estimateFee: estimateFee, + }, }); - dashd.estimateFee(1, function(err) { + dashd.estimateFee(1, function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will call client estimateFee and give result', function(done) { + it("will call client estimateFee and give result", function (done) { var dashd = new DashService(baseConfig); var estimateFee = sinon.stub().callsArgWith(1, null, { - result: -1 + result: -1, }); dashd.nodes.push({ client: { - estimateFee: estimateFee - } + estimateFee: estimateFee, + }, }); - dashd.estimateFee(1, function(err, feesPerKb) { + dashd.estimateFee(1, function (err, feesPerKb) { if (err) { return done(err); } @@ -4585,110 +4616,110 @@ describe('Dash Service', function() { }); }); - describe('#sendTransaction', function(done) { + describe("#sendTransaction", function (done) { var tx = dashcore.Transaction(txhex); - it('will give rpc error', function() { + it("will give rpc error", function () { var dashd = new DashService(baseConfig); - var sendRawTransaction = sinon.stub().callsArgWith(3, {message: 'error', code: -1}); + var sendRawTransaction = sinon.stub().callsArgWith(3, { message: "error", code: -1 }); dashd.nodes.push({ client: { - sendRawTransaction: sendRawTransaction - } + sendRawTransaction: sendRawTransaction, + }, }); - dashd.sendTransaction(txhex, function(err) { + dashd.sendTransaction(txhex, function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); }); }); - it('will send to client and get hash', function() { + it("will send to client and get hash", function () { var dashd = new DashService(baseConfig); var sendRawTransaction = sinon.stub().callsArgWith(3, null, { - result: tx.hash + result: tx.hash, }); dashd.nodes.push({ client: { - sendRawTransaction: sendRawTransaction - } + sendRawTransaction: sendRawTransaction, + }, }); - dashd.sendTransaction(txhex, function(err, hash) { + dashd.sendTransaction(txhex, function (err, hash) { if (err) { return done(err); } hash.should.equal(tx.hash); }); }); - it('will send to client with absurd fees and get hash', function() { + it("will send to client with absurd fees and get hash", function () { var dashd = new DashService(baseConfig); var sendRawTransaction = sinon.stub().callsArgWith(3, null, { - result: tx.hash + result: tx.hash, }); dashd.nodes.push({ client: { - sendRawTransaction: sendRawTransaction - } + sendRawTransaction: sendRawTransaction, + }, }); - dashd.sendTransaction(txhex, {maxFeeRate: 0}, function(err, hash) { + dashd.sendTransaction(txhex, { maxFeeRate: 0 }, function (err, hash) { if (err) { return done(err); } hash.should.equal(tx.hash); }); }); - it('missing callback will throw error', function() { + it("missing callback will throw error", function () { var dashd = new DashService(baseConfig); var sendRawTransaction = sinon.stub().callsArgWith(3, null, { - result: tx.hash + result: tx.hash, }); dashd.nodes.push({ client: { - sendRawTransaction: sendRawTransaction - } + sendRawTransaction: sendRawTransaction, + }, }); var transaction = dashcore.Transaction(); - (function() { + (function () { dashd.sendTransaction(transaction); }).should.throw(Error); }); }); - describe('#getRawTransaction', function() { - it('will give rpc error', function(done) { + describe("#getRawTransaction", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var getRawTransaction = sinon.stub().callsArgWith(1, {message: 'error', code: -1}); + var getRawTransaction = sinon.stub().callsArgWith(1, { message: "error", code: -1 }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransaction - } + getRawTransaction: getRawTransaction, + }, }); - dashd.getRawTransaction('txid', function(err) { + dashd.getRawTransaction("txid", function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will try all nodes', function(done) { + it("will try all nodes", function (done) { var dashd = new DashService(baseConfig); dashd.tryAllInterval = 1; - var getRawTransactionWithError = sinon.stub().callsArgWith(1, {message: 'error', code: -1}); + var getRawTransactionWithError = sinon.stub().callsArgWith(1, { message: "error", code: -1 }); var getRawTransaction = sinon.stub().callsArgWith(1, null, { - result: txhex + result: txhex, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransactionWithError - } + getRawTransaction: getRawTransactionWithError, + }, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransactionWithError - } + getRawTransaction: getRawTransactionWithError, + }, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransaction - } + getRawTransaction: getRawTransaction, + }, }); - dashd.getRawTransaction('txid', function(err, tx) { + dashd.getRawTransaction("txid", function (err, tx) { if (err) { return done(err); } @@ -4697,24 +4728,24 @@ describe('Dash Service', function() { done(); }); }); - it('will get from cache', function(done) { + it("will get from cache", function (done) { var dashd = new DashService(baseConfig); var getRawTransaction = sinon.stub().callsArgWith(1, null, { - result: txhex + result: txhex, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransaction - } + getRawTransaction: getRawTransaction, + }, }); - dashd.getRawTransaction('txid', function(err, tx) { + dashd.getRawTransaction("txid", function (err, tx) { if (err) { return done(err); } should.exist(tx); tx.should.be.an.instanceof(Buffer); - dashd.getRawTransaction('txid', function(err, tx) { + dashd.getRawTransaction("txid", function (err, tx) { should.exist(tx); tx.should.be.an.instanceof(Buffer); getRawTransaction.callCount.should.equal(1); @@ -4724,44 +4755,44 @@ describe('Dash Service', function() { }); }); - describe('#getTransaction', function() { - it('will give rpc error', function(done) { + describe("#getTransaction", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var getRawTransaction = sinon.stub().callsArgWith(1, {message: 'error', code: -1}); + var getRawTransaction = sinon.stub().callsArgWith(1, { message: "error", code: -1 }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransaction - } + getRawTransaction: getRawTransaction, + }, }); - dashd.getTransaction('txid', function(err) { + dashd.getTransaction("txid", function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will try all nodes', function(done) { + it("will try all nodes", function (done) { var dashd = new DashService(baseConfig); dashd.tryAllInterval = 1; - var getRawTransactionWithError = sinon.stub().callsArgWith(1, {message: 'error', code: -1}); + var getRawTransactionWithError = sinon.stub().callsArgWith(1, { message: "error", code: -1 }); var getRawTransaction = sinon.stub().callsArgWith(1, null, { - result: txhex + result: txhex, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransactionWithError - } + getRawTransaction: getRawTransactionWithError, + }, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransactionWithError - } + getRawTransaction: getRawTransactionWithError, + }, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransaction - } + getRawTransaction: getRawTransaction, + }, }); - dashd.getTransaction('txid', function(err, tx) { + dashd.getTransaction("txid", function (err, tx) { if (err) { return done(err); } @@ -4770,44 +4801,46 @@ describe('Dash Service', function() { done(); }); }); - it('will get from cache', function(done) { + it("will get from cache", function (done) { var dashd = new DashService(baseConfig); var getRawTransaction = sinon.stub().callsArgWith(1, null, { - result: txhex + result: txhex, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransaction - } + getRawTransaction: getRawTransaction, + }, }); - dashd.getTransaction('txid', function(err, tx) { + dashd.getTransaction("txid", function (err, tx) { if (err) { return done(err); } should.exist(tx); tx.should.be.an.instanceof(dashcore.Transaction); - dashd.getTransaction('txid', function(err, tx) { + dashd.getTransaction("txid", function (err, tx) { should.exist(tx); tx.should.be.an.instanceof(dashcore.Transaction); getRawTransaction.callCount.should.equal(1); done(); }); - }); }); }); - describe('#getDetailedTransaction', function() { - var txBuffer = new Buffer('01000000016f95980911e01c2c664b3e78299527a47933aac61a515930a8fe0213d1ac9abe01000000da0047304402200e71cda1f71e087c018759ba3427eb968a9ea0b1decd24147f91544629b17b4f0220555ee111ed0fc0f751ffebf097bdf40da0154466eb044e72b6b3dcd5f06807fa01483045022100c86d6c8b417bff6cc3bbf4854c16bba0aaca957e8f73e19f37216e2b06bb7bf802205a37be2f57a83a1b5a8cc511dc61466c11e9ba053c363302e7b99674be6a49fc0147522102632178d046673c9729d828cfee388e121f497707f810c131e0d3fc0fe0bd66d62103a0951ec7d3a9da9de171617026442fcd30f34d66100fab539853b43f508787d452aeffffffff0240420f000000000017a9148a31d53a448c18996e81ce67811e5fb7da21e4468738c9d6f90000000017a9148ce5408cfeaddb7ccb2545ded41ef478109454848700000000', 'hex'); + describe("#getDetailedTransaction", function () { + var txBuffer = new Buffer( + "01000000016f95980911e01c2c664b3e78299527a47933aac61a515930a8fe0213d1ac9abe01000000da0047304402200e71cda1f71e087c018759ba3427eb968a9ea0b1decd24147f91544629b17b4f0220555ee111ed0fc0f751ffebf097bdf40da0154466eb044e72b6b3dcd5f06807fa01483045022100c86d6c8b417bff6cc3bbf4854c16bba0aaca957e8f73e19f37216e2b06bb7bf802205a37be2f57a83a1b5a8cc511dc61466c11e9ba053c363302e7b99674be6a49fc0147522102632178d046673c9729d828cfee388e121f497707f810c131e0d3fc0fe0bd66d62103a0951ec7d3a9da9de171617026442fcd30f34d66100fab539853b43f508787d452aeffffffff0240420f000000000017a9148a31d53a448c18996e81ce67811e5fb7da21e4468738c9d6f90000000017a9148ce5408cfeaddb7ccb2545ded41ef478109454848700000000", + "hex" + ); var info = { - blockHash: '00000000000ec715852ea2ecae4dc8563f62d603c820f81ac284cd5be0a944d6', + blockHash: "00000000000ec715852ea2ecae4dc8563f62d603c820f81ac284cd5be0a944d6", height: 530482, timestamp: 1439559434000, - buffer: txBuffer + buffer: txBuffer, }; var rpcRawTransaction = { - hex: txBuffer.toString('hex'), + hex: txBuffer.toString("hex"), blockhash: info.blockHash, height: info.height, version: 1, @@ -4816,61 +4849,61 @@ describe('Dash Service', function() { vin: [ { valueSat: 110, - address: 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW', - txid: '3d003413c13eec3fa8ea1fe8bbff6f40718c66facffe2544d7516c9e2900cac2', - sequence: 0xFFFFFFFF, + address: "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW", + txid: "3d003413c13eec3fa8ea1fe8bbff6f40718c66facffe2544d7516c9e2900cac2", + sequence: 0xffffffff, vout: 0, scriptSig: { - hex: 'scriptSigHex', - asm: 'scriptSigAsm' - } - } + hex: "scriptSigHex", + asm: "scriptSigAsm", + }, + }, ], vout: [ { - spentTxId: '4316b98e7504073acd19308b4b8c9f4eeb5e811455c54c0ebfe276c0b1eb6315', + spentTxId: "4316b98e7504073acd19308b4b8c9f4eeb5e811455c54c0ebfe276c0b1eb6315", spentIndex: 2, spentHeight: 100, valueSat: 100, scriptPubKey: { - hex: '76a9140b2f0a0c31bfe0406b0ccc1381fdbe311946dadc88ac', - asm: 'OP_DUP OP_HASH160 0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc OP_EQUALVERIFY OP_CHECKSIG', - addresses: ['mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW'] - } - } - ] + hex: "76a9140b2f0a0c31bfe0406b0ccc1381fdbe311946dadc88ac", + asm: "OP_DUP OP_HASH160 0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc OP_EQUALVERIFY OP_CHECKSIG", + addresses: ["mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"], + }, + }, + ], }; - it('should give a transaction with height and timestamp', function(done) { + it("should give a transaction with height and timestamp", function (done) { var dashd = new DashService(baseConfig); dashd.nodes.push({ client: { - getRawTransaction: sinon.stub().callsArgWith(2, {code: -1, message: 'Test error'}) - } + getRawTransaction: sinon.stub().callsArgWith(2, { code: -1, message: "Test error" }), + }, }); - var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f'; - dashd.getDetailedTransaction(txid, function(err) { + var txid = "2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f"; + dashd.getDetailedTransaction(txid, function (err) { should.exist(err); err.should.be.instanceof(errors.RPCError); done(); }); }); - it('should give a transaction with all properties', function(done) { + it("should give a transaction with all properties", function (done) { var dashd = new DashService(baseConfig); var getRawTransaction = sinon.stub().callsArgWith(2, null, { - result: rpcRawTransaction + result: rpcRawTransaction, }); dashd.nodes.push({ client: { - getRawTransaction: getRawTransaction - } + getRawTransaction: getRawTransaction, + }, }); - var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f'; + var txid = "2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f"; function checkTx(tx) { /* jshint maxstatements: 30 */ should.exist(tx); should.not.exist(tx.coinbase); - should.equal(tx.hex, txBuffer.toString('hex')); - should.equal(tx.blockHash, '00000000000ec715852ea2ecae4dc8563f62d603c820f81ac284cd5be0a944d6'); + should.equal(tx.hex, txBuffer.toString("hex")); + should.equal(tx.blockHash, "00000000000ec715852ea2ecae4dc8563f62d603c820f81ac284cd5be0a944d6"); should.equal(tx.height, 530482); should.equal(tx.blockTimestamp, 1439559434000); should.equal(tx.version, 1); @@ -4880,28 +4913,31 @@ describe('Dash Service', function() { should.equal(tx.outputSatoshis, 100); should.equal(tx.hash, txid); var input = tx.inputs[0]; - should.equal(input.prevTxId, '3d003413c13eec3fa8ea1fe8bbff6f40718c66facffe2544d7516c9e2900cac2'); + should.equal(input.prevTxId, "3d003413c13eec3fa8ea1fe8bbff6f40718c66facffe2544d7516c9e2900cac2"); should.equal(input.outputIndex, 0); should.equal(input.satoshis, 110); - should.equal(input.sequence, 0xFFFFFFFF); - should.equal(input.script, 'scriptSigHex'); - should.equal(input.scriptAsm, 'scriptSigAsm'); - should.equal(input.address, 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW'); + should.equal(input.sequence, 0xffffffff); + should.equal(input.script, "scriptSigHex"); + should.equal(input.scriptAsm, "scriptSigAsm"); + should.equal(input.address, "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"); var output = tx.outputs[0]; should.equal(output.satoshis, 100); - should.equal(output.script, '76a9140b2f0a0c31bfe0406b0ccc1381fdbe311946dadc88ac'); - should.equal(output.scriptAsm, 'OP_DUP OP_HASH160 0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc OP_EQUALVERIFY OP_CHECKSIG'); - should.equal(output.address, 'mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW'); - should.equal(output.spentTxId, '4316b98e7504073acd19308b4b8c9f4eeb5e811455c54c0ebfe276c0b1eb6315'); + should.equal(output.script, "76a9140b2f0a0c31bfe0406b0ccc1381fdbe311946dadc88ac"); + should.equal( + output.scriptAsm, + "OP_DUP OP_HASH160 0b2f0a0c31bfe0406b0ccc1381fdbe311946dadc OP_EQUALVERIFY OP_CHECKSIG" + ); + should.equal(output.address, "mgY65WSfEmsyYaYPQaXhmXMeBhwp4EcsQW"); + should.equal(output.spentTxId, "4316b98e7504073acd19308b4b8c9f4eeb5e811455c54c0ebfe276c0b1eb6315"); should.equal(output.spentIndex, 2); should.equal(output.spentHeight, 100); } - dashd.getDetailedTransaction(txid, function(err, tx) { + dashd.getDetailedTransaction(txid, function (err, tx) { if (err) { return done(err); } checkTx(tx); - dashd.getDetailedTransaction(txid, function(err, tx) { + dashd.getDetailedTransaction(txid, function (err, tx) { if (err) { return done(err); } @@ -4911,115 +4947,115 @@ describe('Dash Service', function() { }); }); }); - it('should set coinbase to true', function(done) { + it("should set coinbase to true", function (done) { var dashd = new DashService(baseConfig); - var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction))); + var rawTransaction = JSON.parse(JSON.stringify(rpcRawTransaction)); delete rawTransaction.vin[0]; rawTransaction.vin = [ { - coinbase: 'abcdef' - } + coinbase: "abcdef", + }, ]; dashd.nodes.push({ client: { getRawTransaction: sinon.stub().callsArgWith(2, null, { - result: rawTransaction - }) - } + result: rawTransaction, + }), + }, }); - var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f'; - dashd.getDetailedTransaction(txid, function(err, tx) { + var txid = "2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f"; + dashd.getDetailedTransaction(txid, function (err, tx) { should.exist(tx); should.equal(tx.coinbase, true); done(); }); }); - it('will not include address if address length is zero', function(done) { + it("will not include address if address length is zero", function (done) { var dashd = new DashService(baseConfig); - var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction))); + var rawTransaction = JSON.parse(JSON.stringify(rpcRawTransaction)); rawTransaction.vout[0].scriptPubKey.addresses = []; dashd.nodes.push({ client: { getRawTransaction: sinon.stub().callsArgWith(2, null, { - result: rawTransaction - }) - } + result: rawTransaction, + }), + }, }); - var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f'; - dashd.getDetailedTransaction(txid, function(err, tx) { + var txid = "2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f"; + dashd.getDetailedTransaction(txid, function (err, tx) { should.exist(tx); should.equal(tx.outputs[0].address, null); done(); }); }); - it('will not include address if address length is greater than 1', function(done) { + it("will not include address if address length is greater than 1", function (done) { var dashd = new DashService(baseConfig); - var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction))); - rawTransaction.vout[0].scriptPubKey.addresses = ['one', 'two']; + var rawTransaction = JSON.parse(JSON.stringify(rpcRawTransaction)); + rawTransaction.vout[0].scriptPubKey.addresses = ["one", "two"]; dashd.nodes.push({ client: { getRawTransaction: sinon.stub().callsArgWith(2, null, { - result: rawTransaction - }) - } + result: rawTransaction, + }), + }, }); - var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f'; - dashd.getDetailedTransaction(txid, function(err, tx) { + var txid = "2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f"; + dashd.getDetailedTransaction(txid, function (err, tx) { should.exist(tx); should.equal(tx.outputs[0].address, null); done(); }); }); - it('will handle scriptPubKey.addresses not being set', function(done) { + it("will handle scriptPubKey.addresses not being set", function (done) { var dashd = new DashService(baseConfig); - var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction))); - delete rawTransaction.vout[0].scriptPubKey['addresses']; + var rawTransaction = JSON.parse(JSON.stringify(rpcRawTransaction)); + delete rawTransaction.vout[0].scriptPubKey["addresses"]; dashd.nodes.push({ client: { getRawTransaction: sinon.stub().callsArgWith(2, null, { - result: rawTransaction - }) - } + result: rawTransaction, + }), + }, }); - var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f'; - dashd.getDetailedTransaction(txid, function(err, tx) { + var txid = "2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f"; + dashd.getDetailedTransaction(txid, function (err, tx) { should.exist(tx); should.equal(tx.outputs[0].address, null); done(); }); }); - it('will not include script if input missing scriptSig or coinbase', function(done) { + it("will not include script if input missing scriptSig or coinbase", function (done) { var dashd = new DashService(baseConfig); - var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction))); + var rawTransaction = JSON.parse(JSON.stringify(rpcRawTransaction)); delete rawTransaction.vin[0].scriptSig; delete rawTransaction.vin[0].coinbase; dashd.nodes.push({ client: { getRawTransaction: sinon.stub().callsArgWith(2, null, { - result: rawTransaction - }) - } + result: rawTransaction, + }), + }, }); - var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f'; - dashd.getDetailedTransaction(txid, function(err, tx) { + var txid = "2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f"; + dashd.getDetailedTransaction(txid, function (err, tx) { should.exist(tx); should.equal(tx.inputs[0].script, null); done(); }); }); - it('will set height to -1 if missing height', function(done) { + it("will set height to -1 if missing height", function (done) { var dashd = new DashService(baseConfig); - var rawTransaction = JSON.parse((JSON.stringify(rpcRawTransaction))); + var rawTransaction = JSON.parse(JSON.stringify(rpcRawTransaction)); delete rawTransaction.height; dashd.nodes.push({ client: { getRawTransaction: sinon.stub().callsArgWith(2, null, { - result: rawTransaction - }) - } + result: rawTransaction, + }), + }, }); - var txid = '2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f'; - dashd.getDetailedTransaction(txid, function(err, tx) { + var txid = "2d950d00494caf6bfc5fff2a3f839f0eb50f663ae85ce092bc5f9d45296ae91f"; + dashd.getDetailedTransaction(txid, function (err, tx) { should.exist(tx); should.equal(tx.height, -1); done(); @@ -5027,50 +5063,50 @@ describe('Dash Service', function() { }); }); - describe('#getBestBlockHash', function() { - it('will give rpc error', function(done) { + describe("#getBestBlockHash", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var getBestBlockHash = sinon.stub().callsArgWith(0, {message: 'error', code: -1}); + var getBestBlockHash = sinon.stub().callsArgWith(0, { message: "error", code: -1 }); dashd.nodes.push({ client: { - getBestBlockHash: getBestBlockHash - } + getBestBlockHash: getBestBlockHash, + }, }); - dashd.getBestBlockHash(function(err) { + dashd.getBestBlockHash(function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will call client getInfo and give result', function(done) { + it("will call client getInfo and give result", function (done) { var dashd = new DashService(baseConfig); var getBestBlockHash = sinon.stub().callsArgWith(0, null, { - result: 'besthash' + result: "besthash", }); dashd.nodes.push({ client: { - getBestBlockHash: getBestBlockHash - } + getBestBlockHash: getBestBlockHash, + }, }); - dashd.getBestBlockHash(function(err, hash) { + dashd.getBestBlockHash(function (err, hash) { if (err) { return done(err); } should.exist(hash); - hash.should.equal('besthash'); + hash.should.equal("besthash"); done(); }); }); }); - describe('#getBestChainLock', function () { - it('will give rpc error', function (done) { + describe("#getBestChainLock", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var getBestChainLock = sinon.stub().callsArgWith(0, { message: 'error', code: -32603 }); + var getBestChainLock = sinon.stub().callsArgWith(0, { message: "error", code: -32603 }); dashd.nodes.push({ client: { - getBestChainLock: getBestChainLock - } + getBestChainLock: getBestChainLock, + }, }); dashd.getBestChainLock(function (err) { should.exist(err); @@ -5078,21 +5114,21 @@ describe('Dash Service', function() { done(); }); }); - it('will call getBestChainLock and give result', function (done) { + it("will call getBestChainLock and give result", function (done) { var dashd = new DashService(baseConfig); var getBestChainLock = sinon.stub().callsArgWith(0, null, { result: { bestchainlock: { - blockhash: '20b6cc0600037171b8bb634bbd04ea754945be44db8d9199b74798f1abdb382d', + blockhash: "20b6cc0600037171b8bb634bbd04ea754945be44db8d9199b74798f1abdb382d", height: 151, - known_block: true - } - } + known_block: true, + }, + }, }); dashd.nodes.push({ client: { - getBestChainLock: getBestChainLock - } + getBestChainLock: getBestChainLock, + }, }); dashd.getBestChainLock(function (err, result) { if (err) { @@ -5101,64 +5137,64 @@ describe('Dash Service', function() { should.exist(result); result.should.deep.equal({ bestchainlock: { - blockhash: '20b6cc0600037171b8bb634bbd04ea754945be44db8d9199b74798f1abdb382d', + blockhash: "20b6cc0600037171b8bb634bbd04ea754945be44db8d9199b74798f1abdb382d", height: 151, - known_block: true - } + known_block: true, + }, }); done(); }); }); }); - describe('#getSpentInfo', function() { - it('will give rpc error', function(done) { + describe("#getSpentInfo", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var getSpentInfo = sinon.stub().callsArgWith(1, {message: 'error', code: -1}); + var getSpentInfo = sinon.stub().callsArgWith(1, { message: "error", code: -1 }); dashd.nodes.push({ client: { - getSpentInfo: getSpentInfo - } + getSpentInfo: getSpentInfo, + }, }); - dashd.getSpentInfo({}, function(err) { + dashd.getSpentInfo({}, function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will empty object when not found', function(done) { + it("will empty object when not found", function (done) { var dashd = new DashService(baseConfig); - var getSpentInfo = sinon.stub().callsArgWith(1, {message: 'test', code: -5}); + var getSpentInfo = sinon.stub().callsArgWith(1, { message: "test", code: -5 }); dashd.nodes.push({ client: { - getSpentInfo: getSpentInfo - } + getSpentInfo: getSpentInfo, + }, }); - dashd.getSpentInfo({}, function(err, info) { + dashd.getSpentInfo({}, function (err, info) { should.not.exist(err); info.should.deep.equal({}); done(); }); }); - it('will call client getSpentInfo and give result', function(done) { + it("will call client getSpentInfo and give result", function (done) { var dashd = new DashService(baseConfig); var getSpentInfo = sinon.stub().callsArgWith(1, null, { result: { - txid: 'txid', + txid: "txid", index: 10, - height: 101 - } + height: 101, + }, }); dashd.nodes.push({ client: { - getSpentInfo: getSpentInfo - } + getSpentInfo: getSpentInfo, + }, }); - dashd.getSpentInfo({}, function(err, info) { + dashd.getSpentInfo({}, function (err, info) { if (err) { return done(err); } - info.txid.should.equal('txid'); + info.txid.should.equal("txid"); info.index.should.equal(10); info.height.should.equal(101); done(); @@ -5166,213 +5202,222 @@ describe('Dash Service', function() { }); }); - describe('#getInfo', function() { - it('will give rpc error', function(done) { + describe("#getInfo", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var getBlockchainInfo = sinon.stub().callsArgWith(0, {message: 'error', code: -1}); - var getNetworkInfo = sinon.stub().callsArgWith(0, {message: 'error', code: -1}); - var getInfo = sinon.stub().callsArgWith(0, {message: 'error', code: -1}); + var getBlockchainInfo = sinon.stub().callsArgWith(0, { message: "error", code: -1 }); + var getNetworkInfo = sinon.stub().callsArgWith(0, { message: "error", code: -1 }); + var getInfo = sinon.stub().callsArgWith(0, { message: "error", code: -1 }); dashd.nodes.push({ client: { getInfo: getInfo, getNetworkInfo: getNetworkInfo, getBlockchainInfo: getBlockchainInfo, - } + }, }); - dashd.getInfo(function(err) { + dashd.getInfo(function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will call client getInfo and give result', function(done) { + it("will call client getInfo and give result", function (done) { var dashd = new DashService(baseConfig); - dashd.node.getNetworkName = sinon.stub().returns('testnet'); + dashd.node.getNetworkName = sinon.stub().returns("testnet"); var getNetworkInfo = sinon.stub().callsArgWith(0, null, { result: { version: 1, protocolversion: 1, - subversion: '/Dashd-test:1.0.0/', + subversion: "/Dashd-test:1.0.0/", timeoffset: 1, connections: 1, relayfee: 10, - warnings: '' - } + warnings: "", + }, }); var getBlockchainInfo = sinon.stub().callsArgWith(0, null, { result: { - bestblockhash: '00000000', + bestblockhash: "00000000", blocks: 1, - chain: 'test', + chain: "test", difficulty: 1, - warnings: '' - } + warnings: "", + }, }); var getInfo = sinon.stub().callsArgWith(0, null, { - network: 'testnet' + network: "testnet", }); dashd.nodes.push({ client: { getInfo: getInfo, getNetworkInfo: getNetworkInfo, getBlockchainInfo: getBlockchainInfo, - } + }, }); - dashd.getInfo(function(err, info) { + dashd.getInfo(function (err, info) { if (err) { return done(err); } should.exist(info); - should.equal(info.bestBlockHash, '00000000'); + should.equal(info.bestBlockHash, "00000000"); should.equal(info.version, 1); - should.equal(info.chain, 'test'); - should.equal(info.subVersion, '/Dashd-test:1.0.0/'); + should.equal(info.chain, "test"); + should.equal(info.subVersion, "/Dashd-test:1.0.0/"); should.equal(info.protocolVersion, 1); should.equal(info.blocks, 1); should.equal(info.timeOffset, 1); should.equal(info.connections, 1); should.equal(info.difficulty, 1); should.equal(info.relayFee, 10); - should.equal(info.errors, ''); - info.network.should.equal('testnet'); + should.equal(info.errors, ""); + info.network.should.equal("testnet"); done(); }); }); }); - describe('#govObject', function() { - it('will call client gobject list and give result', function(done) { - var dashd = new DashService(baseConfig); - var gobject = sinon.stub().callsArgWith(1, null, { - result: [{ - "Hash": "9ce5609d41b88fca51dd3f4ad098467cf8c6f2c1b2adf93a6862a7b9bdf01a00", - "DataHex": "5b5b2270726f706f73616c222c7b22656e645f65706f6368223a313438343830393436302c226e616d65223a2264363534366361353232363730633664303039333662393562323766666233393631643063663234222c227061796d656e745f61646472657373223a22796a42746b73586b47483731693341346d6e374b7848793975634d6473717a756b57222c227061796d656e745f616d6f756e74223a332c2273746172745f65706f6368223a313438343636313730392c2274797065223a312c2275726c223a2268747470733a2f2f7777772e646173682e6f7267227d5d5d", - "DataObject": { - "end_epoch": 1484809460, - "name": "d6546ca522670c6d00936b95b27ffb3961d0cf24", - "payment_address": "yjBtksXkGH71i3A4mn7KxHy9ucMdsqzukW", - "payment_amount": 3, - "start_epoch": 1484661709, - "type": 1, - "url": "https://www.dash.org" - }, - "AbsoluteYesCount": 0, - "YesCount": 0, - "NoCount": 0, - "AbstainCount": 0 - }, { - "Hash": "21af004754d57660a5b83818b26263699b9e25c53a46395b7386e786d1644c00", - "DataHex": "5b5b2270726f706f73616c222c7b22656e645f65706f6368223a313438343636353636372c226e616d65223a2236306164663935366535313138663331633131353564613866373662396134376464363863306361222c227061796d656e745f61646472657373223a227967684b6f5272526a31696f644c6f684e4e704b52504a5a7673537562367a626756222c227061796d656e745f616d6f756e74223a39382c2273746172745f65706f6368223a313438343635343931352c2274797065223a312c2275726c223a2268747470733a2f2f7777772e646173682e6f7267227d5d5d", - "DataObject": { - "end_epoch": 1484665667, - "name": "60adf956e5118f31c1155da8f76b9a47dd68c0ca", - "payment_address": "yghKoRrRj1iodLohNNpKRPJZvsSub6zbgV", - "payment_amount": 98, - "start_epoch": 1484654915, - "type": 1, - "url": "https://www.dash.org" - }, - "AbsoluteYesCount": 0, - "YesCount": 0, - "NoCount": 0, - "AbstainCount": 0 - }, { - "Hash": "4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00", - "DataHex": "5b5b2270726f706f73616c222c7b22656e645f65706f6368223a313438333835353139332c226e616d65223a2237656139616366663561653833643863396532313764333061326234643130656638663137316638222c227061796d656e745f61646472657373223a22795a3744596b44484348664831647737724b6459614b6356796b5a6d756e62714e4c222c227061796d656e745f616d6f756e74223a38342c2273746172745f65706f6368223a313438333736353238322c2274797065223a312c2275726c223a2268747470733a2f2f7777772e646173682e6f7267227d5d5d", - "DataObject": { - "end_epoch": 1483855193, - "name": "7ea9acff5ae83d8c9e217d30a2b4d10ef8f171f8", - "payment_address": "yZ7DYkDHCHfH1dw7rKdYaKcVykZmunbqNL", - "payment_amount": 84, - "start_epoch": 1483765282, - "type": 1, - "url": "https://www.dash.org" - }, - "AbsoluteYesCount": 0, - "YesCount": 0, - "NoCount": 0, - "AbstainCount": 0 - }] - }); - dashd.nodes.push({ - client: { - gobject: gobject - } - }); - dashd.govObjectList({type: 1}, function(err, result) { - if (err) { - return done(err); - } - should.exist(result); - should.equal(result.length, 3); - done(); - }); + describe("#govObject", function () { + it("will call client gobject list and give result", function (done) { + var dashd = new DashService(baseConfig); + var gobject = sinon.stub().callsArgWith(1, null, { + result: [ + { + Hash: "9ce5609d41b88fca51dd3f4ad098467cf8c6f2c1b2adf93a6862a7b9bdf01a00", + DataHex: + "5b5b2270726f706f73616c222c7b22656e645f65706f6368223a313438343830393436302c226e616d65223a2264363534366361353232363730633664303039333662393562323766666233393631643063663234222c227061796d656e745f61646472657373223a22796a42746b73586b47483731693341346d6e374b7848793975634d6473717a756b57222c227061796d656e745f616d6f756e74223a332c2273746172745f65706f6368223a313438343636313730392c2274797065223a312c2275726c223a2268747470733a2f2f7777772e646173682e6f7267227d5d5d", + DataObject: { + end_epoch: 1484809460, + name: "d6546ca522670c6d00936b95b27ffb3961d0cf24", + payment_address: "yjBtksXkGH71i3A4mn7KxHy9ucMdsqzukW", + payment_amount: 3, + start_epoch: 1484661709, + type: 1, + url: "https://www.dash.org", + }, + AbsoluteYesCount: 0, + YesCount: 0, + NoCount: 0, + AbstainCount: 0, + }, + { + Hash: "21af004754d57660a5b83818b26263699b9e25c53a46395b7386e786d1644c00", + DataHex: + "5b5b2270726f706f73616c222c7b22656e645f65706f6368223a313438343636353636372c226e616d65223a2236306164663935366535313138663331633131353564613866373662396134376464363863306361222c227061796d656e745f61646472657373223a227967684b6f5272526a31696f644c6f684e4e704b52504a5a7673537562367a626756222c227061796d656e745f616d6f756e74223a39382c2273746172745f65706f6368223a313438343635343931352c2274797065223a312c2275726c223a2268747470733a2f2f7777772e646173682e6f7267227d5d5d", + DataObject: { + end_epoch: 1484665667, + name: "60adf956e5118f31c1155da8f76b9a47dd68c0ca", + payment_address: "yghKoRrRj1iodLohNNpKRPJZvsSub6zbgV", + payment_amount: 98, + start_epoch: 1484654915, + type: 1, + url: "https://www.dash.org", + }, + AbsoluteYesCount: 0, + YesCount: 0, + NoCount: 0, + AbstainCount: 0, + }, + { + Hash: "4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00", + DataHex: + "5b5b2270726f706f73616c222c7b22656e645f65706f6368223a313438333835353139332c226e616d65223a2237656139616366663561653833643863396532313764333061326234643130656638663137316638222c227061796d656e745f61646472657373223a22795a3744596b44484348664831647737724b6459614b6356796b5a6d756e62714e4c222c227061796d656e745f616d6f756e74223a38342c2273746172745f65706f6368223a313438333736353238322c2274797065223a312c2275726c223a2268747470733a2f2f7777772e646173682e6f7267227d5d5d", + DataObject: { + end_epoch: 1483855193, + name: "7ea9acff5ae83d8c9e217d30a2b4d10ef8f171f8", + payment_address: "yZ7DYkDHCHfH1dw7rKdYaKcVykZmunbqNL", + payment_amount: 84, + start_epoch: 1483765282, + type: 1, + url: "https://www.dash.org", + }, + AbsoluteYesCount: 0, + YesCount: 0, + NoCount: 0, + AbstainCount: 0, + }, + ], + }); + dashd.nodes.push({ + client: { + gobject: gobject, + }, + }); + dashd.govObjectList({ type: 1 }, function (err, result) { + if (err) { + return done(err); + } + should.exist(result); + should.equal(result.length, 3); + done(); + }); }); - it('will call client gobject list and return error', function(done) { + it("will call client gobject list and return error", function (done) { var dashd = new DashService(baseConfig); - var gobject = sinon.stub().callsArgWith(1, {message: 'error', code: -1}); + var gobject = sinon.stub().callsArgWith(1, { message: "error", code: -1 }); dashd.nodes.push({ client: { - gobject: gobject - } + gobject: gobject, + }, }); - dashd.govObjectList({type: 1}, function(err, result) { + dashd.govObjectList({ type: 1 }, function (err, result) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will call client gobject get and give result', function(done) { + it("will call client gobject get and give result", function (done) { var dashd = new DashService(baseConfig); var hash = "4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00"; var gobject = sinon.stub().callsArgWith(2, null, { result: { - "DataHex": "5b5b2270726f706f73616c222c7b22656e645f65706f6368223a313438333835353139332c226e616d65223a2237656139616366663561653833643863396532313764333061326234643130656638663137316638222c227061796d656e745f61646472657373223a22795a3744596b44484348664831647737724b6459614b6356796b5a6d756e62714e4c222c227061796d656e745f616d6f756e74223a38342c2273746172745f65706f6368223a313438333736353238322c2274797065223a312c2275726c223a2268747470733a2f2f7777772e646173682e6f7267227d5d5d", - "DataString": "[[\"proposal\",{\"end_epoch\":1483855193,\"name\":\"7ea9acff5ae83d8c9e217d30a2b4d10ef8f171f8\",\"payment_address\":\"yZ7DYkDHCHfH1dw7rKdYaKcVykZmunbqNL\",\"payment_amount\":84,\"start_epoch\":1483765282,\"type\":1,\"url\":\"https://www.dash.org\"}]]", - "Hash": "4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00", - "CollateralHash": "6be3a3ae49498ec8f4e5cba56ac44164aeb78e57f2dbc716f4ff863034830d08", - "CreationTime": 1483724928, - "FundingResult": { - "AbsoluteYesCount": 0, - "YesCount": 0, - "NoCount": 0, - "AbstainCount": 0 + DataHex: + "5b5b2270726f706f73616c222c7b22656e645f65706f6368223a313438333835353139332c226e616d65223a2237656139616366663561653833643863396532313764333061326234643130656638663137316638222c227061796d656e745f61646472657373223a22795a3744596b44484348664831647737724b6459614b6356796b5a6d756e62714e4c222c227061796d656e745f616d6f756e74223a38342c2273746172745f65706f6368223a313438333736353238322c2274797065223a312c2275726c223a2268747470733a2f2f7777772e646173682e6f7267227d5d5d", + DataString: + '[["proposal",{"end_epoch":1483855193,"name":"7ea9acff5ae83d8c9e217d30a2b4d10ef8f171f8","payment_address":"yZ7DYkDHCHfH1dw7rKdYaKcVykZmunbqNL","payment_amount":84,"start_epoch":1483765282,"type":1,"url":"https://www.dash.org"}]]', + Hash: "4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00", + CollateralHash: "6be3a3ae49498ec8f4e5cba56ac44164aeb78e57f2dbc716f4ff863034830d08", + CreationTime: 1483724928, + FundingResult: { + AbsoluteYesCount: 0, + YesCount: 0, + NoCount: 0, + AbstainCount: 0, }, - "ValidResult": { - "AbsoluteYesCount": -11, - "YesCount": 36, - "NoCount": 47, - "AbstainCount": 0 + ValidResult: { + AbsoluteYesCount: -11, + YesCount: 36, + NoCount: 47, + AbstainCount: 0, }, - "DeleteResult": { - "AbsoluteYesCount": 0, - "YesCount": 0, - "NoCount": 0, - "AbstainCount": 0 + DeleteResult: { + AbsoluteYesCount: 0, + YesCount: 0, + NoCount: 0, + AbstainCount: 0, }, - "EndorsedResult": { - "AbsoluteYesCount": 0, - "YesCount": 0, - "NoCount": 0, - "AbstainCount": 0 + EndorsedResult: { + AbsoluteYesCount: 0, + YesCount: 0, + NoCount: 0, + AbstainCount: 0, }, - "fLocalValidity": true, - "IsValidReason": "", - "fCachedValid": false, - "fCachedFunding": false, - "fCachedDelete": false, - "fCachedEndorsed": false - } + fLocalValidity: true, + IsValidReason: "", + fCachedValid: false, + fCachedFunding: false, + fCachedDelete: false, + fCachedEndorsed: false, + }, }); dashd.nodes.push({ client: { - gobject: gobject - } + gobject: gobject, + }, }); - dashd.govObjectHash('4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00', function(err, result) { + dashd.govObjectHash("4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00", function (err, result) { if (err) { return done(err); } @@ -5380,330 +5425,383 @@ describe('Dash Service', function() { var DataObject = result[0].DataObject; should.equal(DataObject.end_epoch, 1483855193); - should.equal(DataObject.name, '7ea9acff5ae83d8c9e217d30a2b4d10ef8f171f8'); - should.equal(DataObject.payment_address, 'yZ7DYkDHCHfH1dw7rKdYaKcVykZmunbqNL'); + should.equal(DataObject.name, "7ea9acff5ae83d8c9e217d30a2b4d10ef8f171f8"); + should.equal(DataObject.payment_address, "yZ7DYkDHCHfH1dw7rKdYaKcVykZmunbqNL"); should.equal(DataObject.payment_amount, 84); should.equal(DataObject.start_epoch, 1483765282); should.equal(DataObject.type, 1); - should.equal(DataObject.url, 'https://www.dash.org'); + should.equal(DataObject.url, "https://www.dash.org"); done(); }); }); - it('will call client gobject get and return error', function(done) { + it("will call client gobject get and return error", function (done) { var dashd = new DashService(baseConfig); - var gobject = sinon.stub().callsArgWith(2, {message: 'error', code: -1}); + var gobject = sinon.stub().callsArgWith(2, { message: "error", code: -1 }); dashd.nodes.push({ client: { - gobject: gobject - } + gobject: gobject, + }, }); - dashd.govObjectHash('4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00', function(err, result) { + dashd.govObjectHash("4ef24027c631c43035aa4cf5c672e1298311decd9cffbd16731f454c9c0d6d00", function (err, result) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - }); - describe('#sporksList', function(){ - it('will call client sporks and give result', function(done){ - var dashd = new DashService(baseConfig); + describe("#sporksList", function () { + it("will call client sporks and give result", function (done) { + var dashd = new DashService(baseConfig); - dashd.nodes.push({ - client: { - spork: function(param, callback){ - if(param==="show"){ - callback(null,{result:{ - "SPORK_2_INSTANTSEND_ENABLED":0, - "SPORK_3_INSTANTSEND_BLOCK_FILTERING":0, - "SPORK_5_INSTANTSEND_MAX_VALUE":2000, - "SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT":0, - "SPORK_9_SUPERBLOCKS_ENABLED":0, - "SPORK_10_MASTERNODE_PAY_UPDATED_NODES":0, - "SPORK_12_RECONSIDER_BLOCKS":0, - "SPORK_13_OLD_SUPERBLOCK_FLAG":4070908800, - "SPORK_14_REQUIRE_SENTINEL_FLAG":4070908800 - } - }) - } - } - } - }); - dashd.getSpork(function(err, SporkList) { - if (err) { - return done(err); - } - SporkList.should.have.property('sporks'); - var sporks = SporkList.sporks; - Object.keys(sporks).length.should.equal(9); - sporks['SPORK_2_INSTANTSEND_ENABLED'].should.equal(0); - sporks['SPORK_3_INSTANTSEND_BLOCK_FILTERING'].should.equal(0); - sporks['SPORK_5_INSTANTSEND_MAX_VALUE'].should.equal(2000); - sporks['SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT'].should.equal(0); - sporks['SPORK_9_SUPERBLOCKS_ENABLED'].should.equal(0); - sporks['SPORK_10_MASTERNODE_PAY_UPDATED_NODES'].should.equal(0); - sporks['SPORK_12_RECONSIDER_BLOCKS'].should.equal(0); - sporks['SPORK_13_OLD_SUPERBLOCK_FLAG'].should.equal(4070908800); - sporks['SPORK_14_REQUIRE_SENTINEL_FLAG'].should.equal(4070908800); - done(); - }); - }); - }); - describe('#getMNList', function(){ - it('will call client masternode list and give result', function(done){ - var dashd = new DashService(baseConfig); - dashd.isSynced = function(callback) { return callback(null, true) }; - dashd.nodes.push({ - client: { - masternodelist: function(type, cb){ - switch (type){ - case "rank": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 1, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 2} - }); - case "protocol": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 70206, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 70206} - }); - case "payee": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "Xfpp5BxPfFistPPjTe6FucYmtDVmT1GDG3", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "Xn16rfdygfViHe2u36jkDUs9NLmUrUsEKa"} - }); - case "lastseen": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 1502078120, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 1502078203} - }); - case "activeseconds": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 7016289, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 2871829} - }); - break; - case "addr": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "108.61.209.47:9999", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "34.226.228.73:9999"} - }); - case "status": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "ENABLED", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "ENABLED"} - }); - } - } - } - }); + dashd.nodes.push({ + client: { + spork: function (param, callback) { + if (param === "show") { + callback(null, { + result: { + SPORK_2_INSTANTSEND_ENABLED: 0, + SPORK_3_INSTANTSEND_BLOCK_FILTERING: 0, + SPORK_5_INSTANTSEND_MAX_VALUE: 2000, + SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT: 0, + SPORK_9_SUPERBLOCKS_ENABLED: 0, + SPORK_10_MASTERNODE_PAY_UPDATED_NODES: 0, + SPORK_12_RECONSIDER_BLOCKS: 0, + SPORK_13_OLD_SUPERBLOCK_FLAG: 4070908800, + SPORK_14_REQUIRE_SENTINEL_FLAG: 4070908800, + }, + }); + } + }, + }, + }); + dashd.getSpork(function (err, SporkList) { + if (err) { + return done(err); + } + SporkList.should.have.property("sporks"); + var sporks = SporkList.sporks; + Object.keys(sporks).length.should.equal(9); + sporks["SPORK_2_INSTANTSEND_ENABLED"].should.equal(0); + sporks["SPORK_3_INSTANTSEND_BLOCK_FILTERING"].should.equal(0); + sporks["SPORK_5_INSTANTSEND_MAX_VALUE"].should.equal(2000); + sporks["SPORK_8_MASTERNODE_PAYMENT_ENFORCEMENT"].should.equal(0); + sporks["SPORK_9_SUPERBLOCKS_ENABLED"].should.equal(0); + sporks["SPORK_10_MASTERNODE_PAY_UPDATED_NODES"].should.equal(0); + sporks["SPORK_12_RECONSIDER_BLOCKS"].should.equal(0); + sporks["SPORK_13_OLD_SUPERBLOCK_FLAG"].should.equal(4070908800); + sporks["SPORK_14_REQUIRE_SENTINEL_FLAG"].should.equal(4070908800); + done(); + }); + }); + }); + describe("#getMNList", function () { + it("will call client masternode list and give result", function (done) { + var dashd = new DashService(baseConfig); + dashd.isSynced = function (callback) { + return callback(null, true); + }; + dashd.nodes.push({ + client: { + masternodelist: function (type, cb) { + switch (type) { + case "rank": + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 1, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 2, + }, + }); + case "protocol": + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 70206, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 70206, + }, + }); + case "payee": + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": + "Xfpp5BxPfFistPPjTe6FucYmtDVmT1GDG3", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": + "Xn16rfdygfViHe2u36jkDUs9NLmUrUsEKa", + }, + }); + case "lastseen": + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 1502078120, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 1502078203, + }, + }); + case "activeseconds": + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 7016289, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 2871829, + }, + }); + break; + case "addr": + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": "108.61.209.47:9999", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": "34.226.228.73:9999", + }, + }); + case "status": + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": "ENABLED", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": "ENABLED", + }, + }); + } + }, + }, + }); - dashd.getMNList(function(err, MNList) { - if (err) { - return done(err); - } - MNList.length.should.equal(2); - MNList[0].vin.should.equal("06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0"); - MNList[0].status.should.equal("ENABLED"); - MNList[0].rank.should.equal(1); - MNList[0].ip.should.equal("108.61.209.47:9999"); - MNList[0].protocol.should.equal(70206); - MNList[0].payee.should.equal("Xfpp5BxPfFistPPjTe6FucYmtDVmT1GDG3"); - MNList[0].activeseconds.should.equal(7016289); - MNList[0].lastseen.should.equal(1502078120); - done(); - }); + dashd.getMNList(function (err, MNList) { + if (err) { + return done(err); + } + MNList.length.should.equal(2); + MNList[0].vin.should.equal("06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0"); + MNList[0].status.should.equal("ENABLED"); + MNList[0].rank.should.equal(1); + MNList[0].ip.should.equal("108.61.209.47:9999"); + MNList[0].protocol.should.equal(70206); + MNList[0].payee.should.equal("Xfpp5BxPfFistPPjTe6FucYmtDVmT1GDG3"); + MNList[0].activeseconds.should.equal(7016289); + MNList[0].lastseen.should.equal(1502078120); + done(); + }); }); - it('will return error if one of nodes not synced yet', function(done){ + it("will return error if one of nodes not synced yet", function (done) { var dashd = new DashService(baseConfig); - dashd.isSynced = function(callback) { return callback(null, false) }; + dashd.isSynced = function (callback) { + return callback(null, false); + }; dashd.nodes.push({ client: { - masternodelist: function(type, cb){ - switch (type){ + masternodelist: function (type, cb) { + switch (type) { case "rank": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 1, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 2} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 1, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 2, + }, }); case "protocol": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 70206, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 60000} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 70206, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 60000, + }, }); case "payee": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "Xfpp5BxPfFistPPjTe6FucYmtDVmT1GDG3", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "Xn16rfdygfViHe2u36jkDUs9NLmUrUsEKa"} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": + "Xfpp5BxPfFistPPjTe6FucYmtDVmT1GDG3", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": + "Xn16rfdygfViHe2u36jkDUs9NLmUrUsEKa", + }, }); case "lastseen": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 1502078120, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 1502078203} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 1502078120, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 1502078203, + }, }); case "activeseconds": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 7016289, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 2871829} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 7016289, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 2871829, + }, }); break; case "addr": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "108.61.209.47:9999", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "34.226.228.73:9999"} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": "108.61.209.47:9999", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": "34.226.228.73:9999", + }, }); case "status": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "ENABLED", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "ENABLED"} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": "ENABLED", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": "ENABLED", + }, }); } - } - } + }, + }, }); - dashd.getMNList(function(err, MNList) { + dashd.getMNList(function (err, MNList) { err.should.be.instanceof(Error); - err.message.should.be.equal('Blockchain is not synced yet'); + err.message.should.be.equal("Blockchain is not synced yet"); done(); }); }); - it('will return error if checking synced state of nodes failed', function(done){ + it("will return error if checking synced state of nodes failed", function (done) { var dashd = new DashService(baseConfig); - dashd.isSynced = function(callback) { return callback(new Error('Failed')) }; + dashd.isSynced = function (callback) { + return callback(new Error("Failed")); + }; dashd.nodes.push({ client: { - masternodelist: function(type, cb){ - switch (type){ + masternodelist: function (type, cb) { + switch (type) { case "rank": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 1, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 2} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 1, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 2, + }, }); case "protocol": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 70206, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 60000} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 70206, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 60000, + }, }); case "payee": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "Xfpp5BxPfFistPPjTe6FucYmtDVmT1GDG3", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "Xn16rfdygfViHe2u36jkDUs9NLmUrUsEKa"} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": + "Xfpp5BxPfFistPPjTe6FucYmtDVmT1GDG3", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": + "Xn16rfdygfViHe2u36jkDUs9NLmUrUsEKa", + }, }); case "lastseen": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 1502078120, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 1502078203} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 1502078120, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 1502078203, + }, }); case "activeseconds": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': 7016289, - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': 2871829} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": 7016289, + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": 2871829, + }, }); break; case "addr": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "108.61.209.47:9999", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "34.226.228.73:9999"} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": "108.61.209.47:9999", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": "34.226.228.73:9999", + }, }); case "status": - return cb(null, { result: - { '06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0': "ENABLED", - 'b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1': "ENABLED"} + return cb(null, { + result: { + "06c4c53b64019a021e8597c19e40807038cab4cd422ca9241db82aa19887354b-0": "ENABLED", + "b76bafae974b80204e79858eb62aedec41159519c90d23f811cca1eca40f2e4c-1": "ENABLED", + }, }); } - } - } + }, + }, }); - dashd.getMNList(function(err, MNList) { + dashd.getMNList(function (err, MNList) { err.should.be.instanceof(Error); done(); }); }); }); - describe('#generateBlock', function() { - it('will give rpc error', function(done) { + describe("#generateBlock", function () { + it("will give rpc error", function (done) { var dashd = new DashService(baseConfig); - var generate = sinon.stub().callsArgWith(1, {message: 'error', code: -1}); + var generate = sinon.stub().callsArgWith(1, { message: "error", code: -1 }); dashd.nodes.push({ client: { - generate: generate - } + generate: generate, + }, }); - dashd.generateBlock(10, function(err) { + dashd.generateBlock(10, function (err) { should.exist(err); err.should.be.an.instanceof(errors.RPCError); done(); }); }); - it('will call client generate and give result', function(done) { + it("will call client generate and give result", function (done) { var dashd = new DashService(baseConfig); var generate = sinon.stub().callsArgWith(1, null, { - result: ['hash'] + result: ["hash"], }); dashd.nodes.push({ client: { - generate: generate - } + generate: generate, + }, }); - dashd.generateBlock(10, function(err, hashes) { + dashd.generateBlock(10, function (err, hashes) { if (err) { return done(err); } hashes.length.should.equal(1); - hashes[0].should.equal('hash'); + hashes[0].should.equal("hash"); done(); }); }); }); - describe('#stop', function() { - it('will callback if spawn is not set', function(done) { + describe("#stop", function () { + it("will callback if spawn is not set", function (done) { var dashd = new DashService(baseConfig); dashd.stop(done); }); - it('will exit spawned process', function(done) { + it("will exit spawned process", function (done) { var dashd = new DashService(baseConfig); dashd.spawn = {}; dashd.spawn.process = new EventEmitter(); dashd.spawn.process.kill = sinon.stub(); dashd.stop(done); dashd.spawn.process.kill.callCount.should.equal(1); - dashd.spawn.process.kill.args[0][0].should.equal('SIGINT'); - dashd.spawn.process.emit('exit', 0); + dashd.spawn.process.kill.args[0][0].should.equal("SIGINT"); + dashd.spawn.process.emit("exit", 0); }); - it('will give error with non-zero exit status code', function(done) { + it("will give error with non-zero exit status code", function (done) { var dashd = new DashService(baseConfig); dashd.spawn = {}; dashd.spawn.process = new EventEmitter(); dashd.spawn.process.kill = sinon.stub(); - dashd.stop(function(err) { + dashd.stop(function (err) { err.should.be.instanceof(Error); err.code.should.equal(1); done(); }); dashd.spawn.process.kill.callCount.should.equal(1); - dashd.spawn.process.kill.args[0][0].should.equal('SIGINT'); - dashd.spawn.process.emit('exit', 1); + dashd.spawn.process.kill.args[0][0].should.equal("SIGINT"); + dashd.spawn.process.emit("exit", 1); }); - it('will stop after timeout', function(done) { + it("will stop after timeout", function (done) { var dashd = new DashService(baseConfig); dashd.shutdownTimeout = 300; dashd.spawn = {}; dashd.spawn.process = new EventEmitter(); dashd.spawn.process.kill = sinon.stub(); - dashd.stop(function(err) { + dashd.stop(function (err) { err.should.be.instanceof(Error); done(); }); dashd.spawn.process.kill.callCount.should.equal(1); - dashd.spawn.process.kill.args[0][0].should.equal('SIGINT'); + dashd.spawn.process.kill.args[0][0].should.equal("SIGINT"); }); }); - }); diff --git a/test/services/web.unit.js b/test/services/web.unit.js index 3d0ff593b..c6dbe35c3 100644 --- a/test/services/web.unit.js +++ b/test/services/web.unit.js @@ -1,75 +1,75 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var sinon = require('sinon'); -var EventEmitter = require('events').EventEmitter; -var proxyquire = require('proxyquire'); +var should = require("chai").should(); +var sinon = require("sinon"); +var EventEmitter = require("events").EventEmitter; +var proxyquire = require("proxyquire"); -var index = require('../../lib'); +var index = require("../../lib"); var log = index.log; var httpStub = { - createServer: sinon.spy() + createServer: sinon.spy(), }; var httpsStub = { - createServer: sinon.spy() + createServer: sinon.spy(), }; var fsStub = { - readFileSync: function(arg1) { - return arg1 + '-buffer'; - } + readFileSync: function (arg1) { + return arg1 + "-buffer"; + }, }; var fakeSocketListener = new EventEmitter(); var fakeSocket = new EventEmitter(); -fakeSocket.on('test/event1', function(data) { - data.should.equal('testdata'); +fakeSocket.on("test/event1", function (data) { + data.should.equal("testdata"); }); -fakeSocketListener.emit('connection', fakeSocket); -fakeSocket.emit('subscribe', 'test/event1'); +fakeSocketListener.emit("connection", fakeSocket); +fakeSocket.emit("subscribe", "test/event1"); -var WebService = proxyquire('../../lib/services/web', {http: httpStub, https: httpsStub, fs: fsStub}); +var WebService = proxyquire("../../lib/services/web", { http: httpStub, https: httpsStub, fs: fsStub }); -describe('WebService', function() { +describe("WebService", function () { var defaultNode = new EventEmitter(); - describe('@constructor', function() { - it('will set socket rpc settings', function() { - var web = new WebService({node: defaultNode, enableSocketRPC: false}); + describe("@constructor", function () { + it("will set socket rpc settings", function () { + var web = new WebService({ node: defaultNode, enableSocketRPC: false }); web.enableSocketRPC.should.equal(false); - var web2 = new WebService({node: defaultNode, enableSocketRPC: true}); + var web2 = new WebService({ node: defaultNode, enableSocketRPC: true }); web2.enableSocketRPC.should.equal(true); - var web3 = new WebService({node: defaultNode}); + var web3 = new WebService({ node: defaultNode }); web3.enableSocketRPC.should.equal(WebService.DEFAULT_SOCKET_RPC); }); }); - describe('#start', function() { - beforeEach(function() { + describe("#start", function () { + beforeEach(function () { httpStub.createServer.reset(); httpsStub.createServer.reset(); }); - it('should create an http server if no options are specified and node is not configured for https', function(done) { - var web = new WebService({node: defaultNode}); + it("should create an http server if no options are specified and node is not configured for https", function (done) { + var web = new WebService({ node: defaultNode }); web.deriveHttpsOptions = sinon.spy(); - web.start(function(err) { + web.start(function (err) { should.not.exist(err); httpStub.createServer.called.should.equal(true); done(); }); }); - it('should create an https server if no options are specified and node is configured for https', function(done) { + it("should create an https server if no options are specified and node is configured for https", function (done) { var node = new EventEmitter(); node.https = true; - var web = new WebService({node: node}); + var web = new WebService({ node: node }); web.transformHttpsOptions = sinon.spy(); - web.start(function(err) { + web.start(function (err) { should.not.exist(err); httpsStub.createServer.called.should.equal(true); done(); @@ -77,14 +77,14 @@ describe('WebService', function() { }); }); - describe('#stop', function() { - it('should close the server if it exists', function(done) { - var web = new WebService({node: defaultNode}); + describe("#stop", function () { + it("should close the server if it exists", function (done) { + var web = new WebService({ node: defaultNode }); web.server = { - close: sinon.spy() + close: sinon.spy(), }; - web.stop(function(err) { + web.stop(function (err) { should.not.exist(err); web.server.close.callCount.should.equal(1); done(); @@ -92,25 +92,25 @@ describe('WebService', function() { }); }); - describe('#setupAllRoutes', function() { - it('should call setupRoutes on each module', function() { + describe("#setupAllRoutes", function () { + it("should call setupRoutes on each module", function () { var node = { on: sinon.spy(), services: { one: { setupRoutes: sinon.spy(), - getRoutePrefix: sinon.stub().returns('one') + getRoutePrefix: sinon.stub().returns("one"), }, two: { setupRoutes: sinon.spy(), - getRoutePrefix: sinon.stub().returns('two') - } - } + getRoutePrefix: sinon.stub().returns("two"), + }, + }, }; - var web = new WebService({node: node}); + var web = new WebService({ node: node }); web.app = { - use: sinon.spy() + use: sinon.spy(), }; web.setupAllRoutes(); @@ -123,19 +123,19 @@ describe('WebService', function() { }); }); - describe('#createMethodsMap', function() { - it('should create the methodsMap correctly', function(done) { - var Module1 = function() {}; - Module1.prototype.getAPIMethods = function() { + describe("#createMethodsMap", function () { + it("should create the methodsMap correctly", function (done) { + var Module1 = function () {}; + Module1.prototype.getAPIMethods = function () { return [ - ['one', this, this.one, 1], - ['two', this, this.two, 2] + ["one", this, this.one, 1], + ["two", this, this.two, 2], ]; }; - Module1.prototype.one = function(param1, callback) { + Module1.prototype.one = function (param1, callback) { callback(null, param1); }; - Module1.prototype.two = function(param1, param2, callback) { + Module1.prototype.two = function (param1, param2, callback) { callback(null, param1 + param2); }; @@ -143,20 +143,20 @@ describe('WebService', function() { var node = { on: sinon.spy(), - getAllAPIMethods: sinon.stub().returns(module1.getAPIMethods()) + getAllAPIMethods: sinon.stub().returns(module1.getAPIMethods()), }; - var web = new WebService({node: node}); + var web = new WebService({ node: node }); web.createMethodsMap(); Object.keys(web.methodsMap).length.should.equal(2); web.methodsMap.one.args.should.equal(1); web.methodsMap.two.args.should.equal(2); - web.methodsMap.one.fn(1, function(err, result) { + web.methodsMap.one.fn(1, function (err, result) { should.not.exist(err); result.should.equal(1); - web.methodsMap.two.fn(1, 2, function(err, result) { + web.methodsMap.two.fn(1, 2, function (err, result) { should.not.exist(err); result.should.equal(3); done(); @@ -165,99 +165,99 @@ describe('WebService', function() { }); }); - describe('#getEventNames', function() { - it('should get event names', function() { - var Module1 = function() {}; - Module1.prototype.getPublishEvents = function() { + describe("#getEventNames", function () { + it("should get event names", function () { + var Module1 = function () {}; + Module1.prototype.getPublishEvents = function () { return [ { - name: 'event1', - extraEvents: ['event2'] - } + name: "event1", + extraEvents: ["event2"], + }, ]; }; var module1 = new Module1(); var node = { on: sinon.spy(), - getAllPublishEvents: sinon.stub().returns(module1.getPublishEvents()) + getAllPublishEvents: sinon.stub().returns(module1.getPublishEvents()), }; - var web = new WebService({node: node}); + var web = new WebService({ node: node }); var events = web.getEventNames(); - events.should.deep.equal(['event1', 'event2']); + events.should.deep.equal(["event1", "event2"]); }); - it('should throw an error if there is a duplicate event', function() { - var Module1 = function() {}; - Module1.prototype.getPublishEvents = function() { + it("should throw an error if there is a duplicate event", function () { + var Module1 = function () {}; + Module1.prototype.getPublishEvents = function () { return [ { - name: 'event1', - extraEvents: ['event1'] - } + name: "event1", + extraEvents: ["event1"], + }, ]; }; var module1 = new Module1(); var node = { on: sinon.spy(), - getAllPublishEvents: sinon.stub().returns(module1.getPublishEvents()) + getAllPublishEvents: sinon.stub().returns(module1.getPublishEvents()), }; - var web = new WebService({node: node}); - (function() { + var web = new WebService({ node: node }); + (function () { var events = web.getEventNames(); - }).should.throw('Duplicate event event1'); + }).should.throw("Duplicate event event1"); }); }); - describe('#_getRemoteAddress', function() { - it('will get remote address from cloudflare header', function() { - var web = new WebService({node: defaultNode}); + describe("#_getRemoteAddress", function () { + it("will get remote address from cloudflare header", function () { + var web = new WebService({ node: defaultNode }); var socket = {}; socket.conn = {}; socket.client = {}; socket.client.request = {}; socket.client.request.headers = { - 'cf-connecting-ip': '127.0.0.1' + "cf-connecting-ip": "127.0.0.1", }; var remoteAddress = web._getRemoteAddress(socket); - remoteAddress.should.equal('127.0.0.1'); + remoteAddress.should.equal("127.0.0.1"); }); - it('will get remote address from connection', function() { - var web = new WebService({node: defaultNode}); + it("will get remote address from connection", function () { + var web = new WebService({ node: defaultNode }); var socket = {}; socket.conn = {}; - socket.conn.remoteAddress = '127.0.0.1'; + socket.conn.remoteAddress = "127.0.0.1"; socket.client = {}; socket.client.request = {}; socket.client.request.headers = {}; var remoteAddress = web._getRemoteAddress(socket); - remoteAddress.should.equal('127.0.0.1'); + remoteAddress.should.equal("127.0.0.1"); }); }); - describe('#socketHandler', function() { + describe("#socketHandler", function () { var sandbox = sinon.sandbox.create(); - beforeEach(function() { - sandbox.stub(log, 'info'); + beforeEach(function () { + sandbox.stub(log, "info"); }); - afterEach(function() { + afterEach(function () { sandbox.restore(); }); var bus = new EventEmitter(); - bus.remoteAddress = '127.0.0.1'; + bus.remoteAddress = "127.0.0.1"; - var Module1 = function() {}; - Module1.prototype.getPublishEvents = function() { + var Module1 = function () {}; + Module1.prototype.getPublishEvents = function () { return [ { - name: 'event1', - extraEvents: ['event2'] - } + name: "event1", + extraEvents: ["event2"], + }, ]; }; @@ -265,181 +265,180 @@ describe('WebService', function() { var node = { on: sinon.spy(), openBus: sinon.stub().returns(bus), - getAllPublishEvents: sinon.stub().returns(module1.getPublishEvents()) + getAllPublishEvents: sinon.stub().returns(module1.getPublishEvents()), }; var web; var socket; - it('on message should call socketMessageHandler', function(done) { - web = new WebService({node: node}); + it("on message should call socketMessageHandler", function (done) { + web = new WebService({ node: node }); web.eventNames = web.getEventNames(); - web.socketMessageHandler = function(param1) { - param1.should.equal('data'); + web.socketMessageHandler = function (param1) { + param1.should.equal("data"); done(); }; socket = new EventEmitter(); socket.conn = {}; - socket.conn.remoteAddress = '127.0.0.1'; + socket.conn.remoteAddress = "127.0.0.1"; socket.client = {}; socket.client.request = {}; socket.client.request.headers = {}; web.socketHandler(socket); - socket.emit('message', 'data'); + socket.emit("message", "data"); }); - it('on message should NOT call socketMessageHandler if not enabled', function(done) { - web = new WebService({node: node, enableSocketRPC: false}); + it("on message should NOT call socketMessageHandler if not enabled", function (done) { + web = new WebService({ node: node, enableSocketRPC: false }); web.eventNames = web.getEventNames(); web.socketMessageHandler = sinon.stub(); socket = new EventEmitter(); socket.conn = {}; - socket.conn.remoteAddress = '127.0.0.1'; + socket.conn.remoteAddress = "127.0.0.1"; socket.client = {}; socket.client.request = {}; socket.client.request.headers = {}; web.socketHandler(socket); - socket.on('message', function() { + socket.on("message", function () { web.socketMessageHandler.callCount.should.equal(0); done(); }); - socket.emit('message', 'data'); + socket.emit("message", "data"); }); - it('on subscribe should call bus.subscribe', function(done) { - bus.subscribe = function(param1) { - param1.should.equal('data'); + it("on subscribe should call bus.subscribe", function (done) { + bus.subscribe = function (param1) { + param1.should.equal("data"); done(); }; - socket.emit('subscribe', 'data'); + socket.emit("subscribe", "data"); }); - it('on unsubscribe should call bus.unsubscribe', function(done) { - bus.unsubscribe = function(param1) { - param1.should.equal('data'); + it("on unsubscribe should call bus.unsubscribe", function (done) { + bus.unsubscribe = function (param1) { + param1.should.equal("data"); done(); }; - socket.emit('unsubscribe', 'data'); + socket.emit("unsubscribe", "data"); }); - it('publish events from bus should be emitted from socket', function(done) { - socket.once('event2', function(param1, param2) { - param1.should.equal('param1'); - param2.should.equal('param2'); + it("publish events from bus should be emitted from socket", function (done) { + socket.once("event2", function (param1, param2) { + param1.should.equal("param1"); + param2.should.equal("param2"); done(); }); socket.connected = true; - bus.emit('event2', 'param1', 'param2'); + bus.emit("event2", "param1", "param2"); }); - it('on disconnect should close bus', function(done) { - bus.close = function() { + it("on disconnect should close bus", function (done) { + bus.close = function () { done(); }; - socket.emit('disconnect'); + socket.emit("disconnect"); }); }); - describe('#socketMessageHandler', function() { + describe("#socketMessageHandler", function () { var node = { - on: sinon.spy() + on: sinon.spy(), }; - var web = new WebService({node: node}); + var web = new WebService({ node: node }); web.methodsMap = { one: { - fn: function(param1, param2, callback) { + fn: function (param1, param2, callback) { var result = param1 + param2; - if(result > 0) { + if (result > 0) { return callback(null, result); } else { - return callback(new Error('error')); + return callback(new Error("error")); } }, - args: 2 - } + args: 2, + }, }; - it('should give a Method Not Found error if method does not exist', function(done) { + it("should give a Method Not Found error if method does not exist", function (done) { var message = { - method: 'two', - params: [1, 2] + method: "two", + params: [1, 2], }; - web.socketMessageHandler(message, function(response) { + web.socketMessageHandler(message, function (response) { should.exist(response.error); - response.error.message.should.equal('Method Not Found'); + response.error.message.should.equal("Method Not Found"); done(); }); }); - it('should call the method and return the result', function(done) { + it("should call the method and return the result", function (done) { var message = { - method: 'one', - params: [1, 2] + method: "one", + params: [1, 2], }; - web.socketMessageHandler(message, function(response) { + web.socketMessageHandler(message, function (response) { should.not.exist(response.error); response.result.should.equal(3); done(); }); }); - it('should give an error if there is a param count mismatch', function(done) { + it("should give an error if there is a param count mismatch", function (done) { var message = { - method: 'one', - params: [1] + method: "one", + params: [1], }; - web.socketMessageHandler(message, function(response) { + web.socketMessageHandler(message, function (response) { should.exist(response.error); - response.error.message.should.equal('Expected 2 parameter(s)'); + response.error.message.should.equal("Expected 2 parameter(s)"); done(); }); }); - it('should give an error if the method gave an error', function(done) { + it("should give an error if the method gave an error", function (done) { var message = { - method: 'one', - params: [-1, -2] + method: "one", + params: [-1, -2], }; - web.socketMessageHandler(message, function(response) { + web.socketMessageHandler(message, function (response) { should.exist(response.error); - response.error.message.should.equal('Error: error'); + response.error.message.should.equal("Error: error"); done(); }); }); }); - describe('#deriveHttpsOptions', function() { - it('should read key and cert from files specified', function() { + describe("#deriveHttpsOptions", function () { + it("should read key and cert from files specified", function () { var web = new WebService({ node: defaultNode, https: true, httpsOptions: { - key: 'key', - cert: 'cert' - } + key: "key", + cert: "cert", + }, }); web.transformHttpsOptions(); - web.httpsOptions.key.should.equal('key-buffer'); - web.httpsOptions.cert.should.equal('cert-buffer'); + web.httpsOptions.key.should.equal("key-buffer"); + web.httpsOptions.cert.should.equal("cert-buffer"); }); - it('should throw an error if https is specified but key or cert is not specified', function() { + it("should throw an error if https is specified but key or cert is not specified", function () { var web = new WebService({ node: defaultNode, https: true, httpsOptions: { - key: 'key' - } + key: "key", + }, }); - (function() { + (function () { web.transformHttpsOptions(); - }).should.throw('Missing https options'); + }).should.throw("Missing https options"); }); }); - }); diff --git a/test/utils.unit.js b/test/utils.unit.js index ff166b830..2dabf73cf 100644 --- a/test/utils.unit.js +++ b/test/utils.unit.js @@ -1,151 +1,143 @@ -'use strict'; +"use strict"; -var should = require('chai').should(); -var utils = require('../lib/utils'); +var should = require("chai").should(); +var utils = require("../lib/utils"); -describe('Utils', function() { - - describe('#isHash', function() { - - it('false for short string', function() { - var a = utils.isHash('ashortstring'); +describe("Utils", function () { + describe("#isHash", function () { + it("false for short string", function () { + var a = utils.isHash("ashortstring"); a.should.equal(false); }); - it('false for long string', function() { - var a = utils.isHash('00000000000000000000000000000000000000000000000000000000000000000'); + it("false for long string", function () { + var a = utils.isHash("00000000000000000000000000000000000000000000000000000000000000000"); a.should.equal(false); }); - it('false for correct length invalid char', function() { - var a = utils.isHash('z000000000000000000000000000000000000000000000000000000000000000'); + it("false for correct length invalid char", function () { + var a = utils.isHash("z000000000000000000000000000000000000000000000000000000000000000"); a.should.equal(false); }); - it('false for invalid type (buffer)', function() { - var a = utils.isHash(new Buffer('abcdef', 'hex')); + it("false for invalid type (buffer)", function () { + var a = utils.isHash(new Buffer("abcdef", "hex")); a.should.equal(false); }); - it('false for invalid type (number)', function() { + it("false for invalid type (number)", function () { var a = utils.isHash(123456); a.should.equal(false); }); - it('true for hash', function() { - var a = utils.isHash('fc63629e2106c3440d7e56751adc8cfa5266a5920c1b54b81565af25aec1998b'); + it("true for hash", function () { + var a = utils.isHash("fc63629e2106c3440d7e56751adc8cfa5266a5920c1b54b81565af25aec1998b"); a.should.equal(true); }); - }); - describe('#isSafeNatural', function() { - - it('false for float', function() { + describe("#isSafeNatural", function () { + it("false for float", function () { var a = utils.isSafeNatural(0.1); a.should.equal(false); }); - it('false for string float', function() { - var a = utils.isSafeNatural('0.1'); + it("false for string float", function () { + var a = utils.isSafeNatural("0.1"); a.should.equal(false); }); - it('false for string integer', function() { - var a = utils.isSafeNatural('1'); + it("false for string integer", function () { + var a = utils.isSafeNatural("1"); a.should.equal(false); }); - it('false for negative integer', function() { + it("false for negative integer", function () { var a = utils.isSafeNatural(-1); a.should.equal(false); }); - it('false for negative integer string', function() { - var a = utils.isSafeNatural('-1'); + it("false for negative integer string", function () { + var a = utils.isSafeNatural("-1"); a.should.equal(false); }); - it('false for infinity', function() { + it("false for infinity", function () { var a = utils.isSafeNatural(Infinity); a.should.equal(false); }); - it('false for NaN', function() { + it("false for NaN", function () { var a = utils.isSafeNatural(NaN); a.should.equal(false); }); - it('false for unsafe number', function() { + it("false for unsafe number", function () { var a = utils.isSafeNatural(Math.pow(2, 53)); a.should.equal(false); }); - it('true for positive integer', function() { + it("true for positive integer", function () { var a = utils.isSafeNatural(1000); a.should.equal(true); }); - }); - describe('#startAtZero', function() { - - it('will set key to zero if not set', function() { + describe("#startAtZero", function () { + it("will set key to zero if not set", function () { var obj = {}; - utils.startAtZero(obj, 'key'); + utils.startAtZero(obj, "key"); obj.key.should.equal(0); }); - it('not if already set', function() { + it("not if already set", function () { var obj = { - key: 10 + key: 10, }; - utils.startAtZero(obj, 'key'); + utils.startAtZero(obj, "key"); obj.key.should.equal(10); }); - it('not if set to false', function() { + it("not if set to false", function () { var obj = { - key: false + key: false, }; - utils.startAtZero(obj, 'key'); + utils.startAtZero(obj, "key"); obj.key.should.equal(false); }); - it('not if set to undefined', function() { + it("not if set to undefined", function () { var obj = { - key: undefined + key: undefined, }; - utils.startAtZero(obj, 'key'); + utils.startAtZero(obj, "key"); should.equal(obj.key, undefined); }); - it('not if set to null', function() { + it("not if set to null", function () { var obj = { - key: null + key: null, }; - utils.startAtZero(obj, 'key'); + utils.startAtZero(obj, "key"); should.equal(obj.key, null); }); - }); - describe('#parseParamsWithJSON', function() { - it('will parse object', function() { - var paramsArg = ['3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou', '{"start": 100, "end": 1}']; + describe("#parseParamsWithJSON", function () { + it("will parse object", function () { + var paramsArg = ["3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", '{"start": 100, "end": 1}']; var params = utils.parseParamsWithJSON(paramsArg); - params.should.deep.equal(['3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou', {start: 100, end: 1}]); + params.should.deep.equal(["3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", { start: 100, end: 1 }]); }); - it('will parse array', function() { - var paramsArg = ['3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou', '[0, 1]']; + it("will parse array", function () { + var paramsArg = ["3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", "[0, 1]"]; var params = utils.parseParamsWithJSON(paramsArg); - params.should.deep.equal(['3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou', [0, 1]]); + params.should.deep.equal(["3CMNFxN1oHBc4R1EpboAL5yzHGgE611Xou", [0, 1]]); }); - it('will parse numbers', function() { - var paramsArg = ['3', 0, 'b', '0', 0x12, '0.0001']; + it("will parse numbers", function () { + var paramsArg = ["3", 0, "b", "0", 0x12, "0.0001"]; var params = utils.parseParamsWithJSON(paramsArg); - params.should.deep.equal([3, 0, 'b', 0, 0x12, 0.0001]); + params.should.deep.equal([3, 0, "b", 0, 0x12, 0.0001]); }); }); - });