mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
Implement MigrateToSQLite
This commit is contained in:
parent
5b62f095e7
commit
e7b16f925a
2 changed files with 80 additions and 1 deletions
|
@ -3654,4 +3654,76 @@ ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const Flat
|
|||
|
||||
return spk_man;
|
||||
}
|
||||
|
||||
bool CWallet::MigrateToSQLite(bilingual_str& error)
|
||||
{
|
||||
AssertLockHeld(cs_wallet);
|
||||
|
||||
WalletLogPrintf("Migrating wallet storage database from BerkeleyDB to SQLite.\n");
|
||||
|
||||
if (m_database->Format() == "sqlite") {
|
||||
error = _("Error: This wallet already uses SQLite");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get all of the records for DB type migration
|
||||
std::unique_ptr<DatabaseBatch> batch = m_database->MakeBatch();
|
||||
std::vector<std::pair<SerializeData, SerializeData>> records;
|
||||
if (!batch->StartCursor()) {
|
||||
error = _("Error: Unable to begin reading all records in the database");
|
||||
return false;
|
||||
}
|
||||
bool complete = false;
|
||||
while (true) {
|
||||
CDataStream ss_key(SER_DISK, CLIENT_VERSION);
|
||||
CDataStream ss_value(SER_DISK, CLIENT_VERSION);
|
||||
bool ret = batch->ReadAtCursor(ss_key, ss_value, complete);
|
||||
if (!ret) {
|
||||
break;
|
||||
}
|
||||
SerializeData key(ss_key.begin(), ss_key.end());
|
||||
SerializeData value(ss_value.begin(), ss_value.end());
|
||||
records.emplace_back(key, value);
|
||||
}
|
||||
batch->CloseCursor();
|
||||
batch.reset();
|
||||
if (!complete) {
|
||||
error = _("Error: Unable to read all records in the database");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Close this database and delete the file
|
||||
fs::path db_path = fs::PathFromString(m_database->Filename());
|
||||
fs::path db_dir = db_path.parent_path();
|
||||
m_database->Close();
|
||||
fs::remove(db_path);
|
||||
|
||||
// Make new DB
|
||||
DatabaseOptions opts;
|
||||
opts.require_create = true;
|
||||
opts.require_format = DatabaseFormat::SQLITE;
|
||||
DatabaseStatus db_status;
|
||||
std::unique_ptr<WalletDatabase> new_db = MakeDatabase(db_dir, opts, db_status, error);
|
||||
assert(new_db); // This is to prevent doing anything further with this wallet. The original file was deleted, but a backup exists.
|
||||
m_database.reset();
|
||||
m_database = std::move(new_db);
|
||||
|
||||
// Write existing records into the new DB
|
||||
batch = m_database->MakeBatch();
|
||||
bool began = batch->TxnBegin();
|
||||
assert(began); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution.
|
||||
for (const auto& [key, value] : records) {
|
||||
CDataStream ss_key(key, SER_DISK, CLIENT_VERSION);
|
||||
CDataStream ss_value(value, SER_DISK, CLIENT_VERSION);
|
||||
if (!batch->Write(ss_key, ss_value)) {
|
||||
batch->TxnAbort();
|
||||
m_database->Close();
|
||||
fs::remove(m_database->Filename());
|
||||
assert(false); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution.
|
||||
}
|
||||
}
|
||||
bool committed = batch->TxnCommit();
|
||||
assert(committed); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution.
|
||||
return true;
|
||||
}
|
||||
} // namespace wallet
|
||||
|
|
|
@ -316,7 +316,7 @@ private:
|
|||
std::string m_name;
|
||||
|
||||
/** Internal database handle. */
|
||||
std::unique_ptr<WalletDatabase> const m_database;
|
||||
std::unique_ptr<WalletDatabase> m_database;
|
||||
|
||||
/**
|
||||
* The following is used to keep track of how far behind the wallet is
|
||||
|
@ -920,6 +920,13 @@ public:
|
|||
|
||||
//! Add a descriptor to the wallet, return a ScriptPubKeyMan & associated output type
|
||||
ScriptPubKeyMan* AddWalletDescriptor(WalletDescriptor& desc, const FlatSigningProvider& signing_provider, const std::string& label, bool internal) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
|
||||
/** Move all records from the BDB database to a new SQLite database for storage.
|
||||
* The original BDB file will be deleted and replaced with a new SQLite file.
|
||||
* A backup is not created.
|
||||
* May crash if something unexpected happens in the filesystem.
|
||||
*/
|
||||
bool MigrateToSQLite(bilingual_str& error) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue