Bitcoin Core  27.99.0
P2P Digital Currency
sqlite.cpp
Go to the documentation of this file.
1 // Copyright (c) 2020-2022 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4 
5 #if defined(HAVE_CONFIG_H)
7 #endif
8 
9 #include <wallet/sqlite.h>
10 
11 #include <chainparams.h>
12 #include <crypto/common.h>
13 #include <logging.h>
14 #include <sync.h>
15 #include <util/fs_helpers.h>
16 #include <util/check.h>
17 #include <util/strencodings.h>
18 #include <util/translation.h>
19 #include <wallet/db.h>
20 
21 #include <sqlite3.h>
22 #include <stdint.h>
23 
24 #include <optional>
25 #include <utility>
26 #include <vector>
27 
28 namespace wallet {
29 static constexpr int32_t WALLET_SCHEMA_VERSION = 0;
30 
31 static Span<const std::byte> SpanFromBlob(sqlite3_stmt* stmt, int col)
32 {
33  return {reinterpret_cast<const std::byte*>(sqlite3_column_blob(stmt, col)),
34  static_cast<size_t>(sqlite3_column_bytes(stmt, col))};
35 }
36 
37 static void ErrorLogCallback(void* arg, int code, const char* msg)
38 {
39  // From sqlite3_config() documentation for the SQLITE_CONFIG_LOG option:
40  // "The void pointer that is the second argument to SQLITE_CONFIG_LOG is passed through as
41  // the first parameter to the application-defined logger function whenever that function is
42  // invoked."
43  // Assert that this is the case:
44  assert(arg == nullptr);
45  LogPrintf("SQLite Error. Code: %d. Message: %s\n", code, msg);
46 }
47 
48 static int TraceSqlCallback(unsigned code, void* context, void* param1, void* param2)
49 {
50  auto* db = static_cast<SQLiteDatabase*>(context);
51  if (code == SQLITE_TRACE_STMT) {
52  auto* stmt = static_cast<sqlite3_stmt*>(param1);
53  // To be conservative and avoid leaking potentially secret information
54  // in the log file, only expand statements that query the database, not
55  // statements that update the database.
56  char* expanded{sqlite3_stmt_readonly(stmt) ? sqlite3_expanded_sql(stmt) : nullptr};
57  LogPrintf("[%s] SQLite Statement: %s\n", db->Filename(), expanded ? expanded : sqlite3_sql(stmt));
58  if (expanded) sqlite3_free(expanded);
59  }
60  return SQLITE_OK;
61 }
62 
63 static bool BindBlobToStatement(sqlite3_stmt* stmt,
64  int index,
66  const std::string& description)
67 {
68  // Pass a pointer to the empty string "" below instead of passing the
69  // blob.data() pointer if the blob.data() pointer is null. Passing a null
70  // data pointer to bind_blob would cause sqlite to bind the SQL NULL value
71  // instead of the empty blob value X'', which would mess up SQL comparisons.
72  int res = sqlite3_bind_blob(stmt, index, blob.data() ? static_cast<const void*>(blob.data()) : "", blob.size(), SQLITE_STATIC);
73  if (res != SQLITE_OK) {
74  LogPrintf("Unable to bind %s to statement: %s\n", description, sqlite3_errstr(res));
75  sqlite3_clear_bindings(stmt);
76  sqlite3_reset(stmt);
77  return false;
78  }
79 
80  return true;
81 }
82 
83 static std::optional<int> ReadPragmaInteger(sqlite3* db, const std::string& key, const std::string& description, bilingual_str& error)
84 {
85  std::string stmt_text = strprintf("PRAGMA %s", key);
86  sqlite3_stmt* pragma_read_stmt{nullptr};
87  int ret = sqlite3_prepare_v2(db, stmt_text.c_str(), -1, &pragma_read_stmt, nullptr);
88  if (ret != SQLITE_OK) {
89  sqlite3_finalize(pragma_read_stmt);
90  error = Untranslated(strprintf("SQLiteDatabase: Failed to prepare the statement to fetch %s: %s", description, sqlite3_errstr(ret)));
91  return std::nullopt;
92  }
93  ret = sqlite3_step(pragma_read_stmt);
94  if (ret != SQLITE_ROW) {
95  sqlite3_finalize(pragma_read_stmt);
96  error = Untranslated(strprintf("SQLiteDatabase: Failed to fetch %s: %s", description, sqlite3_errstr(ret)));
97  return std::nullopt;
98  }
99  int result = sqlite3_column_int(pragma_read_stmt, 0);
100  sqlite3_finalize(pragma_read_stmt);
101  return result;
102 }
103 
104 static void SetPragma(sqlite3* db, const std::string& key, const std::string& value, const std::string& err_msg)
105 {
106  std::string stmt_text = strprintf("PRAGMA %s = %s", key, value);
107  int ret = sqlite3_exec(db, stmt_text.c_str(), nullptr, nullptr, nullptr);
108  if (ret != SQLITE_OK) {
109  throw std::runtime_error(strprintf("SQLiteDatabase: %s: %s\n", err_msg, sqlite3_errstr(ret)));
110  }
111 }
112 
114 int SQLiteDatabase::g_sqlite_count = 0;
115 
116 SQLiteDatabase::SQLiteDatabase(const fs::path& dir_path, const fs::path& file_path, const DatabaseOptions& options, bool mock)
117  : WalletDatabase(), m_mock(mock), m_dir_path(fs::PathToString(dir_path)), m_file_path(fs::PathToString(file_path)), m_write_semaphore(1), m_use_unsafe_sync(options.use_unsafe_sync)
118 {
119  {
121  LogPrintf("Using SQLite Version %s\n", SQLiteDatabaseVersion());
122  LogPrintf("Using wallet %s\n", m_dir_path);
123 
124  if (++g_sqlite_count == 1) {
125  // Setup logging
126  int ret = sqlite3_config(SQLITE_CONFIG_LOG, ErrorLogCallback, nullptr);
127  if (ret != SQLITE_OK) {
128  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to setup error log: %s\n", sqlite3_errstr(ret)));
129  }
130  // Force serialized threading mode
131  ret = sqlite3_config(SQLITE_CONFIG_SERIALIZED);
132  if (ret != SQLITE_OK) {
133  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to configure serialized threading mode: %s\n", sqlite3_errstr(ret)));
134  }
135  }
136  int ret = sqlite3_initialize(); // This is a no-op if sqlite3 is already initialized
137  if (ret != SQLITE_OK) {
138  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to initialize SQLite: %s\n", sqlite3_errstr(ret)));
139  }
140  }
141 
142  try {
143  Open();
144  } catch (const std::runtime_error&) {
145  // If open fails, cleanup this object and rethrow the exception
146  Cleanup();
147  throw;
148  }
149 }
150 
152 {
153  const std::vector<std::pair<sqlite3_stmt**, const char*>> statements{
154  {&m_read_stmt, "SELECT value FROM main WHERE key = ?"},
155  {&m_insert_stmt, "INSERT INTO main VALUES(?, ?)"},
156  {&m_overwrite_stmt, "INSERT or REPLACE into main values(?, ?)"},
157  {&m_delete_stmt, "DELETE FROM main WHERE key = ?"},
158  {&m_delete_prefix_stmt, "DELETE FROM main WHERE instr(key, ?) = 1"},
159  };
160 
161  for (const auto& [stmt_prepared, stmt_text] : statements) {
162  if (*stmt_prepared == nullptr) {
163  int res = sqlite3_prepare_v2(m_database.m_db, stmt_text, -1, stmt_prepared, nullptr);
164  if (res != SQLITE_OK) {
165  throw std::runtime_error(strprintf(
166  "SQLiteDatabase: Failed to setup SQL statements: %s\n", sqlite3_errstr(res)));
167  }
168  }
169  }
170 }
171 
173 {
174  Cleanup();
175 }
176 
177 void SQLiteDatabase::Cleanup() noexcept
178 {
180 
181  Close();
182 
184  if (--g_sqlite_count == 0) {
185  int ret = sqlite3_shutdown();
186  if (ret != SQLITE_OK) {
187  LogPrintf("SQLiteDatabase: Failed to shutdown SQLite: %s\n", sqlite3_errstr(ret));
188  }
189  }
190 }
191 
193 {
194  assert(m_db);
195 
196  // Check the application ID matches our network magic
197  auto read_result = ReadPragmaInteger(m_db, "application_id", "the application id", error);
198  if (!read_result.has_value()) return false;
199  uint32_t app_id = static_cast<uint32_t>(read_result.value());
200  uint32_t net_magic = ReadBE32(Params().MessageStart().data());
201  if (app_id != net_magic) {
202  error = strprintf(_("SQLiteDatabase: Unexpected application id. Expected %u, got %u"), net_magic, app_id);
203  return false;
204  }
205 
206  // Check our schema version
207  read_result = ReadPragmaInteger(m_db, "user_version", "sqlite wallet schema version", error);
208  if (!read_result.has_value()) return false;
209  int32_t user_ver = read_result.value();
210  if (user_ver != WALLET_SCHEMA_VERSION) {
211  error = strprintf(_("SQLiteDatabase: Unknown sqlite wallet schema version %d. Only version %d is supported"), user_ver, WALLET_SCHEMA_VERSION);
212  return false;
213  }
214 
215  sqlite3_stmt* stmt{nullptr};
216  int ret = sqlite3_prepare_v2(m_db, "PRAGMA integrity_check", -1, &stmt, nullptr);
217  if (ret != SQLITE_OK) {
218  sqlite3_finalize(stmt);
219  error = strprintf(_("SQLiteDatabase: Failed to prepare statement to verify database: %s"), sqlite3_errstr(ret));
220  return false;
221  }
222  while (true) {
223  ret = sqlite3_step(stmt);
224  if (ret == SQLITE_DONE) {
225  break;
226  }
227  if (ret != SQLITE_ROW) {
228  error = strprintf(_("SQLiteDatabase: Failed to execute statement to verify database: %s"), sqlite3_errstr(ret));
229  break;
230  }
231  const char* msg = (const char*)sqlite3_column_text(stmt, 0);
232  if (!msg) {
233  error = strprintf(_("SQLiteDatabase: Failed to read database verification error: %s"), sqlite3_errstr(ret));
234  break;
235  }
236  std::string str_msg(msg);
237  if (str_msg == "ok") {
238  continue;
239  }
240  if (error.empty()) {
241  error = _("Failed to verify database") + Untranslated("\n");
242  }
243  error += Untranslated(strprintf("%s\n", str_msg));
244  }
245  sqlite3_finalize(stmt);
246  return error.empty();
247 }
248 
250 {
251  int flags = SQLITE_OPEN_FULLMUTEX | SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
252  if (m_mock) {
253  flags |= SQLITE_OPEN_MEMORY; // In memory database for mock db
254  }
255 
256  if (m_db == nullptr) {
257  if (!m_mock) {
259  }
260  int ret = sqlite3_open_v2(m_file_path.c_str(), &m_db, flags, nullptr);
261  if (ret != SQLITE_OK) {
262  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to open database: %s\n", sqlite3_errstr(ret)));
263  }
264  ret = sqlite3_extended_result_codes(m_db, 1);
265  if (ret != SQLITE_OK) {
266  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to enable extended result codes: %s\n", sqlite3_errstr(ret)));
267  }
268  // Trace SQL statements if tracing is enabled with -debug=walletdb -loglevel=walletdb:trace
270  ret = sqlite3_trace_v2(m_db, SQLITE_TRACE_STMT, TraceSqlCallback, this);
271  if (ret != SQLITE_OK) {
272  LogPrintf("Failed to enable SQL tracing for %s\n", Filename());
273  }
274  }
275  }
276 
277  if (sqlite3_db_readonly(m_db, "main") != 0) {
278  throw std::runtime_error("SQLiteDatabase: Database opened in readonly mode but read-write permissions are needed");
279  }
280 
281  // Acquire an exclusive lock on the database
282  // First change the locking mode to exclusive
283  SetPragma(m_db, "locking_mode", "exclusive", "Unable to change database locking mode to exclusive");
284  // Now begin a transaction to acquire the exclusive lock. This lock won't be released until we close because of the exclusive locking mode.
285  int ret = sqlite3_exec(m_db, "BEGIN EXCLUSIVE TRANSACTION", nullptr, nullptr, nullptr);
286  if (ret != SQLITE_OK) {
287  throw std::runtime_error("SQLiteDatabase: Unable to obtain an exclusive lock on the database, is it being used by another instance of " PACKAGE_NAME "?\n");
288  }
289  ret = sqlite3_exec(m_db, "COMMIT", nullptr, nullptr, nullptr);
290  if (ret != SQLITE_OK) {
291  throw std::runtime_error(strprintf("SQLiteDatabase: Unable to end exclusive lock transaction: %s\n", sqlite3_errstr(ret)));
292  }
293 
294  // Enable fullfsync for the platforms that use it
295  SetPragma(m_db, "fullfsync", "true", "Failed to enable fullfsync");
296 
297  if (m_use_unsafe_sync) {
298  // Use normal synchronous mode for the journal
299  LogPrintf("WARNING SQLite is configured to not wait for data to be flushed to disk. Data loss and corruption may occur.\n");
300  SetPragma(m_db, "synchronous", "OFF", "Failed to set synchronous mode to OFF");
301  }
302 
303  // Make the table for our key-value pairs
304  // First check that the main table exists
305  sqlite3_stmt* check_main_stmt{nullptr};
306  ret = sqlite3_prepare_v2(m_db, "SELECT name FROM sqlite_master WHERE type='table' AND name='main'", -1, &check_main_stmt, nullptr);
307  if (ret != SQLITE_OK) {
308  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to prepare statement to check table existence: %s\n", sqlite3_errstr(ret)));
309  }
310  ret = sqlite3_step(check_main_stmt);
311  if (sqlite3_finalize(check_main_stmt) != SQLITE_OK) {
312  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to finalize statement checking table existence: %s\n", sqlite3_errstr(ret)));
313  }
314  bool table_exists;
315  if (ret == SQLITE_DONE) {
316  table_exists = false;
317  } else if (ret == SQLITE_ROW) {
318  table_exists = true;
319  } else {
320  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to execute statement to check table existence: %s\n", sqlite3_errstr(ret)));
321  }
322 
323  // Do the db setup things because the table doesn't exist only when we are creating a new wallet
324  if (!table_exists) {
325  ret = sqlite3_exec(m_db, "CREATE TABLE main(key BLOB PRIMARY KEY NOT NULL, value BLOB NOT NULL)", nullptr, nullptr, nullptr);
326  if (ret != SQLITE_OK) {
327  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to create new database: %s\n", sqlite3_errstr(ret)));
328  }
329 
330  // Set the application id
331  uint32_t app_id = ReadBE32(Params().MessageStart().data());
332  SetPragma(m_db, "application_id", strprintf("%d", static_cast<int32_t>(app_id)),
333  "Failed to set the application id");
334 
335  // Set the user version
336  SetPragma(m_db, "user_version", strprintf("%d", WALLET_SCHEMA_VERSION),
337  "Failed to set the wallet schema version");
338  }
339 }
340 
341 bool SQLiteDatabase::Rewrite(const char* skip)
342 {
343  // Rewrite the database using the VACUUM command: https://sqlite.org/lang_vacuum.html
344  int ret = sqlite3_exec(m_db, "VACUUM", nullptr, nullptr, nullptr);
345  return ret == SQLITE_OK;
346 }
347 
348 bool SQLiteDatabase::Backup(const std::string& dest) const
349 {
350  sqlite3* db_copy;
351  int res = sqlite3_open(dest.c_str(), &db_copy);
352  if (res != SQLITE_OK) {
353  sqlite3_close(db_copy);
354  return false;
355  }
356  sqlite3_backup* backup = sqlite3_backup_init(db_copy, "main", m_db, "main");
357  if (!backup) {
358  LogPrintf("%s: Unable to begin backup: %s\n", __func__, sqlite3_errmsg(m_db));
359  sqlite3_close(db_copy);
360  return false;
361  }
362  // Specifying -1 will copy all of the pages
363  res = sqlite3_backup_step(backup, -1);
364  if (res != SQLITE_DONE) {
365  LogPrintf("%s: Unable to backup: %s\n", __func__, sqlite3_errstr(res));
366  sqlite3_backup_finish(backup);
367  sqlite3_close(db_copy);
368  return false;
369  }
370  res = sqlite3_backup_finish(backup);
371  sqlite3_close(db_copy);
372  return res == SQLITE_OK;
373 }
374 
376 {
377  int res = sqlite3_close(m_db);
378  if (res != SQLITE_OK) {
379  throw std::runtime_error(strprintf("SQLiteDatabase: Failed to close database: %s\n", sqlite3_errstr(res)));
380  }
381  m_db = nullptr;
382 }
383 
385 {
386  // 'sqlite3_get_autocommit' returns true by default, and false if a transaction has begun and not been committed or rolled back.
387  return m_db && sqlite3_get_autocommit(m_db) == 0;
388 }
389 
390 int SQliteExecHandler::Exec(SQLiteDatabase& database, const std::string& statement)
391 {
392  return sqlite3_exec(database.m_db, statement.data(), nullptr, nullptr, nullptr);
393 }
394 
395 std::unique_ptr<DatabaseBatch> SQLiteDatabase::MakeBatch(bool flush_on_close)
396 {
397  // We ignore flush_on_close because we don't do manual flushing for SQLite
398  return std::make_unique<SQLiteBatch>(*this);
399 }
400 
402  : m_database(database)
403 {
404  // Make sure we have a db handle
406 
408 }
409 
411 {
412  bool force_conn_refresh = false;
413 
414  // If we began a transaction, and it wasn't committed, abort the transaction in progress
415  if (m_txn) {
416  if (TxnAbort()) {
417  LogPrintf("SQLiteBatch: Batch closed unexpectedly without the transaction being explicitly committed or aborted\n");
418  } else {
419  // If transaction cannot be aborted, it means there is a bug or there has been data corruption. Try to recover in this case
420  // by closing and reopening the database. Closing the database should also ensure that any changes made since the transaction
421  // was opened will be rolled back and future transactions can succeed without committing old data.
422  force_conn_refresh = true;
423  LogPrintf("SQLiteBatch: Batch closed and failed to abort transaction, resetting db connection..\n");
424  }
425  }
426 
427  // Free all of the prepared statements
428  const std::vector<std::pair<sqlite3_stmt**, const char*>> statements{
429  {&m_read_stmt, "read"},
430  {&m_insert_stmt, "insert"},
431  {&m_overwrite_stmt, "overwrite"},
432  {&m_delete_stmt, "delete"},
433  {&m_delete_prefix_stmt, "delete prefix"},
434  };
435 
436  for (const auto& [stmt_prepared, stmt_description] : statements) {
437  int res = sqlite3_finalize(*stmt_prepared);
438  if (res != SQLITE_OK) {
439  LogPrintf("SQLiteBatch: Batch closed but could not finalize %s statement: %s\n",
440  stmt_description, sqlite3_errstr(res));
441  }
442  *stmt_prepared = nullptr;
443  }
444 
445  if (force_conn_refresh) {
446  m_database.Close();
447  try {
448  m_database.Open();
449  // If TxnAbort failed and we refreshed the connection, the semaphore was not released, so release it here to avoid deadlocks on future writes.
451  } catch (const std::runtime_error&) {
452  // If open fails, cleanup this object and rethrow the exception
453  m_database.Close();
454  throw;
455  }
456  }
457 }
458 
460 {
461  if (!m_database.m_db) return false;
463 
464  // Bind: leftmost parameter in statement is index 1
465  if (!BindBlobToStatement(m_read_stmt, 1, key, "key")) return false;
466  int res = sqlite3_step(m_read_stmt);
467  if (res != SQLITE_ROW) {
468  if (res != SQLITE_DONE) {
469  // SQLITE_DONE means "not found", don't log an error in that case.
470  LogPrintf("%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
471  }
472  sqlite3_clear_bindings(m_read_stmt);
473  sqlite3_reset(m_read_stmt);
474  return false;
475  }
476  // Leftmost column in result is index 0
477  value.clear();
478  value.write(SpanFromBlob(m_read_stmt, 0));
479 
480  sqlite3_clear_bindings(m_read_stmt);
481  sqlite3_reset(m_read_stmt);
482  return true;
483 }
484 
485 bool SQLiteBatch::WriteKey(DataStream&& key, DataStream&& value, bool overwrite)
486 {
487  if (!m_database.m_db) return false;
489 
490  sqlite3_stmt* stmt;
491  if (overwrite) {
492  stmt = m_overwrite_stmt;
493  } else {
494  stmt = m_insert_stmt;
495  }
496 
497  // Bind: leftmost parameter in statement is index 1
498  // Insert index 1 is key, 2 is value
499  if (!BindBlobToStatement(stmt, 1, key, "key")) return false;
500  if (!BindBlobToStatement(stmt, 2, value, "value")) return false;
501 
502  // Acquire semaphore if not previously acquired when creating a transaction.
504 
505  // Execute
506  int res = sqlite3_step(stmt);
507  sqlite3_clear_bindings(stmt);
508  sqlite3_reset(stmt);
509  if (res != SQLITE_DONE) {
510  LogPrintf("%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
511  }
512 
514 
515  return res == SQLITE_DONE;
516 }
517 
518 bool SQLiteBatch::ExecStatement(sqlite3_stmt* stmt, Span<const std::byte> blob)
519 {
520  if (!m_database.m_db) return false;
521  assert(stmt);
522 
523  // Bind: leftmost parameter in statement is index 1
524  if (!BindBlobToStatement(stmt, 1, blob, "key")) return false;
525 
526  // Acquire semaphore if not previously acquired when creating a transaction.
528 
529  // Execute
530  int res = sqlite3_step(stmt);
531  sqlite3_clear_bindings(stmt);
532  sqlite3_reset(stmt);
533  if (res != SQLITE_DONE) {
534  LogPrintf("%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
535  }
536 
538 
539  return res == SQLITE_DONE;
540 }
541 
543 {
544  return ExecStatement(m_delete_stmt, key);
545 }
546 
548 {
550 }
551 
553 {
554  if (!m_database.m_db) return false;
556 
557  // Bind: leftmost parameter in statement is index 1
558  if (!BindBlobToStatement(m_read_stmt, 1, key, "key")) return false;
559  int res = sqlite3_step(m_read_stmt);
560  sqlite3_clear_bindings(m_read_stmt);
561  sqlite3_reset(m_read_stmt);
562  return res == SQLITE_ROW;
563 }
564 
566 {
567  int res = sqlite3_step(m_cursor_stmt);
568  if (res == SQLITE_DONE) {
569  return Status::DONE;
570  }
571  if (res != SQLITE_ROW) {
572  LogPrintf("%s: Unable to execute cursor step: %s\n", __func__, sqlite3_errstr(res));
573  return Status::FAIL;
574  }
575 
576  key.clear();
577  value.clear();
578 
579  // Leftmost column in result is index 0
581  value.write(SpanFromBlob(m_cursor_stmt, 1));
582  return Status::MORE;
583 }
584 
586 {
587  sqlite3_clear_bindings(m_cursor_stmt);
588  sqlite3_reset(m_cursor_stmt);
589  int res = sqlite3_finalize(m_cursor_stmt);
590  if (res != SQLITE_OK) {
591  LogPrintf("%s: cursor closed but could not finalize cursor statement: %s\n",
592  __func__, sqlite3_errstr(res));
593  }
594 }
595 
596 std::unique_ptr<DatabaseCursor> SQLiteBatch::GetNewCursor()
597 {
598  if (!m_database.m_db) return nullptr;
599  auto cursor = std::make_unique<SQLiteCursor>();
600 
601  const char* stmt_text = "SELECT key, value FROM main";
602  int res = sqlite3_prepare_v2(m_database.m_db, stmt_text, -1, &cursor->m_cursor_stmt, nullptr);
603  if (res != SQLITE_OK) {
604  throw std::runtime_error(strprintf(
605  "%s: Failed to setup cursor SQL statement: %s\n", __func__, sqlite3_errstr(res)));
606  }
607 
608  return cursor;
609 }
610 
612 {
613  if (!m_database.m_db) return nullptr;
614 
615  // To get just the records we want, the SQL statement does a comparison of the binary data
616  // where the data must be greater than or equal to the prefix, and less than
617  // the prefix incremented by one (when interpreted as an integer)
618  std::vector<std::byte> start_range(prefix.begin(), prefix.end());
619  std::vector<std::byte> end_range(prefix.begin(), prefix.end());
620  auto it = end_range.rbegin();
621  for (; it != end_range.rend(); ++it) {
622  if (*it == std::byte(std::numeric_limits<unsigned char>::max())) {
623  *it = std::byte(0);
624  continue;
625  }
626  *it = std::byte(std::to_integer<unsigned char>(*it) + 1);
627  break;
628  }
629  if (it == end_range.rend()) {
630  // If the prefix is all 0xff bytes, clear end_range as we won't need it
631  end_range.clear();
632  }
633 
634  auto cursor = std::make_unique<SQLiteCursor>(start_range, end_range);
635  if (!cursor) return nullptr;
636 
637  const char* stmt_text = end_range.empty() ? "SELECT key, value FROM main WHERE key >= ?" :
638  "SELECT key, value FROM main WHERE key >= ? AND key < ?";
639  int res = sqlite3_prepare_v2(m_database.m_db, stmt_text, -1, &cursor->m_cursor_stmt, nullptr);
640  if (res != SQLITE_OK) {
641  throw std::runtime_error(strprintf(
642  "SQLiteDatabase: Failed to setup cursor SQL statement: %s\n", sqlite3_errstr(res)));
643  }
644 
645  if (!BindBlobToStatement(cursor->m_cursor_stmt, 1, cursor->m_prefix_range_start, "prefix_start")) return nullptr;
646  if (!end_range.empty()) {
647  if (!BindBlobToStatement(cursor->m_cursor_stmt, 2, cursor->m_prefix_range_end, "prefix_end")) return nullptr;
648  }
649 
650  return cursor;
651 }
652 
654 {
655  if (!m_database.m_db || m_txn) return false;
658  int res = Assert(m_exec_handler)->Exec(m_database, "BEGIN TRANSACTION");
659  if (res != SQLITE_OK) {
660  LogPrintf("SQLiteBatch: Failed to begin the transaction\n");
662  } else {
663  m_txn = true;
664  }
665  return res == SQLITE_OK;
666 }
667 
669 {
670  if (!m_database.m_db || !m_txn) return false;
672  int res = Assert(m_exec_handler)->Exec(m_database, "COMMIT TRANSACTION");
673  if (res != SQLITE_OK) {
674  LogPrintf("SQLiteBatch: Failed to commit the transaction\n");
675  } else {
676  m_txn = false;
678  }
679  return res == SQLITE_OK;
680 }
681 
683 {
684  if (!m_database.m_db || !m_txn) return false;
686  int res = Assert(m_exec_handler)->Exec(m_database, "ROLLBACK TRANSACTION");
687  if (res != SQLITE_OK) {
688  LogPrintf("SQLiteBatch: Failed to abort the transaction\n");
689  } else {
690  m_txn = false;
692  }
693  return res == SQLITE_OK;
694 }
695 
696 std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error)
697 {
698  try {
699  fs::path data_file = SQLiteDataFile(path);
700  auto db = std::make_unique<SQLiteDatabase>(data_file.parent_path(), data_file, options);
701  if (options.verify && !db->Verify(error)) {
703  return nullptr;
704  }
705  status = DatabaseStatus::SUCCESS;
706  return db;
707  } catch (const std::runtime_error& e) {
709  error = Untranslated(e.what());
710  return nullptr;
711  }
712 }
713 
715 {
716  return std::string(sqlite3_libversion());
717 }
718 } // namespace wallet
int ret
#define PACKAGE_NAME
int flags
Definition: bitcoin-tx.cpp:530
const CChainParams & Params()
Return the currently selected parameters.
#define Assert(val)
Identity function.
Definition: check.h:77
void wait() noexcept
Definition: sync.h:324
void post() noexcept
Definition: sync.h:341
Double ended buffer combining vector and stream-like interfaces.
Definition: streams.h:147
void write(Span< const value_type > src)
Definition: streams.h:251
void clear()
Definition: streams.h:187
constexpr std::size_t size() const noexcept
Definition: span.h:187
constexpr C * data() const noexcept
Definition: span.h:174
Path class wrapper to block calls to the fs::path(std::string) implicit constructor and the fs::path:...
Definition: fs.h:33
bool ReadKey(DataStream &&key, DataStream &value) override
Definition: sqlite.cpp:459
bool TxnCommit() override
Definition: sqlite.cpp:668
SQLiteBatch(SQLiteDatabase &database)
Definition: sqlite.cpp:401
std::unique_ptr< SQliteExecHandler > m_exec_handler
Definition: sqlite.h:53
bool HasKey(DataStream &&key) override
Definition: sqlite.cpp:552
bool m_txn
Whether this batch has started a database transaction and whether it owns SQLiteDatabase::m_write_sem...
Definition: sqlite.h:71
std::unique_ptr< DatabaseCursor > GetNewCursor() override
Definition: sqlite.cpp:596
bool ErasePrefix(Span< const std::byte > prefix) override
Definition: sqlite.cpp:547
bool EraseKey(DataStream &&key) override
Definition: sqlite.cpp:542
sqlite3_stmt * m_delete_stmt
Definition: sqlite.h:58
bool TxnBegin() override
Definition: sqlite.cpp:653
sqlite3_stmt * m_read_stmt
Definition: sqlite.h:55
void Close() override
Definition: sqlite.cpp:410
sqlite3_stmt * m_overwrite_stmt
Definition: sqlite.h:57
bool ExecStatement(sqlite3_stmt *stmt, Span< const std::byte > blob)
Definition: sqlite.cpp:518
std::unique_ptr< DatabaseCursor > GetNewPrefixCursor(Span< const std::byte > prefix) override
Definition: sqlite.cpp:611
sqlite3_stmt * m_delete_prefix_stmt
Definition: sqlite.h:59
void SetupSQLStatements()
Definition: sqlite.cpp:151
sqlite3_stmt * m_insert_stmt
Definition: sqlite.h:56
SQLiteDatabase & m_database
Definition: sqlite.h:52
bool TxnAbort() override
Definition: sqlite.cpp:682
bool WriteKey(DataStream &&key, DataStream &&value, bool overwrite=true) override
Definition: sqlite.cpp:485
~SQLiteCursor() override
Definition: sqlite.cpp:585
Status Next(DataStream &key, DataStream &value) override
Definition: sqlite.cpp:565
sqlite3_stmt * m_cursor_stmt
Definition: sqlite.h:23
An instance of this class represents one SQLite3 database.
Definition: sqlite.h:103
static Mutex g_sqlite_mutex
This mutex protects SQLite initialization and shutdown.
Definition: sqlite.h:117
CSemaphore m_write_semaphore
Definition: sqlite.h:132
void Open() override
Open the database if it is not already opened.
Definition: sqlite.cpp:249
std::string Filename() override
Return path to main database file for logs and error messages.
Definition: sqlite.h:167
bool Rewrite(const char *skip=nullptr) override
Rewrite the entire database on disk.
Definition: sqlite.cpp:341
void Cleanup() noexcept EXCLUSIVE_LOCKS_REQUIRED(!g_sqlite_mutex)
Definition: sqlite.cpp:177
const bool m_mock
Definition: sqlite.h:105
void Close() override
Close the database.
Definition: sqlite.cpp:375
bool Backup(const std::string &dest) const override
Back up the entire database to a file.
Definition: sqlite.cpp:348
const std::string m_dir_path
Definition: sqlite.h:107
const std::string m_file_path
Definition: sqlite.h:109
std::unique_ptr< DatabaseBatch > MakeBatch(bool flush_on_close=true) override
Make a SQLiteBatch connected to this database.
Definition: sqlite.cpp:395
bool Verify(bilingual_str &error)
Definition: sqlite.cpp:192
bool HasActiveTxn()
Return true if there is an on-going txn in this connection.
Definition: sqlite.cpp:384
virtual int Exec(SQLiteDatabase &database, const std::string &statement)
Definition: sqlite.cpp:390
An instance of this class represents one database.
Definition: db.h:124
static uint32_t ReadBE32(const unsigned char *ptr)
Definition: common.h:59
bool TryCreateDirectories(const fs::path &p)
Ignores exceptions thrown by create_directories if the requested directory exists.
Definition: fs_helpers.cpp:262
static bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level level)
Return true if log accepts specified category, at the specified level.
Definition: logging.h:210
#define LogPrintf(...)
Definition: logging.h:245
@ WALLETDB
Definition: logging.h:47
Filesystem operations and types.
static std::string PathToString(const path &path)
Convert path object to a byte string.
Definition: fs.h:151
static path PathFromString(const std::string &string)
Convert byte string to path object.
Definition: fs.h:174
std::unique_ptr< SQLiteDatabase > MakeSQLiteDatabase(const fs::path &path, const DatabaseOptions &options, DatabaseStatus &status, bilingual_str &error)
Definition: sqlite.cpp:696
fs::path SQLiteDataFile(const fs::path &path)
Definition: db.cpp:78
static constexpr int32_t WALLET_SCHEMA_VERSION
Definition: sqlite.cpp:29
static int TraceSqlCallback(unsigned code, void *context, void *param1, void *param2)
Definition: sqlite.cpp:48
static bool BindBlobToStatement(sqlite3_stmt *stmt, int index, Span< const std::byte > blob, const std::string &description)
Definition: sqlite.cpp:63
static void SetPragma(sqlite3 *db, const std::string &key, const std::string &value, const std::string &err_msg)
Definition: sqlite.cpp:104
static std::optional< int > ReadPragmaInteger(sqlite3 *db, const std::string &key, const std::string &description, bilingual_str &error)
Definition: sqlite.cpp:83
std::string SQLiteDatabaseVersion()
Definition: sqlite.cpp:714
static void ErrorLogCallback(void *arg, int code, const char *msg)
Definition: sqlite.cpp:37
DatabaseStatus
Definition: db.h:196
static Span< const std::byte > SpanFromBlob(sqlite3_stmt *stmt, int col)
Definition: sqlite.cpp:31
const char * prefix
Definition: rest.cpp:1007
Bilingual messages:
Definition: translation.h:18
bool empty() const
Definition: translation.h:29
bool verify
Check data integrity on load.
Definition: db.h:190
#define AssertLockNotHeld(cs)
Definition: sync.h:147
#define LOCK(cs)
Definition: sync.h:257
#define strprintf
Format arguments and return the string or write to given std::ostream (see tinyformat::format doc for...
Definition: tinyformat.h:1162
bilingual_str _(const char *psz)
Translation function.
Definition: translation.h:74
bilingual_str Untranslated(std::string original)
Mark a bilingual_str as untranslated.
Definition: translation.h:48
assert(!tx.IsCoinBase())