Skip to content

Commit 49c87e9

Browse files
laanwjvijaydasmp
authored andcommitted
Merge bitcoin#23142: Return false on corrupt tx rather than asserting
0ab4c3b Return false on corrupt tx rather than asserting (Samuel Dobson) Pull request description: Takes up bitcoin#19793 Rather than asserting, we log an error and return CORRUPT so that the user is informed. This type of error isn't critical so it isn't worth `assert`ing. ACKs for top commit: achow101: ACK 0ab4c3b laanwj: Code review ACK 0ab4c3b ryanofsky: Code review ACK 0ab4c3b. There may be room for more improvements later like better error messages or easier recovery options, but changing from an assert to an error seems like a clear improvement, and this seems to avoid all the pitfalls of the last PR that tried this. Tree-SHA512: 4a1a412e7c473d176c4e09123b85f390a6b0ea195e78d28ebd50b13814b7852f8225a172511a2efb6affb555b11bd4e667c19eb8c78b060c5444b62f0fae5f7a
1 parent 1464e69 commit 49c87e9

File tree

1 file changed

+13
-1
lines changed

1 file changed

+13
-1
lines changed

src/wallet/walletdb.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,7 @@ class CWalletScanState {
324324
std::map<uint256, DescriptorCache> m_descriptor_caches;
325325
std::map<std::pair<uint256, CKeyID>, CKey> m_descriptor_keys;
326326
std::map<std::pair<uint256, CKeyID>, std::pair<CPubKey, std::vector<unsigned char>>> m_descriptor_crypt_keys;
327+
bool tx_corrupt{false};
327328

328329
CWalletScanState() {
329330
}
@@ -358,7 +359,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
358359
// LoadToWallet call below creates a new CWalletTx that fill_wtx
359360
// callback fills with transaction metadata.
360361
auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
361-
assert(new_tx);
362+
if(!new_tx) {
363+
// There's some corruption here since the tx we just tried to load was already in the wallet.
364+
// We don't consider this type of corruption critical, and can fix it by removing tx data and
365+
// rescanning.
366+
wss.tx_corrupt = true;
367+
return false;
368+
}
362369
ssValue >> wtx;
363370
if (wtx.GetHash() != hash)
364371
return false;
@@ -797,6 +804,11 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
797804
} else if (strType == DBKeys::FLAGS) {
798805
// reading the wallet flags can only fail if unknown flags are present
799806
result = DBErrors::TOO_NEW;
807+
} else if (wss.tx_corrupt) {
808+
pwallet->WalletLogPrintf("Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.\n");
809+
// Set tx_corrupt back to false so that the error is only printed once (per corrupt tx)
810+
wss.tx_corrupt = false;
811+
result = DBErrors::CORRUPT;
800812
} else {
801813
// Leave other errors alone, if we try to fix them we might make things worse.
802814
fNoncriticalErrors = true; // ... but do warn the user there is something wrong.

0 commit comments

Comments
 (0)