25 std::vector<bilingual_str> &warnings) {
30 std::unique_ptr<WalletDatabase> database =
37 std::shared_ptr<BerkeleyEnvironment> env =
40 if (!env->Open(error)) {
52 std::string newFilename =
strprintf(
"%s.%d.bak", filename, now);
54 int result = env->dbenv->dbrename(
nullptr, filename.c_str(),
nullptr,
55 newFilename.c_str(), DB_AUTO_COMMIT);
69 std::vector<KeyValPair> salvagedData;
71 std::stringstream strDump;
73 Db
db(env->dbenv.get(), 0);
74 result =
db.verify(newFilename.c_str(),
nullptr, &strDump,
75 DB_SALVAGE | DB_AGGRESSIVE);
76 if (result == DB_VERIFY_BAD) {
78 Untranslated(
"Salvage: Database salvage found errors, all data may "
79 "not be recoverable."));
81 if (result != 0 && result != DB_VERIFY_BAD) {
83 Untranslated(
"Salvage: Database salvage failed with result %d."),
97 while (!strDump.eof() && strLine !=
HEADER_END) {
98 getline(strDump, strLine);
101 std::string keyHex, valueHex;
102 while (!strDump.eof() && keyHex !=
DATA_END) {
103 getline(strDump, keyHex);
108 getline(strDump, valueHex);
111 Untranslated(
"Salvage: WARNING: Number of keys in data "
112 "does not match number of values."));
115 salvagedData.push_back(
122 warnings.push_back(
Untranslated(
"Salvage: WARNING: Unexpected end of "
123 "file while reading salvage output."));
126 fSuccess = (result == 0);
129 if (salvagedData.empty()) {
131 Untranslated(
"Salvage(aggressive) found no records in %s."),
136 std::unique_ptr<Db> pdbCopy = std::make_unique<Db>(env->dbenv.get(), 0);
137 int ret = pdbCopy->open(
nullptr,
150 DbTxn *ptxn = env->TxnBegin();
157 std::string strType, strErr;
162 fReadOK =
ReadKeyValue(&dummyWallet, ssKey, ssValue, strType,
170 Untranslated(
"WARNING: WalletBatch::Recover skipping %s: %s"),
174 Dbt datKey(row.first.data(), row.first.size());
175 Dbt datValue(row.second.data(), row.second.size());
176 int ret2 = pdbCopy->put(ptxn, &datKey, &datValue, DB_NOOVERWRITE);
std::shared_ptr< BerkeleyEnvironment > GetWalletEnv(const fs::path &wallet_path, std::string &database_filename)
Get BerkeleyEnvironment and database filename given a wallet path.
static bool ReadKeyValue(CWallet *pwallet, DataStream &ssKey, DataStream &ssValue, CWalletScanState &wss, std::string &strType, std::string &strErr, const KeyFilterFn &filter_fn=nullptr) EXCLUSIVE_LOCKS_REQUIRED(pwallet -> cs_wallet)