upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/main_gui.cpp
diff options
context:
space:
mode:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-09-01 17:16:04 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-09-01 17:19:47 +0000
commit1017644bc8d4bf183086ffb816c5e3f18068568e (patch)
tree040e468018ad067811be744f55091294666f3fea /src/main_gui.cpp
parentb4f0bc693ef7175702f82bcb2110b627922e8cbd (diff)
wallet: refuse to mint a wallet a headless node never asked for
v1.2.20 makes SQLite the default backend for a datadir that holds no wallet. On a desktop that is a first run. On a headless node it is usually a fault -- the datadir is not mounted, or wallet.dat was caught mid-rename by a backup -- and the new default turns that fault into a silent loss of custody rather than a loud failure. The damage is not the empty wallet, it is the marker. Creating the wallet also writes <datadir>/wallet-backend = sqlite, and every later start reads that marker first: putting the real wallet.dat back no longer does anything, because the node stays on the empty SQLite wallet it made. 1.2.19 had the same fail-open on a missing wallet, but it created a wallet.dat, and restoring the backup over it recovered the funds. That runbook stops working here. So refuse when the startup is headless and no wallet of either kind is present, and say which flag makes it deliberate: /createwallet to start a new one, or /walletbackend=bdb for the Berkeley DB path. A node that meant to create a wallet says so; a node that lost its datadir gets an error instead of a fresh identity and a re-paid ledger. Upstream keeps the old behaviour; this is a fork divergence, and the three findings that would gate enabling the SQLite backend at all -- the non-atomic backend marker, WriteHDMaster's connection-wide transaction, and the encrypt-swap crash window -- remain open against upstream.
Diffstat (limited to 'src/main_gui.cpp')
-rw-r--r--src/main_gui.cpp29
1 files changed, 29 insertions, 0 deletions
diff --git a/src/main_gui.cpp b/src/main_gui.cpp
index 2743429..25cde1c 100644
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -196,6 +196,9 @@ static void PrintUsage()
196 printf(" /walletsqlite=FILE (stage-load a SQLite wallet export, then exit)\n"); 196 printf(" /walletsqlite=FILE (stage-load a SQLite wallet export, then exit)\n");
197 printf(" /walletbackend=sqlite (opt-in: run the node on <datadir>/wallet.sqlite\n"); 197 printf(" /walletbackend=sqlite (opt-in: run the node on <datadir>/wallet.sqlite\n");
198 printf(" instead of wallet.dat; export one first)\n"); 198 printf(" instead of wallet.dat; export one first)\n");
199 printf(" /createwallet (headless only: permit creating a new wallet in a\n");
200 printf(" datadir that has none -- otherwise refused, since\n");
201 printf(" a missing wallet is usually a mount/backup fault)\n");
199 printf(" /rescan (walk the chain for coins this wallet owns\n"); 202 printf(" /rescan (walk the chain for coins this wallet owns\n");
200 printf(" but never recorded, then exit)\n"); 203 printf(" but never recorded, then exit)\n");
201 printf("\n"); 204 printf("\n");
@@ -835,6 +838,32 @@ int main(int argc, char* argv[])
835 else { fUseSQLite = true; fCreateSQLite = true; } 838 else { fUseSQLite = true; fCreateSQLite = true; }
836 } 839 }
837 840
841 // A headless node whose datadir holds no wallet of either kind is
842 // far more often an operations fault -- datadir not mounted, or
843 // wallet.dat caught mid-rename by a backup -- than a first run.
844 // Creating one here is not the harmless default it looks like:
845 // success also writes the backend marker, and from then on
846 // restoring the real wallet.dat no longer takes effect, because the
847 // marker keeps the node on the empty wallet it just made. Under
848 // 1.2.19 the same fault created a wallet.dat that a restore
849 // overwrote, so operators could recover by putting the file back.
850 // Refuse instead, and name the flag that makes it deliberate.
851 if (fCreateSQLite && fHeadlessStartup &&
852 !arg(argc, argv, "/createwallet") && !arg(argc, argv, "-createwallet"))
853 {
854 AttachTerminal();
855 fprintf(stderr,
856 "No wallet found in %s\n"
857 "Refusing to create one. On a headless node an absent wallet is\n"
858 "usually a mount or backup fault, and creating one would record a\n"
859 "backend marker that makes restoring the real wallet a no-op.\n"
860 "Pass -createwallet to start a new one deliberately, or\n"
861 "-walletbackend=bdb to run on a Berkeley DB wallet.dat.\n",
862 GetAppDir().c_str());
863 fflush(stderr);
864 return 1;
865 }
866
838 if (fUseSQLite) 867 if (fUseSQLite)
839 { 868 {
840 AttachTerminal(); 869 AttachTerminal();