Skip to content

Commit 7e3dbe4

Browse files
committed
wallet: Write best block to disk before backup
This ensures that the best block is included in the backup which leads to a more consistent behavior when loading the backup.
1 parent ab0b570 commit 7e3dbe4

File tree

2 files changed

+23
-4
lines changed

2 files changed

+23
-4
lines changed

src/wallet/wallet.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3410,6 +3410,14 @@ void CWallet::postInitProcess()
34103410

34113411
bool CWallet::BackupWallet(const std::string& strDest) const
34123412
{
3413+
if (m_chain) {
3414+
CBlockLocator loc;
3415+
WITH_LOCK(cs_wallet, chain().findBlock(m_last_block_processed, FoundBlock().locator(loc)));
3416+
if (!loc.IsNull()) {
3417+
WalletBatch batch(GetDatabase());
3418+
batch.WriteBestBlock(loc);
3419+
}
3420+
}
34133421
return GetDatabase().Backup(strDest);
34143422
}
34153423

test/functional/wallet_assumeutxo.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,15 @@ def run_test(self):
6262
for n in self.nodes:
6363
n.setmocktime(n.getblockheader(n.getbestblockhash())['time'])
6464

65+
# Create a wallet that we will create a backup for later (at snapshot height)
6566
n0.createwallet('w')
6667
w = n0.get_wallet_rpc("w")
6768

69+
# Create another wallet and backup now (before snapshot height)
70+
n0.createwallet('w2')
71+
w2 = n0.get_wallet_rpc("w2")
72+
w2.backupwallet("backup_w2.dat")
73+
6874
# Generate a series of blocks that `n0` will have in the snapshot,
6975
# but that n1 doesn't yet see. In order for the snapshot to activate,
7076
# though, we have to ferry over the new headers to n1 so that it
@@ -84,6 +90,8 @@ def run_test(self):
8490
assert_equal(n.getblockchaininfo()[
8591
"headers"], SNAPSHOT_BASE_HEIGHT)
8692

93+
# This backup is created at the snapshot height, so it's
94+
# not part of the background sync anymore
8795
w.backupwallet("backup_w.dat")
8896

8997
self.log.info("-- Testing assumeutxo")
@@ -126,8 +134,11 @@ def run_test(self):
126134

127135
assert_equal(n1.getblockchaininfo()["blocks"], SNAPSHOT_BASE_HEIGHT)
128136

129-
self.log.info("Backup can't be loaded during background sync")
130-
assert_raises_rpc_error(-4, "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", n1.restorewallet, "w", "backup_w.dat")
137+
self.log.info("Backup from the snapshot height can be loaded during background sync")
138+
n1.restorewallet("w", "backup_w.dat")
139+
140+
self.log.info("Backup from before the snapshot height can't be loaded during background sync")
141+
assert_raises_rpc_error(-4, "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", n1.restorewallet, "w2", "backup_w2.dat")
131142

132143
PAUSE_HEIGHT = FINAL_HEIGHT - 40
133144

@@ -159,8 +170,8 @@ def run_test(self):
159170
self.log.info("Ensuring background validation completes")
160171
self.wait_until(lambda: len(n1.getchainstates()['chainstates']) == 1)
161172

162-
self.log.info("Ensuring wallet can be restored from backup")
163-
n1.restorewallet("w", "backup_w.dat")
173+
self.log.info("Ensuring wallet can be restored from a backup that was created before the snapshot height")
174+
n1.restorewallet("w2", "backup_w2.dat")
164175

165176

166177
if __name__ == '__main__':

0 commit comments

Comments
 (0)