@@ -311,6 +311,7 @@ class CWalletScanState {
311
311
std::map<std::pair<uint256, CKeyID>, CKey> m_descriptor_keys;
312
312
std::map<std::pair<uint256, CKeyID>, std::pair<CPubKey, std::vector<unsigned char >>> m_descriptor_crypt_keys;
313
313
std::map<uint160, CHDChain> m_hd_chains;
314
+ bool tx_corrupt{false };
314
315
315
316
CWalletScanState () {
316
317
}
@@ -345,7 +346,13 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
345
346
// LoadToWallet call below creates a new CWalletTx that fill_wtx
346
347
// callback fills with transaction metadata.
347
348
auto fill_wtx = [&](CWalletTx& wtx, bool new_tx) {
348
- assert (new_tx);
349
+ if (!new_tx) {
350
+ // There's some corruption here since the tx we just tried to load was already in the wallet.
351
+ // We don't consider this type of corruption critical, and can fix it by removing tx data and
352
+ // rescanning.
353
+ wss.tx_corrupt = true ;
354
+ return false ;
355
+ }
349
356
ssValue >> wtx;
350
357
if (wtx.GetHash () != hash)
351
358
return false ;
@@ -818,6 +825,11 @@ DBErrors WalletBatch::LoadWallet(CWallet* pwallet)
818
825
} else if (strType == DBKeys::FLAGS) {
819
826
// reading the wallet flags can only fail if unknown flags are present
820
827
result = DBErrors::TOO_NEW;
828
+ } else if (wss.tx_corrupt ) {
829
+ pwallet->WalletLogPrintf (" Error: Corrupt transaction found. This can be fixed by removing transactions from wallet and rescanning.\n " );
830
+ // Set tx_corrupt back to false so that the error is only printed once (per corrupt tx)
831
+ wss.tx_corrupt = false ;
832
+ result = DBErrors::CORRUPT;
821
833
} else {
822
834
// Leave other errors alone, if we try to fix them we might make things worse.
823
835
fNoncriticalErrors = true ; // ... but do warn the user there is something wrong.
0 commit comments