diff options
| author | bitflash <dev@bitflash.network> | 2026-08-18 16:14:19 -0300 |
|---|---|---|
| committer | bitflash <dev@bitflash.network> | 2026-08-18 16:14:19 -0300 |
| commit | 3f94ec0649f935d00de49ad7b55026317dc64a27 (patch) | |
| tree | e67ff06c8341889cf90cbbc3b835507a90510b64 /src | |
| parent | f3fb7ce6759ac98a7cc39d586fc2824982c74acd (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.cpp | 91 | ||||
| -rw-r--r-- | src/db.h | 5 | ||||
| -rw-r--r-- | src/main_gui.cpp | 80 | ||||
| -rw-r--r-- | src/makefile.mingw | 1 | ||||
| -rw-r--r-- | src/selftest.cpp | 135 |
5 files changed, 301 insertions, 11 deletions
| @@ -101,10 +101,13 @@ bool WalletSQLiteRuntimeActive() | |||
| 101 | return pWalletSQLiteRuntime != NULL; | 101 | return pWalletSQLiteRuntime != NULL; |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet) | 104 | bool 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. | ||
| 239 | static string WalletBackendMarkerPath() | ||
| 240 | { | ||
| 241 | return GetAppDir() + "/wallet-backend"; | ||
| 242 | } | ||
| 243 | |||
| 244 | string 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 | |||
| 262 | bool 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 | ||
| 234 | CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) | 278 | CDB::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. | ||
| 1663 | bool 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 | // |
| @@ -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 | ||
| 359 | bool WalletSQLiteRuntimeActive(); | 359 | bool WalletSQLiteRuntimeActive(); |
| 360 | bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet); | 360 | bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet, bool fMustExist=true); |
| 361 | void WalletSQLiteRuntimeClose(); | 361 | void WalletSQLiteRuntimeClose(); |
| 362 | bool WalletSQLiteRuntimeReadRecord(const vector<unsigned char>& vchKey, | 362 | bool WalletSQLiteRuntimeReadRecord(const vector<unsigned char>& vchKey, |
| 363 | vector<unsigned char>& vchValueRet); | 363 | vector<unsigned char>& vchValueRet); |
| @@ -370,6 +370,9 @@ bool WalletSQLiteRuntimeCommitTxn(); | |||
| 370 | void WalletSQLiteRuntimeRollbackTxn(); | 370 | void WalletSQLiteRuntimeRollbackTxn(); |
| 371 | bool WalletSQLiteRuntimeOpenReadOnly(const string& strPath, string& strErrorRet); | 371 | bool WalletSQLiteRuntimeOpenReadOnly(const string& strPath, string& strErrorRet); |
| 372 | bool WalletSQLiteRuntimeCheckpoint(string& strErrorRet); | 372 | bool WalletSQLiteRuntimeCheckpoint(string& strErrorRet); |
| 373 | string ReadWalletBackendMarker(); | ||
| 374 | bool WriteWalletBackendMarker(const string& strBackend); | ||
| 375 | bool 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. | ||
| 2543 | static 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 | |||
| 2537 | static int RunWalletPortabilitySelfTest() | 2667 | static 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 | } |