diff options
Diffstat (limited to 'src/main_gui.cpp')
| -rw-r--r-- | src/main_gui.cpp | 81 |
1 files changed, 77 insertions, 4 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index ee875c7..4be4995 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp | |||
| @@ -190,6 +190,8 @@ static void PrintUsage() | |||
| 190 | printf(" /walletsqliteloadcheck=FILE\n"); | 190 | printf(" /walletsqliteloadcheck=FILE\n"); |
| 191 | printf(" (parse a SQLite export like the wallet loader)\n"); | 191 | printf(" (parse a SQLite export like the wallet loader)\n"); |
| 192 | printf(" /walletsqlite=FILE (stage-load a SQLite wallet export, then exit)\n"); | 192 | printf(" /walletsqlite=FILE (stage-load a SQLite wallet export, then exit)\n"); |
| 193 | printf(" /walletbackend=sqlite (opt-in: run the node on <datadir>/wallet.sqlite\n"); | ||
| 194 | printf(" instead of wallet.dat; export one first)\n"); | ||
| 193 | printf(" /rescan (walk the chain for coins this wallet owns\n"); | 195 | printf(" /rescan (walk the chain for coins this wallet owns\n"); |
| 194 | printf(" but never recorded, then exit)\n"); | 196 | printf(" but never recorded, then exit)\n"); |
| 195 | printf("\n"); | 197 | printf("\n"); |
| @@ -618,9 +620,74 @@ int main(int argc, char* argv[]) | |||
| 618 | printf("Loading wallet...\n"); | 620 | printf("Loading wallet...\n"); |
| 619 | try | 621 | try |
| 620 | { | 622 | { |
| 623 | string strWalletBackend = | ||
| 624 | argval2(argc, argv, "/walletbackend", "-walletbackend"); | ||
| 621 | string strWalletSQLite = | 625 | string strWalletSQLite = |
| 622 | argval2(argc, argv, "/walletsqlite", "-walletsqlite"); | 626 | argval2(argc, argv, "/walletsqlite", "-walletsqlite"); |
| 623 | if (!strWalletSQLite.empty()) | 627 | |
| 628 | // A misspelled backend must not fall through to Berkeley DB silently -- | ||
| 629 | // someone who typed -walletbackend=sqlit meant to run on SQLite, and | ||
| 630 | // opening wallet.dat instead of telling them is the wrong surprise. | ||
| 631 | if (!strWalletBackend.empty() && | ||
| 632 | strWalletBackend != "sqlite" && strWalletBackend != "bdb") | ||
| 633 | { | ||
| 634 | AttachTerminal(); | ||
| 635 | FatalStartupError(fHeadlessStartup, | ||
| 636 | strprintf("Unknown wallet backend '%s'.", strWalletBackend.c_str()), | ||
| 637 | "Use -walletbackend=sqlite for the experimental SQLite backend, " | ||
| 638 | "or omit -walletbackend (or -walletbackend=bdb) to use the " | ||
| 639 | "default Berkeley DB wallet.dat."); | ||
| 640 | return 1; | ||
| 641 | } | ||
| 642 | |||
| 643 | if (strWalletBackend == "sqlite") | ||
| 644 | { | ||
| 645 | // Opt-in, experimental. The node runs on <datadir>/wallet.sqlite and | ||
| 646 | // never opens wallet.dat, but the user has to have exported one | ||
| 647 | // first -- there is no silent migration, and wallet.dat is left | ||
| 648 | // exactly where it is so a plain restart goes back to it. | ||
| 649 | AttachTerminal(); | ||
| 650 | string strSQLitePath = GetAppDir() + "/wallet.sqlite"; | ||
| 651 | if (!FileExists(strSQLitePath.c_str())) | ||
| 652 | { | ||
| 653 | string strGuide = strprintf( | ||
| 654 | "No SQLite wallet was found at\n" | ||
| 655 | " %s\n\n" | ||
| 656 | "The SQLite wallet backend is opt-in and needs an exported\n" | ||
| 657 | "wallet first. Your Berkeley DB wallet.dat is not touched by\n" | ||
| 658 | "any of this.\n\n" | ||
| 659 | " Step 1 Export your existing wallet to SQLite:\n" | ||
| 660 | " bitflash -walletsqliteexport=\"%s\"\n" | ||
| 661 | " Step 2 Start again with the SQLite backend:\n" | ||
| 662 | " bitflash -walletbackend=sqlite\n\n" | ||
| 663 | "To go back to Berkeley DB at any time, just start without\n" | ||
| 664 | "-walletbackend=sqlite. wallet.dat is still your wallet.", | ||
| 665 | strSQLitePath.c_str(), strSQLitePath.c_str()); | ||
| 666 | FatalStartupError(fHeadlessStartup, | ||
| 667 | "The SQLite wallet backend needs an exported wallet first.", | ||
| 668 | strGuide); | ||
| 669 | return 1; | ||
| 670 | } | ||
| 671 | |||
| 672 | if (!LoadWalletFromSQLiteRuntime(strSQLitePath)) | ||
| 673 | { | ||
| 674 | FatalStartupError(fHeadlessStartup, | ||
| 675 | "Cannot open the SQLite wallet backend.", | ||
| 676 | strWalletLoadError); | ||
| 677 | return 1; | ||
| 678 | } | ||
| 679 | |||
| 680 | fprintf(stderr, | ||
| 681 | "Wallet backend: SQLite (experimental)\n" | ||
| 682 | " %s\n" | ||
| 683 | "Your Berkeley DB wallet.dat is left untouched. Restart without\n" | ||
| 684 | "-walletbackend=sqlite to go back to it.\n", | ||
| 685 | strSQLitePath.c_str()); | ||
| 686 | fflush(stderr); | ||
| 687 | // Fall through and run the node normally: every CWalletDB read, | ||
| 688 | // write, and erase now routes to this SQLite file. | ||
| 689 | } | ||
| 690 | else if (!strWalletSQLite.empty()) | ||
| 624 | { | 691 | { |
| 625 | AttachTerminal(); | 692 | AttachTerminal(); |
| 626 | if (!LoadWalletFromSQLite(strWalletSQLite)) | 693 | if (!LoadWalletFromSQLite(strWalletSQLite)) |
| @@ -638,8 +705,7 @@ int main(int argc, char* argv[]) | |||
| 638 | DBFlush(true); | 705 | DBFlush(true); |
| 639 | return 0; | 706 | return 0; |
| 640 | } | 707 | } |
| 641 | 708 | else if (!LoadWallet()) | |
| 642 | if (!LoadWallet()) | ||
| 643 | { | 709 | { |
| 644 | // LoadWallet() explains itself into strWalletLoadError when it | 710 | // LoadWallet() explains itself into strWalletLoadError when it |
| 645 | // knows why -- an unsupported wallet format, for one, which is the | 711 | // knows why -- an unsupported wallet format, for one, which is the |
| @@ -650,7 +716,9 @@ int main(int argc, char* argv[]) | |||
| 650 | } | 716 | } |
| 651 | 717 | ||
| 652 | // After the block index, so there is a chain to compare the wallet | 718 | // After the block index, so there is a chain to compare the wallet |
| 653 | // against, and before anything reports a balance. | 719 | // against, and before anything reports a balance. Works on either |
| 720 | // backend: RescanSpentFlags writes corrected flags through CWalletDB, | ||
| 721 | // which routes to SQLite when that backend is active. | ||
| 654 | RescanSpentFlags(); | 722 | RescanSpentFlags(); |
| 655 | } | 723 | } |
| 656 | catch (const std::exception& e) | 724 | catch (const std::exception& e) |
| @@ -894,6 +962,10 @@ int main(int argc, char* argv[]) | |||
| 894 | // called here, which is why a wallet.dat copied elsewhere would not | 962 | // called here, which is why a wallet.dat copied elsewhere would not |
| 895 | // open -- issue #40. Not optional. | 963 | // open -- issue #40. Not optional. |
| 896 | DBFlush(true); | 964 | DBFlush(true); |
| 965 | // Checkpoint and close the SQLite wallet backend if one is active. A | ||
| 966 | // no-op on the Berkeley DB path. Safe to kill before this runs: WAL + | ||
| 967 | // synchronous=FULL already made every committed write durable. | ||
| 968 | WalletSQLiteRuntimeClose(); | ||
| 897 | #ifdef _WIN32 | 969 | #ifdef _WIN32 |
| 898 | // wallet.dat is safely flushed and closed now; let a pending console | 970 | // wallet.dat is safely flushed and closed now; let a pending console |
| 899 | // control handler (CLOSE/LOGOFF/SHUTDOWN) return so the OS can finish. | 971 | // control handler (CLOSE/LOGOFF/SHUTDOWN) return so the OS can finish. |
| @@ -910,6 +982,7 @@ int main(int argc, char* argv[]) | |||
| 910 | StopNode(); | 982 | StopNode(); |
| 911 | BtfStopManagedTor(); | 983 | BtfStopManagedTor(); |
| 912 | DBFlush(true); | 984 | DBFlush(true); |
| 985 | WalletSQLiteRuntimeClose(); | ||
| 913 | return ret; | 986 | return ret; |
| 914 | #endif | 987 | #endif |
| 915 | } | 988 | } |