Skip to content

Commit

Permalink
wallettool: Have RecoverDatabaseFile return errors and warnings
Browse files Browse the repository at this point in the history
Summary:
Instead of logging or printing these errors and warnings, return them to
the caller.

This is a backport of [[bitcoin/bitcoin#19457 | core#19457]] [2/3]
bitcoin/bitcoin@9f536d4

Depends on D9640

Test Plan: `ninja all check-all`

Reviewers: #bitcoin_abc, Fabien

Reviewed By: #bitcoin_abc, Fabien

Differential Revision: https://reviews.bitcoinabc.org/D9641
  • Loading branch information
achow101 authored and PiRK committed Jun 8, 2021
1 parent 7e28604 commit d37ccae
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 22 deletions.
45 changes: 25 additions & 20 deletions src/wallet/salvage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@ static const char *HEADER_END = "HEADER=END";
static const char *DATA_END = "DATA=END";
typedef std::pair<std::vector<uint8_t>, std::vector<uint8_t>> KeyValPair;

bool RecoverDatabaseFile(const fs::path &file_path) {
bool RecoverDatabaseFile(const fs::path &file_path, bilingual_str &error,
std::vector<bilingual_str> &warnings) {
std::string filename;
std::shared_ptr<BerkeleyEnvironment> env =
GetWalletEnv(file_path, filename);

bilingual_str open_err;
if (!env->Open(open_err)) {
tfm::format(std::cerr, "%s\n", open_err.original);
if (!env->Open(error)) {
return false;
}

Expand All @@ -40,10 +39,9 @@ bool RecoverDatabaseFile(const fs::path &file_path) {

int result = env->dbenv->dbrename(nullptr, filename.c_str(), nullptr,
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);
if (result != 0) {
error = strprintf(Untranslated("Failed to rename %s to %s"), filename,
newFilename);
return false;
}

Expand All @@ -62,11 +60,14 @@ bool RecoverDatabaseFile(const fs::path &file_path) {
result = db.verify(newFilename.c_str(), nullptr, &strDump,
DB_SALVAGE | DB_AGGRESSIVE);
if (result == DB_VERIFY_BAD) {
LogPrintf("Salvage: Database salvage found errors, all data may not be "
"recoverable.\n");
warnings.push_back(
Untranslated("Salvage: Database salvage found errors, all data may "
"not be recoverable."));
}
if (result != 0 && result != DB_VERIFY_BAD) {
LogPrintf("Salvage: Database salvage failed with result %d.\n", result);
error = strprintf(
Untranslated("Salvage: Database salvage failed with result %d."),
result);
return false;
}

Expand All @@ -92,8 +93,9 @@ bool RecoverDatabaseFile(const fs::path &file_path) {
}
getline(strDump, valueHex);
if (valueHex == DATA_END) {
LogPrintf("Salvage: WARNING: Number of keys in data does not "
"match number of values.\n");
warnings.push_back(
Untranslated("Salvage: WARNING: Number of keys in data "
"does not match number of values."));
break;
}
salvagedData.push_back(
Expand All @@ -103,18 +105,19 @@ bool RecoverDatabaseFile(const fs::path &file_path) {

bool fSuccess;
if (keyHex != DATA_END) {
LogPrintf("Salvage: WARNING: Unexpected end of file while reading "
"salvage output.\n");
warnings.push_back(Untranslated("Salvage: WARNING: Unexpected end of "
"file while reading salvage output."));
fSuccess = false;
} else {
fSuccess = (result == 0);
}

if (salvagedData.empty()) {
LogPrintf("Salvage(aggressive) found no records in %s.\n", newFilename);
error = strprintf(
Untranslated("Salvage(aggressive) found no records in %s."),
newFilename);
return false;
}
LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());

std::unique_ptr<Db> pdbCopy = std::make_unique<Db>(env->dbenv.get(), 0);
int ret = pdbCopy->open(nullptr, // Txn pointer
Expand All @@ -124,7 +127,8 @@ bool RecoverDatabaseFile(const fs::path &file_path) {
DB_CREATE, // Flags
0);
if (ret > 0) {
LogPrintf("Cannot create database file %s\n", filename);
error =
strprintf(Untranslated("Cannot create database file %s"), filename);
pdbCopy->close(0);
return false;
}
Expand All @@ -148,8 +152,9 @@ bool RecoverDatabaseFile(const fs::path &file_path) {
continue;
}
if (!fReadOK) {
LogPrintf("WARNING: WalletBatch::Recover skipping %s: %s\n",
strType, strErr);
warnings.push_back(strprintf(
Untranslated("WARNING: WalletBatch::Recover skipping %s: %s"),
strType, strErr));
continue;
}
Dbt datKey(&row.first[0], row.first.size());
Expand Down
5 changes: 4 additions & 1 deletion src/wallet/salvage.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include <fs.h>
#include <streams.h>

bool RecoverDatabaseFile(const fs::path &file_path);
struct bilingual_str;

bool RecoverDatabaseFile(const fs::path &file_path, bilingual_str &error,
std::vector<bilingual_str> &warnings);

#endif // BITCOIN_WALLET_SALVAGE_H
13 changes: 12 additions & 1 deletion src/wallet/wallettool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,18 @@ bool ExecuteWalletToolFunc(const std::string &command,
WalletShowInfo(wallet_instance.get());
wallet_instance->Flush(true);
} else if (command == "salvage") {
return RecoverDatabaseFile(path);
bilingual_str error;
std::vector<bilingual_str> warnings;
bool ret = RecoverDatabaseFile(path, error, warnings);
if (!ret) {
for (const auto &warning : warnings) {
tfm::format(std::cerr, "%s\n", warning.original);
}
if (!error.empty()) {
tfm::format(std::cerr, "%s\n", error.original);
}
}
return ret;
}
} else {
tfm::format(std::cerr, "Invalid command: %s\n", command);
Expand Down

0 comments on commit d37ccae

Please sign in to comment.