From 5837b5bc05338966cf4a62d21bed7e153ad5b3f0 Mon Sep 17 00:00:00 2001 From: blackjok3r Date: Fri, 4 Jan 2019 16:11:51 +0800 Subject: [PATCH] Wallet corruption fix. No longer calls a rescan on daemon load, instead we now delete the non existant txs from the wallet, so next time you load it the error is gone. --- src/main.cpp | 5 ++--- src/wallet/walletdb.cpp | 22 +++++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9537a5c81..c8af01656 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1342,11 +1342,10 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio // Transactions containing empty `vin` must have either non-empty // `vjoinsplit` or non-empty `vShieldedSpend`. - if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty()) { - fprintf(stderr,"vin empty for tx: %s\n",tx.GetHash().ToString().c_str()); + if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty()) return state.DoS(10, error("CheckTransaction(): vin empty"), REJECT_INVALID, "bad-txns-vin-empty"); - } + // Transactions containing empty `vout` must have either non-empty // `vjoinsplit` or non-empty `vShieldedOutput`. if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty()) diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index ed37877e7..fc9f4b20f 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -39,6 +39,7 @@ using namespace std; static uint64_t nAccountingEntryNumber = 0; +static list deadTxns; // // CWalletDB @@ -484,8 +485,11 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue, CValidationState state; auto verifier = libzcash::ProofVerifier::Strict(); if (!(CheckTransaction(0,wtx, state, verifier) && (wtx.GetHash() == hash) && state.IsValid())) + { + fprintf(stderr, "Removing corrupt tx from wallet.%s\n", hash.ToString().c_str()); + deadTxns.push_back(hash); return false; - + } // Undo serialize changes in 31600 if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703) { @@ -933,12 +937,6 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) { // 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. - if (strType == "tx" ) - { - // Rescan if there is a bad transaction record.. - //SoftSetBoolArg("-rescan", true); - fprintf(stderr, "TX corrupted.. aborted rescan!\n"); - } } } if (!strErr.empty()) @@ -952,6 +950,16 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet) catch (...) { result = DB_CORRUPT; } + + if (!deadTxns.empty()) + { + BOOST_FOREACH (uint256& hash, deadTxns) { + if (!EraseTx(hash)) + fprintf(stderr, "could not delete tx.%s\n",hash.ToString().c_str()); + } + fprintf(stderr, "Cleared %i corrupted transactions from wallet.\n",deadTxns.size()); + deadTxns.clear(); + } if (fNoncriticalErrors && result == DB_LOAD_OK) result = DB_NONCRITICAL_ERROR;