Skip to content

Commit 6d3a8b1

Browse files
committed
wallet: Replace chainStateFlushed in loading with SetLastBlockProcessed
The only reason to call chainStateFlushed during wallet loading is to ensure that the best block is written. Do these writes explicitly to prepare for removing chainStateFlushed, while also ensuring that the wallet's in memory state tracking is written to disk. Additionally, after rescanning on wallet loading, instead of writing the locator for the current chain tip, write the locator for the last block that the rescan had scanned. This ensures that the stored best block record matches the wallet's current state. Any blocks dis/connected during the rescan are processed after the rescan and the last block processed will be updated accordingly.
1 parent 7bacabb commit 6d3a8b1

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

src/wallet/wallet.cpp

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2912,6 +2912,8 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
29122912
!walletInstance->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET);
29132913
if (fFirstRun)
29142914
{
2915+
LOCK(walletInstance->cs_wallet);
2916+
29152917
// ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
29162918
walletInstance->SetMinVersion(FEATURE_LATEST);
29172919

@@ -2921,7 +2923,6 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
29212923
assert(walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
29222924

29232925
if ((wallet_creation_flags & WALLET_FLAG_EXTERNAL_SIGNER) || !(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) {
2924-
LOCK(walletInstance->cs_wallet);
29252926
if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
29262927
walletInstance->SetupDescriptorScriptPubKeyMans();
29272928
// SetupDescriptorScriptPubKeyMans already calls SetupGeneration for us so we don't need to call SetupGeneration separately
@@ -2937,7 +2938,10 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
29372938
}
29382939

29392940
if (chain) {
2940-
walletInstance->chainStateFlushed(ChainstateRole::NORMAL, chain->getTipLocator());
2941+
std::optional<int> tip_height = chain->getHeight();
2942+
if (tip_height) {
2943+
walletInstance->SetLastBlockProcessed(*tip_height, chain->getBlockHash(*tip_height));
2944+
}
29412945
}
29422946
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
29432947
// Make it impossible to disable private keys after creation
@@ -3220,13 +3224,21 @@ bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interf
32203224

32213225
{
32223226
WalletRescanReserver reserver(*walletInstance);
3223-
if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(chain.getBlockHash(rescan_height), rescan_height, /*max_height=*/{}, reserver, /*fUpdate=*/true, /*save_progress=*/true).status)) {
3227+
if (!reserver.reserve()) {
3228+
error = _("Failed to acquire rescan reserver during wallet initialization");
3229+
return false;
3230+
}
3231+
ScanResult scan_res = walletInstance->ScanForWalletTransactions(chain.getBlockHash(rescan_height), rescan_height, /*max_height=*/{}, reserver, /*fUpdate=*/true, /*save_progress=*/true);
3232+
if (ScanResult::SUCCESS != scan_res.status) {
32243233
error = _("Failed to rescan the wallet during initialization");
32253234
return false;
32263235
}
3236+
walletInstance->m_attaching_chain = false;
3237+
// Set and update the best block record
3238+
// Set last block scanned as the last block processed as it may be different in case the case of a reorg.
3239+
// Also save the best block locator because rescanning only updates it intermittently.
3240+
walletInstance->SetLastBlockProcessed(*scan_res.last_scanned_height, scan_res.last_scanned_block);
32273241
}
3228-
walletInstance->m_attaching_chain = false;
3229-
walletInstance->chainStateFlushed(ChainstateRole::NORMAL, chain.getTipLocator());
32303242
}
32313243
walletInstance->m_attaching_chain = false;
32323244

0 commit comments

Comments
 (0)