test: add coverage for importdescriptors when manually interrupting a wallet rescan
What changed, and why it matters
This commit adds a new automated test to Bitcoin Core. The test checks what happens when a user cancels a wallet rescan while importing descriptors. It does not change any production wallet code; it only adds test coverage. There is no security vulnerability here.
No action needed. This is a benign test-only commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff adds a functional test case in test/functional/wallet_importdescriptors.py. It creates a blank wallet, starts an importdescriptors RPC call with a large range that triggers a rescan, then concurrently calls abortrescan. The test asserts that the importdescriptors call fails with JSONRPCException error code -1 and message ‘Rescan aborted by user.’ This is purely a regression/behavioral test for an existing abort-rescan code path.
Changed components
test/functional/wallet_importdescriptors.pyInspect captured patch +27 / −0
diff --git a/test/functional/wallet_importdescriptors.py b/test/functional/wallet_importdescriptors.py
index 85fb38e5..f9429079 100755
--- a/test/functional/wallet_importdescriptors.py
+++ b/test/functional/wallet_importdescriptors.py
@@ -168,6 +168,33 @@ class ImportDescriptorsTest(BitcoinTestFramework):
result = w_import.importdescriptors([{"desc": other_desc, "timestamp": "now"}])
assert_equal(result[0]['success'], True)
+ self.log.info("Aborting an importdescriptors rescan should fail the RPC call")
+ wallet_name = "abort_import_wallet"
+ self.nodes[0].createwallet(wallet_name, blank=True)
+
+ with concurrent.futures.ThreadPoolExecutor(max_workers=1) as thread:
+ w_import = self.nodes[0].create_new_rpc_connection(mode="AUTHPROXY") / f"wallet/{wallet_name}"
+ abort_rpc = self.nodes[0].create_new_rpc_connection(mode="AUTHPROXY") / f"wallet/{wallet_name}"
+ descriptor = [{"desc": descsum_create("pkh(" + xpriv + "/2h/*h)"),
+ "timestamp": 0, "range": [0, 4000]}]
+
+ importing = thread.submit(w_import.importdescriptors, descriptor)
+
+ # Keep trying because an abort before ScanForWalletTransactions starts
+ # is reset when the scan loop begins.
+ abort_succeeded = False
+ abort_deadline = time.time() + 30 * self.options.timeout_factor
+ while not importing.done() and time.time() < abort_deadline:
+ abort_succeeded = abort_rpc.abortrescan() or abort_succeeded
+
+ assert_equal(abort_succeeded, True)
+ try:
+ importing.result(timeout=30 * self.options.timeout_factor)
+ raise AssertionError("importdescriptors unexpectedly succeeded")
+ except JSONRPCException as e:
+ assert_equal(e.error["code"], -1)
+ assert_equal(e.error["message"], "Rescan aborted by user.")
+
def run_test(self):
self.log.info('Setting up wallets')
self.nodes[0].createwallet(wallet_name='w0', disable_private_keys=False)
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.