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 <btf01@proton.me>2026-08-01 14:48:12 -0300
committerGitHub <noreply@github.com>2026-08-01 14:48:12 -0300
commitae81fa37123730982c4e054d7433c9d0c944a373 (patch)
tree771c0e5ca58c476a0a6ba1138fef3efeaf767524 /src
parent9da2183bb16e4c32cafbb71eeadc7f112b48ab05 (diff)
wallet: keep the default backup out of the directory it protects (#90)
Two follow-ups to #89. The default backup path was inside the data directory -- same disk, same folder the README says to copy wholesale, same folder the user eventually deletes, which is the moment the backup was for. It now defaults to the home directory and the dialog says so when a path under the data directory is chosen anyway. And nLastWalletBackup was written by the GUI, so anyone backing up with /backupwallet -- the method the README documents first -- was told forever that they had never backed up. BackupWallet records it now, so both paths count.
Diffstat (limited to 'src')
-rw-r--r--src/db.cpp9
-rw-r--r--src/gui.cpp55
2 files changed, 61 insertions, 3 deletions
diff --git a/src/db.cpp b/src/db.cpp
index 7763af8..d482c5a 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -834,6 +834,15 @@ bool BackupWallet(const string& strDest)
834 { return error("BackupWallet() : %s\n", e.what()); } 834 { return error("BackupWallet() : %s\n", e.what()); }
835 } 835 }
836 836
837 // Recorded here rather than by whoever called, so that a backup taken with
838 // /backupwallet counts as much as one taken from the GUI. When the GUI
839 // wrote this itself, anyone following the README -- which documents the
840 // command line first -- was told forever that they had never backed up.
841 // Outside the cs_db block above: this opens the wallet for writing, and
842 // there is no reason to do that while holding the database lock.
843 try { CWalletDB().WriteSetting("nLastWalletBackup", (int64)GetTime()); }
844 catch (...) { } // the backup is written; failing to note it is not fatal
845
837 printf("BackupWallet() : wrote %s\n", strDest.c_str()); 846 printf("BackupWallet() : wrote %s\n", strDest.c_str());
838 return true; 847 return true;
839} 848}
diff --git a/src/gui.cpp b/src/gui.cpp
index df61bb1..51b5d5f 100644
--- a/src/gui.cpp
+++ b/src/gui.cpp
@@ -125,9 +125,47 @@ static std::string BackupTimeSuffix()
125 return strprintf("%lld", (long long)GetTime()); 125 return strprintf("%lld", (long long)GetTime());
126} 126}
127 127
128// Where to put a backup by default.
129//
130// Not the data directory. A copy that lives in the folder it is meant to
131// outlive is not a backup: same disk, same directory the README tells people to
132// copy wholesale, and the same directory they are eventually going to delete --
133// which is the moment the backup was for. The home directory is not off-site
134// either, but it survives the one accident this file exists to survive.
135static std::string DefaultBackupDir()
136{
137#ifdef _WIN32
138 const char* pszHome = getenv("USERPROFILE");
139#else
140 const char* pszHome = getenv("HOME");
141#endif
142 if (pszHome && *pszHome)
143 return std::string(pszHome);
144 return GetAppDir(); // nothing better available; the warning below still fires
145}
146
147// True when a path sits inside the data directory, so the dialog can say so.
148static bool PathIsInsideDataDir(const std::string& strPath)
149{
150 std::string strDir = GetAppDir();
151 if (strPath.size() < strDir.size())
152 return false;
153 std::string a = strPath.substr(0, strDir.size());
154 // Windows paths are case-insensitive and mix separators; compare loosely.
155 for (size_t i = 0; i < a.size(); i++)
156 {
157 char c1 = a[i], c2 = strDir[i];
158 if (c1 == '\\') c1 = '/';
159 if (c2 == '\\') c2 = '/';
160 if (tolower((unsigned char)c1) != tolower((unsigned char)c2))
161 return false;
162 }
163 return true;
164}
165
128static void SetDefaultBackupPath() 166static void SetDefaultBackupPath()
129{ 167{
130 std::string path = GetAppDir() + "/wallet-backup-" + BackupTimeSuffix() + ".dat"; 168 std::string path = DefaultBackupDir() + "/wallet-backup-" + BackupTimeSuffix() + ".dat";
131 strncpy(g_backupPath, path.c_str(), sizeof(g_backupPath)-1); 169 strncpy(g_backupPath, path.c_str(), sizeof(g_backupPath)-1);
132 g_backupPath[sizeof(g_backupPath)-1] = '\0'; 170 g_backupPath[sizeof(g_backupPath)-1] = '\0';
133} 171}
@@ -899,6 +937,16 @@ static void DrawWalletSafetyDialog()
899 ImGui::SetNextItemWidth(-1.0f); 937 ImGui::SetNextItemWidth(-1.0f);
900 ImGui::InputText("##backup-path", g_backupPath, sizeof(g_backupPath)); 938 ImGui::InputText("##backup-path", g_backupPath, sizeof(g_backupPath));
901 939
940 if (PathIsInsideDataDir(g_backupPath))
941 {
942 ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.75f, 0.25f, 1.0f));
943 ImGui::TextWrapped(
944 "This path is inside the data directory. A backup kept there is lost "
945 "with the thing it was protecting -- put it on another disk, or at "
946 "least somewhere you would not delete along with the node's files.");
947 ImGui::PopStyleColor();
948 }
949
902 if (ImGui::Button("Use new default name", ImVec2(170.0f, 0.0f))) 950 if (ImGui::Button("Use new default name", ImVec2(170.0f, 0.0f)))
903 SetDefaultBackupPath(); 951 SetDefaultBackupPath();
904 ImGui::SameLine(); 952 ImGui::SameLine();
@@ -922,8 +970,9 @@ static void DrawWalletSafetyDialog()
922 TopUpKeyPool(); 970 TopUpKeyPool();
923 if (BackupWallet(path)) 971 if (BackupWallet(path))
924 { 972 {
925 g_lastWalletBackup = GetTime(); 973 // BackupWallet records the time itself, so a backup taken
926 CWalletDB().WriteSetting("nLastWalletBackup", g_lastWalletBackup); 974 // with /backupwallet counts the same as one taken here.
975 CWalletDB("r").ReadSetting("nLastWalletBackup", g_lastWalletBackup);
927 g_backupStatus = "Backup written: " + path; 976 g_backupStatus = "Backup written: " + path;
928 SetDefaultBackupPath(); 977 SetDefaultBackupPath();
929 } 978 }