upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbitflash <dev@bitflash.network>2026-08-18 16:14:19 -0300
committerbitflash <dev@bitflash.network>2026-08-18 16:14:19 -0300
commit3f94ec0649f935d00de49ad7b55026317dc64a27 (patch)
treee67ff06c8341889cf90cbbc3b835507a90510b64 /src
parentf3fb7ce6759ac98a7cc39d586fc2824982c74acd (diff)
wallet: make SQLite the default backend for new wallets
A fresh install with no wallet.dat now starts on the SQLite backend and creates wallet.sqlite, instead of a Berkeley DB wallet.dat. The choice is recorded in a plain-text <datadir>/wallet-backend marker so it survives a restart without a command-line flag. Backend resolution when no -walletbackend is given: an existing wallet.sqlite (or a "sqlite" marker) stays on SQLite; an existing wallet.dat stays on Berkeley DB -- nothing is converted behind the user; a fresh datadir starts on SQLite. An explicit -walletbackend=bdb or a "bdb" marker forces Berkeley DB and overrides the default. Adds CreateNewSQLiteWallet() (WalletSQLiteRuntimeOpen gains fMustExist so the create path can make a new file) which mints the first default key straight into the SQLite store via the same FinishLoadedWallet() call the Berkeley DB create path uses, then cleans up on failure. Marker read/write helpers are plain text, hand-editable. New wallet-backend-default self-test proves the resolution in child processes (fresh->SQLite+marker, existing wallet.dat->BDB, "bdb" marker->BDB, explicit flag->wallet.dat). The three wallet.dat-specific suites now ask for -walletbackend=bdb explicitly, since a flagless fresh datadir is SQLite now. All wallet suites pass.
Diffstat (limited to 'src')
-rw-r--r--src/db.cpp91
-rw-r--r--src/db.h5
-rw-r--r--src/main_gui.cpp80
-rw-r--r--src/makefile.mingw1
-rw-r--r--src/selftest.cpp135
5 files changed, 301 insertions, 11 deletions
diff --git a/src/db.cpp b/src/db.cpp
index aafc0f9..949865f 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -101,10 +101,13 @@ bool WalletSQLiteRuntimeActive()
101 return pWalletSQLiteRuntime != NULL; 101 return pWalletSQLiteRuntime != NULL;
102} 102}
103 103
104bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet) 104bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet, bool fMustExist)
105{ 105{
106 strErrorRet.clear(); 106 strErrorRet.clear();
107 if (!FileExists(strPath.c_str())) 107 // Callers that load an existing wallet want the clear "does not exist"
108 // message rather than silently creating a blank one; the create path passes
109 // fMustExist=false so Open() (SQLITE_OPEN_CREATE) can make a fresh file.
110 if (fMustExist && !FileExists(strPath.c_str()))
108 { 111 {
109 strErrorRet = strprintf("SQLite wallet does not exist: %s", 112 strErrorRet = strprintf("SQLite wallet does not exist: %s",
110 strPath.c_str()); 113 strPath.c_str());
@@ -230,6 +233,47 @@ bool WalletSQLiteRuntimeCheckpoint(string& strErrorRet)
230 return pWalletSQLiteRuntime->Checkpoint(strErrorRet); 233 return pWalletSQLiteRuntime->Checkpoint(strErrorRet);
231} 234}
232 235
236// The persistent record of which backend this datadir uses, so the choice
237// survives a restart without a command-line flag. A plain text file holding
238// "sqlite" or "bdb" -- visible and hand-editable on purpose, no hidden state.
239static string WalletBackendMarkerPath()
240{
241 return GetAppDir() + "/wallet-backend";
242}
243
244string ReadWalletBackendMarker()
245{
246 FILE* pf = fopen(WalletBackendMarkerPath().c_str(), "rb");
247 if (!pf)
248 return "";
249 char buf[16] = {0};
250 size_t n = fread(buf, 1, sizeof(buf) - 1, pf);
251 fclose(pf);
252 string s(buf, n);
253 while (!s.empty() && isspace((unsigned char)s[s.size() - 1]))
254 s.erase(s.size() - 1);
255 while (!s.empty() && isspace((unsigned char)s[0]))
256 s.erase(0, 1);
257 if (s == "sqlite" || s == "bdb")
258 return s;
259 return "";
260}
261
262bool WriteWalletBackendMarker(const string& strBackend)
263{
264 if (strBackend != "sqlite" && strBackend != "bdb")
265 return false;
266 FILE* pf = fopen(WalletBackendMarkerPath().c_str(), "wb");
267 if (!pf)
268 return false;
269 bool fOk = fwrite(strBackend.c_str(), 1, strBackend.size(), pf) == strBackend.size();
270 if (fputc('\n', pf) == EOF)
271 fOk = false;
272 if (fclose(pf) != 0)
273 fOk = false;
274 return fOk;
275}
276
233 277
234CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) 278CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
235{ 279{
@@ -1609,6 +1653,49 @@ bool LoadWalletFromSQLiteRuntime(const string& strPath)
1609 return true; 1653 return true;
1610} 1654}
1611 1655
1656// Create a brand-new wallet directly in the SQLite backend. For a fresh install
1657// where SQLite is the default there is no wallet.dat to export from, so open a
1658// new wallet.sqlite (Open() creates the file and its schema) and let
1659// FinishLoadedWallet mint the first default key straight into it -- the same
1660// call the Berkeley DB create path uses, so a new wallet is identical either
1661// way. Refuses to touch an existing file, and cleans up on failure so a broken
1662// half-initialised wallet.sqlite is never left for the next start to load.
1663bool CreateNewSQLiteWallet(const string& strPath)
1664{
1665 strWalletLoadError.clear();
1666
1667 if (FileExists(strPath.c_str()))
1668 {
1669 strWalletLoadError = strprintf("SQLite wallet already exists: %s",
1670 strPath.c_str());
1671 printf("CreateNewSQLiteWallet: %s\n", strWalletLoadError.c_str());
1672 return false;
1673 }
1674
1675 string strError;
1676 if (!WalletSQLiteRuntimeOpen(strPath, strError, false))
1677 {
1678 strWalletLoadError = strError;
1679 printf("CreateNewSQLiteWallet: cannot create SQLite wallet: %s\n",
1680 strError.c_str());
1681 return false;
1682 }
1683
1684 vector<unsigned char> vchNoDefaultKey;
1685 if (!FinishLoadedWallet(vchNoDefaultKey, true))
1686 {
1687 WalletSQLiteRuntimeClose();
1688 remove(strPath.c_str());
1689 remove((strPath + "-wal").c_str());
1690 remove((strPath + "-shm").c_str());
1691 if (strWalletLoadError.empty())
1692 strWalletLoadError = "could not initialise the new SQLite wallet";
1693 return false;
1694 }
1695
1696 return true;
1697}
1698
1612 1699
1613// Write a copy of wallet.dat that can be opened anywhere. 1700// Write a copy of wallet.dat that can be opened anywhere.
1614// 1701//
diff --git a/src/db.h b/src/db.h
index 5bc94b1..c50065b 100644
--- a/src/db.h
+++ b/src/db.h
@@ -357,7 +357,7 @@ private:
357// peer discovery is entirely Nostr/.btf-based now. 357// peer discovery is entirely Nostr/.btf-based now.
358 358
359bool WalletSQLiteRuntimeActive(); 359bool WalletSQLiteRuntimeActive();
360bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet); 360bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet, bool fMustExist=true);
361void WalletSQLiteRuntimeClose(); 361void WalletSQLiteRuntimeClose();
362bool WalletSQLiteRuntimeReadRecord(const vector<unsigned char>& vchKey, 362bool WalletSQLiteRuntimeReadRecord(const vector<unsigned char>& vchKey,
363 vector<unsigned char>& vchValueRet); 363 vector<unsigned char>& vchValueRet);
@@ -370,6 +370,9 @@ bool WalletSQLiteRuntimeCommitTxn();
370void WalletSQLiteRuntimeRollbackTxn(); 370void WalletSQLiteRuntimeRollbackTxn();
371bool WalletSQLiteRuntimeOpenReadOnly(const string& strPath, string& strErrorRet); 371bool WalletSQLiteRuntimeOpenReadOnly(const string& strPath, string& strErrorRet);
372bool WalletSQLiteRuntimeCheckpoint(string& strErrorRet); 372bool WalletSQLiteRuntimeCheckpoint(string& strErrorRet);
373string ReadWalletBackendMarker();
374bool WriteWalletBackendMarker(const string& strBackend);
375bool CreateNewSQLiteWallet(const string& strPath);
373 376
374 377
375 378
diff --git a/src/main_gui.cpp b/src/main_gui.cpp
index af6053f..6cd8b75 100644
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -743,14 +743,80 @@ int main(int argc, char* argv[])
743 DBFlush(true); 743 DBFlush(true);
744 return 0; 744 return 0;
745 } 745 }
746 else if (!LoadWallet()) 746 else if (strWalletBackend == "bdb")
747 { 747 {
748 // LoadWallet() explains itself into strWalletLoadError when it 748 // Explicit -walletbackend=bdb overrides the marker and the default:
749 // knows why -- an unsupported wallet format, for one, which is the 749 // force Berkeley DB (LoadWallet creates wallet.dat if none exists).
750 // case this whole path exists to make visible. 750 if (!LoadWallet())
751 FatalStartupError(fHeadlessStartup, "Cannot open wallet.dat.", 751 {
752 strWalletLoadError); 752 FatalStartupError(fHeadlessStartup, "Cannot open wallet.dat.",
753 return 1; 753 strWalletLoadError);
754 return 1;
755 }
756 }
757 else
758 {
759 // No explicit -walletbackend on the command line. Resolve it from
760 // the persistent marker, then defaults: an existing wallet.sqlite
761 // stays on SQLite, an existing wallet.dat stays on Berkeley DB (the
762 // GUI offers to convert), and a fresh install starts on SQLite --
763 // the new default. wallet.dat is never touched by any of this.
764 string strSQLitePath = GetAppDir() + "/wallet.sqlite";
765 bool fSQLiteExists = FileExists(strSQLitePath.c_str());
766 bool fWalletDatExists = FileExists((GetAppDir() + "/wallet.dat").c_str());
767 string strMarker = ReadWalletBackendMarker();
768
769 bool fUseSQLite = false;
770 bool fCreateSQLite = false;
771 if (strMarker == "sqlite")
772 {
773 if (fSQLiteExists) fUseSQLite = true;
774 else if (fWalletDatExists) fUseSQLite = false; // marker stale; real wallet is BDB
775 else { fUseSQLite = true; fCreateSQLite = true; }
776 }
777 else if (strMarker == "bdb")
778 {
779 fUseSQLite = false;
780 }
781 else // no marker recorded yet
782 {
783 if (fSQLiteExists && !fWalletDatExists) fUseSQLite = true;
784 else if (fWalletDatExists) fUseSQLite = false;
785 else { fUseSQLite = true; fCreateSQLite = true; }
786 }
787
788 if (fUseSQLite)
789 {
790 AttachTerminal();
791 bool fOk = fCreateSQLite
792 ? CreateNewSQLiteWallet(strSQLitePath)
793 : LoadWalletFromSQLiteRuntime(strSQLitePath);
794 if (!fOk)
795 {
796 FatalStartupError(fHeadlessStartup,
797 fCreateSQLite ? "Cannot create the SQLite wallet."
798 : "Cannot open the SQLite wallet.",
799 strWalletLoadError);
800 return 1;
801 }
802 // Record the choice so it is stable from here on.
803 if (ReadWalletBackendMarker() != "sqlite")
804 WriteWalletBackendMarker("sqlite");
805 fprintf(stderr, "Wallet backend: SQLite\n %s\n%s",
806 strSQLitePath.c_str(),
807 fCreateSQLite ? "A new wallet was created here.\n" : "");
808 fflush(stderr);
809 // Fall through and run the node; CWalletDB routes to this file.
810 }
811 else if (!LoadWallet())
812 {
813 // LoadWallet() explains itself into strWalletLoadError when it
814 // knows why -- an unsupported wallet format, for one, which is
815 // the case this whole path exists to make visible.
816 FatalStartupError(fHeadlessStartup, "Cannot open wallet.dat.",
817 strWalletLoadError);
818 return 1;
819 }
754 } 820 }
755 821
756 // After the block index, so there is a chain to compare the wallet 822 // After the block index, so there is a chain to compare the wallet
diff --git a/src/makefile.mingw b/src/makefile.mingw
index 1cb47fb..06c9211 100644
--- a/src/makefile.mingw
+++ b/src/makefile.mingw
@@ -113,6 +113,7 @@ tests: test_bip32.exe bitflash.exe
113 ./bitflash.exe -selftest=wallet-crypto 113 ./bitflash.exe -selftest=wallet-crypto
114 ./bitflash.exe -selftest=wallet-encrypt 114 ./bitflash.exe -selftest=wallet-encrypt
115 ./bitflash.exe -selftest=wallet-sqlite-encrypt 115 ./bitflash.exe -selftest=wallet-sqlite-encrypt
116 ./bitflash.exe -selftest=wallet-backend-default
116 ./bitflash.exe -selftest=net-message 117 ./bitflash.exe -selftest=net-message
117 ./bitflash.exe -selftest=consensus-limits 118 ./bitflash.exe -selftest=consensus-limits
118 ./bitflash.exe -selftest=pool-stratum 119 ./bitflash.exe -selftest=pool-stratum
diff --git a/src/selftest.cpp b/src/selftest.cpp
index 90a30d2..1960003 100644
--- a/src/selftest.cpp
+++ b/src/selftest.cpp
@@ -911,6 +911,7 @@ static int RunWalletStorageSanitySelfTest()
911 vCreateArgs.push_back("-datadir=" + strScenarioDir); 911 vCreateArgs.push_back("-datadir=" + strScenarioDir);
912 vCreateArgs.push_back("-nomanagedtor"); 912 vCreateArgs.push_back("-nomanagedtor");
913 vCreateArgs.push_back("-nogui"); 913 vCreateArgs.push_back("-nogui");
914 vCreateArgs.push_back("-walletbackend=bdb"); // this suite is about wallet.dat
914 vCreateArgs.push_back("-newphrase"); 915 vCreateArgs.push_back("-newphrase");
915 int nCreateRet = RunBitflashChild(strExe, vCreateArgs, NULL, &strCreateOut); 916 int nCreateRet = RunBitflashChild(strExe, vCreateArgs, NULL, &strCreateOut);
916 nFail += Check(nCreateRet == 0 && 917 nFail += Check(nCreateRet == 0 &&
@@ -1474,6 +1475,7 @@ static int RunWalletSQLiteMigrationSelfTest()
1474 vCreateArgs.push_back("-datadir=" + strWalletDir); 1475 vCreateArgs.push_back("-datadir=" + strWalletDir);
1475 vCreateArgs.push_back("-nomanagedtor"); 1476 vCreateArgs.push_back("-nomanagedtor");
1476 vCreateArgs.push_back("-nogui"); 1477 vCreateArgs.push_back("-nogui");
1478 vCreateArgs.push_back("-walletbackend=bdb"); // migrate FROM a Berkeley DB wallet.dat
1477 vCreateArgs.push_back("-newphrase"); 1479 vCreateArgs.push_back("-newphrase");
1478 int nCreateRet = RunBitflashChild(strExe, vCreateArgs, NULL, &strCreateOut); 1480 int nCreateRet = RunBitflashChild(strExe, vCreateArgs, NULL, &strCreateOut);
1479 nFail += Check(nCreateRet == 0 && 1481 nFail += Check(nCreateRet == 0 &&
@@ -2534,6 +2536,134 @@ static int RunWalletSQLiteEncryptSelfTest()
2534 return nFail == 0 ? 0 : 1; 2536 return nFail == 0 ? 0 : 1;
2535} 2537}
2536 2538
2539// Backend resolution when no -walletbackend flag is given: a fresh install
2540// starts on SQLite (the new default), an existing wallet.dat stays on Berkeley
2541// DB, the persistent marker overrides the default, and an explicit flag
2542// overrides everything. Each scenario runs a real child process.
2543static int RunWalletBackendDefaultSelfTest()
2544{
2545 fflush(stdout);
2546 printf("wallet-backend-default self-test\n");
2547
2548 std::string tmp, cwd;
2549 if (!MakeTempDir(tmp))
2550 {
2551 printf(" FAIL could not create a temporary data directory\n");
2552 return 1;
2553 }
2554 if (!GetCurrentDir(cwd) || !SetCurrentDir(tmp))
2555 {
2556 printf(" FAIL could not move into the temporary data directory\n");
2557 RemoveTree(tmp);
2558 return 1;
2559 }
2560
2561 int nFail = 0;
2562 strSetDataDir = tmp;
2563 printf(" temp datadir: %s\n", tmp.c_str());
2564
2565#ifdef _WIN32
2566 string strExe = cwd + "\\bitflash.exe";
2567#else
2568 string strExe = cwd + "/bitflash-node";
2569#endif
2570
2571 try
2572 {
2573 // 1. Fresh datadir, no flag -> new wallet.sqlite, marker "sqlite", no wallet.dat.
2574 string d1 = tmp + "/fresh";
2575 nFail += Check(MakeDirLocal(d1), "fresh scenario dir can be created") ? 0 : 1;
2576 vector<string> a1;
2577 a1.push_back("-datadir=" + d1);
2578 a1.push_back("-nomanagedtor");
2579 a1.push_back("-nogui");
2580 a1.push_back("-newaddress");
2581 int r1 = RunBitflashChild(strExe, a1);
2582 nFail += Check(r1 == 0 &&
2583 FileExists((d1 + "/wallet.sqlite").c_str()) &&
2584 !FileExists((d1 + "/wallet.dat").c_str()) &&
2585 FileContainsText(d1 + "/wallet-backend", "sqlite"),
2586 "a fresh install starts on SQLite (new default) and records the marker") ? 0 : 1;
2587
2588 // 1b. Second run reuses it, still SQLite, still no wallet.dat.
2589 int r1b = RunBitflashChild(strExe, a1);
2590 nFail += Check(r1b == 0 &&
2591 FileExists((d1 + "/wallet.sqlite").c_str()) &&
2592 !FileExists((d1 + "/wallet.dat").c_str()),
2593 "the recorded SQLite choice survives a restart") ? 0 : 1;
2594
2595 // 2. Existing wallet.dat, no flag -> stays on Berkeley DB.
2596 string d2 = tmp + "/existing-bdb";
2597 nFail += Check(MakeDirLocal(d2), "existing-bdb scenario dir can be created") ? 0 : 1;
2598 vector<string> a2c;
2599 a2c.push_back("-datadir=" + d2);
2600 a2c.push_back("-nomanagedtor");
2601 a2c.push_back("-nogui");
2602 a2c.push_back("-walletbackend=bdb");
2603 a2c.push_back("-newphrase");
2604 RunBitflashChild(strExe, a2c);
2605 vector<string> a2;
2606 a2.push_back("-datadir=" + d2);
2607 a2.push_back("-nomanagedtor");
2608 a2.push_back("-nogui");
2609 a2.push_back("-newaddress");
2610 int r2 = RunBitflashChild(strExe, a2);
2611 nFail += Check(r2 == 0 &&
2612 FileExists((d2 + "/wallet.dat").c_str()) &&
2613 !FileExists((d2 + "/wallet.sqlite").c_str()),
2614 "an existing wallet.dat keeps a flagless start on Berkeley DB") ? 0 : 1;
2615
2616 // 3. Marker "bdb" forces Berkeley DB even on a fresh datadir.
2617 string d3 = tmp + "/marker-bdb";
2618 nFail += Check(MakeDirLocal(d3), "marker-bdb scenario dir can be created") ? 0 : 1;
2619 nFail += Check(WriteTextFile(d3 + "/wallet-backend", "bdb\n"),
2620 "a bdb marker can be written") ? 0 : 1;
2621 vector<string> a3;
2622 a3.push_back("-datadir=" + d3);
2623 a3.push_back("-nomanagedtor");
2624 a3.push_back("-nogui");
2625 a3.push_back("-newaddress");
2626 int r3 = RunBitflashChild(strExe, a3);
2627 nFail += Check(r3 == 0 &&
2628 FileExists((d3 + "/wallet.dat").c_str()) &&
2629 !FileExists((d3 + "/wallet.sqlite").c_str()),
2630 "a bdb marker forces Berkeley DB on a fresh datadir") ? 0 : 1;
2631
2632 // 4. Explicit -walletbackend=bdb on a fresh datadir -> wallet.dat.
2633 string d4 = tmp + "/explicit-bdb";
2634 nFail += Check(MakeDirLocal(d4), "explicit-bdb scenario dir can be created") ? 0 : 1;
2635 vector<string> a4;
2636 a4.push_back("-datadir=" + d4);
2637 a4.push_back("-nomanagedtor");
2638 a4.push_back("-nogui");
2639 a4.push_back("-walletbackend=bdb");
2640 a4.push_back("-newaddress");
2641 int r4 = RunBitflashChild(strExe, a4);
2642 nFail += Check(r4 == 0 &&
2643 FileExists((d4 + "/wallet.dat").c_str()) &&
2644 !FileExists((d4 + "/wallet.sqlite").c_str()),
2645 "an explicit -walletbackend=bdb creates wallet.dat on a fresh datadir") ? 0 : 1;
2646 }
2647 catch (const std::exception& e)
2648 {
2649 printf(" FAIL exception: %s\n", e.what());
2650 nFail++;
2651 }
2652 catch (...)
2653 {
2654 printf(" FAIL unknown exception\n");
2655 nFail++;
2656 }
2657
2658 DBFlush(true);
2659 SetCurrentDir(cwd);
2660 RemoveTree(tmp);
2661 printf("%s (%d failure%s)\n", nFail == 0 ? "ALL TESTS PASSED" : "TESTS FAILED",
2662 nFail, nFail == 1 ? "" : "s");
2663 fflush(stdout);
2664 return nFail == 0 ? 0 : 1;
2665}
2666
2537static int RunWalletPortabilitySelfTest() 2667static int RunWalletPortabilitySelfTest()
2538{ 2668{
2539 fflush(stdout); 2669 fflush(stdout);
@@ -2576,6 +2706,7 @@ static int RunWalletPortabilitySelfTest()
2576 vCreateArgs.push_back("-datadir=" + strOriginal); 2706 vCreateArgs.push_back("-datadir=" + strOriginal);
2577 vCreateArgs.push_back("-nomanagedtor"); 2707 vCreateArgs.push_back("-nomanagedtor");
2578 vCreateArgs.push_back("-nogui"); 2708 vCreateArgs.push_back("-nogui");
2709 vCreateArgs.push_back("-walletbackend=bdb"); // this suite is about wallet.dat portability
2579 vCreateArgs.push_back("-newphrase"); 2710 vCreateArgs.push_back("-newphrase");
2580 int nCreateRet = RunBitflashChild(strExe, vCreateArgs, NULL, &strCreateOut); 2711 int nCreateRet = RunBitflashChild(strExe, vCreateArgs, NULL, &strCreateOut);
2581 nFail += Check(nCreateRet == 0 && 2712 nFail += Check(nCreateRet == 0 &&
@@ -3265,6 +3396,8 @@ int RunSelfTest(const std::string& name)
3265 return RunWalletEncryptSelfTest(); 3396 return RunWalletEncryptSelfTest();
3266 if (name == "wallet-sqlite-encrypt") 3397 if (name == "wallet-sqlite-encrypt")
3267 return RunWalletSQLiteEncryptSelfTest(); 3398 return RunWalletSQLiteEncryptSelfTest();
3399 if (name == "wallet-backend-default")
3400 return RunWalletBackendDefaultSelfTest();
3268 if (name == "wallet-portability") 3401 if (name == "wallet-portability")
3269 return RunWalletPortabilitySelfTest(); 3402 return RunWalletPortabilitySelfTest();
3270 if (name == "net-message") 3403 if (name == "net-message")
@@ -3281,6 +3414,6 @@ int RunSelfTest(const std::string& name)
3281 return RunManagedTorSelfTest(); 3414 return RunManagedTorSelfTest();
3282 3415
3283 printf("Unknown self-test '%s'\n", name.c_str()); 3416 printf("Unknown self-test '%s'\n", name.c_str());
3284 printf("Known self-tests: wallet-keypool, wallet-hd, wallet-format, wallet-storage-sanity, db-env-reopen, wallet-sqlite, wallet-sqlite-migration, wallet-crypto, wallet-encrypt, wallet-sqlite-encrypt, wallet-portability, net-message, consensus-limits, pool-stratum, parse-money, socks5-proxy, managed-tor\n"); 3417 printf("Known self-tests: wallet-keypool, wallet-hd, wallet-format, wallet-storage-sanity, db-env-reopen, wallet-sqlite, wallet-sqlite-migration, wallet-crypto, wallet-encrypt, wallet-sqlite-encrypt, wallet-backend-default, wallet-portability, net-message, consensus-limits, pool-stratum, parse-money, socks5-proxy, managed-tor\n");
3285 return 1; 3418 return 1;
3286} 3419}