diff options
Diffstat (limited to 'src/main_gui.cpp')
| -rw-r--r-- | src/main_gui.cpp | 66 |
1 files changed, 62 insertions, 4 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp index ee875c7..4d77533 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,59 @@ 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 | if (strWalletBackend == "sqlite") | ||
| 629 | { | ||
| 630 | // Opt-in, experimental. The node runs on <datadir>/wallet.sqlite and | ||
| 631 | // never opens wallet.dat, but the user has to have exported one | ||
| 632 | // first -- there is no silent migration, and wallet.dat is left | ||
| 633 | // exactly where it is so a plain restart goes back to it. | ||
| 634 | AttachTerminal(); | ||
| 635 | string strSQLitePath = GetAppDir() + "/wallet.sqlite"; | ||
| 636 | if (!FileExists(strSQLitePath.c_str())) | ||
| 637 | { | ||
| 638 | string strGuide = strprintf( | ||
| 639 | "No SQLite wallet was found at\n" | ||
| 640 | " %s\n\n" | ||
| 641 | "The SQLite wallet backend is opt-in and needs an exported\n" | ||
| 642 | "wallet first. Your Berkeley DB wallet.dat is not touched by\n" | ||
| 643 | "any of this.\n\n" | ||
| 644 | " Step 1 Export your existing wallet to SQLite:\n" | ||
| 645 | " bitflash -walletsqliteexport=\"%s\"\n" | ||
| 646 | " Step 2 Start again with the SQLite backend:\n" | ||
| 647 | " bitflash -walletbackend=sqlite\n\n" | ||
| 648 | "To go back to Berkeley DB at any time, just start without\n" | ||
| 649 | "-walletbackend=sqlite. wallet.dat is still your wallet.", | ||
| 650 | strSQLitePath.c_str(), strSQLitePath.c_str()); | ||
| 651 | FatalStartupError(fHeadlessStartup, | ||
| 652 | "The SQLite wallet backend needs an exported wallet first.", | ||
| 653 | strGuide); | ||
| 654 | return 1; | ||
| 655 | } | ||
| 656 | |||
| 657 | if (!LoadWalletFromSQLiteRuntime(strSQLitePath)) | ||
| 658 | { | ||
| 659 | FatalStartupError(fHeadlessStartup, | ||
| 660 | "Cannot open the SQLite wallet backend.", | ||
| 661 | strWalletLoadError); | ||
| 662 | return 1; | ||
| 663 | } | ||
| 664 | |||
| 665 | fprintf(stderr, | ||
| 666 | "Wallet backend: SQLite (experimental)\n" | ||
| 667 | " %s\n" | ||
| 668 | "Your Berkeley DB wallet.dat is left untouched. Restart without\n" | ||
| 669 | "-walletbackend=sqlite to go back to it.\n", | ||
| 670 | strSQLitePath.c_str()); | ||
| 671 | fflush(stderr); | ||
| 672 | // Fall through and run the node normally: every CWalletDB read, | ||
| 673 | // write, and erase now routes to this SQLite file. | ||
| 674 | } | ||
| 675 | else if (!strWalletSQLite.empty()) | ||
| 624 | { | 676 | { |
| 625 | AttachTerminal(); | 677 | AttachTerminal(); |
| 626 | if (!LoadWalletFromSQLite(strWalletSQLite)) | 678 | if (!LoadWalletFromSQLite(strWalletSQLite)) |
| @@ -638,8 +690,7 @@ int main(int argc, char* argv[]) | |||
| 638 | DBFlush(true); | 690 | DBFlush(true); |
| 639 | return 0; | 691 | return 0; |
| 640 | } | 692 | } |
| 641 | 693 | else if (!LoadWallet()) | |
| 642 | if (!LoadWallet()) | ||
| 643 | { | 694 | { |
| 644 | // LoadWallet() explains itself into strWalletLoadError when it | 695 | // LoadWallet() explains itself into strWalletLoadError when it |
| 645 | // knows why -- an unsupported wallet format, for one, which is the | 696 | // knows why -- an unsupported wallet format, for one, which is the |
| @@ -650,7 +701,9 @@ int main(int argc, char* argv[]) | |||
| 650 | } | 701 | } |
| 651 | 702 | ||
| 652 | // After the block index, so there is a chain to compare the wallet | 703 | // After the block index, so there is a chain to compare the wallet |
| 653 | // against, and before anything reports a balance. | 704 | // against, and before anything reports a balance. Works on either |
| 705 | // backend: RescanSpentFlags writes corrected flags through CWalletDB, | ||
| 706 | // which routes to SQLite when that backend is active. | ||
| 654 | RescanSpentFlags(); | 707 | RescanSpentFlags(); |
| 655 | } | 708 | } |
| 656 | catch (const std::exception& e) | 709 | catch (const std::exception& e) |
| @@ -894,6 +947,10 @@ int main(int argc, char* argv[]) | |||
| 894 | // called here, which is why a wallet.dat copied elsewhere would not | 947 | // called here, which is why a wallet.dat copied elsewhere would not |
| 895 | // open -- issue #40. Not optional. | 948 | // open -- issue #40. Not optional. |
| 896 | DBFlush(true); | 949 | DBFlush(true); |
| 950 | // Checkpoint and close the SQLite wallet backend if one is active. A | ||
| 951 | // no-op on the Berkeley DB path. Safe to kill before this runs: WAL + | ||
| 952 | // synchronous=FULL already made every committed write durable. | ||
| 953 | WalletSQLiteRuntimeClose(); | ||
| 897 | #ifdef _WIN32 | 954 | #ifdef _WIN32 |
| 898 | // wallet.dat is safely flushed and closed now; let a pending console | 955 | // wallet.dat is safely flushed and closed now; let a pending console |
| 899 | // control handler (CLOSE/LOGOFF/SHUTDOWN) return so the OS can finish. | 956 | // control handler (CLOSE/LOGOFF/SHUTDOWN) return so the OS can finish. |
| @@ -910,6 +967,7 @@ int main(int argc, char* argv[]) | |||
| 910 | StopNode(); | 967 | StopNode(); |
| 911 | BtfStopManagedTor(); | 968 | BtfStopManagedTor(); |
| 912 | DBFlush(true); | 969 | DBFlush(true); |
| 970 | WalletSQLiteRuntimeClose(); | ||
| 913 | return ret; | 971 | return ret; |
| 914 | #endif | 972 | #endif |
| 915 | } | 973 | } |