mirror of
https://github.com/Retropex/bitcoin.git
synced 2025-05-28 04:52:36 +02:00
Corrupt wallet tx shouldn't trigger rescan of all wallets
This commit is contained in:
parent
6c006495ef
commit
f963b0fa8c
@ -2007,10 +2007,7 @@ DBErrors CWallet::LoadWallet()
|
|||||||
assert(m_internal_spk_managers.empty());
|
assert(m_internal_spk_managers.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nLoadWalletRet != DBErrors::LOAD_OK)
|
return nLoadWalletRet;
|
||||||
return nLoadWalletRet;
|
|
||||||
|
|
||||||
return DBErrors::LOAD_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
|
DBErrors CWallet::ZapSelectTx(std::vector<uint256>& vHashIn, std::vector<uint256>& vHashOut)
|
||||||
@ -2542,6 +2539,7 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
|||||||
// TODO: Can't use std::make_shared because we need a custom deleter but
|
// TODO: Can't use std::make_shared because we need a custom deleter but
|
||||||
// should be possible to use std::allocate_shared.
|
// should be possible to use std::allocate_shared.
|
||||||
std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, std::move(database)), ReleaseWallet);
|
std::shared_ptr<CWallet> walletInstance(new CWallet(chain, name, std::move(database)), ReleaseWallet);
|
||||||
|
bool rescan_required = false;
|
||||||
DBErrors nLoadWalletRet = walletInstance->LoadWallet();
|
DBErrors nLoadWalletRet = walletInstance->LoadWallet();
|
||||||
if (nLoadWalletRet != DBErrors::LOAD_OK) {
|
if (nLoadWalletRet != DBErrors::LOAD_OK) {
|
||||||
if (nLoadWalletRet == DBErrors::CORRUPT) {
|
if (nLoadWalletRet == DBErrors::CORRUPT) {
|
||||||
@ -2562,6 +2560,10 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
|||||||
{
|
{
|
||||||
error = strprintf(_("Wallet needed to be rewritten: restart %s to complete"), PACKAGE_NAME);
|
error = strprintf(_("Wallet needed to be rewritten: restart %s to complete"), PACKAGE_NAME);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
} else if (nLoadWalletRet == DBErrors::RESCAN_REQUIRED) {
|
||||||
|
warnings.push_back(strprintf(_("Error reading %s! Transaction data may be missing or incorrect."
|
||||||
|
" Rescanning wallet."), walletFile));
|
||||||
|
rescan_required = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
error = strprintf(_("Error loading %s"), walletFile);
|
error = strprintf(_("Error loading %s"), walletFile);
|
||||||
@ -2753,7 +2755,7 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
|||||||
|
|
||||||
LOCK(walletInstance->cs_wallet);
|
LOCK(walletInstance->cs_wallet);
|
||||||
|
|
||||||
if (chain && !AttachChain(walletInstance, *chain, error, warnings)) {
|
if (chain && !AttachChain(walletInstance, *chain, rescan_required, error, warnings)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2775,7 +2777,7 @@ std::shared_ptr<CWallet> CWallet::Create(WalletContext& context, const std::stri
|
|||||||
return walletInstance;
|
return walletInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interfaces::Chain& chain, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interfaces::Chain& chain, const bool rescan_required, bilingual_str& error, std::vector<bilingual_str>& warnings)
|
||||||
{
|
{
|
||||||
LOCK(walletInstance->cs_wallet);
|
LOCK(walletInstance->cs_wallet);
|
||||||
// allow setting the chain if it hasn't been set already but prevent changing it
|
// allow setting the chain if it hasn't been set already but prevent changing it
|
||||||
@ -2792,8 +2794,9 @@ bool CWallet::AttachChain(const std::shared_ptr<CWallet>& walletInstance, interf
|
|||||||
// interface.
|
// interface.
|
||||||
walletInstance->m_chain_notifications_handler = walletInstance->chain().handleNotifications(walletInstance);
|
walletInstance->m_chain_notifications_handler = walletInstance->chain().handleNotifications(walletInstance);
|
||||||
|
|
||||||
|
// If either rescan_required = true or -rescan is set, rescan_height remains equal to 0
|
||||||
int rescan_height = 0;
|
int rescan_height = 0;
|
||||||
if (!gArgs.GetBoolArg("-rescan", false))
|
if (!rescan_required && !gArgs.GetBoolArg("-rescan", false))
|
||||||
{
|
{
|
||||||
WalletBatch batch(walletInstance->GetDatabase());
|
WalletBatch batch(walletInstance->GetDatabase());
|
||||||
CBlockLocator locator;
|
CBlockLocator locator;
|
||||||
|
@ -337,7 +337,7 @@ private:
|
|||||||
* block locator and m_last_block_processed, and registering for
|
* block locator and m_last_block_processed, and registering for
|
||||||
* notifications about new blocks and transactions.
|
* notifications about new blocks and transactions.
|
||||||
*/
|
*/
|
||||||
static bool AttachChain(const std::shared_ptr<CWallet>& wallet, interfaces::Chain& chain, bilingual_str& error, std::vector<bilingual_str>& warnings);
|
static bool AttachChain(const std::shared_ptr<CWallet>& wallet, interfaces::Chain& chain, const bool rescan_required, bilingual_str& error, std::vector<bilingual_str>& warnings);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
|
@ -755,6 +755,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
|
|||||||
{
|
{
|
||||||
CWalletScanState wss;
|
CWalletScanState wss;
|
||||||
bool fNoncriticalErrors = false;
|
bool fNoncriticalErrors = false;
|
||||||
|
bool rescan_required = false;
|
||||||
DBErrors result = DBErrors::LOAD_OK;
|
DBErrors result = DBErrors::LOAD_OK;
|
||||||
|
|
||||||
LOCK(pwallet->cs_wallet);
|
LOCK(pwallet->cs_wallet);
|
||||||
@ -823,7 +824,7 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
|
|||||||
fNoncriticalErrors = true; // ... but do warn the user there is something wrong.
|
fNoncriticalErrors = true; // ... but do warn the user there is something wrong.
|
||||||
if (strType == DBKeys::TX)
|
if (strType == DBKeys::TX)
|
||||||
// Rescan if there is a bad transaction record:
|
// Rescan if there is a bad transaction record:
|
||||||
gArgs.SoftSetBoolArg("-rescan", true);
|
rescan_required = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!strErr.empty())
|
if (!strErr.empty())
|
||||||
@ -859,8 +860,11 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
|
|||||||
((DescriptorScriptPubKeyMan*)spk_man)->AddCryptedKey(desc_key_pair.first.second, desc_key_pair.second.first, desc_key_pair.second.second);
|
((DescriptorScriptPubKeyMan*)spk_man)->AddCryptedKey(desc_key_pair.first.second, desc_key_pair.second.first, desc_key_pair.second.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fNoncriticalErrors && result == DBErrors::LOAD_OK)
|
if (rescan_required && result == DBErrors::LOAD_OK) {
|
||||||
|
result = DBErrors::RESCAN_REQUIRED;
|
||||||
|
} else if (fNoncriticalErrors && result == DBErrors::LOAD_OK) {
|
||||||
result = DBErrors::NONCRITICAL_ERROR;
|
result = DBErrors::NONCRITICAL_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// Any wallet corruption at all: skip any rewriting or
|
// Any wallet corruption at all: skip any rewriting or
|
||||||
// upgrading, we don't want to make it worse.
|
// upgrading, we don't want to make it worse.
|
||||||
|
@ -48,7 +48,8 @@ enum class DBErrors
|
|||||||
NONCRITICAL_ERROR,
|
NONCRITICAL_ERROR,
|
||||||
TOO_NEW,
|
TOO_NEW,
|
||||||
LOAD_FAIL,
|
LOAD_FAIL,
|
||||||
NEED_REWRITE
|
NEED_REWRITE,
|
||||||
|
RESCAN_REQUIRED
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace DBKeys {
|
namespace DBKeys {
|
||||||
|
@ -76,6 +76,10 @@ static std::shared_ptr<CWallet> MakeWallet(const std::string& name, const fs::pa
|
|||||||
} else if (load_wallet_ret == DBErrors::NEED_REWRITE) {
|
} else if (load_wallet_ret == DBErrors::NEED_REWRITE) {
|
||||||
tfm::format(std::cerr, "Wallet needed to be rewritten: restart %s to complete", PACKAGE_NAME);
|
tfm::format(std::cerr, "Wallet needed to be rewritten: restart %s to complete", PACKAGE_NAME);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
} else if (load_wallet_ret == DBErrors::RESCAN_REQUIRED) {
|
||||||
|
tfm::format(std::cerr, "Error reading %s! Some transaction data might be missing or"
|
||||||
|
" incorrect. Wallet requires a rescan.",
|
||||||
|
name);
|
||||||
} else {
|
} else {
|
||||||
tfm::format(std::cerr, "Error loading %s", name);
|
tfm::format(std::cerr, "Error loading %s", name);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
Loading…
Reference in New Issue
Block a user