From b367f42814326d888787e0c2d349d82e20d74bca Mon Sep 17 00:00:00 2001 From: kenshin-samourai Date: Thu, 19 Nov 2020 17:10:04 +0100 Subject: [PATCH] track progress of import/rescan --- accounts/xpub-rest-api.js | 25 ++++++++++++++++++------- doc/GET_xpub_import_status.md | 11 +++++++++++ lib/remote-importer/remote-importer.js | 23 +++++++++++++++++++---- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/accounts/xpub-rest-api.js b/accounts/xpub-rest-api.js index b612a5b..cce81d8 100644 --- a/accounts/xpub-rest-api.js +++ b/accounts/xpub-rest-api.js @@ -16,6 +16,7 @@ const RpcClient = require('../lib/bitcoind-rpc/rpc-client') const HdAccountInfo = require('../lib/wallet/hd-account-info') const authMgr = require('../lib/auth/authorizations-manager') const HttpServer = require('../lib/http-server/http-server') +const remoteImporter = require('../lib/remote-importer/remote-importer') const debugApi = !!(process.argv.indexOf('api-debug') > -1) const gap = require('../keys/')[network.key].gap @@ -230,8 +231,18 @@ class XPubRestApi { return HttpServer.sendError(res, e) } - const ret = { - import_in_progress: hdaService.importInProgress(xpub) + let ret = { + import_in_progress: false + } + + const status = hdaService.importInProgress(xpub) + if (status != null) { + ret['import_in_progress'] = true + ret['status'] = status['status'] + if (ret['status'] == remoteImporter.STATUS_RESCAN) + ret['hits'] = status['txs_int'] + status['txs_ext'] + else + ret['hits'] = status['txs'] } HttpServer.sendOkData(res, ret) @@ -275,7 +286,7 @@ class XPubRestApi { const argAddr = req.body.address const argSig = req.body.signature const argMsg = req.body.message - + // Translate xpub if needed try { const ret = this.xlatHdAccount(argXpub) @@ -323,7 +334,7 @@ class XPubRestApi { const argXpub = req.params.xpub const argAddr = req.body.address const argSig = req.body.signature - + // Translate xpub if needed try { const ret = this.xlatHdAccount(argXpub) @@ -398,15 +409,15 @@ class XPubRestApi { validateArgsPostXpub(req, res, next) { const isValidXpub = validator.isAlphanumeric(req.body.xpub) - const isValidSegwit = + const isValidSegwit = !req.body.segwit || validator.isAlphanumeric(req.body.segwit) - const isValidType = + const isValidType = !req.body.type || validator.isAlphanumeric(req.body.type) - const isValidForce = + const isValidForce = !req.body.force || validator.isAlphanumeric(req.body.force) diff --git a/doc/GET_xpub_import_status.md b/doc/GET_xpub_import_status.md index 4c9849a..8d0d45e 100644 --- a/doc/GET_xpub_import_status.md +++ b/doc/GET_xpub_import_status.md @@ -27,6 +27,17 @@ Status code 200 with JSON response: } ``` +```json +{ + "status": "ok", + "data": { + "import_in_progress": true, + "status": "rescan", + "hits": 1143 + } +} +``` + #### Failure Status code 400 with JSON response: ```json diff --git a/lib/remote-importer/remote-importer.js b/lib/remote-importer/remote-importer.js index 54b5e8c..a46aa7e 100644 --- a/lib/remote-importer/remote-importer.js +++ b/lib/remote-importer/remote-importer.js @@ -34,6 +34,8 @@ class RemoteImporter { * Constructor */ constructor() { + this.STATUS_RESCAN = 'rescan' + this.STATUS_IMPORT = 'import' // Guard against overlapping imports this.importing = {} this.sources = new Sources() @@ -50,12 +52,12 @@ class RemoteImporter { /** * Check if a xpub is currently being imported or rescanned by Dojo - * Returns true if import/rescan is in progress, otherwise returns false + * Returns infor about the operation if import/rescan is in progress, otherwise returns null * @param {string} xpub - xpub - * @returns {boolean} + * @returns {object} */ importInProgress(xpub) { - return this.importing[xpub] ? true : false + return this.importing[xpub] ? this.importing[xpub] : null } /** @@ -147,7 +149,11 @@ class RemoteImporter { return Promise.reject(errors.xpub.OVERLAP) } - this.importing[xpub] = true + this.importing[xpub] = { + 'status': this.STATUS_RESCAN, + 'txs_ext': 0, + 'txs_int': 0 + } const ts = hdaHelper.typeString(type) Logger.info(`Importer : Importing ${xpub} ${ts}`) @@ -182,6 +188,11 @@ class RemoteImporter { addresses = addresses.concat(result.addresses) } + this.importing[xpub] = { + 'status': this.STATUS_IMPORT, + 'txs': txns.length + } + // Store the hdaccount and the addresses into the database await db.ensureHDAccountId(xpub, type) await db.addAddressesToHDAccount(xpub, addresses) @@ -290,6 +301,10 @@ class RemoteImporter { } if (gotTransactions) { + if (c == 0) + this.importing[xpub]['txs_ext'] = Object.keys(txids).length + else + this.importing[xpub]['txs_int'] = Object.keys(txids).length // We must go deeper const result = await this.xpubScan(xpub, c, d, u, G, type, txids) // Accumulate results from further down the rabbit hole