mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-09 10:43:19 -05:00
wallettool: Have RecoverDatabaseFile return errors and warnings
Instead of logging or printing these errors and warnings, return them to the caller.
This commit is contained in:
parent
06e263a4e3
commit
9f536d4fe9
3 changed files with 26 additions and 18 deletions
|
@ -16,14 +16,12 @@ static const char *HEADER_END = "HEADER=END";
|
||||||
static const char *DATA_END = "DATA=END";
|
static const char *DATA_END = "DATA=END";
|
||||||
typedef std::pair<std::vector<unsigned char>, std::vector<unsigned char> > KeyValPair;
|
typedef std::pair<std::vector<unsigned char>, std::vector<unsigned char> > 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::string filename;
|
||||||
std::shared_ptr<BerkeleyEnvironment> env = GetWalletEnv(file_path, filename);
|
std::shared_ptr<BerkeleyEnvironment> env = GetWalletEnv(file_path, filename);
|
||||||
|
|
||||||
bilingual_str open_err;
|
if (!env->Open(error)) {
|
||||||
if (!env->Open(open_err)) {
|
|
||||||
tfm::format(std::cerr, "%s\n", open_err.original);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +37,9 @@ bool RecoverDatabaseFile(const fs::path& file_path)
|
||||||
|
|
||||||
int result = env->dbenv->dbrename(nullptr, filename.c_str(), nullptr,
|
int result = env->dbenv->dbrename(nullptr, filename.c_str(), nullptr,
|
||||||
newFilename.c_str(), DB_AUTO_COMMIT);
|
newFilename.c_str(), DB_AUTO_COMMIT);
|
||||||
if (result == 0)
|
if (result != 0)
|
||||||
LogPrintf("Renamed %s to %s\n", filename, newFilename);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
LogPrintf("Failed to rename %s to %s\n", filename, newFilename);
|
error = strprintf(Untranslated("Failed to rename %s to %s"), filename, newFilename);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,10 +56,10 @@ bool RecoverDatabaseFile(const fs::path& file_path)
|
||||||
Db db(env->dbenv.get(), 0);
|
Db db(env->dbenv.get(), 0);
|
||||||
result = db.verify(newFilename.c_str(), nullptr, &strDump, DB_SALVAGE | DB_AGGRESSIVE);
|
result = db.verify(newFilename.c_str(), nullptr, &strDump, DB_SALVAGE | DB_AGGRESSIVE);
|
||||||
if (result == DB_VERIFY_BAD) {
|
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) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +83,7 @@ bool RecoverDatabaseFile(const fs::path& file_path)
|
||||||
break;
|
break;
|
||||||
getline(strDump, valueHex);
|
getline(strDump, valueHex);
|
||||||
if (valueHex == DATA_END) {
|
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;
|
break;
|
||||||
}
|
}
|
||||||
salvagedData.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
|
salvagedData.push_back(make_pair(ParseHex(keyHex), ParseHex(valueHex)));
|
||||||
|
@ -96,7 +92,7 @@ bool RecoverDatabaseFile(const fs::path& file_path)
|
||||||
|
|
||||||
bool fSuccess;
|
bool fSuccess;
|
||||||
if (keyHex != DATA_END) {
|
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;
|
fSuccess = false;
|
||||||
} else {
|
} else {
|
||||||
fSuccess = (result == 0);
|
fSuccess = (result == 0);
|
||||||
|
@ -104,10 +100,9 @@ bool RecoverDatabaseFile(const fs::path& file_path)
|
||||||
|
|
||||||
if (salvagedData.empty())
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
LogPrintf("Salvage(aggressive) found %u records\n", salvagedData.size());
|
|
||||||
|
|
||||||
std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0);
|
std::unique_ptr<Db> pdbCopy = MakeUnique<Db>(env->dbenv.get(), 0);
|
||||||
int ret = pdbCopy->open(nullptr, // Txn pointer
|
int ret = pdbCopy->open(nullptr, // Txn pointer
|
||||||
|
@ -117,7 +112,7 @@ bool RecoverDatabaseFile(const fs::path& file_path)
|
||||||
DB_CREATE, // Flags
|
DB_CREATE, // Flags
|
||||||
0);
|
0);
|
||||||
if (ret > 0) {
|
if (ret > 0) {
|
||||||
LogPrintf("Cannot create database file %s\n", filename);
|
error = strprintf(Untranslated("Cannot create database file %s"), filename);
|
||||||
pdbCopy->close(0);
|
pdbCopy->close(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +136,7 @@ bool RecoverDatabaseFile(const fs::path& file_path)
|
||||||
}
|
}
|
||||||
if (!fReadOK)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
Dbt datKey(&row.first[0], row.first.size());
|
Dbt datKey(&row.first[0], row.first.size());
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <streams.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
|
#endif // BITCOIN_WALLET_SALVAGE_H
|
||||||
|
|
|
@ -126,7 +126,18 @@ bool ExecuteWalletToolFunc(const std::string& command, const std::string& name)
|
||||||
WalletShowInfo(wallet_instance.get());
|
WalletShowInfo(wallet_instance.get());
|
||||||
wallet_instance->Flush(true);
|
wallet_instance->Flush(true);
|
||||||
} else if (command == "salvage") {
|
} 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 {
|
} else {
|
||||||
tfm::format(std::cerr, "Invalid command: %s\n", command);
|
tfm::format(std::cerr, "Invalid command: %s\n", command);
|
||||||
|
|
Loading…
Add table
Reference in a new issue