Merge bitcoin/bitcoin#34286: test: verify node state after restart in assumeutxo

5cd57943b8adc76ed0b8a75a83f27bc0f971cbef test: verify node state after restart in assumeutxo (Yash Bhutwala)

Pull request description:

  ## Summary

  This PR replaces the TODO comment in `wallet_assumeutxo.py` (line 242) with actual test assertions that verify node and wallet behavior after a restart during assumeutxo background sync.

  ## Changes

  The new tests verify:
  - Two chainstates exist (background validation not complete)
  - Background chainstate is still at `START_HEIGHT`
  - Snapshot chainstate has synced to at least `PAUSE_HEIGHT`
  - Wallets cannot be loaded after restart (expected behavior)
  - Wallet backup from before snapshot height cannot be restored

  ## Motivation

  During implementation, I discovered that **wallets cannot be loaded after a node restart during assumeutxo background sync**. This is expected behavior because:
  - The wallet loading code checks if required blocks are available for rescanning
  - During assumeutxo background sync, blocks before the snapshot are not available
  - This applies to all wallets, including watch-only wallets created at the snapshot height

  This is a valuable test addition because it documents this expected behavior and ensures it doesn't regress. Users should be aware that if they restart their node during assumeutxo background sync, they won't be able to load their wallets until the background sync completes.

  ## Related

  refs #28648

  Addresses the TODO comment that was originally added as part of the assumeutxo wallet test implementation.

ACKs for top commit:
  Bicaru20:
    Code review ACK 5cd57943b8adc76ed0b8a75a83f27bc0f971cbef
  achow101:
    ACK 5cd57943b8adc76ed0b8a75a83f27bc0f971cbef
  fjahr:
    ACK 5cd57943b8adc76ed0b8a75a83f27bc0f971cbef
  sedited:
    ACK 5cd57943b8adc76ed0b8a75a83f27bc0f971cbef
  polespinasa:
    code lgtm ACK 5cd57943b8adc76ed0b8a75a83f27bc0f971cbef

Tree-SHA512: 4a125c5247168da2bbf4d855b4150ca453bb5e4cce1a62e633ce5e43acdc2c58883a6a94dcc46b38f8b4c44206fe42cec4db151a76aded53d8ea433ea5eb2562
This commit is contained in:
Ava Chow 2026-02-24 14:32:27 -08:00
commit 21cd1ba182
No known key found for this signature in database
GPG Key ID: 17565732E08E5E41

View File

@ -12,6 +12,7 @@ from test_framework.messages import COIN
from test_framework.util import (
assert_equal,
assert_greater_than,
assert_greater_than_or_equal,
assert_raises_rpc_error,
ensure_for,
)
@ -201,10 +202,13 @@ class AssumeutxoTest(BitcoinTestFramework):
assert_equal(n1.getbalance(), 0)
self.log.info("Backup from before the snapshot height can't be loaded during background sync")
expected_error_message = "Wallet loading failed. Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order when using assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height 299"
assert_raises_rpc_error(-4, expected_error_message, n1.restorewallet, "w2", "backup_w2.dat")
# Error message for wallets that need blocks before the snapshot height.
def loading_error(height):
return f"Wallet loading failed. Error loading wallet. Wallet requires blocks to be downloaded, and software does not currently support loading wallets while blocks are being downloaded out of order when using assumeutxo snapshots. Wallet should be able to load successfully after node sync reaches height {height}"
# The target height is SNAPSHOT_BASE_HEIGHT because that's when background sync completes.
assert_raises_rpc_error(-4, loading_error(SNAPSHOT_BASE_HEIGHT), n1.restorewallet, "w2", "backup_w2.dat")
self.test_backup_during_background_sync_pruned_node(n3, dump_output, expected_error_message)
self.test_backup_during_background_sync_pruned_node(n3, dump_output, loading_error(SNAPSHOT_BASE_HEIGHT))
self.log.info("Test loading descriptors during background sync")
wallet_name = "w1"
@ -239,7 +243,28 @@ class AssumeutxoTest(BitcoinTestFramework):
"Restarted node before snapshot validation completed, reloading...")
self.restart_node(1, extra_args=self.extra_args[1])
# TODO: inspect state of e.g. the wallet before reconnecting
self.log.info("Verify node state after restart during background sync")
# Verify there are still two chainstates (background validation not complete)
chainstates = n1.getchainstates()['chainstates']
assert_equal(len(chainstates), 2)
# The background chainstate should still be at START_HEIGHT
assert_equal(chainstates[0]['blocks'], START_HEIGHT)
# The snapshot chainstate should be at least PAUSE_HEIGHT. It may be
# higher because stopatheight may allow additional blocks to be
# processed during shutdown (per stopatheight documentation).
assert_greater_than_or_equal(chainstates[1]['blocks'], PAUSE_HEIGHT)
# After restart, wallets that existed before cannot be loaded because
# the wallet loading code checks if required blocks are available for
# rescanning. During assumeutxo background sync, blocks before the
# snapshot are not available, so wallet loading fails.
# After restart, the required height is SNAPSHOT_BASE_HEIGHT + 1 for all wallets.
assert_raises_rpc_error(-4, loading_error(SNAPSHOT_BASE_HEIGHT + 1), n1.loadwallet, "w")
assert_raises_rpc_error(-4, loading_error(SNAPSHOT_BASE_HEIGHT + 1), n1.loadwallet, wallet_name)
# Verify backup from before snapshot height still can't be restored
assert_raises_rpc_error(-4, loading_error(SNAPSHOT_BASE_HEIGHT + 1), n1.restorewallet, "w2_test", "backup_w2.dat")
self.complete_background_validation(n1)
self.log.info("Ensuring wallet can be restored from a backup that was created before the snapshot height")