mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-01-21 15:50:07 +01:00
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.
This commit is contained in:
@@ -2912,6 +2912,8 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
||||
!walletInstance->IsWalletFlagSet(WALLET_FLAG_BLANK_WALLET);
|
||||
if (fFirstRun)
|
||||
{
|
||||
LOCK(walletInstance->cs_wallet);
|
||||
|
||||
// ensure this wallet.dat can only be opened by clients supporting HD with chain split and expects no default key
|
||||
walletInstance->SetMinVersion(FEATURE_LATEST);
|
||||
|
||||
@@ -2921,7 +2923,6 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
||||
assert(walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
|
||||
|
||||
if ((wallet_creation_flags & WALLET_FLAG_EXTERNAL_SIGNER) || !(wallet_creation_flags & (WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET))) {
|
||||
LOCK(walletInstance->cs_wallet);
|
||||
if (walletInstance->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS)) {
|
||||
walletInstance->SetupDescriptorScriptPubKeyMans();
|
||||
// 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
|
||||
}
|
||||
|
||||
if (chain) {
|
||||
walletInstance->chainStateFlushed(ChainstateRole::NORMAL, chain->getTipLocator());
|
||||
std::optional<int> tip_height = chain->getHeight();
|
||||
if (tip_height) {
|
||||
walletInstance->SetLastBlockProcessed(*tip_height, chain->getBlockHash(*tip_height));
|
||||
}
|
||||
}
|
||||
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
|
||||
// Make it impossible to disable private keys after creation
|
||||
@@ -3220,13 +3224,21 @@ bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interf
|
||||
|
||||
{
|
||||
WalletRescanReserver reserver(*walletInstance);
|
||||
if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(chain.getBlockHash(rescan_height), rescan_height, /*max_height=*/{}, reserver, /*fUpdate=*/true, /*save_progress=*/true).status)) {
|
||||
if (!reserver.reserve()) {
|
||||
error = _("Failed to acquire rescan reserver during wallet initialization");
|
||||
return false;
|
||||
}
|
||||
ScanResult scan_res = walletInstance->ScanForWalletTransactions(chain.getBlockHash(rescan_height), rescan_height, /*max_height=*/{}, reserver, /*fUpdate=*/true, /*save_progress=*/true);
|
||||
if (ScanResult::SUCCESS != scan_res.status) {
|
||||
error = _("Failed to rescan the wallet during initialization");
|
||||
return false;
|
||||
}
|
||||
walletInstance->m_attaching_chain = false;
|
||||
// Set and update the best block record
|
||||
// Set last block scanned as the last block processed as it may be different in case the case of a reorg.
|
||||
// Also save the best block locator because rescanning only updates it intermittently.
|
||||
walletInstance->SetLastBlockProcessed(*scan_res.last_scanned_height, scan_res.last_scanned_block);
|
||||
}
|
||||
walletInstance->m_attaching_chain = false;
|
||||
walletInstance->chainStateFlushed(ChainstateRole::NORMAL, chain.getTipLocator());
|
||||
}
|
||||
walletInstance->m_attaching_chain = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user