X-Git-Url: https://git.novaco.in/?a=blobdiff_plain;f=src%2Fdb.cpp;h=783b079963900cb5800a71d5a22e9b068dfb95f9;hb=4664aae3fe2eba4eec84d20f1e7e701ceeeb49bd;hp=d41da68abad698abc9c0b15d07089569e753c68d;hpb=00eae584a26295dbf7b1aebf99c1b8a4c9a86c37;p=novacoin.git diff --git a/src/db.cpp b/src/db.cpp index d41da68..783b079 100644 --- a/src/db.cpp +++ b/src/db.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2011 The Bitcoin developers +// Copyright (c) 2009-2012 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. @@ -28,6 +28,23 @@ DbEnv dbenv(0); static map mapFileUseCount; static map mapDb; +static void EnvShutdown() +{ + if (!fDbEnvInit) + return; + + fDbEnvInit = false; + try + { + dbenv.close(0); + } + catch (const DbException& e) + { + printf("EnvShutdown exception: %s (%d)\n", e.what(), e.get_errno()); + } + DbEnv(0).remove(GetDataDir().c_str(), 0); +} + class CDBInit { public: @@ -36,11 +53,7 @@ public: } ~CDBInit() { - if (fDbEnvInit) - { - dbenv.close(0); - fDbEnvInit = false; - } + EnvShutdown(); } } instance_of_cdbinit; @@ -165,7 +178,7 @@ void static CloseDb(const string& strFile) } } -bool Resilver(const string& strFile) +bool CDB::Rewrite(const string& strFile, const char* pszSkip) { while (!fShutdown) { @@ -180,54 +193,65 @@ bool Resilver(const string& strFile) mapFileUseCount.erase(strFile); bool fSuccess = true; - printf("Resilvering %s...\n", strFile.c_str()); - string strFileRes = strFile + ".resilver"; - CDB db(strFile.c_str(), "r"); - Db* pdbCopy = new Db(&dbenv, 0); - - int ret = pdbCopy->open(NULL, // Txn pointer - strFileRes.c_str(), // Filename - "main", // Logical db name - DB_BTREE, // Database type - DB_CREATE, // Flags - 0); - if (ret > 0) - { - printf("Cannot create database file %s\n", strFileRes.c_str()); - fSuccess = false; - } - - Dbc* pcursor = db.GetCursor(); - if (pcursor) - while (fSuccess) + printf("Rewriting %s...\n", strFile.c_str()); + string strFileRes = strFile + ".rewrite"; + { // surround usage of db with extra {} + CDB db(strFile.c_str(), "r"); + Db* pdbCopy = new Db(&dbenv, 0); + + int ret = pdbCopy->open(NULL, // Txn pointer + strFileRes.c_str(), // Filename + "main", // Logical db name + DB_BTREE, // Database type + DB_CREATE, // Flags + 0); + if (ret > 0) { - CDataStream ssKey; - CDataStream ssValue; - int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); - if (ret == DB_NOTFOUND) - break; - else if (ret != 0) + printf("Cannot create database file %s\n", strFileRes.c_str()); + fSuccess = false; + } + + Dbc* pcursor = db.GetCursor(); + if (pcursor) + while (fSuccess) { - pcursor->close(); - fSuccess = false; - break; + CDataStream ssKey; + CDataStream ssValue; + int ret = db.ReadAtCursor(pcursor, ssKey, ssValue, DB_NEXT); + if (ret == DB_NOTFOUND) + { + pcursor->close(); + break; + } + else if (ret != 0) + { + pcursor->close(); + fSuccess = false; + break; + } + if (pszSkip && + strncmp(&ssKey[0], pszSkip, std::min(ssKey.size(), strlen(pszSkip))) == 0) + continue; + if (strncmp(&ssKey[0], "\x07version", 8) == 0) + { + // Update version: + ssValue.clear(); + ssValue << VERSION; + } + Dbt datKey(&ssKey[0], ssKey.size()); + Dbt datValue(&ssValue[0], ssValue.size()); + int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); + if (ret2 > 0) + fSuccess = false; } - Dbt datKey(&ssKey[0], ssKey.size()); - Dbt datValue(&ssValue[0], ssValue.size()); - int ret2 = pdbCopy->put(NULL, &datKey, &datValue, DB_NOOVERWRITE); - if (ret2 > 0) + if (fSuccess) + { + db.Close(); + CloseDb(strFile); + if (pdbCopy->close(0)) fSuccess = false; + delete pdbCopy; } - if (fSuccess) - { - Db* pdb = mapDb[strFile]; - if (pdb->close(0)) - fSuccess = false; - if (pdbCopy->close(0)) - fSuccess = false; - delete pdb; - delete pdbCopy; - mapDb[strFile] = NULL; } if (fSuccess) { @@ -239,7 +263,7 @@ bool Resilver(const string& strFile) fSuccess = false; } if (!fSuccess) - printf("Resilvering of %s FAILED!\n", strFileRes.c_str()); + printf("Rewriting of %s FAILED!\n", strFileRes.c_str()); return fSuccess; } } @@ -280,9 +304,10 @@ void DBFlush(bool fShutdown) { char** listp; if (mapFileUseCount.empty()) + { dbenv.log_archive(&listp, DB_ARCH_REMOVE); - dbenv.close(0); - fDbEnvInit = false; + EnvShutdown(); + } } } } @@ -758,7 +783,6 @@ int CWalletDB::LoadWallet(CWallet* pwallet) pwallet->vchDefaultKey.clear(); int nFileVersion = 0; vector vWalletUpgrade; - bool fIsResilvered = false; bool fIsEncrypted = false; // Modify defaults @@ -855,12 +879,16 @@ int CWalletDB::LoadWallet(CWallet* pwallet) CPrivKey pkey; ssValue >> pkey; key.SetPrivKey(pkey); + if (key.GetPubKey() != vchPubKey || !key.IsValid()) + return DB_CORRUPT; } else { CWalletKey wkey; ssValue >> wkey; key.SetPrivKey(wkey.vchPrivKey); + if (key.GetPubKey() != vchPubKey || !key.IsValid()) + return DB_CORRUPT; } if (!pwallet->LoadKey(key)) return DB_CORRUPT; @@ -919,7 +947,6 @@ int CWalletDB::LoadWallet(CWallet* pwallet) if (strKey == "fMinimizeOnClose") ssValue >> fMinimizeOnClose; if (strKey == "fUseProxy") ssValue >> fUseProxy; if (strKey == "addrProxy") ssValue >> addrProxy; - if (strKey == "fIsResilvered") ssValue >> fIsResilvered; if (fHaveUPnP && strKey == "fUseUPnP") ssValue >> fUseUPnP; } else if (strType == "minversion") @@ -947,8 +974,11 @@ int CWalletDB::LoadWallet(CWallet* pwallet) printf("fUseUPnP = %d\n", fUseUPnP); - // Upgrade - if (nFileVersion < VERSION) + // Rewrite encrypted wallets of versions 0.4.0 and 0.5.0rc: + if (fIsEncrypted && (nFileVersion == 40000 || nFileVersion == 50000)) + return DB_NEED_REWRITE; + + if (nFileVersion < VERSION) // Update { // Get rid of old debug.log file in current directory if (nFileVersion <= 105 && !pszSetDataDir[0]) @@ -957,9 +987,6 @@ int CWalletDB::LoadWallet(CWallet* pwallet) WriteVersion(VERSION); } - if (fIsEncrypted && !fIsResilvered) - return DB_NEED_RESILVER; - return DB_LOAD_OK; }