From e2fa6719640b543ed3aba65287616b6b37849545 Mon Sep 17 00:00:00 2001 From: Chris Troutner Date: Wed, 23 Dec 2020 19:30:38 -0800 Subject: [PATCH] fix(SLPDB status): Adding GET /slp/status to get status on SLPDB --- src/routes/v4/slp.js | 44 ++++ test/v4/integration/slp.js | 9 + test/v4/mocks/slp-mocks.js | 408 ++++++++++++++++++++++++++++++++++++- test/v4/slp.js | 28 +++ 4 files changed, 488 insertions(+), 1 deletion(-) diff --git a/src/routes/v4/slp.js b/src/routes/v4/slp.js index a0bda97..fd39da9 100644 --- a/src/routes/v4/slp.js +++ b/src/routes/v4/slp.js @@ -89,6 +89,7 @@ class Slp { ) _this.router.post('/generateSendOpReturn', _this.generateSendOpReturn) _this.router.post('/hydrateUtxos', _this.hydrateUtxos) + _this.router.get('/status', _this.getStatus) } // DRY error handler. @@ -2006,6 +2007,49 @@ class Slp { }) } } + + /** + * @api {get} /slp/status Get the health status of SLPDB + * @apiName Get the health status of SLPDB + * @apiGroup SLP + * @apiDescription Get the health status of SLPDB + * + * + * @apiExample Example usage: + * curl -X GET "https://api.fullstack.cash/v4/slp/status" -H "accept:application/json" -H "Content-Type: application/json" + * + */ + async getStatus (req, res, next) { + try { + const query = { + v: 3, + q: { + db: ['s'], + find: { context: 'SLPDB' }, + limit: 10 + } + } + + const s = JSON.stringify(query) + const b64 = Buffer.from(s).toString('base64') + const url = `${process.env.SLPDB_URL}q/${b64}` + // Request options + const opt = { + method: 'get', + baseURL: url + } + const tokenRes = await _this.axios.request(opt) + + const status = tokenRes.data.s[0] + + res.status(200) + return res.json(status) + } catch (err) { + // console.log(err) + wlogger.error('Error in slp.js/getStatus().', err) + return _this.errorHandler(err, res) + } + } } module.exports = Slp diff --git a/test/v4/integration/slp.js b/test/v4/integration/slp.js index 0b1f4e3..8fabae6 100644 --- a/test/v4/integration/slp.js +++ b/test/v4/integration/slp.js @@ -416,4 +416,13 @@ describe('#slp', () => { } }) }) + + describe('#getStatus', () => { + it('should get the SLPDB status', async () => { + const result = await slp.getStatus(req, res) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.property(result, 'bchBlockHeight') + }) + }) }) diff --git a/test/v4/mocks/slp-mocks.js b/test/v4/mocks/slp-mocks.js index d18ab98..bd06b95 100644 --- a/test/v4/mocks/slp-mocks.js +++ b/test/v4/mocks/slp-mocks.js @@ -614,6 +614,411 @@ const mockValidate3Bulk = { u: [] } +const mockStatus = { + _id: '5fe408b7cd2bd2000f7fdd0a', + version: '1.0.0-beta-rc13', + versionHash: 'bb4a805610b9e4d67c1595b716df36190c75e8b1', + deplVersionHash: null, + startCmd: 'node index run', + context: 'SLPDB', + lastStatusUpdate: { + utc: 'Thu, 24 Dec 2020 03:19:19 GMT', + unix: 1608779959 + }, + lastIncomingTxnZmq: { + utc: 'Thu, 24 Dec 2020 03:19:16 GMT', + unix: 1608779956 + }, + lastIncomingBlockZmq: { + utc: 'Thu, 24 Dec 2020 03:00:27 GMT', + unix: 1608778827 + }, + lastOutgoingTxnZmq: null, + lastOutgoingBlockZmq: null, + state: 'RUNNING', + stateHistory: [ + { + utc: 'Mon, 07 Dec 2020 15:26:23 GMT', + state: 'STARTUP_BLOCK_SYNC' + }, + { + utc: 'Mon, 07 Dec 2020 15:52:20 GMT', + state: 'RUNNING' + }, + { + utc: 'Tue, 08 Dec 2020 14:42:29 GMT', + state: 'PRE_STARTUP' + }, + { + utc: 'Tue, 08 Dec 2020 14:42:29 GMT', + state: 'STARTUP_BLOCK_SYNC' + }, + { + utc: 'Tue, 08 Dec 2020 14:59:53 GMT', + state: 'RUNNING' + }, + { + utc: 'Tue, 08 Dec 2020 19:35:36 GMT', + state: 'EXITED_ON_ERROR' + }, + { + utc: 'Tue, 08 Dec 2020 19:35:36 GMT', + state: 'EXITED_ON_ERROR' + }, + { + utc: 'Tue, 08 Dec 2020 19:35:49 GMT', + state: 'PRE_STARTUP' + }, + { + utc: 'Tue, 08 Dec 2020 19:35:49 GMT', + state: 'STARTUP_BLOCK_SYNC' + }, + { + utc: 'Tue, 08 Dec 2020 19:53:04 GMT', + state: 'RUNNING' + } + ], + network: 'mainnet', + bchBlockHeight: 667203, + bchBlockHash: + '0000000000000000035f9c26b9ef3db37eba8c9351218c67c92d80444b867858', + slpProcessedBlockHeight: 667203, + mempoolInfoBch: { + loaded: true, + size: 441, + bytes: 192651, + usage: 663056, + maxmempool: 300000000, + mempoolminfee: 0.00001, + minrelaytxfee: 0.00001 + }, + mempoolSizeSlp: 68, + tokensCount: 77879, + pastStackTraces: [ + '[Tue, 08 Dec 2020 19:35:36 GMT] MongoServerSelectionError: connection to 172.17.0.1:12301 timed out\n at Timeout._onTimeout (/home/safeuser/SLPDB/node_modules/mongodb/lib/core/sdam/topology.js:438:30)\n at listOnTimeout (internal/timers.js:554:17)\n at processTimers (internal/timers.js:497:7)', + '[Tue, 08 Dec 2020 19:35:36 GMT] MongoServerSelectionError: connection to 172.17.0.1:12301 timed out\n at Timeout._onTimeout (/home/safeuser/SLPDB/node_modules/mongodb/lib/core/sdam/topology.js:438:30)\n at listOnTimeout (internal/timers.js:554:17)\n at processTimers (internal/timers.js:497:7)' + ], + doubleSpends: [ + { + txo: + '3e377f67e9d065f02e47633d847cdb04b0679d51baccdc0feea5297529e330b5:820', + details: { + originalTxid: + 'dc148149d25a546fffe0b207c62b192811c288481df5f43f1f76f67b6004f98c', + current: + 'de12db60e253c378eeebb1df85153168a998db8267ec54b38589cc31348b2b8d', + time: { + utc: 'Sat, 19 Dec 2020 02:25:37 GMT', + unix: 1608344737 + } + } + }, + { + txo: '4b7e94fc59a685bce31ee9444d20ebb0ae0478111a8bfa7ec9b5c381e2657191:2', + details: { + originalTxid: + 'a4e00c025c07a770874ecc6b2d1004fe3c561f2aceb0a8b95996e26709df1a57', + current: + '33ccab4a971331897bb3ff3978366e3575c54d83ae1a35984e50d93cffe66b95', + time: { + utc: 'Sat, 19 Dec 2020 02:33:28 GMT', + unix: 1608345208 + } + } + }, + { + txo: 'bd5ac3d02652038cc888922e50c9b57db0dfdbb5b26bb28a2e85fd28493e85e1:2', + details: { + originalTxid: + '53032355ab142ac050f1e37445ecb19ad22c5331185df7b3173e88563194ba18', + current: + '0b3ab983c5abb1ceb6f60035ff869e159e27ab5d2a4173d0d6ce027348d4dbdd', + time: { + utc: 'Sat, 19 Dec 2020 04:21:27 GMT', + unix: 1608351687 + } + } + }, + { + txo: + '8d91432598943cc22b93d10df6808abccba4baebdf2273b375ce3616a2001c07:573', + details: { + originalTxid: + '53032355ab142ac050f1e37445ecb19ad22c5331185df7b3173e88563194ba18', + current: + '7ddc241b62625ddc1d134ae17e74bf2b6f63a4c28e3c3a4f11d833270bdebcdb', + time: { + utc: 'Sat, 19 Dec 2020 04:26:12 GMT', + unix: 1608351972 + } + } + }, + { + txo: 'ff3a9268952408217f60f1689aa1137e929e6572413e429554996ec3e9b223b5:2', + details: { + originalTxid: + '342adc882eff630aa7b50098adaace3626c1e60acbdf937e41832c4508bbdb4b', + current: + '01538a27e7e164bd52a9fd3df36cd724846f44a4c26aea8764ee982486b580ff', + time: { + utc: 'Sat, 19 Dec 2020 12:58:36 GMT', + unix: 1608382716 + } + } + }, + { + txo: + '9f7de7ea735d46fbb9214353fec0b250f48a24340e0909eecd83f53817b6aaa3:314', + details: { + originalTxid: + '342adc882eff630aa7b50098adaace3626c1e60acbdf937e41832c4508bbdb4b', + current: + '01538a27e7e164bd52a9fd3df36cd724846f44a4c26aea8764ee982486b580ff', + time: { + utc: 'Sat, 19 Dec 2020 12:58:36 GMT', + unix: 1608382716 + } + } + }, + { + txo: 'ff28ad4063faa250797fa39c823b919d157ecae82b8bf68199eb0b9babbb0c12:2', + details: { + originalTxid: + 'eced12b6e07e4d830edf6d3244055ba22e953065070985755c9e7f9ea7626d1d', + current: + '512073e40e033106c45af47acfd05092b0206ac276bda459f76dfa019a0e257c', + time: { + utc: 'Sat, 19 Dec 2020 12:58:38 GMT', + unix: 1608382718 + } + } + }, + { + txo: + '9f7de7ea735d46fbb9214353fec0b250f48a24340e0909eecd83f53817b6aaa3:316', + details: { + originalTxid: + '53cffad1ffd9de20355f89ee0310cd39876c21e2d2a9d5b09548286de1e78565', + current: + 'a988c9f46f97de27eccd4f50e1bba751cdc9c49a6cac31de2f4dbf3763fb4ab3', + time: { + utc: 'Sat, 19 Dec 2020 12:58:45 GMT', + unix: 1608382725 + } + } + }, + { + txo: + '1a57786c472034b2d3d944a3cad69447c30ed5de46bd708ddead33f946ea2578:10', + details: { + originalTxid: + 'eced12b6e07e4d830edf6d3244055ba22e953065070985755c9e7f9ea7626d1d', + current: + '8ef975bd11d82c3dfb6645cc15eeaecebde23423b6506daa5145d3b20c02fab5', + time: { + utc: 'Sat, 19 Dec 2020 13:01:30 GMT', + unix: 1608382890 + } + } + }, + { + txo: + '9f7de7ea735d46fbb9214353fec0b250f48a24340e0909eecd83f53817b6aaa3:317', + details: { + originalTxid: + '5bf0b00b41a9cc1068d8573f0fb65e875743ce3ea5a3e521fff960da9223d508', + current: + '4f3bf7452f5409964cdb9f68a493b2c1f89dd16fc6eb1cc6d2b1dc753c7bfb59', + time: { + utc: 'Sat, 19 Dec 2020 13:04:46 GMT', + unix: 1608383086 + } + } + }, + { + txo: + '1a57786c472034b2d3d944a3cad69447c30ed5de46bd708ddead33f946ea2578:11', + details: { + originalTxid: + 'f1973c96dabf923f7f1e65630366921da9a806316f3e4f2478cbd754d52f6c70', + current: + '76493aaa8bdcb21bb45452250f9518674ea94b3e70fb890252278c9f8bfe3cef', + time: { + utc: 'Sat, 19 Dec 2020 13:06:31 GMT', + unix: 1608383191 + } + } + }, + { + txo: + '1a57786c472034b2d3d944a3cad69447c30ed5de46bd708ddead33f946ea2578:12', + details: { + originalTxid: + '15b22f6c97a3390c13ae79a61eb9beb34ab87d2245bf8e63d91d7b2477ccdf00', + current: + '6e529eeecd268b1763467152ff76a427c80a26750229de3ad0edbfb2b40ee43a', + time: { + utc: 'Sat, 19 Dec 2020 13:07:37 GMT', + unix: 1608383257 + } + } + }, + { + txo: 'c75126b129584314d7657ce7140f4aef64ff410053a3d9017a13307b778d4e16:2', + details: { + originalTxid: + 'cf2234e2a71a5ae7cf525c2ced332c16bde86734d841649913b4ce698a43506d', + current: + 'f98a430d9772962353cb15a58d447d3de056abde41730b92d9301d7510d1d04c', + time: { + utc: 'Sat, 19 Dec 2020 14:52:28 GMT', + unix: 1608389548 + } + } + }, + { + txo: + '9f7de7ea735d46fbb9214353fec0b250f48a24340e0909eecd83f53817b6aaa3:343', + details: { + originalTxid: + 'cf2234e2a71a5ae7cf525c2ced332c16bde86734d841649913b4ce698a43506d', + current: + 'f98a430d9772962353cb15a58d447d3de056abde41730b92d9301d7510d1d04c', + time: { + utc: 'Sat, 19 Dec 2020 14:52:28 GMT', + unix: 1608389548 + } + } + }, + { + txo: + '22fa91e7961388ec071254c65cccf824d7923a0291af0967394fc7bffb6185c1:25', + details: { + originalTxid: + '5ed601fb5b2c6fee6eb1298671471108cf656f5d19186db484c2a6711f0867c8', + current: + 'a30535841e874fe7ddefe6285bc44e5f932d1866c343b3298448985c428049a1', + time: { + utc: 'Sat, 19 Dec 2020 18:41:13 GMT', + unix: 1608403273 + } + } + }, + { + txo: + '22fa91e7961388ec071254c65cccf824d7923a0291af0967394fc7bffb6185c1:26', + details: { + originalTxid: + 'a7015340be3ff27b1773208bf7c4501811e9adfb11363c11a7ac080946fb1cd2', + current: + 'b9959428becca1c0850409a960153a55fa8cacac3ad5c7b0ba67c57e46814baf', + time: { + utc: 'Sat, 19 Dec 2020 18:42:13 GMT', + unix: 1608403333 + } + } + }, + { + txo: + '22fa91e7961388ec071254c65cccf824d7923a0291af0967394fc7bffb6185c1:27', + details: { + originalTxid: + '72435b1d8234d5ca00c6653beec318c3d40f4e902f0fec892f769125bdfc0987', + current: + '43277c2fffa2a7ff632fd2bdd0a2be950523816c42012fa00efa860ade428127', + time: { + utc: 'Sat, 19 Dec 2020 18:53:26 GMT', + unix: 1608404006 + } + } + }, + { + txo: 'b46d46d2d8b081cf4dd3fbf4bb1d36c8f22954e92f999a07c730be52006303ee:2', + details: { + originalTxid: + '93aca660517a8ea847ca5bb39dfa1b26ae72f2eabfedc7cb3ef6e804c293c697', + current: + '377c89f649de123c52ef23a1f0ec844aa6ac032c4ec1242b59ca15e1b64a883d', + time: { + utc: 'Sat, 19 Dec 2020 20:33:14 GMT', + unix: 1608409994 + } + } + }, + { + txo: + '9f7de7ea735d46fbb9214353fec0b250f48a24340e0909eecd83f53817b6aaa3:409', + details: { + originalTxid: + '4f355dfeed4a71ec0fd10688ddb3c03ea10db7629e844adfb033a859f12dc87f', + current: + '377c89f649de123c52ef23a1f0ec844aa6ac032c4ec1242b59ca15e1b64a883d', + time: { + utc: 'Sat, 19 Dec 2020 20:33:14 GMT', + unix: 1608409994 + } + } + }, + { + txo: '4bd177144edbf495f614b839c5828ec6c2d21b4a5a478b6324d681b7ecdce976:2', + details: { + originalTxid: + '4f355dfeed4a71ec0fd10688ddb3c03ea10db7629e844adfb033a859f12dc87f', + current: + '9c480d23e99fc3a31558ffb8a402bc819bf0906ca21351749db4d5fceca263b6', + time: { + utc: 'Sat, 19 Dec 2020 20:33:16 GMT', + unix: 1608409996 + } + } + }, + { + txo: + '190c84d8cb06fe750fcbf0bd11c62e23fa60cd4f7c970a1079ac746e270982be:155', + details: { + originalTxid: + '93aca660517a8ea847ca5bb39dfa1b26ae72f2eabfedc7cb3ef6e804c293c697', + current: + '75e3759d5167395aa1dca327b9b042eb1b86e893bdffc66c2480e8194c2cdc61', + time: { + utc: 'Sat, 19 Dec 2020 20:45:04 GMT', + unix: 1608410704 + } + } + } + ], + reorgs: [], + mongoDbStats: { + db: 'slpdb', + collections: 5, + views: 0, + objects: 2495075, + avgObjSize: 3188.4621913168944, + dataSize: 7586.910535812378, + storageSize: 3353.39453125, + indexes: 71, + indexSize: 1490.08203125, + totalSize: 4843.4765625, + scaleFactor: 1048576, + fsUsedSize: 74352.5859375, + fsTotalSize: 153676.98046875, + ok: 1 + }, + publicUrl: 'fullstack--bchn-02', + telemetryHash: null, + system: { + loadAvg1: 0.04, + loadAvg5: 0.03, + loadAvg15: 0, + platform: 'linux', + cpuCount: 8, + freeMem: 5832.546875, + totalMem: 31360.8828125, + uptime: 1603692, + processUptime: 1323812.053445836 + } +} + module.exports = { mockList, mockSingleToken, @@ -632,5 +1037,6 @@ module.exports = { mockTxHistory, mockPsfToken, mockValidateBulk, - mockValidate3Bulk + mockValidate3Bulk, + mockStatus } diff --git a/test/v4/slp.js b/test/v4/slp.js index c07ef7a..bffc9ac 100644 --- a/test/v4/slp.js +++ b/test/v4/slp.js @@ -192,6 +192,7 @@ describe('#SLP', () => { 'Error message expected' ) }) + it('should get token balance for an address', async () => { // Mock the RPC call for unit tests. if (process.env.TEST === 'unit') { @@ -1557,6 +1558,33 @@ describe('#SLP', () => { ) }) }) + + describe('#getStatus', () => { + it('should get the SLPDB status', async () => { + if (process.env.TEST === 'unit') { + // Mock to prevent live network connection. + sandbox + .stub(slpRoute.axios, 'request') + .resolves({ data: { s: [mockData.mockStatus] } }) + } + + const result = await slpRoute.getStatus(req, res) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.property(result, 'bchBlockHeight') + }) + + it('returns proper error when downstream service is down', async () => { + // Mock the timeout error. + sandbox.stub(slpRoute.axios, 'request').throws({ code: 'ECONNREFUSED' }) + + slpRoute.getStatus(req, res) + // const result = slpRoute.getStatus(req, res) + // console.log(`result: ${JSON.stringify(result, null, 2)}`) + + assert.isAbove(res.statusCode, 499, 'HTTP status code 503 expected.') + }) + }) }) /*