upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/walletcmd.cpp
diff options
context:
space:
mode:
authorBitflash <admin@bitflash.network>2026-08-14 17:15:59 -0300
committerBitflash <admin@bitflash.network>2026-08-14 17:15:59 -0300
commit3227564b26d0a9c5b8f1bcc5e21bb572a2968e5f (patch)
treea72cd83e2981deb95a2f17d0e02a7dfd64ab2eca /src/walletcmd.cpp
parent35f6c752f9f879ca94478985978e4a9c862ede3e (diff)
parentdf129cc672b9b894ff2558d3e9361ddab082433d (diff)
Merge pull request 'wallet: restore BDB wallets from SQLite exports' (#51) from wallet-sqlite-restore into main
Diffstat (limited to 'src/walletcmd.cpp')
-rw-r--r--src/walletcmd.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/walletcmd.cpp b/src/walletcmd.cpp
index 36f6783..d1bad98 100644
--- a/src/walletcmd.cpp
+++ b/src/walletcmd.cpp
@@ -844,6 +844,52 @@ public:
844 } 844 }
845}; 845};
846 846
847class CWalletRawRestoreDB : public CWalletDB
848{
849public:
850 CWalletRawRestoreDB(const char* pszMode="cr+", bool fTxn=true)
851 : CWalletDB(pszMode, fTxn) { }
852
853 bool WriteRaw(CDataStream ssKey, CDataStream ssValue)
854 {
855 if (!pdb || ssKey.empty())
856 return false;
857
858 Dbt datKey((void*)&ssKey[0], ssKey.size());
859 Dbt datValue(ssValue.empty() ? NULL : (void*)&ssValue[0],
860 ssValue.size());
861 int ret = pdb->put(GetTxn(), &datKey, &datValue, 0);
862
863 memset(datKey.get_data(), 0, datKey.get_size());
864 if (datValue.get_data())
865 memset(datValue.get_data(), 0, datValue.get_size());
866 return ret == 0;
867 }
868};
869
870class CWalletSQLiteRestoreVisitor : public CWalletRecordVisitor
871{
872public:
873 CWalletRawRestoreDB& db;
874 int& nCopied;
875
876 CWalletSQLiteRestoreVisitor(CWalletRawRestoreDB& dbIn, int& nCopiedIn)
877 : db(dbIn), nCopied(nCopiedIn) { }
878
879 bool VisitWalletRecord(const CDataStream& ssKey,
880 const CDataStream& ssValue,
881 string& strErrorRet)
882 {
883 if (!db.WriteRaw(ssKey, ssValue))
884 {
885 strErrorRet = "could not write raw wallet record";
886 return false;
887 }
888 nCopied++;
889 return true;
890 }
891};
892
847} // namespace 893} // namespace
848 894
849int CmdWalletSQLiteExport(const std::string& strDest) 895int CmdWalletSQLiteExport(const std::string& strDest)
@@ -994,6 +1040,86 @@ int CmdWalletSQLiteVerify(const std::string& strPath)
994 return 2; 1040 return 2;
995} 1041}
996 1042
1043int CmdWalletSQLiteRestore(const std::string& strPath)
1044{
1045 AttachTerminal();
1046
1047 if (strPath.empty())
1048 {
1049 fprintf(stderr, "Missing SQLite wallet export path.\n");
1050 return 1;
1051 }
1052 if (!FileExists(strPath.c_str()))
1053 {
1054 fprintf(stderr, "SQLite wallet export does not exist: %s\n",
1055 strPath.c_str());
1056 return 1;
1057 }
1058
1059 string strWalletPath = GetAppDir() + "/wallet.dat";
1060 if (FileExists(strWalletPath.c_str()))
1061 {
1062 fprintf(stderr, "Refusing to overwrite existing wallet.dat: %s\n",
1063 strWalletPath.c_str());
1064 return 1;
1065 }
1066
1067 string strError;
1068 CWalletDBSQLite sqlite;
1069 if (!sqlite.Open(strPath, strError))
1070 {
1071 fprintf(stderr, "Cannot open SQLite wallet export: %s\n", strError.c_str());
1072 return 1;
1073 }
1074
1075 int nSQLiteRecords = 0;
1076 if (!sqlite.CountRecords(nSQLiteRecords, strError))
1077 {
1078 fprintf(stderr, "Cannot count SQLite wallet export records: %s\n",
1079 strError.c_str());
1080 return 1;
1081 }
1082 if (nSQLiteRecords <= 0)
1083 {
1084 fprintf(stderr, "SQLite wallet export contains no records.\n");
1085 return 2;
1086 }
1087
1088 CWalletRawRestoreDB bdb("cr+", true);
1089 if (!bdb.TxnBegin())
1090 {
1091 fprintf(stderr, "Cannot begin Berkeley DB restore transaction.\n");
1092 return 1;
1093 }
1094
1095 int nCopied = 0;
1096 CWalletSQLiteRestoreVisitor visitor(bdb, nCopied);
1097 if (!sqlite.ScanRecords(visitor, strError))
1098 {
1099 bdb.TxnAbort();
1100 fprintf(stderr, "Cannot restore SQLite wallet export: %s\n",
1101 strError.c_str());
1102 return 1;
1103 }
1104 if (nCopied != nSQLiteRecords)
1105 {
1106 bdb.TxnAbort();
1107 fprintf(stderr, "SQLite wallet restore copied %d records, expected %d.\n",
1108 nCopied, nSQLiteRecords);
1109 return 2;
1110 }
1111 if (!bdb.TxnCommit())
1112 {
1113 fprintf(stderr, "Cannot commit Berkeley DB restore transaction.\n");
1114 return 1;
1115 }
1116
1117 printf("SQLite wallet export restored to wallet.dat\n");
1118 printf(" records restored: %d\n", nCopied);
1119 fflush(stdout);
1120 return 0;
1121}
1122
997int CmdEncryptWallet(const std::string& strPassphrase) 1123int CmdEncryptWallet(const std::string& strPassphrase)
998{ 1124{
999 AttachTerminal(); 1125 AttachTerminal();