v30.3-roots.1 · Commit 4: [PATCH 04/68] fix(wallet): preserve Roots database hardening on Core 30.3
src/wallet/sqlite.cpp
Before: src/wallet/sqlite.cpp · After: src/wallet/sqlite.cpp
File metadata
index 0940cbac3b1e2e6bbd26839137475bb0b620086e..a3f3dca63fd9ffbd1785f8d62549428d5a71a7c0 100644
Download original patch · Release notes
Diff rows 1–156 of 156. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
src/wallet/sqlite.cpp
CHANGED
|
@@ -40,7 +40,7 @@ static void ErrorLogCallback(void* arg, int code, const char* msg)
|
|
|
40
40
|
// invoked."
|
|
41
41
|
// Assert that this is the case:
|
|
42
42
|
assert(arg == nullptr);
|
|
43
|
-
LogPrintf("SQLite Error. Code: %d. Message: %s\n", code, msg);
|
|
43
|
+
LogWarning("SQLite Error. Code: %d. Message: %s", code, msg);
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
static int TraceSqlCallback(unsigned code, void* context, void* param1, void* param2)
|
|
@@ -69,7 +69,7 @@ static bool BindBlobToStatement(sqlite3_stmt* stmt,
|
|
|
69
69
|
// instead of the empty blob value X'', which would mess up SQL comparisons.
|
|
70
70
|
int res = sqlite3_bind_blob(stmt, index, blob.data() ? static_cast<const void*>(blob.data()) : "", blob.size(), SQLITE_STATIC);
|
|
71
71
|
if (res != SQLITE_OK) {
|
|
72
|
-
LogPrintf("Unable to bind %s to statement: %s\n", description, sqlite3_errstr(res));
|
|
72
|
+
LogWarning("Unable to bind %s to statement: %s", description, sqlite3_errstr(res));
|
|
73
73
|
sqlite3_clear_bindings(stmt);
|
|
74
74
|
sqlite3_reset(stmt);
|
|
75
75
|
return false;
|
|
@@ -182,7 +182,7 @@ void SQLiteDatabase::Cleanup() noexcept
|
|
|
182
182
|
if (--g_sqlite_count == 0) {
|
|
183
183
|
int ret = sqlite3_shutdown();
|
|
184
184
|
if (ret != SQLITE_OK) {
|
|
185
|
-
LogPrintf("SQLiteDatabase: Failed to shutdown SQLite: %s\n", sqlite3_errstr(ret));
|
|
185
|
+
LogWarning("SQLiteDatabase: Failed to shutdown SQLite: %s", sqlite3_errstr(ret));
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
}
|
|
@@ -254,7 +254,11 @@ void SQLiteDatabase::Open()
|
|
|
254
254
|
if (m_db == nullptr) {
|
|
255
255
|
if (!m_mock) {
|
|
256
256
|
TryCreateDirectories(m_dir_path);
|
|
257
|
+
if (!IsDirWritable(m_dir_path)) {
|
|
258
|
+
throw std::runtime_error(strprintf("SQLiteDatabase: Failed to open database in directory '%s': directory is not writable", fs::PathToString(m_dir_path)));
|
|
259
|
+
}
|
|
257
260
|
}
|
|
261
|
+
|
|
258
262
|
int ret = sqlite3_open_v2(m_file_path.c_str(), &m_db, flags, nullptr);
|
|
259
263
|
if (ret != SQLITE_OK) {
|
|
260
264
|
throw std::runtime_error(strprintf("SQLiteDatabase: Failed to open database: %s\n", sqlite3_errstr(ret)));
|
|
@@ -267,7 +271,7 @@ void SQLiteDatabase::Open()
|
|
|
267
271
|
if (LogAcceptCategory(BCLog::WALLETDB, BCLog::Level::Trace)) {
|
|
268
272
|
ret = sqlite3_trace_v2(m_db, SQLITE_TRACE_STMT, TraceSqlCallback, this);
|
|
269
273
|
if (ret != SQLITE_OK) {
|
|
270
|
-
LogPrintf("Failed to enable SQL tracing for %s\n", Filename());
|
|
274
|
+
LogWarning("Failed to enable SQL tracing for %s", Filename());
|
|
271
275
|
}
|
|
272
276
|
}
|
|
273
277
|
}
|
|
@@ -294,7 +298,7 @@ void SQLiteDatabase::Open()
|
|
|
294
298
|
|
|
295
299
|
if (m_use_unsafe_sync) {
|
|
296
300
|
// Use normal synchronous mode for the journal
|
|
297
|
-
LogPrintf("WARNING SQLite is configured to not wait for data to be flushed to disk. Data loss and corruption may occur.\n");
|
|
301
|
+
LogWarning("SQLite is configured to not wait for data to be flushed to disk. Data loss and corruption may occur.");
|
|
298
302
|
SetPragma(m_db, "synchronous", "OFF", "Failed to set synchronous mode to OFF");
|
|
299
303
|
}
|
|
300
304
|
|
|
@@ -353,14 +357,14 @@ bool SQLiteDatabase::Backup(const std::string& dest) const
|
|
|
353
357
|
}
|
|
354
358
|
sqlite3_backup* backup = sqlite3_backup_init(db_copy, "main", m_db, "main");
|
|
355
359
|
if (!backup) {
|
|
356
|
-
LogPrintf("%s: Unable to begin backup: %s\n", __func__, sqlite3_errmsg(m_db));
|
|
360
|
+
LogWarning("Unable to begin sqlite backup: %s", sqlite3_errmsg(m_db));
|
|
357
361
|
sqlite3_close(db_copy);
|
|
358
362
|
return false;
|
|
359
363
|
}
|
|
360
364
|
// Specifying -1 will copy all of the pages
|
|
361
365
|
res = sqlite3_backup_step(backup, -1);
|
|
362
366
|
if (res != SQLITE_DONE) {
|
|
363
|
-
LogPrintf("%s: Unable to backup: %s\n", __func__, sqlite3_errstr(res));
|
|
367
|
+
LogWarning("Unable to continue sqlite backup: %s", sqlite3_errstr(res));
|
|
364
368
|
sqlite3_backup_finish(backup);
|
|
365
369
|
sqlite3_close(db_copy);
|
|
366
370
|
return false;
|
|
@@ -412,13 +416,13 @@ void SQLiteBatch::Close()
|
|
|
412
416
|
// If we began a transaction, and it wasn't committed, abort the transaction in progress
|
|
413
417
|
if (m_txn) {
|
|
414
418
|
if (TxnAbort()) {
|
|
415
|
-
LogPrintf("SQLiteBatch: Batch closed unexpectedly without the transaction being explicitly committed or aborted\n");
|
|
419
|
+
LogWarning("SQLiteBatch: Batch closed unexpectedly without the transaction being explicitly committed or aborted");
|
|
416
420
|
} else {
|
|
417
421
|
// If transaction cannot be aborted, it means there is a bug or there has been data corruption. Try to recover in this case
|
|
418
422
|
// by closing and reopening the database. Closing the database should also ensure that any changes made since the transaction
|
|
419
423
|
// was opened will be rolled back and future transactions can succeed without committing old data.
|
|
420
424
|
force_conn_refresh = true;
|
|
421
|
-
LogPrintf("SQLiteBatch: Batch closed and failed to abort transaction, resetting db connection..\n");
|
|
425
|
+
LogWarning("SQLiteBatch: Batch closed and failed to abort transaction, resetting db connection..");
|
|
422
426
|
}
|
|
423
427
|
}
|
|
424
428
|
|
|
@@ -434,7 +438,7 @@ void SQLiteBatch::Close()
|
|
|
434
438
|
for (const auto& [stmt_prepared, stmt_description] : statements) {
|
|
435
439
|
int res = sqlite3_finalize(*stmt_prepared);
|
|
436
440
|
if (res != SQLITE_OK) {
|
|
437
|
-
LogPrintf("SQLiteBatch: Batch closed but could not finalize %s statement: %s\n",
|
|
441
|
+
LogWarning("SQLiteBatch: Batch closed but could not finalize %s statement: %s",
|
|
438
442
|
stmt_description, sqlite3_errstr(res));
|
|
439
443
|
}
|
|
440
444
|
*stmt_prepared = nullptr;
|
|
@@ -465,7 +469,7 @@ bool SQLiteBatch::ReadKey(DataStream&& key, DataStream& value)
|
|
|
465
469
|
if (res != SQLITE_ROW) {
|
|
466
470
|
if (res != SQLITE_DONE) {
|
|
467
471
|
// SQLITE_DONE means "not found", don't log an error in that case.
|
|
468
|
-
LogPrintf("%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
|
|
472
|
+
LogWarning("Unable to execute read statement: %s", sqlite3_errstr(res));
|
|
469
473
|
}
|
|
470
474
|
sqlite3_clear_bindings(m_read_stmt);
|
|
471
475
|
sqlite3_reset(m_read_stmt);
|
|
@@ -505,7 +509,7 @@ bool SQLiteBatch::WriteKey(DataStream&& key, DataStream&& value, bool overwrite)
|
|
|
505
509
|
sqlite3_clear_bindings(stmt);
|
|
506
510
|
sqlite3_reset(stmt);
|
|
507
511
|
if (res != SQLITE_DONE) {
|
|
508
|
-
LogPrintf("%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
|
|
512
|
+
LogWarning("Unable to execute write statement: %s", sqlite3_errstr(res));
|
|
509
513
|
}
|
|
510
514
|
|
|
511
515
|
if (!m_txn) m_database.m_write_semaphore.release();
|
|
@@ -529,7 +533,7 @@ bool SQLiteBatch::ExecStatement(sqlite3_stmt* stmt, std::span<const std::byte> b
|
|
|
529
533
|
sqlite3_clear_bindings(stmt);
|
|
530
534
|
sqlite3_reset(stmt);
|
|
531
535
|
if (res != SQLITE_DONE) {
|
|
532
|
-
LogPrintf("%s: Unable to execute statement: %s\n", __func__, sqlite3_errstr(res));
|
|
536
|
+
LogWarning("Unable to execute exec statement: %s", sqlite3_errstr(res));
|
|
533
537
|
}
|
|
534
538
|
|
|
535
539
|
if (!m_txn) m_database.m_write_semaphore.release();
|
|
@@ -567,7 +571,7 @@ DatabaseCursor::Status SQLiteCursor::Next(DataStream& key, DataStream& value)
|
|
|
567
571
|
return Status::DONE;
|
|
568
572
|
}
|
|
569
573
|
if (res != SQLITE_ROW) {
|
|
570
|
-
LogPrintf("%s: Unable to execute cursor step: %s\n", __func__, sqlite3_errstr(res));
|
|
574
|
+
LogWarning("Unable to execute cursor step: %s", sqlite3_errstr(res));
|
|
571
575
|
return Status::FAIL;
|
|
572
576
|
}
|
|
573
577
|
|
|
@@ -586,8 +590,8 @@ SQLiteCursor::~SQLiteCursor()
|
|
|
586
590
|
sqlite3_reset(m_cursor_stmt);
|
|
587
591
|
int res = sqlite3_finalize(m_cursor_stmt);
|
|
588
592
|
if (res != SQLITE_OK) {
|
|
589
|
-
LogPrintf("%s: cursor closed but could not finalize cursor statement: %s\n",
|
|
590
|
-
__func__, sqlite3_errstr(res));
|
|
593
|
+
LogWarning("Cursor closed but could not finalize cursor statement: %s",
|
|
594
|
+
sqlite3_errstr(res));
|
|
591
595
|
}
|
|
592
596
|
}
|
|
593
597
|
|
|
@@ -655,7 +659,7 @@ bool SQLiteBatch::TxnBegin()
|
|
|
655
659
|
Assert(!m_database.HasActiveTxn());
|
|
656
660
|
int res = Assert(m_exec_handler)->Exec(m_database, "BEGIN TRANSACTION");
|
|
657
661
|
if (res != SQLITE_OK) {
|
|
658
|
-
LogPrintf("SQLiteBatch: Failed to begin the transaction\n");
|
|
662
|
+
LogWarning("SQLiteBatch: Failed to begin the transaction");
|
|
659
663
|
m_database.m_write_semaphore.release();
|
|
660
664
|
} else {
|
|
661
665
|
m_txn = true;
|
|
@@ -669,7 +673,7 @@ bool SQLiteBatch::TxnCommit()
|
|
|
669
673
|
Assert(m_database.HasActiveTxn());
|
|
670
674
|
int res = Assert(m_exec_handler)->Exec(m_database, "COMMIT TRANSACTION");
|
|
671
675
|
if (res != SQLITE_OK) {
|
|
672
|
-
LogPrintf("SQLiteBatch: Failed to commit the transaction\n");
|
|
676
|
+
LogWarning("SQLiteBatch: Failed to commit the transaction");
|
|
673
677
|
} else {
|
|
674
678
|
m_txn = false;
|
|
675
679
|
m_database.m_write_semaphore.release();
|
|
@@ -683,7 +687,7 @@ bool SQLiteBatch::TxnAbort()
|
|
|
683
687
|
Assert(m_database.HasActiveTxn());
|
|
684
688
|
int res = Assert(m_exec_handler)->Exec(m_database, "ROLLBACK TRANSACTION");
|
|
685
689
|
if (res != SQLITE_OK) {
|
|
686
|
-
LogPrintf("SQLiteBatch: Failed to abort the transaction\n");
|
|
690
|
+
LogWarning("SQLiteBatch: Failed to abort the transaction");
|
|
687
691
|
} else {
|
|
688
692
|
m_txn = false;
|
|
689
693
|
m_database.m_write_semaphore.release();
|