Skip to content

Commit 1b5c545

Browse files
committed
wallet, test: best block locator matches scan state follow-ups
Few follows-ups from #30221: Use `SetLastBlockProcessedInMem` more in `AttachChain`, add not null locator check in `WriteBestBlock`. Add log and few assertions in `wallet_reorgstore` test.
1 parent fa33592 commit 1b5c545

File tree

2 files changed

+14
-10
lines changed

2 files changed

+14
-10
lines changed

src/wallet/wallet.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,11 +3103,9 @@ bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interf
31033103

31043104
const std::optional<int> tip_height = chain.getHeight();
31053105
if (tip_height) {
3106-
walletInstance->m_last_block_processed = chain.getBlockHash(*tip_height);
3107-
walletInstance->m_last_block_processed_height = *tip_height;
3106+
walletInstance->SetLastBlockProcessedInMem(*tip_height, chain.getBlockHash(*tip_height));
31083107
} else {
3109-
walletInstance->m_last_block_processed.SetNull();
3110-
walletInstance->m_last_block_processed_height = -1;
3108+
walletInstance->SetLastBlockProcessedInMem(-1, uint256());
31113109
}
31123110

31133111
if (tip_height && *tip_height != rescan_height)
@@ -3172,7 +3170,7 @@ bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interf
31723170
return false;
31733171
}
31743172
// Set and update the best block record
3175-
// Set last block scanned as the last block processed as it may be different in case the case of a reorg.
3173+
// Set last block scanned as the last block processed as it may be different in case of a reorg.
31763174
// Also save the best block locator because rescanning only updates it intermittently.
31773175
walletInstance->SetLastBlockProcessed(*scan_res.last_scanned_height, scan_res.last_scanned_block);
31783176
}
@@ -4427,8 +4425,10 @@ void CWallet::WriteBestBlock() const
44274425
CBlockLocator loc;
44284426
chain().findBlock(m_last_block_processed, FoundBlock().locator(loc));
44294427

4430-
WalletBatch batch(GetDatabase());
4431-
batch.WriteBestBlock(loc);
4428+
if (!loc.IsNull()) {
4429+
WalletBatch batch(GetDatabase());
4430+
batch.WriteBestBlock(loc);
4431+
}
44324432
}
44334433
}
44344434

test/functional/wallet_reorgsrestore.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def test_coinbase_automatic_abandon_during_startup(self):
9090
assert_equal(wallet0.gettransaction(descendant_tx_id)['details'][0]['abandoned'], True)
9191

9292
def test_reorg_handling_during_unclean_shutdown(self):
93-
self.log.info("Test that wallet doesn't crash due to a duplicate block disconnection event after an unclean shutdown")
93+
self.log.info("Test that wallet transactions are un-abandoned in case of temporarily invalidated blocks and wallet doesn't crash due to a duplicate block disconnection event after an unclean shutdown")
9494
node = self.nodes[0]
9595
# Receive coinbase reward on a new wallet
9696
node.createwallet(wallet_name="reorg_crash", load_on_startup=True)
@@ -104,6 +104,7 @@ def test_reorg_handling_during_unclean_shutdown(self):
104104

105105
# Disconnect tip and sync wallet state
106106
tip = wallet.getbestblockhash()
107+
tip_height = wallet.getblockstats(tip)["height"]
107108
wallet.invalidateblock(tip)
108109
wallet.syncwithvalidationinterfacequeue()
109110

@@ -116,14 +117,17 @@ def test_reorg_handling_during_unclean_shutdown(self):
116117
node.kill_process()
117118

118119
# Restart the node and confirm that it has not persisted the last chain state changes to disk
119-
self.start_node(0)
120+
# that leads to a rescan by the wallet
121+
with self.nodes[0].assert_debug_log(expected_msgs=[f"Rescanning last 1 blocks (from block {tip_height - 1})...\n"]):
122+
self.start_node(0)
120123
assert_equal(node.getbestblockhash(), tip)
121124

122125
# After disconnecting the block, the wallet should record the new best block.
123126
# Upon reload after the crash, since the chainstate was not flushed, the tip contains the previously abandoned
124-
# coinbase. This should be rescanned and now un-abandoned.
127+
# coinbase. This was rescanned and now un-abandoned.
125128
wallet = node.get_wallet_rpc("reorg_crash")
126129
assert_equal(wallet.gettransaction(coinbase_tx_id)['details'][0]['abandoned'], False)
130+
assert_greater_than(wallet.getbalances()["mine"]["immature"], 0)
127131

128132
# Previously, a bug caused the node to crash if two block disconnection events occurred consecutively.
129133
# Ensure this is no longer the case by simulating a new reorg.

0 commit comments

Comments
 (0)