src/walletdb.cpp
//
// Try to (very carefully!) recover wallet.dat if there is a problem.
//
Try to (very carefully!) recover wallet.dat if there is a problem.
Try to ( very carefully! ) recover wallet . dat if there is a problem .
bool CWalletDB::Recover(CDBEnv& dbenv, std::string filename, bool fOnlyKeys)
{
    int64_t now = GetTime();
    std::string newFilename = strprintf("wallet.%d.bak", now);
    int result = dbenv.dbenv.dbrename(NULL, filename.c_str(), NULL,
        newFilename.c_str(), DB_AUTO_COMMIT);
    if (result == 0)
        LogPrintf("Renamed %s to %s\n", filename, newFilename);
    else {
        LogPrintf("Failed to rename %s to %s\n", filename, newFilename);
        return false;
    }
    std::vector<CDBEnv::KeyValPair> salvagedData;
    bool allOK = dbenv.Salvage(newFilename, true, salvagedData);
    if (salvagedData.empty()) {
        LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename);
        return false;
    }
    LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());
    bool fSuccess = allOK;
    boost::scoped_ptr<Db> pdbCopy(new Db(&dbenv.dbenv, 0));
    int ret = pdbCopy->open(NULL, 
        filename.c_str(),         
        "main",                   
        DB_BTREE,                 
        DB_CREATE,                
        0);
    if (ret > 0) {
        LogPrintf("Cannot create database file %s\n", filename);
        return false;
    }
    CWallet dummyWallet;
    CWalletScanState wss;
    DbTxn* ptxn = dbenv.TxnBegin();
    BOOST_FOREACH (CDBEnv::KeyValPair& row, salvagedData) {
        if (fOnlyKeys) {
            CDataStream ssKey(row.first, SER_DISK, CLIENT_VERSION);
            CDataStream ssValue(row.second, SER_DISK, CLIENT_VERSION);
            string strType, strErr;
            bool fReadOK = ReadKeyValue(&dummyWallet, ssKey, ssValue,
                wss, strType, strErr);
            if (!IsKeyType(strType))
                continue;
            if (!fReadOK) {
                LogPrintf("WARNING: CWalletDB::Recover skipping %s: %s\n", strType, strErr);
                continue;
            }
        }
        Dbt datKey(&row.first[0], row.first.size());
        Dbt datValue(&row.second[0], row.second.size());
        int ret2 = pdbCopy->put(ptxn, &datKey, &datValue, DB_NOOVERWRITE);
        if (ret2 > 0)
            fSuccess = false;
    }
    ptxn->commit(0);
    pdbCopy->close(0);
    return fSuccess;
}
bool CWalletDB :: Recover ( CDBEnv & dbenv , std :: string filename , bool fOnlyKeys ) { int64_t now = GetTime ( ) ; std :: string newFilename = strprintf ( " " , now ) ; int result = dbenv . dbenv . dbrename ( NULL , filename . c_str ( ) , NULL , newFilename . c_str ( ) , DB_AUTO_COMMIT ) ; if ( result == 0 ) LogPrintf ( " \n " , filename , newFilename ) ; else { LogPrintf ( " \n " , filename , newFilename ) ; return false ; } std :: vector < CDBEnv :: KeyValPair > salvagedData ; bool allOK = dbenv . Salvage ( newFilename , true , salvagedData ) ; if ( salvagedData . empty ( ) ) { LogPrintf ( " \n " , newFilename ) ; return false ; } LogPrintf ( " \n " , salvagedData . size ( ) ) ; bool fSuccess = allOK ; boost :: scoped_ptr < Db > pdbCopy ( new Db ( & dbenv . dbenv , 0 ) ) ; int ret = pdbCopy -> open ( NULL , filename . c_str ( ) , " " , DB_BTREE , DB_CREATE , 0 ) ; if ( ret > 0 ) { LogPrintf ( " \n " , filename ) ; return false ; } CWallet dummyWallet ; CWalletScanState wss ; DbTxn * ptxn = dbenv . TxnBegin ( ) ; BOOST_FOREACH ( CDBEnv :: KeyValPair & row , salvagedData ) { if ( fOnlyKeys ) { CDataStream ssKey ( row . first , SER_DISK , CLIENT_VERSION ) ; CDataStream ssValue ( row . second , SER_DISK , CLIENT_VERSION ) ; string strType , strErr ; bool fReadOK = ReadKeyValue ( & dummyWallet , ssKey , ssValue , wss , strType , strErr ) ; if ( ! IsKeyType ( strType ) ) continue ; if ( ! fReadOK ) { LogPrintf ( " \n " , strType , strErr ) ; continue ; } } Dbt datKey ( & row . first [ 0 ] , row . first . size ( ) ) ; Dbt datValue ( & row . second [ 0 ] , row . second . size ( ) ) ; int ret2 = pdbCopy -> put ( ptxn , & datKey , & datValue , DB_NOOVERWRITE ) ; if ( ret2 > 0 ) fSuccess = false ; } ptxn -> commit ( 0 ) ; pdbCopy -> close ( 0 ) ; return fSuccess ; }
Try to (very carefully!)
Try to ( very carefully! )
// Recovery procedure: // move wallet.dat to wallet.timestamp.bak // Call Salvage with fAggressive=true to // get as much data as possible. // Rewrite salvaged data to wallet.dat // Set -rescan so any missing transactions will be // found. // Txn pointer // Filename // Logical db name // Database type // Flags