upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/db.cpp
diff options
context:
space:
mode:
authorBitflash <admin@bitflash.network>2026-08-18 16:35:42 -0300
committerBitflash <admin@bitflash.network>2026-08-18 16:35:42 -0300
commitb1c6d19fe2855c30d839dbc484165da58a8ee120 (patch)
treec320e5c1f6e486affdf255a1a4ac806a01b9da7c /src/db.cpp
parentf3fb7ce6759ac98a7cc39d586fc2824982c74acd (diff)
parent477d57b9a01102b6f79ad9b10b2dcfd280faa1cb (diff)
Merge pull request 'wallet/gui: SQLite is the default for new wallets + a first-run conversion wizard' (#62) from wallet-sqlite-default into main
Diffstat (limited to 'src/db.cpp')
-rw-r--r--src/db.cpp91
1 files changed, 89 insertions, 2 deletions
diff --git a/src/db.cpp b/src/db.cpp
index aafc0f9..949865f 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -101,10 +101,13 @@ bool WalletSQLiteRuntimeActive()
101 return pWalletSQLiteRuntime != NULL; 101 return pWalletSQLiteRuntime != NULL;
102} 102}
103 103
104bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet) 104bool WalletSQLiteRuntimeOpen(const string& strPath, string& strErrorRet, bool fMustExist)
105{ 105{
106 strErrorRet.clear(); 106 strErrorRet.clear();
107 if (!FileExists(strPath.c_str())) 107 // Callers that load an existing wallet want the clear "does not exist"
108 // message rather than silently creating a blank one; the create path passes
109 // fMustExist=false so Open() (SQLITE_OPEN_CREATE) can make a fresh file.
110 if (fMustExist && !FileExists(strPath.c_str()))
108 { 111 {
109 strErrorRet = strprintf("SQLite wallet does not exist: %s", 112 strErrorRet = strprintf("SQLite wallet does not exist: %s",
110 strPath.c_str()); 113 strPath.c_str());
@@ -230,6 +233,47 @@ bool WalletSQLiteRuntimeCheckpoint(string& strErrorRet)
230 return pWalletSQLiteRuntime->Checkpoint(strErrorRet); 233 return pWalletSQLiteRuntime->Checkpoint(strErrorRet);
231} 234}
232 235
236// The persistent record of which backend this datadir uses, so the choice
237// survives a restart without a command-line flag. A plain text file holding
238// "sqlite" or "bdb" -- visible and hand-editable on purpose, no hidden state.
239static string WalletBackendMarkerPath()
240{
241 return GetAppDir() + "/wallet-backend";
242}
243
244string ReadWalletBackendMarker()
245{
246 FILE* pf = fopen(WalletBackendMarkerPath().c_str(), "rb");
247 if (!pf)
248 return "";
249 char buf[16] = {0};
250 size_t n = fread(buf, 1, sizeof(buf) - 1, pf);
251 fclose(pf);
252 string s(buf, n);
253 while (!s.empty() && isspace((unsigned char)s[s.size() - 1]))
254 s.erase(s.size() - 1);
255 while (!s.empty() && isspace((unsigned char)s[0]))
256 s.erase(0, 1);
257 if (s == "sqlite" || s == "bdb")
258 return s;
259 return "";
260}
261
262bool WriteWalletBackendMarker(const string& strBackend)
263{
264 if (strBackend != "sqlite" && strBackend != "bdb")
265 return false;
266 FILE* pf = fopen(WalletBackendMarkerPath().c_str(), "wb");
267 if (!pf)
268 return false;
269 bool fOk = fwrite(strBackend.c_str(), 1, strBackend.size(), pf) == strBackend.size();
270 if (fputc('\n', pf) == EOF)
271 fOk = false;
272 if (fclose(pf) != 0)
273 fOk = false;
274 return fOk;
275}
276
233 277
234CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL) 278CDB::CDB(const char* pszFile, const char* pszMode, bool fTxn) : pdb(NULL)
235{ 279{
@@ -1609,6 +1653,49 @@ bool LoadWalletFromSQLiteRuntime(const string& strPath)
1609 return true; 1653 return true;
1610} 1654}
1611 1655
1656// Create a brand-new wallet directly in the SQLite backend. For a fresh install
1657// where SQLite is the default there is no wallet.dat to export from, so open a
1658// new wallet.sqlite (Open() creates the file and its schema) and let
1659// FinishLoadedWallet mint the first default key straight into it -- the same
1660// call the Berkeley DB create path uses, so a new wallet is identical either
1661// way. Refuses to touch an existing file, and cleans up on failure so a broken
1662// half-initialised wallet.sqlite is never left for the next start to load.
1663bool CreateNewSQLiteWallet(const string& strPath)
1664{
1665 strWalletLoadError.clear();
1666
1667 if (FileExists(strPath.c_str()))
1668 {
1669 strWalletLoadError = strprintf("SQLite wallet already exists: %s",
1670 strPath.c_str());
1671 printf("CreateNewSQLiteWallet: %s\n", strWalletLoadError.c_str());
1672 return false;
1673 }
1674
1675 string strError;
1676 if (!WalletSQLiteRuntimeOpen(strPath, strError, false))
1677 {
1678 strWalletLoadError = strError;
1679 printf("CreateNewSQLiteWallet: cannot create SQLite wallet: %s\n",
1680 strError.c_str());
1681 return false;
1682 }
1683
1684 vector<unsigned char> vchNoDefaultKey;
1685 if (!FinishLoadedWallet(vchNoDefaultKey, true))
1686 {
1687 WalletSQLiteRuntimeClose();
1688 remove(strPath.c_str());
1689 remove((strPath + "-wal").c_str());
1690 remove((strPath + "-shm").c_str());
1691 if (strWalletLoadError.empty())
1692 strWalletLoadError = "could not initialise the new SQLite wallet";
1693 return false;
1694 }
1695
1696 return true;
1697}
1698
1612 1699
1613// Write a copy of wallet.dat that can be opened anywhere. 1700// Write a copy of wallet.dat that can be opened anywhere.
1614// 1701//