diff --git a/src/app.js b/src/app.js index 5e4dc52..54661d7 100644 --- a/src/app.js +++ b/src/app.js @@ -31,7 +31,6 @@ const utilV3 = require("./routes/v3/util") const slpV3 = require("./routes/v3/slp") const xpubV3 = require("./routes/v3/xpub") const blockbookV3 = require("./routes/v3/blockbook") -const Ninsight = require("./routes/v3/ninsight") require("dotenv").config() @@ -94,9 +93,6 @@ app.use(`/${v3prefix}/` + `slp`, slpV3.router) app.use(`/${v3prefix}/` + `xpub`, xpubV3.router) app.use(`/${v3prefix}/` + `blockbook`, blockbookV3.router) -const ninsight = new Ninsight() -app.use(`/${v3prefix}/` + `ninsight`, ninsight.router) - // catch 404 and forward to error handler app.use((req, res, next) => { const err = { diff --git a/src/routes/v3/full-node/blockchain.js b/src/routes/v3/full-node/blockchain.js index 201244a..6056ce7 100644 --- a/src/routes/v3/full-node/blockchain.js +++ b/src/routes/v3/full-node/blockchain.js @@ -56,14 +56,18 @@ function root(req, res, next) { */ async function getBestBlockHash(req, res, next) { try { - // Axios options - const options = routeUtils.getAxiosOptions() - options.data.id = "getbestblockhash" - options.data.method = "getbestblockhash" - options.data.params = [] + const { + BitboxHTTP, + username, + password, + requestConfig + } = routeUtils.setEnvVars() - const response = await axios.request(options) + requestConfig.data.id = "getbestblockhash" + requestConfig.data.method = "getbestblockhash" + requestConfig.data.params = [] + const response = await BitboxHTTP(requestConfig) return res.json(response.data.result) } catch (err) { // Attempt to decode the error message. diff --git a/src/routes/v3/full-node/blockchain2.js b/src/routes/v3/full-node/blockchain2.js deleted file mode 100644 index a7c103f..0000000 --- a/src/routes/v3/full-node/blockchain2.js +++ /dev/null @@ -1,133 +0,0 @@ -/* - A library for interacting with the Full Node -*/ - -"use strict" - -const express = require("express") -const router = express.Router() - -const axios = require("axios") -const wlogger = require("../../../util/winston-logging") - -const RouteUtils = require("../route-utils2") -const routeUtils = new RouteUtils() - -// Used to convert error messages to strings, to safely pass to users. -const util = require("util") -util.inspect.defaultOptions = { depth: 1 } - -const BCHJS = require("@chris.troutner/bch-js") -const bchjs = new BCHJS() - -let _this - -class Blockchain { - constructor() { - _this = this - - this.bchjs = bchjs - this.axios = axios - this.routeUtils = routeUtils - - this.router = router - this.router.get("/", this.root) - this.router.get("/getBestBlockHash", this.getBestBlockHash) - this.router.get("/getBlockchainInfo", this.getBlockchainInfo) - } - - root(req, res, next) { - return res.json({ status: "blockchain" }) - } - - // DRY error handler. - errorHandler(err, res) { - // Attempt to decode the error message. - const { msg, status } = this.routeUtils.decodeError(err) - if (msg) { - res.status(status) - return res.json({ error: msg }) - } - - res.status(500) - return res.json({ error: util.inspect(err) }) - } - - /** - * @api {get} /blockchain/getBestBlockHash Get best block hash - * @apiName GetBestBlockHash - * @apiGroup Blockchain - * @apiDescription Returns the hash of the best (tip) block in the longest - * block chain. - * - * @apiExample Example usage: - * curl -X GET "https://mainnet.bchjs.cash/v3/blockchain/getBestBlockHash" -H "accept: application/json" - * - * @apiSuccess {String} bestBlockHash 000000000000000002bc884334336d99c9a9c616670a9244c6a8c1fc35aa91a1 - */ - async getBestBlockHash(req, res, next) { - try { - // Axios options - const options = this.routeUtils.getAxiosOptions() - options.data.id = "getbestblockhash" - options.data.method = "getbestblockhash" - options.data.params = [] - - const response = await this.axios.request(options) - // console.log(`response.data: ${JSON.stringify(response.data, null, 2)}`) - - return res.json(response.data.result) - } catch (err) { - // Write out error to error log. - wlogger.error(`Error in blockchain.ts/getBestBlockHash().`, err) - - return this.errorHandler(err, res) - } - } - - /** - * @api {get} /blockchain/getBlockchainInfo Get blockchain info - * @apiName GetBlockchainInfo - * @apiGroup Blockchain - * @apiDescription Returns an object containing various state info regarding blockchain processing. - * - * @apiExample Example usage: - * curl -X GET "https://mainnet.bchjs.cash/v3/blockchain/getBlockchainInfo" -H "accept: application/json" - * - * @apiSuccess {Object} object Object containing data - * @apiSuccess {String} object.chain "main" - * @apiSuccess {Number} object.blocks 561838 - * @apiSuccess {Number} object.headers 561838 - * @apiSuccess {String} object.bestblockhash "000000000000000002307dd38cd01c7308b8febfcdf5772cf087b5bb023d55bc" - * @apiSuccess {Number} object.difficulty 246585566638.1496 - * @apiSuccess {String} object.mediantime 1545402693 - * @apiSuccess {Number} object.verificationprogress 0.999998831622689 - * @apiSuccess {Boolean} object.chainwork "000000000000000000000000000000000000000000d8c09a8ab7262080266b3e" - * @apiSuccess {Number} object.pruned false - * @apiSuccess {Array} object.softforks Array of objects - * @apiSuccess {String} object.softforks.id "bip34" - * @apiSuccess {String} object.softforks.version 2 - * @apiSuccess {Object} object.softforks.reject - * @apiSuccess {String} object.softforks.reject.status true - */ - async getBlockchainInfo(req, res, next) { - try { - // Axios options - const options = this.routeUtils.getAxiosOptions() - options.data.id = "getblockchaininfo" - options.data.method = "getblockchaininfo" - options.data.params = [] - - const response = await this.axios.request(options) - - return res.json(response.data.result) - } catch (err) { - // Write out error to error log. - wlogger.error(`Error in blockchain.ts/getBlockchainInfo().`, err) - - return this.errorHandler(err, res) - } - } -} - -module.exports = Blockchain diff --git a/src/routes/v3/ninsight.js b/src/routes/v3/ninsight.js deleted file mode 100644 index 97ee56c..0000000 --- a/src/routes/v3/ninsight.js +++ /dev/null @@ -1,32 +0,0 @@ -/* - A library for interacting with the Bitcoin.com ninsight (not Insight) indexer. -*/ - -"use strict" - -const express = require("express") -const axios = require("axios") -const routeUtils = require("./route-utils") -const wlogger = require("../../util/winston-logging") - -const router = express.Router() - -const BCHJS = require("@chris.troutner/bch-js") -const bchjs = new BCHJS() - -let _this - -class Ninsight { - constructor() { - _this = this - - this.router = router - this.router.get("/", this.root) - } - - root(req, res, next) { - return res.json({ status: "ninsight" }) - } -} - -module.exports = Ninsight diff --git a/src/routes/v3/route-utils.js b/src/routes/v3/route-utils.js index 4f4f580..38652fc 100644 --- a/src/routes/v3/route-utils.js +++ b/src/routes/v3/route-utils.js @@ -17,8 +17,7 @@ module.exports = { validateNetwork, // Prevents a common user error setEnvVars, // Allows RPC variables to be set dynamically based on changing env vars. decodeError, // Extract and interpret error messages. - validateArraySize, // Ensure the passed array meets rate limiting requirements. - getAxiosOptions + validateArraySize // Ensure the passed array meets rate limiting requirements. } // This function expects the Request Express.js object and an array as input. @@ -75,8 +74,7 @@ function validateNetwork(addr) { // Dynamically set these based on env vars. Allows unit testing. function setEnvVars() { const BitboxHTTP = axios.create({ - baseURL: process.env.RPC_BASEURL, - timeout: 15000 + baseURL: process.env.RPC_BASEURL }) const username = process.env.RPC_USERNAME const password = process.env.RPC_PASSWORD @@ -95,22 +93,6 @@ function setEnvVars() { return { BitboxHTTP, username, password, requestConfig } } -// Axios options used when calling axios.post() to talk with a full node. -function getAxiosOptions() { - return { - method: "post", - baseURL: process.env.RPC_BASEURL, - timeout: 15000, - auth: { - username: process.env.RPC_USERNAME, - password: process.env.RPC_PASSWORD - }, - data: { - jsonrpc: "1.0" - } - } -} - // Error messages returned by a full node can be burried pretty deep inside the // error object returned by Axios. This function attempts to extract and interpret // error messages. @@ -131,9 +113,6 @@ function decodeError(err) { if (err.response && err.response.data) return { msg: err.response.data, status: err.response.status } - // console.log(`err.message: ${err.message}`) - // console.log(`err: `, err) - // Attempt to detect a network connection error. if (err.message && err.message.indexOf("ENOTFOUND") > -1) { return { @@ -161,18 +140,6 @@ function decodeError(err) { } } - // Axios timeout (aborted) error, or service is down (connection refused). - if ( - err.code && - (err.code === "ECONNABORTED" || err.code === "ECONNREFUSED") - ) { - return { - msg: - "Network error: Could not communicate with full node or other external service.", - status: 503 - } - } - return { msg: false, status: 500 } } catch (err) { wlogger.error(`unhandled error in route-utils.js/decodeError(): `, err) diff --git a/src/routes/v3/route-utils2.js b/src/routes/v3/route-utils2.js deleted file mode 100644 index f7315d3..0000000 --- a/src/routes/v3/route-utils2.js +++ /dev/null @@ -1,163 +0,0 @@ -/* - A private library of utility functions used by several different routes. -*/ - -"use strict" - -const axios = require("axios") -const wlogger = require("../../util/winston-logging") - -const util = require("util") -util.inspect.defaultOptions = { depth: 1 } - -const BCHJS = require("@chris.troutner/bch-js") -const bchjs = new BCHJS() - -let _this - -class RouteUtils { - constructor() { - _this = this - - this.bchjs = bchjs - this.axios = axios - } - - // This function expects the Request Express.js object and an array as input. - // The array is then validated against freemium and pro-tier rate limiting - // requirements. A boolean is returned to indicate if the array size if valid - // or not. - validateArraySize(req, array) { - const FREEMIUM_INPUT_SIZE = 20 - const PRO_INPUT_SIZE = 20 - - if (req.locals && req.locals.proLimit) { - if (array.length <= PRO_INPUT_SIZE) return true - } else if (array.length <= FREEMIUM_INPUT_SIZE) { - return true - } - - return false - } - - // Axios options used when calling axios.post() to talk with a full node. - getAxiosOptions() { - return { - method: "post", - baseURL: process.env.RPC_BASEURL, - timeout: 15000, - auth: { - username: process.env.RPC_USERNAME, - password: process.env.RPC_PASSWORD - }, - data: { - jsonrpc: "1.0" - } - } - } - - // Returns true if user-provided cash address matches the correct network, - // mainnet or testnet. If NETWORK env var is not defined, it returns false. - // This prevent a common user-error issue that is easy to make: passing a - // testnet address into rest.bitcoin.com or passing a mainnet address into - // trest.bitcoin.com. - validateNetwork(addr) { - try { - const network = process.env.NETWORK - - // Return false if NETWORK is not defined. - if (!network || network === "") { - console.log(`Warning: NETWORK environment variable is not defined!`) - return false - } - - // Convert the user-provided address to a cashaddress, for easy detection - // of the intended network. - const cashAddr = this.bchjs.Address.toCashAddress(addr) - - // Return true if the network and address both match testnet - const addrIsTest = this.bchjs.Address.isTestnetAddress(cashAddr) - if (network === "testnet" && addrIsTest) return true - - // Return true if the network and address both match mainnet - const addrIsMain = this.bchjs.Address.isMainnetAddress(cashAddr) - if (network === "mainnet" && addrIsMain) return true - - return false - } catch (err) { - logger.error(`Error in validateNetwork()`) - return false - } - } - - // Error messages returned by a full node can be burried pretty deep inside the - // error object returned by Axios. This function attempts to extract and interpret - // error messages. - // Returns an object. If successful, obj.msg is a string. - // If there is a failure, obj.msg is false. - decodeError(err) { - try { - // Attempt to extract the full node error message. - if ( - err.response && - err.response.data && - err.response.data.error && - err.response.data.error.message - ) - return { msg: err.response.data.error.message, status: 400 } - - // Attempt to extract the Insight error message - if (err.response && err.response.data) - return { msg: err.response.data, status: err.response.status } - - // console.log(`err.message: ${err.message}`) - // console.log(`err: `, err) - - // Attempt to detect a network connection error. - if (err.message && err.message.indexOf("ENOTFOUND") > -1) { - return { - msg: - "Network error: Could not communicate with full node or other external service.", - status: 503 - } - } - - // Different kind of network error - if (err.message && err.message.indexOf("ENETUNREACH") > -1) { - return { - msg: - "Network error: Could not communicate with full node or other external service.", - status: 503 - } - } - - // Different kind of network error - if (err.message && err.message.indexOf("EAI_AGAIN") > -1) { - return { - msg: - "Network error: Could not communicate with full node or other external service.", - status: 503 - } - } - - // Axios timeout (aborted) error, or service is down (connection refused). - if ( - err.code && - (err.code === "ECONNABORTED" || err.code === "ECONNREFUSED") - ) { - return { - msg: - "Network error: Could not communicate with full node or other external service.", - status: 503 - } - } - - return { msg: false, status: 500 } - } catch (err) { - wlogger.error(`unhandled error in route-utils.js/decodeError(): `, err) - return { msg: false, status: 500 } - } - } -} - -module.exports = RouteUtils diff --git a/test/v3/blockchain.js b/test/v3/blockchain.js index 96bd801..b0daad6 100644 --- a/test/v3/blockchain.js +++ b/test/v3/blockchain.js @@ -115,10 +115,6 @@ describe("#BlockchainRouter", () => { ) }) - // it("return proper error connection is refused", async () => { - // - // }) - it("should GET /getBestBlockHash", async () => { // Mock the RPC call for unit tests. if (process.env.TEST === "unit") { @@ -128,7 +124,7 @@ describe("#BlockchainRouter", () => { } const result = await getBestBlockHash(req, res) - // console.log(`result: ${util.inspect(result)}`) + //console.log(`result: ${util.inspect(result)}`) assert.isString(result) assert.equal(result.length, 64, "Hash string is fixed length") diff --git a/test/v3/blockchain2.js b/test/v3/blockchain2.js deleted file mode 100644 index debaa2d..0000000 --- a/test/v3/blockchain2.js +++ /dev/null @@ -1,1271 +0,0 @@ -/* - TODO: - -getRawMempool - --Add tests for 'verbose' input values - -getMempoolEntry & getMempoolEntryBulk - --Needs e2e test to create unconfirmed tx, for real-world test. -*/ - -"use strict" - -const chai = require("chai") -const assert = chai.assert -const nock = require("nock") // HTTP mocking -const sinon = require("sinon") -// const blockchainRoute = require("../../src/routes/v3/full-node/blockchain") - -const Blockchain = require("../../src/routes/v3/full-node/blockchain2") -const uut = new Blockchain() - -const util = require("util") -util.inspect.defaultOptions = { depth: 1 } - -if (!process.env.TEST) process.env.TEST = "unit" - -// Mocking data. -const { mockReq, mockRes } = require("./mocks/express-mocks") -const mockData = require("./mocks/blockchain-mock") - -let originalEnvVars // Used during transition from integration to unit tests. - -describe("#BlockchainRouter2", () => { - let req, res - let sandbox - - // local node will be started in regtest mode on the port 48332 - //before(panda.runLocalNode) - - before(() => { - // Save existing environment variables. - originalEnvVars = { - BITCOINCOM_BASEURL: process.env.BITCOINCOM_BASEURL, - RPC_BASEURL: process.env.RPC_BASEURL, - RPC_USERNAME: process.env.RPC_USERNAME, - RPC_PASSWORD: process.env.RPC_PASSWORD - } - - // Set default environment variables for unit tests. - if (process.env.TEST === "unit") { - process.env.BITCOINCOM_BASEURL = "http://fakeurl/api/" - process.env.RPC_BASEURL = "http://fakeurl/api" - process.env.RPC_USERNAME = "fakeusername" - process.env.RPC_PASSWORD = "fakepassword" - } - }) - - // Setup the mocks before each test. - beforeEach(() => { - // Mock the req and res objects used by Express routes. - req = mockReq - res = mockRes - - // Explicitly reset the parmas and body. - req.params = {} - req.body = {} - - // Activate nock if it's inactive. - if (!nock.isActive()) nock.activate() - - sandbox = sinon.createSandbox() - }) - - afterEach(() => { - // Clean up HTTP mocks. - nock.cleanAll() // clear interceptor list. - nock.restore() - - sandbox.restore() - }) - - after(() => { - // otherwise the panda will run forever - //process.exit() - - // Restore any pre-existing environment variables. - process.env.BITCOINCOM_BASEURL = originalEnvVars.BITCOINCOM_BASEURL - process.env.RPC_BASEURL = originalEnvVars.RPC_BASEURL - process.env.RPC_USERNAME = originalEnvVars.RPC_USERNAME - process.env.RPC_PASSWORD = originalEnvVars.RPC_PASSWORD - }) - - describe("#root", () => { - it("should respond to GET for base route", async () => { - const result = uut.root(req, res) - - assert.equal(result.status, "blockchain", "Returns static string") - }) - }) - - describe("getBestBlockHash()", () => { - // block route handler. - // const getBestBlockHash = blockchainRoute.testableComponents.getBestBlockHash - - it("should throw 503 when network issues", async () => { - // Save the existing RPC URL. - const savedUrl2 = process.env.RPC_BASEURL - - // Manipulate the URL to cause a 500 network error. - process.env.RPC_BASEURL = "http://fakeurl/api/" - - const result = await uut.getBestBlockHash(req, res) - // console.log(`result: ${util.inspect(result)}`) - - // Restore the saved URL. - process.env.RPC_BASEURL = savedUrl2 - - assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - assert.include( - result.error, - "Could not communicate with full node", - "Error message expected" - ) - }) - - it("returns proper error when downstream service stalls", async () => { - // Mock the timeout error. - sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) - - const result = await uut.getBestBlockHash(req, res) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - assert.include( - result.error, - "Could not communicate with full node", - "Error message expected" - ) - }) - - it("returns proper error when downstream service is down", async () => { - // Mock the timeout error. - sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) - - const result = await uut.getBestBlockHash(req, res) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - assert.include( - result.error, - "Could not communicate with full node", - "Error message expected" - ) - }) - - it("should GET /getBestBlockHash", async () => { - // Mock the RPC call for unit tests. - if (process.env.TEST === "unit") { - sandbox - .stub(uut.axios, "request") - .resolves({ data: { result: mockData.mockBlockHash } }) - } - - const result = await uut.getBestBlockHash(req, res) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isString(result) - assert.equal(result.length, 64, "Hash string is fixed length") - }) - }) - - describe("getBlockchainInfo()", () => { - // block route handler. - // const getBlockchainInfo = - // blockchainRoute.testableComponents.getBlockchainInfo - - it("should throw 503 when network issues", async () => { - // Save the existing RPC URL. - const savedUrl2 = process.env.RPC_BASEURL - - // Manipulate the URL to cause a 500 network error. - process.env.RPC_BASEURL = "http://fakeurl/api/" - - const result = await uut.getBlockchainInfo(req, res) - //console.log(`result: ${util.inspect(result)}`) - - // Restore the saved URL. - process.env.RPC_BASEURL = savedUrl2 - - assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - assert.include( - result.error, - "Could not communicate with full node", - "Error message expected" - ) - }) - - it("returns proper error when downstream service stalls", async () => { - // Mock the timeout error. - sandbox.stub(uut.axios, "request").throws({ code: "ECONNABORTED" }) - - const result = await uut.getBestBlockHash(req, res) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - assert.include( - result.error, - "Could not communicate with full node", - "Error message expected" - ) - }) - - it("returns proper error when downstream service is down", async () => { - // Mock the timeout error. - sandbox.stub(uut.axios, "request").throws({ code: "ECONNREFUSED" }) - - const result = await uut.getBestBlockHash(req, res) - // console.log(`result: ${JSON.stringify(result, null, 2)}`) - - assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - assert.include( - result.error, - "Could not communicate with full node", - "Error message expected" - ) - }) - - it("should GET /getBlockchainInfo", async () => { - // Mock the RPC call for unit tests. - if (process.env.TEST === "unit") { - nock(`${process.env.RPC_BASEURL}`) - .post(uri => uri.includes("/")) - .reply(200, { result: mockData.mockBlockchainInfo }) - } - - const result = await uut.getBlockchainInfo(req, res) - //console.log(`result: ${util.inspect(result)}`) - - assert.hasAnyKeys(result, [ - "chain", - "blocks", - "headers", - "bestblockhash", - "difficulty", - "mediantime", - "verificationprogress", - "chainwork", - "pruned", - "softforks", - "bip9_softforks" - ]) - }) - }) - - // describe("getBlockCount()", () => { - // // block route handler. - // const getBlockCount = blockchainRoute.testableComponents.getBlockCount - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // const result = await getBlockCount(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /getBlockCount", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: 126769 }) - // } - // - // const result = await getBlockCount(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.isNumber(result) - // }) - // }) - // - // describe("getBlockHeaderSingle()", async () => { - // const getBlockHeader = - // blockchainRoute.testableComponents.getBlockHeaderSingle - // - // it("should throw 400 error if hash is missing", async () => { - // const result = await getBlockHeader(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "hash can not be empty") - // }) - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // req.params.hash = - // "00000000000008c3679777df34f1a09565f98b2400a05b7c8da72525fdca3900" - // - // const result = await getBlockHeader(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Network error: Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET block header", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { - // result: - // "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c" - // }) - // } - // - // req.params.hash = - // "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" - // - // const result = await getBlockHeader(req, res) - // // console.log(`result: ${util.inspect(result)}`) - // - // assert.isString(result) - // assert.equal( - // result, - // "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c" - // ) - // }) - // - // it("should GET verbose block header", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockBlockHeader }) - // } - // - // req.query.verbose = true - // req.params.hash = - // "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" - // - // const result = await getBlockHeader(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, [ - // "hash", - // "confirmations", - // "height", - // "version", - // "versionHex", - // "merkleroot", - // "time", - // "mediantime", - // "nonce", - // "bits", - // "difficulty", - // "chainwork", - // "previousblockhash", - // "nextblockhash" - // ]) - // }) - // }) - // - // describe("#getBlockHeaderBulk", () => { - // // route handler. - // const getBlockHeaderBulk = - // blockchainRoute.testableComponents.getBlockHeaderBulk - // - // it("should throw an error for an empty body", async () => { - // req.body = {} - // - // const result = await getBlockHeaderBulk(req, res) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // assert.include( - // result.error, - // "hashes needs to be an array", - // "Proper error message" - // ) - // }) - // - // it("should error on non-array single hash", async () => { - // req.body.hashes = - // "00000000000008c3679777df34f1a09565f98b2400a05b7c8da72525fdca3900" - // - // const result = await getBlockHeaderBulk(req, res) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // assert.include( - // result.error, - // "hashes needs to be an array", - // "Proper error message" - // ) - // }) - // - // it("should throw 400 error if addresses array is too large", async () => { - // const testArray = [] - // for (var i = 0; i < 25; i++) testArray.push("") - // - // req.body.hashes = testArray - // - // const result = await getBlockHeaderBulk(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "Array too large") - // }) - // - // it("should throw a 400 error for an invalid hash", async () => { - // req.body.hashes = ["badHash"] - // - // await getBlockHeaderBulk(req, res) - // // console.log(`result: ${util.inspect(result)}`) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // }) - // - // it("should throw 500 when network issues", async () => { - // const savedUrl = process.env.BITCOINCOM_BASEURL - // - // try { - // req.body.hashes = [ - // "00000000000008c3679777df34f1a09565f98b2400a05b7c8da72525fdca3900" - // ] - // - // // Switch the Insight URL to something that will error out. - // process.env.BITCOINCOM_BASEURL = "http://fakeurl/api/" - // - // const result = await getBlockHeaderBulk(req, res) - // - // // Restore the saved URL. - // process.env.BITCOINCOM_BASEURL = savedUrl - // - // assert.equal(res.statusCode, 500, "HTTP status code 500 expected.") - // assert.include(result.error, "ENOTFOUND", "Error message expected") - // } catch (err) { - // // Restore the saved URL. - // process.env.BITCOINCOM_BASEURL = savedUrl - // } - // }) - // - // it("should get concise block header for a single hash", async () => { - // req.body.hashes = [ - // "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" - // ] - // - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockBlockHeaderConcise }) - // } - // - // // Call the details API. - // const result = await getBlockHeaderBulk(req, res) - // // console.log(`result: ${util.inspect(result)}`) - // - // // Assert that required fields exist in the returned object. - // assert.isArray(result) - // assert.equal( - // result[0], - // "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c" - // ) - // }) - // - // it("should get verbose block header for a single hash", async () => { - // req.body = { - // hashes: [ - // "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" - // ], - // verbose: true - // } - // - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockBlockHeader }) - // } - // - // // Call the details API. - // const result = await getBlockHeaderBulk(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Assert that required fields exist in the returned object. - // assert.isArray(result) - // assert.hasAllKeys(result[0], [ - // "hash", - // "confirmations", - // "height", - // "version", - // "versionHex", - // "merkleroot", - // "time", - // "mediantime", - // "nonce", - // "bits", - // "difficulty", - // "chainwork", - // "previousblockhash", - // "nextblockhash" - // ]) - // }) - // - // it("should get details for multiple block heights", async () => { - // req.body.hashes = [ - // "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0", - // "000000000000000002fa9d7851b284c53a5831651b04211c266badf2ad2d8ef0" - // ] - // - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .times(2) - // .reply(200, { result: mockData.mockBlockHeaderConcise }) - // } - // - // // Call the details API. - // const result = await getBlockHeaderBulk(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.isArray(result) - // assert.equal(result.length, 2, "2 outputs for 2 inputs") - // }) - // }) - // - // describe("getChainTips()", () => { - // // block route handler. - // const getChainTips = blockchainRoute.testableComponents.getChainTips - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // const result = await getChainTips(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /getChainTips", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockChainTips }) - // } - // - // const result = await getChainTips(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.isArray(result) - // assert.hasAnyKeys(result[0], ["height", "hash", "branchlen", "status"]) - // }) - // }) - // - // describe("getDifficulty()", () => { - // // block route handler. - // const getDifficulty = blockchainRoute.testableComponents.getDifficulty - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // const result = await getDifficulty(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /getDifficulty", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: 4049809.205246544 }) - // } - // - // const result = await getDifficulty(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.isNumber(result) - // }) - // }) - // - // describe("getMempoolInfo()", () => { - // // block route handler. - // const getMempoolInfo = blockchainRoute.testableComponents.getMempoolInfo - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // const result = await getMempoolInfo(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /getMempoolInfo", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockMempoolInfo }) - // } - // - // const result = await getMempoolInfo(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAnyKeys(result, [ - // "result", - // "bytes", - // "usage", - // "maxmempool", - // "mempoolminfree" - // ]) - // }) - // }) - // - // describe("getRawMempool()", () => { - // // block route handler. - // const getRawMempool = blockchainRoute.testableComponents.getRawMempool - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // const result = await getRawMempool(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /getMempoolInfo", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockRawMempool }) - // } - // - // const result = await getRawMempool(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.isArray(result) - // // Not sure what other assertions should be made here. - // }) - // }) - // - // describe("getMempoolEntry()", () => { - // // block route handler. - // const getMempoolEntry = - // blockchainRoute.testableComponents.getMempoolEntrySingle - // - // it("should throw 400 if txid is empty", async () => { - // const result = await getMempoolEntry(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "txid can not be empty") - // }) - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // - // const result = await getMempoolEntry(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /getMempoolEntry", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: { error: "Transaction not in mempool" } }) - // } - // - // req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // - // const result = await getMempoolEntry(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.isString(result.error) - // assert.equal(result.error, "Transaction not in mempool") - // }) - // }) - // - // describe("#getMempoolEntryBulk", () => { - // // route handler. - // const getMempoolEntryBulk = - // blockchainRoute.testableComponents.getMempoolEntryBulk - // - // it("should throw an error for an empty body", async () => { - // req.body = {} - // - // const result = await getMempoolEntryBulk(req, res) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // assert.include( - // result.error, - // "txids needs to be an array", - // "Proper error message" - // ) - // }) - // - // it("should error on non-array single txid", async () => { - // req.body.txids = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // - // const result = await getMempoolEntryBulk(req, res) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // assert.include( - // result.error, - // "txids needs to be an array", - // "Proper error message" - // ) - // }) - // - // it("should throw 400 error if addresses array is too large", async () => { - // const testArray = [] - // for (var i = 0; i < 25; i++) testArray.push("") - // - // req.body.txids = testArray - // - // const result = await getMempoolEntryBulk(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "Array too large") - // }) - // - // // Only execute on integration tests. - // if (process.env.TEST !== "unit") { - // // Dev-note: This test passes because it expects an error. TXIDs do not - // // stay in the mempool for long, so it does not work well for a unit or - // // integration test. - // it("should retrieve single mempool entry", async () => { - // req.body.txids = [ - // `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // ] - // - // const result = await getMempoolEntryBulk(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.isString(result.error) - // assert.equal(result.error, "Transaction not in mempool") - // }) - // - // // Dev-note: This test passes because it expects an error. TXIDs do not - // // stay in the mempool for long, so it does not work well for a unit or - // // integration test. - // it("should retrieve multiple mempool entries", async () => { - // req.body.txids = [ - // `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde`, - // `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // ] - // - // const result = await getMempoolEntryBulk(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.isString(result.error) - // assert.equal(result.error, "Transaction not in mempool") - // }) - // } - // }) - // - // describe("getMempoolAncestorsSingle()", () => { - // // block route handler. - // const getMempoolAncestorsSingle = - // blockchainRoute.testableComponents.getMempoolAncestorsSingle - // - // it("should throw 400 if txid is empty", async () => { - // const result = await getMempoolAncestorsSingle(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "txid can not be empty") - // }) - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // - // const result = await getMempoolAncestorsSingle(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /getMempoolAncestorsSingle", async () => { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockAncestors }) - // - // req.params.txid = `bb0d349892d351da2767f8c45f6f7949713ff09bd12838d53e76158ddee3ce93` - // - // const result = await getMempoolAncestorsSingle(req, res) - // // console.log(`result: ${util.inspect(result)}`) - // - // assert.isArray(result) - // }) - // }) - // - // describe("getTxOut()", () => { - // // block route handler. - // const getTxOut = blockchainRoute.testableComponents.getTxOut - // - // it("should throw 400 if txid is empty", async () => { - // const result = await getTxOut(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "txid can not be empty") - // }) - // - // it("should throw 400 if n is empty", async () => { - // req.params.txid = `sometxid` - // const result = await getTxOut(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "n can not be empty") - // }) - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // req.params.n = 0 - // - // const result = await getTxOut(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // // This test can only run for unit tests. See TODO at the top of this file. - // it("should GET /getTxOut", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockTxOut }) - // } - // - // req.params.txid = `197dcda59864b1eee05498fd3c52cad787ec56ab7e635503cb39f9ab6f295d5d` - // req.params.n = 0 - // req.query.include_mempool = "true" - // - // const result = await getTxOut(req, res) - // // console.log(`result: ${JSON.stringify(result, null, 2)}`) - // - // assert.hasAllKeys(result, [ - // "bestblock", - // "confirmations", - // "value", - // "scriptPubKey", - // "coinbase" - // ]) - // assert.hasAllKeys(result.scriptPubKey, [ - // "asm", - // "hex", - // "reqSigs", - // "type", - // "addresses" - // ]) - // assert.isArray(result.scriptPubKey.addresses) - // }) - // }) - // - // describe("getTxOutProof()", () => { - // const getTxOutProof = blockchainRoute.testableComponents.getTxOutProofSingle - // - // it("should throw 400 if txid is empty", async () => { - // const result = await getTxOutProof(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "txid can not be empty") - // }) - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // req.params.txid = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // - // const result = await getTxOutProof(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /getTxOutProof", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockTxOutProof }) - // } - // - // req.params.txid = `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266` - // - // const result = await getTxOutProof(req, res) - // // console.log(`result: ${JSON.stringify(result, null, 2)}`) - // - // assert.isString(result) - // }) - // }) - // - // describe("#getTxOutProofBulk", () => { - // // route handler. - // const getTxOutProofBulk = - // blockchainRoute.testableComponents.getTxOutProofBulk - // - // it("should throw an error for an empty body", async () => { - // req.body = {} - // - // const result = await getTxOutProofBulk(req, res) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // assert.include( - // result.error, - // "txids needs to be an array", - // "Proper error message" - // ) - // }) - // - // it("should error on non-array single txid", async () => { - // req.body.txids = `d65881582ff2bff36747d7a0d0e273f10281abc8bd5c15df5d72f8f3fa779cde` - // - // const result = await getTxOutProofBulk(req, res) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // assert.include( - // result.error, - // "txids needs to be an array", - // "Proper error message" - // ) - // }) - // - // it("should throw 400 error if addresses array is too large", async () => { - // const testArray = [] - // for (var i = 0; i < 25; i++) testArray.push("") - // - // req.body.txids = testArray - // - // const result = await getTxOutProofBulk(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "Array too large") - // }) - // - // it("should GET proof for single txid", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: mockData.mockTxOutProof }) - // } - // - // req.body.txids = [ - // `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266` - // ] - // - // const result = await getTxOutProofBulk(req, res) - // //console.log(`result: ${JSON.stringify(result, null, 2)}`) - // - // assert.isArray(result) - // assert.isString(result[0]) - // }) - // - // it("should GET proof for multiple txids", async () => { - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .times(2) - // .reply(200, { result: mockData.mockTxOutProof }) - // } - // - // req.body.txids = [ - // `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266`, - // `2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266` - // ] - // - // const result = await getTxOutProofBulk(req, res) - // //console.log(`result: ${JSON.stringify(result, null, 2)}`) - // - // assert.isArray(result) - // assert.equal(result.length, 2, "Correct length of returned array") - // }) - // }) - // - // describe("verifyTxOutProof()", () => { - // const verifyTxOutProof = - // blockchainRoute.testableComponents.verifyTxOutProofSingle - // - // it("should throw 400 if proof is empty", async () => { - // const result = await verifyTxOutProof(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "proof can not be empty") - // }) - // - // it("should throw 503 when network issues", async () => { - // // Save the existing RPC URL. - // const savedUrl2 = process.env.RPC_BASEURL - // - // // Manipulate the URL to cause a 500 network error. - // process.env.RPC_BASEURL = "http://fakeurl/api/" - // - // req.params.proof = mockData.mockTxOutProof - // - // const result = await verifyTxOutProof(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // // Restore the saved URL. - // process.env.RPC_BASEURL = savedUrl2 - // - // assert.isAbove(res.statusCode, 499, "HTTP status code 503 expected.") - // assert.include( - // result.error, - // "Could not communicate with full node", - // "Error message expected" - // ) - // }) - // - // it("should GET /verifyTxOutProof", async () => { - // const expected = - // "2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266" - // - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: [expected] }) - // } - // - // req.params.proof = - // "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" - // - // const result = await verifyTxOutProof(req, res) - // //console.log(`result: ${JSON.stringify(result, null, 2)}`) - // - // assert.isArray(result) - // assert.isString(result[0]) - // assert.equal(result[0], expected) - // }) - // }) - // - // describe("#verifyTxOutProofBulk", () => { - // // route handler. - // const verifyTxOutProofBulk = - // blockchainRoute.testableComponents.verifyTxOutProofBulk - // - // it("should throw an error for an empty body", async () => { - // req.body = {} - // - // const result = await verifyTxOutProofBulk(req, res) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // assert.include( - // result.error, - // "proofs needs to be an array", - // "Proper error message" - // ) - // }) - // - // it("should error on non-array single txid", async () => { - // req.body.proofs = mockData.mockTxOutProof - // - // const result = await verifyTxOutProofBulk(req, res) - // - // assert.equal(res.statusCode, 400, "HTTP status code 400 expected.") - // assert.include( - // result.error, - // "proofs needs to be an array", - // "Proper error message" - // ) - // }) - // - // it("should throw 400 error if addresses array is too large", async () => { - // const testArray = [] - // for (var i = 0; i < 25; i++) testArray.push("") - // - // req.body.proofs = testArray - // - // const result = await verifyTxOutProofBulk(req, res) - // //console.log(`result: ${util.inspect(result)}`) - // - // assert.hasAllKeys(result, ["error"]) - // assert.include(result.error, "Array too large") - // }) - // - // it("should get single proof", async () => { - // const expected = - // "2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266" - // - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .reply(200, { result: [expected] }) - // } - // - // req.body.proofs = [ - // "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" - // ] - // - // const result = await verifyTxOutProofBulk(req, res) - // //console.log(`result: ${JSON.stringify(result, null, 2)}`) - // - // assert.isArray(result) - // assert.isString(result[0]) - // assert.equal(result[0], expected) - // }) - // - // it("should get multiple proofs", async () => { - // const expected = - // "2c7ae9f865f7ce0c33c189b2f83414176903ce4b06ed9f8b7bcf55efbd4a7266" - // - // // Mock the RPC call for unit tests. - // if (process.env.TEST === "unit") { - // nock(`${process.env.RPC_BASEURL}`) - // .post(uri => uri.includes("/")) - // .times(2) - // .reply(200, { result: [expected] }) - // } - // - // req.body.proofs = [ - // "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700", - // "000000202ed2723e7590e2b937f6821a99d6764cb8799bf30f8e300000000000000000001d311c02df9a1e3f57b8dbdcf97ec8dbc3109a26779724c63e560b29ad9ea501e2af955d286403183049e39c1e000000067139f230701a2819a76795564bd2f67ded7eeae68596f368eddb3dd5bc54e59320e896f71d61cfc3ae3d4a90fca08b1aa35ba91256d8939d2cad11e638c0081f66724abdef55cf7b8b9fed064bce0369171434f8b289c1330ccef765f8e97a2c0d794d81aafb535855f7daa6bb51e40f77c6b59d7af7f62d0eb726a4fc4df82353d56fcbda7c7ea6bd935d61af8fb3b295637e6f323b10231135b3f10a034cfb238f635830c0595e52c6c31247cf677b555f7a287076e20cd0e1d3cc9af7260f02b700" - // ] - // - // const result = await verifyTxOutProofBulk(req, res) - // //console.log(`result: ${JSON.stringify(result, null, 2)}`) - // - // assert.isArray(result) - // assert.isString(result[0]) - // assert.equal(result[0], expected) - // assert.equal(result.length, 2) - // }) - // }) -})