mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-09-12 05:32:22 +02:00
wallet: store m_additional_flags in SQLiteDatabase to fix reopen path
SQLiteDatabase::Open() (the public override) always reopens the database with no additional flags. If SQLiteBatch::Close() triggers the force_conn_refresh path (TxnAbort failed), it calls Open() which drops the original additional_flags, causing in-memory databases to be reopened as on-disk instead. Store additional_flags as a member and use it in Open() so the reconnect preserves the original flags. For in-memory databases, connection recovery makes no sense as all data would be lost; both the force_conn_refresh path and the public Open() now throw instead. Co-authored-by: Sjors Provoost <sjors@sprovoost.nl>
This commit is contained in:
@@ -116,7 +116,7 @@ SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_pa
|
||||
{}
|
||||
|
||||
SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, int additional_flags)
|
||||
: WalletDatabase(), m_dir_path(dir_path), m_file_path(fs::PathToString(file_path)), m_write_semaphore(1), m_use_unsafe_sync(options.use_unsafe_sync)
|
||||
: WalletDatabase(), m_dir_path(dir_path), m_file_path(fs::PathToString(file_path)), m_additional_flags(additional_flags), m_write_semaphore(1), m_use_unsafe_sync(options.use_unsafe_sync)
|
||||
{
|
||||
{
|
||||
LOCK(g_sqlite_mutex);
|
||||
@@ -139,7 +139,7 @@ SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_pa
|
||||
}
|
||||
|
||||
try {
|
||||
Open(additional_flags);
|
||||
Open(m_additional_flags);
|
||||
} catch (const std::runtime_error&) {
|
||||
// If open fails, cleanup this object and rethrow the exception
|
||||
Cleanup();
|
||||
@@ -247,7 +247,10 @@ bool SQLiteDatabase::Verify(bilingual_str& error)
|
||||
|
||||
void SQLiteDatabase::Open()
|
||||
{
|
||||
Open(/*additional_flags*/0);
|
||||
if (m_additional_flags & SQLITE_OPEN_MEMORY) {
|
||||
throw std::runtime_error("SQLiteDatabase: Cannot reopen an in-memory database");
|
||||
}
|
||||
Open(m_additional_flags);
|
||||
}
|
||||
|
||||
void SQLiteDatabase::Open(int additional_flags)
|
||||
@@ -448,6 +451,9 @@ void SQLiteBatch::Close()
|
||||
}
|
||||
|
||||
if (force_conn_refresh) {
|
||||
if (m_database.m_additional_flags & SQLITE_OPEN_MEMORY) {
|
||||
throw std::runtime_error("SQLiteDatabase: Cannot recover in-memory database connection");
|
||||
}
|
||||
m_database.Close();
|
||||
try {
|
||||
m_database.Open();
|
||||
|
||||
@@ -103,10 +103,14 @@ public:
|
||||
class SQLiteDatabase : public WalletDatabase
|
||||
{
|
||||
private:
|
||||
friend class SQLiteBatch;
|
||||
|
||||
const fs::path m_dir_path;
|
||||
|
||||
const std::string m_file_path;
|
||||
|
||||
const int m_additional_flags;
|
||||
|
||||
/**
|
||||
* This mutex protects SQLite initialization and shutdown.
|
||||
* sqlite3_config() and sqlite3_shutdown() are not thread-safe (sqlite3_initialize() is).
|
||||
|
||||
Reference in New Issue
Block a user