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/selftest.cpp | |
| 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/selftest.cpp')
| -rw-r--r-- | src/selftest.cpp | 135 |
1 files changed, 134 insertions, 1 deletions
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 | } |