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.
This commit is contained in:
@@ -1342,11 +1342,10 @@ bool CheckTransactionWithoutProofVerification(uint32_t tiptime,const CTransactio
|
|||||||
|
|
||||||
// Transactions containing empty `vin` must have either non-empty
|
// Transactions containing empty `vin` must have either non-empty
|
||||||
// `vjoinsplit` or non-empty `vShieldedSpend`.
|
// `vjoinsplit` or non-empty `vShieldedSpend`.
|
||||||
if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty()) {
|
if (tx.vin.empty() && tx.vjoinsplit.empty() && tx.vShieldedSpend.empty())
|
||||||
fprintf(stderr,"vin empty for tx: %s\n",tx.GetHash().ToString().c_str());
|
|
||||||
return state.DoS(10, error("CheckTransaction(): vin empty"),
|
return state.DoS(10, error("CheckTransaction(): vin empty"),
|
||||||
REJECT_INVALID, "bad-txns-vin-empty");
|
REJECT_INVALID, "bad-txns-vin-empty");
|
||||||
}
|
|
||||||
// Transactions containing empty `vout` must have either non-empty
|
// Transactions containing empty `vout` must have either non-empty
|
||||||
// `vjoinsplit` or non-empty `vShieldedOutput`.
|
// `vjoinsplit` or non-empty `vShieldedOutput`.
|
||||||
if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty())
|
if (tx.vout.empty() && tx.vjoinsplit.empty() && tx.vShieldedOutput.empty())
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
static uint64_t nAccountingEntryNumber = 0;
|
static uint64_t nAccountingEntryNumber = 0;
|
||||||
|
static list<uint256> deadTxns;
|
||||||
|
|
||||||
//
|
//
|
||||||
// CWalletDB
|
// CWalletDB
|
||||||
@@ -484,8 +485,11 @@ ReadKeyValue(CWallet* pwallet, CDataStream& ssKey, CDataStream& ssValue,
|
|||||||
CValidationState state;
|
CValidationState state;
|
||||||
auto verifier = libzcash::ProofVerifier::Strict();
|
auto verifier = libzcash::ProofVerifier::Strict();
|
||||||
if (!(CheckTransaction(0,wtx, state, verifier) && (wtx.GetHash() == hash) && state.IsValid()))
|
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;
|
return false;
|
||||||
|
}
|
||||||
// Undo serialize changes in 31600
|
// Undo serialize changes in 31600
|
||||||
if (31404 <= wtx.fTimeReceivedIsTxTime && wtx.fTimeReceivedIsTxTime <= 31703)
|
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.
|
// 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.
|
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())
|
if (!strErr.empty())
|
||||||
@@ -952,6 +950,16 @@ DBErrors CWalletDB::LoadWallet(CWallet* pwallet)
|
|||||||
catch (...) {
|
catch (...) {
|
||||||
result = DB_CORRUPT;
|
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)
|
if (fNoncriticalErrors && result == DB_LOAD_OK)
|
||||||
result = DB_NONCRITICAL_ERROR;
|
result = DB_NONCRITICAL_ERROR;
|
||||||
|
|||||||
Reference in New Issue
Block a user