From 0ab4c3b27265401c59e40adc494041927dc9dbe3 Mon Sep 17 00:00:00 2001 From: Samuel Dobson Date: Thu, 30 Sep 2021 12:20:52 +1300 Subject: [PATCH] Return false on corrupt tx rather than asserting Co-authored-by: Russell Yanofsky Co-authored-by: Andrew Chow --- src/wallet/walletdb.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index c697534c06a97..aa626283eb278 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -311,6 +311,7 @@ class CWalletScanState { std::map, CKey> m_descriptor_keys; std::map, std::pair>> m_descriptor_crypt_keys; std::map m_hd_chains; + bool tx_corrupt{false}; CWalletScanState() { } @@ -345,7 +346,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, // LoadToWallet call below creates a new CWalletTx that fill_wtx // callback fills with transaction metadata. auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) { - assert(new_tx); + if(!new_tx) { + // There's some corruption here since the tx we just tried to load was already in the wallet. + // We don't consider this type of corruption critical, and can fix it by removing tx data and + // rescanning. + wss.tx_corrupt = true; + return false; + } ssValue >> wtx; if (wtx.GetHash() != hash) return false; @@ -818,6 +825,11 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet) } else if (strType == DBKeys::FLAGS) { // reading the wallet flags can only fail if unknown flags are present result = DBErrors::TOO_NEW; + } else if (wss.tx_corrupt) { + pwallet->WalletLogPrintf("Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.\n"); + // Set tx_corrupt back to false so that the error is only printed once (per corrupt tx) + wss.tx_corrupt = false; + result = DBErrors::CORRUPT; } else { // Leave other errors alone, if we try to fix them we might make things worse. fNoncriticalErrors = true; // ... but do warn the user there is something wrong.