diff --git a/lib/blockchain/chain.js b/lib/blockchain/chain.js index f537143e6..3389ce02d 100644 --- a/lib/blockchain/chain.js +++ b/lib/blockchain/chain.js @@ -2266,13 +2266,22 @@ class Chain extends AsyncEmitter { } } + /** @typedef {import('./common').ScanAction} ScanAction */ + + /** + * @callback ScanInteractiveIterCB + * @param {ChainEntry} entry + * @param {TX[]} txs + * @returns {Promise} + */ + /** * Interactive scan the blockchain for transactions containing specified * address hashes. Allows repeat and abort. * @param {Hash|Number} start - Block hash or height to start at. * @param {BloomFilter} filter - Starting bloom filter containing tx, * address and name hashes. - * @param {Function} iter - Iterator. + * @param {ScanInteractiveIterCB} iter - Iterator. * @param {Boolean} [fullLock=false] * @returns {Promise} */ @@ -2300,7 +2309,7 @@ class Chain extends AsyncEmitter { * @param {Hash|Number} start - Block hash or height to start at. * @param {BloomFilter} filter - Starting bloom filter containing tx, * address and name hashes. - * @param {Function} iter - Iterator. + * @param {ScanInteractiveIterCB} iter - Iterator. * @param {Boolean} [lockPerScan=true] - if we should lock per block scan. * @returns {Promise} */ diff --git a/lib/blockchain/chaindb.js b/lib/blockchain/chaindb.js index 7f075349b..1349c0ea7 100644 --- a/lib/blockchain/chaindb.js +++ b/lib/blockchain/chaindb.js @@ -1612,12 +1612,18 @@ class ChainDB { this.logger.info('Finished scanning %d blocks.', total); } + /** + * @typedef {Object} ScanBlockResult + * @property {ChainEntry} entry + * @property {TX[]} txs + */ + /** * Interactive scans block checks. * @param {Hash|Number} blockID - Block hash or height to start at. * @param {BloomFilter} [filter] - Starting bloom filter containing tx, * address and name hashes. - * @returns {Promise} + * @returns {Promise} */ async scanBlock(blockID, filter) { diff --git a/lib/blockchain/common.js b/lib/blockchain/common.js index 2a45e2d45..6a9ab8339 100644 --- a/lib/blockchain/common.js +++ b/lib/blockchain/common.js @@ -84,3 +84,39 @@ exports.scanActions = { REPEAT_ADD: 4, REPEAT: 5 }; + +/** + * @typedef {Object} ActionAbort + * @property {exports.scanActions} type - ABORT + */ + +/** + * @typedef {Object} ActionNext + * @property {exports.scanActions} type - NEXT + */ + +/** + * @typedef {Object} ActionRepeat + * @property {exports.ScanAction} type - REPEAT + */ + +/** + * @typedef {Object} ActionRepeatAdd + * @property {exports.scanActions} type - REPEAT_ADD + * @property {Buffer[]} chunks + */ + +/** + * @typedef {Object} ActionRepeatSet + * @property {exports.scanActions} type - REPEAT_SET + * @property {BloomFilter} filter + */ + +/** + * @typedef {ActionAbort + * | ActionNext + * | ActionRepeat + * | ActionRepeatAdd + * | ActionRepeatSet + * } ScanAction + */ diff --git a/lib/node/http.js b/lib/node/http.js index 93277edb2..c30db1ff1 100644 --- a/lib/node/http.js +++ b/lib/node/http.js @@ -925,10 +925,9 @@ class HTTP extends Server { try { await this.node.scanInteractive(start, filter, iter, fullLock); } catch (err) { - return socket.call('block rescan interactive abort', err.message); + await socket.call('block rescan interactive abort', err.message); + throw err; } - - return null; } } diff --git a/test/node-rescan-test.js b/test/node-rescan-test.js index 86584b7b2..40cbc5069 100644 --- a/test/node-rescan-test.js +++ b/test/node-rescan-test.js @@ -543,7 +543,14 @@ describe('Node Rescan Interactive API', function() { if (test.filter) filter = test.filter.encode(); - await client.rescanInteractive(startHeight, filter); + let err; + try { + await client.rescanInteractive(startHeight, filter); + } catch (e) { + err = e; + } + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(count, 5); assert.strictEqual(aborted, true); @@ -554,7 +561,15 @@ describe('Node Rescan Interactive API', function() { if (test.filter) await client.setFilter(test.filter.encode()); - await client.rescanInteractive(startHeight, null); + err = null; + try { + await client.rescanInteractive(startHeight, null); + } catch (e) { + err = e; + } + + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(count, 5); assert.strictEqual(aborted, true); }); @@ -596,7 +611,14 @@ describe('Node Rescan Interactive API', function() { if (test.filter) filter = test.filter.encode(); - await client.rescanInteractive(startHeight, filter); + let err; + try { + await client.rescanInteractive(startHeight, filter); + } catch (e) { + err = e; + } + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(count, 5); assert.strictEqual(aborted, true); @@ -606,7 +628,14 @@ describe('Node Rescan Interactive API', function() { if (test.filter) await client.setFilter(test.filter.encode()); - await client.rescanInteractive(startHeight); + err = null; + try { + await client.rescanInteractive(startHeight); + } catch (e) { + err = e; + } + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(count, 5); assert.strictEqual(aborted, true); }); @@ -648,7 +677,14 @@ describe('Node Rescan Interactive API', function() { if (test.filter) filter = test.filter.encode(); - await client.rescanInteractive(startHeight, filter); + let err; + try { + await client.rescanInteractive(startHeight, filter); + } catch (e) { + err = e; + } + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(count, 5); assert.strictEqual(aborted, true); @@ -658,7 +694,14 @@ describe('Node Rescan Interactive API', function() { if (test.filter) await client.setFilter(test.filter.encode()); - await client.rescanInteractive(startHeight); + err = null; + try { + await client.rescanInteractive(startHeight); + } catch (e) { + err = e; + } + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(count, 5); assert.strictEqual(aborted, true); }); @@ -705,7 +748,15 @@ describe('Node Rescan Interactive API', function() { if (test.filter) filter = test.filter.encode(); - await client.rescanInteractive(startHeight, filter); + let err; + try { + await client.rescanInteractive(startHeight, filter); + } catch (e) { + err = e; + } + + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(count, tests.length); assert.strictEqual(aborted, true); }); @@ -748,17 +799,33 @@ describe('Node Rescan Interactive API', function() { aborted = true; }); - await client.rescanInteractive(startHeight, filter.encode()); + let err; + try { + await client.rescanInteractive(startHeight, filter.encode()); + } catch (e) { + err = e; + } + + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(aborted, true); // Now try using client.filter + err = null; aborted = false; filter = BloomFilter.fromRate(10000, 0.001); testTXs = allTXs[startHeight].slice(); expected = 0; await client.setFilter(filter.encode()); - await client.rescanInteractive(startHeight); + try { + await client.rescanInteractive(startHeight); + } catch (e) { + err = e; + } + + assert(err); + assert.strictEqual(err.message, 'scan request aborted.'); assert.strictEqual(aborted, true); });