diff --git a/CHANGELOG.md b/CHANGELOG.md index ed13aeab70..36eb1457c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [3.7.11.0] 2018-03-15, leisure +### Fixed + - Fix wallet being locked while flushing. It now requires a clean shutdown + or a backup to migrate the wallet.dat to a different system, #1010 (@jamescowens). + +### Changed + - Automatic backups can now be disabled by using `-walletbackupinterval=0`, + #1018 (@denravonska). + - Trigger a fix spent coins check on start and after block disconnect, #1018 (@denravonska). + ## [3.7.10.0] 2018-03-05, leisure ### Fixed - Fix sync issues due to beacon age checks, #1003 (@denravonska). diff --git a/src/backup.cpp b/src/backup.cpp index 2041f3182e..84550cd466 100644 --- a/src/backup.cpp +++ b/src/backup.cpp @@ -76,6 +76,8 @@ bool BackupWallet(const CWallet& wallet, const std::string& strDest) // Flush log data to the dat file bitdb.CloseDb(wallet.strWalletFile); bitdb.CheckpointLSN(wallet.strWalletFile); + printf("Issuing lsn_reset for backup file portability.\n"); + bitdb.lsn_reset(wallet.strWalletFile); bitdb.mapFileUseCount.erase(wallet.strWalletFile); // Copy wallet.dat diff --git a/src/clientversion.h b/src/clientversion.h index c909c360f1..65b371542c 100644 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -8,7 +8,7 @@ // These need to be macros, as version.cpp's and bitcoin-qt.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 3 #define CLIENT_VERSION_MINOR 7 -#define CLIENT_VERSION_REVISION 10 +#define CLIENT_VERSION_REVISION 11 #define CLIENT_VERSION_BUILD 0 // Converts the parameter X to a string after macro replacement on X has been performed. diff --git a/src/db.cpp b/src/db.cpp old mode 100644 new mode 100755 index e5bf33df56..5bc5c1ff2e --- a/src/db.cpp +++ b/src/db.cpp @@ -227,9 +227,16 @@ void CDBEnv::CheckpointLSN(std::string strFile) dbenv.txn_checkpoint(0, 0, 0); if (fMockDb) return; - dbenv.lsn_reset(strFile.c_str(), 0); + // The below line is commented out. LSN reset is not necessary and improper. Txn_checkpoint alone will flush in memory log to the database file. + // This was causing extraordinary long flush times for large wallets. + // Flush is called when the wallet is closed upon client shutdown, and the below line is included there to ensure portability of wallet.dat. + //dbenv.lsn_reset(strFile.c_str(), 0); } +void CDBEnv::lsn_reset(const std::string& strFile) +{ + dbenv.lsn_reset(strFile.c_str(),0); +} CDB::CDB(const char *pszFile, const char* pszMode) : pdb(NULL), activeTxn(NULL) diff --git a/src/db.h b/src/db.h old mode 100644 new mode 100755 index 623dbfd369..c33d4e1b83 --- a/src/db.h +++ b/src/db.h @@ -71,7 +71,7 @@ class CDBEnv void Close(); void Flush(bool fShutdown); void CheckpointLSN(std::string strFile); - + void lsn_reset(const std::string& strFile); void CloseDb(const std::string& strFile); bool RemoveDb(const std::string& strFile); diff --git a/src/init.cpp b/src/init.cpp index 696ed0d5ff..fc353c642f 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -1032,8 +1032,12 @@ bool AppInit2(ThreadHandlerPtr threads) if (!strErrors.str().empty()) return InitError(strErrors.str()); - // Add wallet transactions that aren't already in a block to mapTransactions + // Add wallet transactions that aren't already in a block to mapTransactions pwalletMain->ReacceptWalletTransactions(); + int nMismatchSpent; + int64_t nBalanceInQuestion; + pwalletMain->FixSpentCoins(nMismatchSpent, nBalanceInQuestion); + return true; } diff --git a/src/main.cpp b/src/main.cpp index 6d66a4325c..617b0fabd6 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3612,6 +3612,10 @@ bool ReorganizeChain(CTxDB& txdb, unsigned &cnt_dis, unsigned &cnt_con, CBlock & "Please Reindex the chain and Restart.\n"); exit(1); //todo } + + int nMismatchSpent; + int64_t nBalanceInQuestion; + pwalletMain->FixSpentCoins(nMismatchSpent, nBalanceInQuestion); } if (fDebug && cnt_dis>0) printf("ReorganizeChain: disconnected %d blocks\n",cnt_dis); @@ -4497,23 +4501,13 @@ void GridcoinServices() //Backup the wallet once per 900 blocks or as specified in config: int nWBI = GetArg("-walletbackupinterval", 900); - if (nWBI == 0) - nWBI = 900; - - if (TimerMain("backupwallet", nWBI)) + if (nWBI && TimerMain("backupwallet", nWBI)) { bool bWalletBackupResults = BackupWallet(*pwalletMain, GetBackupFilename("wallet.dat")); bool bConfigBackupResults = BackupConfigFile(GetBackupFilename("gridcoinresearch.conf")); printf("Daily backup results: Wallet -> %s Config -> %s\r\n", (bWalletBackupResults ? "true" : "false"), (bConfigBackupResults ? "true" : "false")); } - if (false && TimerMain("FixSpentCoins",60)) - { - int nMismatchSpent; - int64_t nBalanceInQuestion; - pwalletMain->FixSpentCoins(nMismatchSpent, nBalanceInQuestion); - } - if (TimerMain("MyNeuralMagnitudeReport",30)) { try @@ -4529,10 +4523,6 @@ void GridcoinServices() { printf("Error in MyNeuralMagnitudeReport1."); } - catch(...) - { - printf("Error in MyNeuralMagnitudeReport."); - } } // Every N blocks as a Synchronized TEAM: diff --git a/src/wallet.cpp b/src/wallet.cpp index 6d95d65db2..7784ae4b19 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -2386,7 +2386,7 @@ void CWallet::FixSpentCoins(int& nMismatchFound, int64_t& nBalanceInQuestion, bo } else if (IsMine(pcoin->vout[n]) && !pcoin->IsSpent(n) && (txindex.vSpent.size() > n && !txindex.vSpent[n].IsNull())) { - if (fDebug) printf("FixSpentCoins found spent coin %s gC %s[%d], %s\n", + printf("FixSpentCoins found spent coin %s gC %s[%d], %s\n", FormatMoney(pcoin->vout[n].nValue).c_str(), pcoin->GetHash().ToString().c_str(), n, fCheckOnly? "repair not attempted" : "repairing"); nMismatchFound++; nBalanceInQuestion += pcoin->vout[n].nValue; diff --git a/src/walletdb.cpp b/src/walletdb.cpp old mode 100644 new mode 100755 index 3822595443..d0187f4120 --- a/src/walletdb.cpp +++ b/src/walletdb.cpp @@ -670,8 +670,11 @@ void ThreadFlushWalletDB(void* parg) // Flush wallet.dat so it's self contained bitdb.CloseDb(strFile); bitdb.CheckpointLSN(strFile); - - bitdb.mapFileUseCount.erase(mi++); + // The below line is commented out, because the above line (CheckpointLSN) should have never had + // lsn_reset in it. lsn_reset should only be called on the final flush when the wallet is closed. + // This is handled in CDB::Flush, which has a while loop that also does in the right place what + // the intention of the below line was. + // bitdb.mapFileUseCount.erase(mi++); if (fDebug10) printf("Flushed wallet.dat %" PRId64 "ms\n", GetTimeMillis() - nStart); } }